c307cd3a7c
- 扩展 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 显示简化编辑界面
182 lines
4.3 KiB
TypeScript
182 lines
4.3 KiB
TypeScript
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');
|
||
}
|
||
|
||
/**
|
||
* 获取内部 Agent(internal 模式)
|
||
*/
|
||
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();
|