feat: 重构为 Monorepo 架构并实现 HTTP Server

架构变更:
- 采用 pnpm workspaces 实现 Monorepo 结构
- 将现有代码迁移到 packages/core
- 新增 packages/server HTTP 服务层

Server 功能:
- REST API: 会话管理、工具管理、配置管理
- WebSocket: 实时双向通信支持
- SSE: 服务端事件推送
- Hono + Bun 作为运行时

API 端点:
- GET/POST /api/sessions - 会话 CRUD
- GET/POST /api/sessions/:id/messages - 消息管理
- GET /api/sessions/:id/events - SSE 事件流
- WS /api/ws/:sessionId - WebSocket 连接
- GET/POST /api/tools - 工具管理
- GET/PUT /api/config - 配置管理
This commit is contained in:
2025-12-12 10:42:20 +08:00
parent 59dbed926e
commit 5e32375f0e
301 changed files with 3281 additions and 43 deletions
+161
View File
@@ -0,0 +1,161 @@
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 工具使用)
*/
listSubagents(): AgentInfo[] {
return this.list().filter((a) => a.mode !== 'primary');
}
/**
* 列出可作为主交互 Agent 的 Agent(供 /agent 命令使用)
*/
listPrimaryAgents(): AgentInfo[] {
return this.list().filter((a) => a.mode !== 'subagent');
}
/**
* 动态注册 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();