Files
ai-terminal-assistant/packages/core/src/agent/registry.ts
T
kurihada c307cd3a7c refactor(agent): 将 Summary Model 改造为内置 Sub Agent
- 扩展 AgentMode 类型添加 'internal' 模式
- 新增 summary agent preset (claude-3-5-haiku)
- AgentRegistry 添加 getInternal/listInternalAgents 方法
- CompressionManager 添加 setSummaryModelFromAgentConfig
- Agent 构造函数改用 Registry 配置初始化 Summary 模型
- 清理旧的 SummaryConfig 配置系统
- UI AgentsPanel 分离显示 System/Preset/Custom agents
- UI AgentEditor 为 internal agent 显示简化编辑界面
2025-12-14 22:12:36 +08:00

182 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { AgentInfo, AgentConfigFile, AgentMode } from './types.js';
import { presetAgents } from './presets/index.js';
import { loadAgentConfig } from './config-loader.js';
import { mergePermissions, SYSTEM_DEFAULT_PERMISSION } from './permission-merger.js';
/**
* Agent 注册表
* 管理所有 Agent 的注册、查询和配置合并
*/
export class AgentRegistry {
private agents: Map<string, AgentInfo> = new Map();
private globalConfig: AgentConfigFile['defaults'] | null = null;
private userConfig: AgentConfigFile | null = null;
private initialized = false;
/**
* 初始化 - 加载预设和用户配置
*/
async init(workdir: string): Promise<void> {
if (this.initialized) return;
// 1. 注册预设 Agent
for (const [name, agentConfig] of Object.entries(presetAgents)) {
this.agents.set(name, { ...agentConfig, name });
}
// 2. 加载用户配置
this.userConfig = await loadAgentConfig(workdir);
if (this.userConfig) {
this.globalConfig = this.userConfig.defaults ?? null;
// 注册用户自定义 Agent
if (this.userConfig.agents) {
for (const [name, config] of Object.entries(this.userConfig.agents)) {
this.agents.set(name, { ...config, name });
}
}
}
this.initialized = true;
}
/**
* 获取 Agent(应用权限合并)
*/
get(name: string): AgentInfo | undefined {
const agent = this.agents.get(name);
if (!agent) return undefined;
return this.applyGlobalConfig(agent);
}
/**
* 列出所有 Agent
*/
list(mode?: AgentMode): AgentInfo[] {
return [...this.agents.values()]
.filter((a) => !mode || a.mode === mode || a.mode === 'all')
.map((a) => this.applyGlobalConfig(a));
}
/**
* 列出可作为子 Agent 的 Agent(供 Task 工具使用)
* 排除 primary 和 internal 模式
*/
listSubagents(): AgentInfo[] {
return this.list().filter((a) => a.mode !== 'primary' && a.mode !== 'internal');
}
/**
* 列出可作为主交互 Agent 的 Agent(供 /agent 命令使用)
* 排除 internal 模式
*/
listPrimaryAgents(): AgentInfo[] {
return this.list().filter((a) => a.mode !== 'subagent' && a.mode !== 'internal');
}
/**
* 获取内部 Agentinternal 模式)
*/
getInternal(name: string): AgentInfo | undefined {
const agent = this.get(name);
if (agent?.mode === 'internal') {
return agent;
}
return undefined;
}
/**
* 列出所有内部 Agent
*/
listInternalAgents(): AgentInfo[] {
return this.list().filter((a) => a.mode === 'internal');
}
/**
* 动态注册 Agent(运行时)
*/
register(agent: AgentInfo): void {
this.agents.set(agent.name, agent);
}
/**
* 移除 Agent
*/
remove(name: string): boolean {
return this.agents.delete(name);
}
/**
* 检查 Agent 是否存在
*/
has(name: string): boolean {
return this.agents.has(name);
}
/**
* 获取 Agent 数量
*/
get size(): number {
return this.agents.size;
}
/**
* 获取所有 Agent 名称
*/
getNames(): string[] {
return [...this.agents.keys()];
}
/**
* 获取全局配置
*/
getGlobalConfig(): AgentConfigFile['defaults'] | null {
return this.globalConfig;
}
/**
* 应用全局配置到 Agent
*/
private applyGlobalConfig(agent: AgentInfo): AgentInfo {
// 合并 maxSteps
const maxSteps = agent.maxSteps ?? this.globalConfig?.maxSteps ?? 10;
// 合并模型配置
const model = {
...this.globalConfig?.model,
...agent.model,
};
// 合并权限配置
const permission = mergePermissions(
SYSTEM_DEFAULT_PERMISSION,
this.globalConfig?.permission,
agent.permission
);
return {
...agent,
maxSteps,
model: Object.keys(model).length > 0 ? model : undefined,
permission,
};
}
/**
* 生成 Task 工具的 Agent 描述(用于工具 description
*/
generateSubagentDescription(): string {
const subagents = this.listSubagents();
if (subagents.length === 0) {
return '当前没有可用的子 Agent';
}
const descriptions = subagents.map((a) => `- ${a.name}: ${a.description}`);
return `可用的 Agent:\n${descriptions.join('\n')}`;
}
}
// 导出单例
export const agentRegistry = new AgentRegistry();