/** * Agents API Routes * * 提供 Agent 预设管理的 REST API */ import { Hono } from 'hono'; import { getConfig } from './config.js'; import type { AgentMode, AgentInfo, AgentConfigFile, AgentModelConfig, AgentPermission, } from '@ai-assistant/core'; import { agentRegistry, loadAgentConfig, saveAgentConfig, presetAgents, isPresetAgent, } from '@ai-assistant/core'; // API 响应类型 interface AgentListItem { name: string; description: string; mode: AgentMode; isPreset: boolean; isCustomized: boolean; model?: string; maxSteps?: number; } interface AgentDefaults { maxSteps?: number; model?: AgentModelConfig; permission?: AgentPermission; } export const agentsRouter = new Hono(); // 初始化状态 let initialized = false; /** * 确保 AgentRegistry 已初始化 */ async function ensureRegistryInitialized(): Promise { if (!initialized) { await agentRegistry.init(); initialized = true; } return true; } /** * 将 AgentInfo 转换为 AgentListItem */ function toListItem(agent: AgentInfo, customAgentNames: Set): AgentListItem { const isPresetAgent_ = isPresetAgent(agent.name); return { name: agent.name, description: agent.description, mode: agent.mode, isPreset: isPresetAgent_, isCustomized: customAgentNames.has(agent.name), model: agent.model?.model, maxSteps: agent.maxSteps, }; } /** * GET /agents - 获取所有 Agent 列表 */ agentsRouter.get('/', async (c) => { if (!(await ensureRegistryInitialized())) { return c.json( { success: false, error: 'Failed to initialize agent registry', }, 503 ); } const config = getConfig(); const userConfig = await loadAgentConfig(config.workdir); const customAgentNames = new Set(Object.keys(userConfig?.agents || {})); const agents = agentRegistry.list(); const items = agents.map((agent) => toListItem(agent, customAgentNames)); return c.json({ success: true, data: items, }); }); /** * GET /agents/presets - 获取预设 Agent 列表 */ agentsRouter.get('/presets', async (c) => { const presets = Object.entries(presetAgents).map(([name, agent]) => ({ name, description: agent.description, mode: agent.mode, isPreset: true, isCustomized: false, model: agent.model?.model, maxSteps: agent.maxSteps, })); return c.json({ success: true, data: presets, }); }); /** * GET /agents/defaults - 获取全局默认配置 */ agentsRouter.get('/defaults', async (c) => { const config = getConfig(); const userConfig = await loadAgentConfig(config.workdir); return c.json({ success: true, data: userConfig?.defaults || {}, }); }); /** * PUT /agents/defaults - 更新全局默认配置 */ agentsRouter.put('/defaults', async (c) => { try { const newDefaults = await c.req.json(); const config = getConfig(); // 加载现有配置 let userConfig = await loadAgentConfig(config.workdir); if (!userConfig) { userConfig = {}; } // 更新 defaults userConfig.defaults = newDefaults; // 保存配置 await saveAgentConfig(config.workdir, userConfig); // 重新初始化 registry 以应用新配置 initialized = false; await ensureRegistryInitialized(); return c.json({ success: true, data: newDefaults, }); } catch (error) { return c.json( { success: false, error: error instanceof Error ? error.message : 'Failed to update defaults', }, 500 ); } }); /** * GET /agents/:name - 获取单个 Agent 详情 */ agentsRouter.get('/:name', async (c) => { if (!(await ensureRegistryInitialized())) { return c.json( { success: false, error: 'Failed to initialize agent registry', }, 503 ); } const name = c.req.param('name'); const agent = agentRegistry.get(name); if (!agent) { return c.json( { success: false, error: `Agent '${name}' not found`, }, 404 ); } const config = getConfig(); const userConfig = await loadAgentConfig(config.workdir); const isPresetAgent_ = isPresetAgent(name); const isCustomized = !!(userConfig?.agents && name in userConfig.agents); return c.json({ success: true, data: { ...agent, isPreset: isPresetAgent_, isCustomized, }, }); }); /** * POST /agents - 创建新 Agent */ agentsRouter.post('/', async (c) => { try { const body = await c.req.json<{ name: string } & Omit>(); const { name, ...agentConfig } = body; if (!name || typeof name !== 'string') { return c.json( { success: false, error: 'Agent name is required', }, 400 ); } // 检查名称是否与预设冲突 if (isPresetAgent(name)) { return c.json( { success: false, error: `Cannot create agent with preset name '${name}'. Use PUT to customize a preset.`, }, 400 ); } const config = getConfig(); let userConfig = await loadAgentConfig(config.workdir); if (!userConfig) { userConfig = {}; } if (!userConfig.agents) { userConfig.agents = {}; } // 检查是否已存在 if (name in userConfig.agents) { return c.json( { success: false, error: `Agent '${name}' already exists`, }, 409 ); } // 添加新 Agent userConfig.agents[name] = agentConfig; // 保存配置 await saveAgentConfig(config.workdir, userConfig); // 重新初始化 registry initialized = false; await ensureRegistryInitialized(); const createdAgent = agentRegistry.get(name); return c.json({ success: true, data: createdAgent ? { ...createdAgent, isPreset: false, isCustomized: false, } : { name, ...agentConfig, isPreset: false, isCustomized: false }, }); } catch (error) { return c.json( { success: false, error: error instanceof Error ? error.message : 'Failed to create agent', }, 500 ); } }); /** * PUT /agents/:name - 更新 Agent */ agentsRouter.put('/:name', async (c) => { try { const name = c.req.param('name'); const agentConfig = await c.req.json>(); const config = getConfig(); let userConfig = await loadAgentConfig(config.workdir); if (!userConfig) { userConfig = {}; } if (!userConfig.agents) { userConfig.agents = {}; } // 更新 Agent(支持覆盖预设) userConfig.agents[name] = agentConfig; // 保存配置 await saveAgentConfig(config.workdir, userConfig); // 重新初始化 registry initialized = false; await ensureRegistryInitialized(); const updatedAgent = agentRegistry.get(name); const isPresetAgent_ = isPresetAgent(name); return c.json({ success: true, data: updatedAgent ? { ...updatedAgent, isPreset: isPresetAgent_, isCustomized: true, } : { name, ...agentConfig, isPreset: isPresetAgent_, isCustomized: true }, }); } catch (error) { return c.json( { success: false, error: error instanceof Error ? error.message : 'Failed to update agent', }, 500 ); } }); /** * DELETE /agents/:name - 删除 Agent */ agentsRouter.delete('/:name', async (c) => { try { const name = c.req.param('name'); const config = getConfig(); const userConfig = await loadAgentConfig(config.workdir); if (!userConfig?.agents || !(name in userConfig.agents)) { // 如果是预设 Agent,返回特定错误 if (isPresetAgent(name)) { return c.json( { success: false, error: `Cannot delete preset agent '${name}'`, }, 400 ); } return c.json( { success: false, error: `Agent '${name}' not found in user configuration`, }, 404 ); } // 删除 Agent delete userConfig.agents[name]; // 保存配置 await saveAgentConfig(config.workdir, userConfig); // 重新初始化 registry initialized = false; await ensureRegistryInitialized(); return c.json({ success: true, data: null, }); } catch (error) { return c.json( { success: false, error: error instanceof Error ? error.message : 'Failed to delete agent', }, 500 ); } });