@starlink-awaken/agentmesh 1.0.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +60 -41
  2. package/README.zh-CN.md +137 -167
  3. package/config/gateway.yaml +78 -0
  4. package/dist/src/adapters/base.d.ts +22 -0
  5. package/dist/src/adapters/base.js +10 -0
  6. package/dist/src/adapters/claude-code.d.ts +22 -0
  7. package/dist/src/adapters/claude-code.js +112 -0
  8. package/dist/src/adapters/openclaw.d.ts +22 -0
  9. package/dist/src/adapters/openclaw.js +110 -0
  10. package/dist/src/adapters/process.d.ts +28 -0
  11. package/dist/src/adapters/process.js +121 -0
  12. package/dist/src/cli/connect.d.ts +26 -0
  13. package/dist/src/cli/connect.js +544 -0
  14. package/dist/src/cli/setup.d.ts +2 -0
  15. package/dist/src/cli/setup.js +97 -0
  16. package/dist/src/cli.d.ts +2 -0
  17. package/dist/src/cli.js +410 -0
  18. package/dist/src/core/agent-registry.d.ts +48 -0
  19. package/dist/src/core/agent-registry.js +295 -0
  20. package/dist/src/core/config.d.ts +59 -0
  21. package/dist/src/core/config.js +101 -0
  22. package/dist/src/core/context-manager.d.ts +52 -0
  23. package/dist/src/core/context-manager.js +165 -0
  24. package/dist/src/core/event-bus.d.ts +35 -0
  25. package/dist/src/core/event-bus.js +62 -0
  26. package/dist/src/core/logger.d.ts +14 -0
  27. package/dist/src/core/logger.js +57 -0
  28. package/dist/src/core/metrics.d.ts +87 -0
  29. package/dist/src/core/metrics.js +167 -0
  30. package/dist/src/core/router.d.ts +46 -0
  31. package/dist/src/core/router.js +90 -0
  32. package/dist/src/core/task-manager.d.ts +41 -0
  33. package/dist/src/core/task-manager.js +197 -0
  34. package/dist/src/core/vector-store.d.ts +37 -0
  35. package/dist/src/core/vector-store.js +175 -0
  36. package/dist/src/index.d.ts +1 -0
  37. package/dist/src/index.js +105 -0
  38. package/dist/src/model-gateway/circuit-breaker.d.ts +21 -0
  39. package/dist/src/model-gateway/circuit-breaker.js +86 -0
  40. package/dist/src/model-gateway/health.d.ts +12 -0
  41. package/dist/src/model-gateway/health.js +80 -0
  42. package/dist/src/model-gateway/providers.d.ts +4 -0
  43. package/dist/src/model-gateway/providers.js +113 -0
  44. package/dist/src/model-gateway/quota.d.ts +4 -0
  45. package/dist/src/model-gateway/quota.js +107 -0
  46. package/dist/src/model-gateway/rate-limit.d.ts +12 -0
  47. package/dist/src/model-gateway/rate-limit.js +51 -0
  48. package/dist/src/model-gateway/retry.d.ts +14 -0
  49. package/dist/src/model-gateway/retry.js +48 -0
  50. package/dist/src/model-gateway/router.d.ts +4 -0
  51. package/dist/src/model-gateway/router.js +79 -0
  52. package/dist/src/model-gateway/routes.d.ts +2 -0
  53. package/dist/src/model-gateway/routes.js +172 -0
  54. package/dist/src/model-gateway/types.d.ts +47 -0
  55. package/dist/src/model-gateway/types.js +1 -0
  56. package/dist/src/routes/api.d.ts +2 -0
  57. package/dist/src/routes/api.js +128 -0
  58. package/dist/src/routes/websocket.d.ts +2 -0
  59. package/dist/src/routes/websocket.js +64 -0
  60. package/dist/src/types/index.d.ts +71 -0
  61. package/dist/src/types/index.js +1 -0
  62. package/dist/tests/core/context-manager.test.d.ts +1 -0
  63. package/dist/tests/core/context-manager.test.js +35 -0
  64. package/dist/tests/core/router.test.d.ts +1 -0
  65. package/dist/tests/core/router.test.js +79 -0
  66. package/dist/tests/model-gateway/circuit-breaker.test.d.ts +1 -0
  67. package/dist/tests/model-gateway/circuit-breaker.test.js +84 -0
  68. package/dist/tests/model-gateway/providers.test.d.ts +1 -0
  69. package/dist/tests/model-gateway/providers.test.js +80 -0
  70. package/dist/tests/model-gateway/quota.test.d.ts +1 -0
  71. package/dist/tests/model-gateway/quota.test.js +60 -0
  72. package/dist/tests/model-gateway/rate-limit.test.d.ts +1 -0
  73. package/dist/tests/model-gateway/rate-limit.test.js +42 -0
  74. package/dist/tests/model-gateway/retry.test.d.ts +1 -0
  75. package/dist/tests/model-gateway/retry.test.js +47 -0
  76. package/dist/tests/model-gateway/router.test.d.ts +1 -0
  77. package/dist/tests/model-gateway/router.test.js +108 -0
  78. package/dist/tests/model-gateway/routes.test.d.ts +1 -0
  79. package/dist/tests/model-gateway/routes.test.js +83 -0
  80. package/docs/api.md +187 -460
  81. package/docs/architecture.md +138 -0
  82. package/docs/configuration.md +188 -0
  83. package/package.json +3 -1
@@ -0,0 +1,295 @@
1
+ import { ProcessAdapter } from '../adapters/process.js';
2
+ import { ClaudeCodeAdapter } from '../adapters/claude-code.js';
3
+ import { OpenClawAdapter } from '../adapters/openclaw.js';
4
+ import { getAllAgentConfigs } from './config.js';
5
+ // 默认 Agent 配置
6
+ const DEFAULT_AGENT_CONFIGS = {
7
+ 'claude-code': {
8
+ name: 'Claude Code',
9
+ capabilities: ['code-generation', 'code-review', 'debugging', 'refactoring', 'documentation', 'file-operations'],
10
+ command: 'claude',
11
+ args: ['-p']
12
+ },
13
+ 'openclaw': {
14
+ name: 'OpenClaw',
15
+ capabilities: ['browser-automation', 'web-scraping', 'form-filling', 'ui-testing'],
16
+ command: 'openclaw',
17
+ args: ['--task']
18
+ },
19
+ 'opencode': {
20
+ name: 'OpenCode',
21
+ capabilities: ['code-completion', 'code-generation', 'refactoring', 'debugging'],
22
+ command: 'opencode',
23
+ args: ['--task']
24
+ },
25
+ 'gemini': {
26
+ name: 'Google Gemini CLI',
27
+ capabilities: ['code-generation', 'multimodal', 'reasoning', 'analysis'],
28
+ command: 'gemini',
29
+ args: ['--prompt']
30
+ },
31
+ 'codex': {
32
+ name: 'OpenAI Codex',
33
+ capabilities: ['code-generation', 'code-explanation', 'refactoring'],
34
+ command: 'codex',
35
+ args: ['complete']
36
+ },
37
+ 'github-copilot': {
38
+ name: 'GitHub Copilot',
39
+ capabilities: ['code-completion', 'code-suggestions', 'refactoring'],
40
+ command: 'copilot',
41
+ args: ['--ask']
42
+ },
43
+ 'qwen-code': {
44
+ name: 'Qwen Code',
45
+ capabilities: ['code-generation', 'code-review', 'multilingual'],
46
+ command: 'qwen-code',
47
+ args: ['--task']
48
+ },
49
+ 'crush': {
50
+ name: 'CRUSH AI',
51
+ capabilities: ['code-generation', 'debugging', 'security-analysis'],
52
+ command: 'crush',
53
+ args: ['run']
54
+ },
55
+ 'droid': {
56
+ name: 'Droid Agent',
57
+ capabilities: ['android-development', 'mobile-debugging', 'device-control'],
58
+ command: 'droid',
59
+ args: ['--task']
60
+ },
61
+ 'factory': {
62
+ name: 'Factory AI',
63
+ capabilities: ['code-generation', 'testing', 'documentation', 'refactoring'],
64
+ command: 'factory',
65
+ args: ['--task']
66
+ },
67
+ 'cursor': {
68
+ name: 'Cursor',
69
+ capabilities: ['code-completion', 'code-generation', 'refactoring', 'chat'],
70
+ command: 'cursor',
71
+ args: ['--task']
72
+ },
73
+ 'windsurf': {
74
+ name: 'Windsurf',
75
+ capabilities: ['code-generation', 'agentic-coding', 'flow-state'],
76
+ command: 'windsurf',
77
+ args: ['--task']
78
+ },
79
+ 'zed': {
80
+ name: 'Zed AI',
81
+ capabilities: ['code-generation', 'collaboration', 'high-performance'],
82
+ command: 'zed',
83
+ args: ['--ai-task']
84
+ },
85
+ 'aider': {
86
+ name: 'Aider',
87
+ capabilities: ['git-based-editing', 'code-refactoring', 'multi-file-changes'],
88
+ command: 'aider',
89
+ args: ['--message']
90
+ },
91
+ 'cline': {
92
+ name: 'Cline',
93
+ capabilities: ['autonomous-coding', 'file-operations', 'command-execution'],
94
+ command: 'cline',
95
+ args: ['--task']
96
+ },
97
+ 'roo-code': {
98
+ name: 'Roo Code',
99
+ capabilities: ['code-generation', 'agentic-mode', 'workspace-awareness'],
100
+ command: 'roo-code',
101
+ args: ['--task']
102
+ },
103
+ // 2026 新增 Agent
104
+ 'perplexity': {
105
+ name: 'Perplexity',
106
+ capabilities: ['research', 'web-search', 'fact-checking', 'analysis'],
107
+ command: 'perplexity',
108
+ args: ['--query']
109
+ },
110
+ 'grok': {
111
+ name: 'xAI Grok',
112
+ capabilities: ['reasoning', 'humor', 'code-generation', 'analysis'],
113
+ command: 'grok',
114
+ args: ['--prompt']
115
+ },
116
+ 'phind': {
117
+ name: 'Phind',
118
+ capabilities: ['developer-search', 'code-search', 'documentation-search'],
119
+ command: 'phind',
120
+ args: ['--search']
121
+ },
122
+ 'you': {
123
+ name: 'You.com AI',
124
+ capabilities: ['web-search', 'code-search', 'general-assistant'],
125
+ command: 'you',
126
+ args: ['--query']
127
+ },
128
+ 'lepton': {
129
+ name: 'Lepton AI',
130
+ capabilities: ['code-generation', 'conversation', 'analysis'],
131
+ command: 'lepton',
132
+ args: ['--prompt']
133
+ },
134
+ 'ollama': {
135
+ name: 'Ollama',
136
+ capabilities: ['local-llm', 'code-generation', 'privacy-focused'],
137
+ command: 'ollama',
138
+ args: ['run']
139
+ },
140
+ 'llama': {
141
+ name: 'Meta Llama',
142
+ capabilities: ['code-generation', 'reasoning', 'open-source'],
143
+ command: 'llama',
144
+ args: ['--prompt']
145
+ },
146
+ 'mistral': {
147
+ name: 'Mistral AI',
148
+ capabilities: ['code-generation', 'reasoning', 'multilingual'],
149
+ command: 'mistral',
150
+ args: ['--task']
151
+ },
152
+ 'anthropic': {
153
+ name: 'Anthropic CLI',
154
+ capabilities: ['conversation', 'reasoning', 'code-generation'],
155
+ command: 'anthropic',
156
+ args: ['--prompt']
157
+ }
158
+ };
159
+ export class AgentRegistry {
160
+ adapters = new Map();
161
+ initialized = false;
162
+ constructor() {
163
+ // 延迟初始化
164
+ }
165
+ /**
166
+ * 初始化注册表
167
+ */
168
+ initialize() {
169
+ if (this.initialized)
170
+ return;
171
+ // 注册内置适配器
172
+ this.register(new ClaudeCodeAdapter());
173
+ this.register(new OpenClawAdapter());
174
+ // 从配置加载所有 Agent
175
+ this.registerAllFromConfig();
176
+ this.initialized = true;
177
+ }
178
+ /**
179
+ * 从配置注册所有 Agent
180
+ */
181
+ registerAllFromConfig() {
182
+ const configAgents = getAllAgentConfigs();
183
+ // 1. 先注册配置文件中的 Agent
184
+ for (const config of configAgents) {
185
+ if (this.adapters.has(config.id))
186
+ continue;
187
+ if (config.type === 'claude-code' || config.type === 'openclaw') {
188
+ // 跳过,内置适配器已注册
189
+ continue;
190
+ }
191
+ if (config.type === 'process' && config.command) {
192
+ const adapter = new ProcessAdapter(config.id, config.name, config.capabilities, {
193
+ command: config.command,
194
+ args: config.args,
195
+ env: config.env
196
+ });
197
+ this.adapters.set(config.id, adapter);
198
+ console.log(`[AgentRegistry] Registered from config: ${config.id}`);
199
+ }
200
+ }
201
+ // 2. 再注册默认 Agent(未被配置覆盖的)
202
+ for (const [id, defaultConfig] of Object.entries(DEFAULT_AGENT_CONFIGS)) {
203
+ if (this.adapters.has(id))
204
+ continue;
205
+ const adapter = new ProcessAdapter(id, defaultConfig.name, defaultConfig.capabilities, {
206
+ command: defaultConfig.command,
207
+ args: defaultConfig.args,
208
+ env: defaultConfig.env
209
+ });
210
+ this.adapters.set(id, adapter);
211
+ console.log(`[AgentRegistry] Registered default: ${id}`);
212
+ }
213
+ }
214
+ /**
215
+ * 注册自定义适配器
216
+ */
217
+ register(adapter) {
218
+ this.adapters.set(adapter.id, adapter);
219
+ console.log(`[AgentRegistry] Registered adapter: ${adapter.id}`);
220
+ }
221
+ /**
222
+ * 获取适配器
223
+ */
224
+ get(agentId) {
225
+ return this.adapters.get(agentId);
226
+ }
227
+ /**
228
+ * 获取所有适配器
229
+ */
230
+ getAll() {
231
+ return Array.from(this.adapters.values());
232
+ }
233
+ /**
234
+ * 获取所有 Agent 信息
235
+ */
236
+ getAgents() {
237
+ return this.getAll().map(adapter => ({
238
+ id: adapter.id,
239
+ name: adapter.name,
240
+ type: adapter.type,
241
+ capabilities: adapter.capabilities,
242
+ status: 'online',
243
+ lastSeen: Date.now()
244
+ }));
245
+ }
246
+ /**
247
+ * 根据能力查找 Agent
248
+ */
249
+ findByCapability(capability) {
250
+ return this.getAll()
251
+ .filter(adapter => adapter.capabilities.includes(capability))
252
+ .map(adapter => ({
253
+ id: adapter.id,
254
+ name: adapter.name,
255
+ type: adapter.type,
256
+ capabilities: adapter.capabilities,
257
+ status: 'online',
258
+ lastSeen: Date.now()
259
+ }));
260
+ }
261
+ /**
262
+ * 检查适配器是否存在
263
+ */
264
+ has(agentId) {
265
+ return this.adapters.has(agentId);
266
+ }
267
+ /**
268
+ * 检查适配器是否健康
269
+ */
270
+ async checkHealth(agentId) {
271
+ const adapter = this.adapters.get(agentId);
272
+ if (!adapter)
273
+ return false;
274
+ return adapter.health();
275
+ }
276
+ /**
277
+ * 获取可用 Agent 列表(健康检查)
278
+ */
279
+ async getAvailableAgents() {
280
+ const results = [];
281
+ for (const adapter of this.adapters.values()) {
282
+ const isHealthy = await adapter.health().catch(() => false);
283
+ results.push({
284
+ id: adapter.id,
285
+ name: adapter.name,
286
+ type: adapter.type,
287
+ capabilities: adapter.capabilities,
288
+ status: isHealthy ? 'online' : 'offline',
289
+ lastSeen: Date.now()
290
+ });
291
+ }
292
+ return results;
293
+ }
294
+ }
295
+ export const agentRegistry = new AgentRegistry();
@@ -0,0 +1,59 @@
1
+ export interface AgentConfig {
2
+ id: string;
3
+ name: string;
4
+ type: 'claude-code' | 'openclaw' | 'process' | 'http';
5
+ command?: string;
6
+ args?: string[];
7
+ env?: Record<string, string>;
8
+ endpoint?: string;
9
+ capabilities: string[];
10
+ }
11
+ export interface RoutingRule {
12
+ name: string;
13
+ keywords: string[];
14
+ agent?: string;
15
+ strategy?: 'direct' | 'broadcast';
16
+ agents?: string[];
17
+ priority: number;
18
+ }
19
+ export interface GatewayConfig {
20
+ port: number;
21
+ wsPort: number;
22
+ host: string;
23
+ dataDir: string;
24
+ logDir: string;
25
+ logLevel: 'debug' | 'info' | 'warn' | 'error';
26
+ routing: {
27
+ defaultAgent?: string;
28
+ rules: RoutingRule[];
29
+ };
30
+ agents: AgentConfig[];
31
+ }
32
+ /**
33
+ * 加载配置文件
34
+ */
35
+ export declare function loadConfig(configPath?: string): GatewayConfig;
36
+ /**
37
+ * 重新加载配置
38
+ */
39
+ export declare function reloadConfig(configPath?: string): GatewayConfig;
40
+ /**
41
+ * 获取配置
42
+ */
43
+ export declare function getConfig(): GatewayConfig;
44
+ /**
45
+ * 获取 Agent 配置
46
+ */
47
+ export declare function getAgentConfig(agentId: string): AgentConfig | undefined;
48
+ /**
49
+ * 获取所有 Agent 配置
50
+ */
51
+ export declare function getAllAgentConfigs(): AgentConfig[];
52
+ /**
53
+ * 获取路由规则
54
+ */
55
+ export declare function getRoutingRules(): RoutingRule[];
56
+ /**
57
+ * 获取默认 Agent
58
+ */
59
+ export declare function getDefaultAgent(): string | undefined;
@@ -0,0 +1,101 @@
1
+ import { readFileSync, existsSync } from 'fs';
2
+ import { parse } from 'yaml';
3
+ import { join } from 'path';
4
+ const DEFAULT_CONFIG = {
5
+ port: 3000,
6
+ wsPort: 3001,
7
+ host: '0.0.0.0',
8
+ dataDir: './data',
9
+ logDir: './logs',
10
+ logLevel: 'info',
11
+ routing: {
12
+ defaultAgent: 'claude-code',
13
+ rules: []
14
+ },
15
+ agents: []
16
+ };
17
+ let cachedConfig = null;
18
+ /**
19
+ * 加载配置文件
20
+ */
21
+ export function loadConfig(configPath) {
22
+ if (cachedConfig) {
23
+ return cachedConfig;
24
+ }
25
+ const paths = configPath
26
+ ? [configPath]
27
+ : [
28
+ './config/gateway.yaml',
29
+ './config/gateway.yml',
30
+ join(process.cwd(), 'config/gateway.yaml'),
31
+ join(process.cwd(), 'config/gateway.yml')
32
+ ];
33
+ for (const path of paths) {
34
+ try {
35
+ if (existsSync(path)) {
36
+ console.log(`[Config] Loading from: ${path}`);
37
+ const content = readFileSync(path, 'utf-8');
38
+ const parsed = parse(content);
39
+ // 合并配置
40
+ cachedConfig = {
41
+ ...DEFAULT_CONFIG,
42
+ ...parsed,
43
+ routing: {
44
+ ...DEFAULT_CONFIG.routing,
45
+ ...parsed.routing,
46
+ rules: parsed.routing?.rules || DEFAULT_CONFIG.routing.rules
47
+ }
48
+ };
49
+ console.log(`[Config] Loaded successfully`);
50
+ return cachedConfig;
51
+ }
52
+ }
53
+ catch (error) {
54
+ console.warn(`[Config] Failed to load ${path}:`, error);
55
+ }
56
+ }
57
+ console.log('[Config] Using default configuration');
58
+ cachedConfig = { ...DEFAULT_CONFIG };
59
+ return cachedConfig;
60
+ }
61
+ /**
62
+ * 重新加载配置
63
+ */
64
+ export function reloadConfig(configPath) {
65
+ cachedConfig = null;
66
+ return loadConfig(configPath);
67
+ }
68
+ /**
69
+ * 获取配置
70
+ */
71
+ export function getConfig() {
72
+ if (!cachedConfig) {
73
+ return loadConfig();
74
+ }
75
+ return cachedConfig;
76
+ }
77
+ /**
78
+ * 获取 Agent 配置
79
+ */
80
+ export function getAgentConfig(agentId) {
81
+ const config = getConfig();
82
+ return config.agents.find(a => a.id === agentId);
83
+ }
84
+ /**
85
+ * 获取所有 Agent 配置
86
+ */
87
+ export function getAllAgentConfigs() {
88
+ return getConfig().agents;
89
+ }
90
+ /**
91
+ * 获取路由规则
92
+ */
93
+ export function getRoutingRules() {
94
+ return getConfig().routing.rules;
95
+ }
96
+ /**
97
+ * 获取默认 Agent
98
+ */
99
+ export function getDefaultAgent() {
100
+ return getConfig().routing.defaultAgent;
101
+ }
@@ -0,0 +1,52 @@
1
+ import type { AgentMessage, ContextRef } from '../types/index.js';
2
+ interface ContextData {
3
+ shared_space_id: string;
4
+ messages: AgentMessage[];
5
+ artifacts: Map<string, string>;
6
+ metadata: Record<string, unknown>;
7
+ createdAt: number;
8
+ updatedAt: number;
9
+ }
10
+ export declare class ContextManager {
11
+ private memoryCache;
12
+ private baseDir;
13
+ constructor(baseDir?: string);
14
+ /**
15
+ * 创建共享空间
16
+ */
17
+ createSharedSpace(metadata?: Record<string, unknown>): Promise<string>;
18
+ /**
19
+ * 获取共享空间
20
+ */
21
+ getSharedSpace(spaceId: string): Promise<ContextData | null>;
22
+ /**
23
+ * 添加消息到共享空间
24
+ */
25
+ addMessage(spaceId: string, message: AgentMessage): Promise<void>;
26
+ /**
27
+ * 获取消息历史
28
+ */
29
+ getMessages(spaceId: string, limit?: number): Promise<AgentMessage[]>;
30
+ /**
31
+ * 添加产物文件
32
+ */
33
+ addArtifact(spaceId: string, filename: string, content: string): Promise<string>;
34
+ /**
35
+ * 获取产物文件
36
+ */
37
+ getArtifact(spaceId: string, filename: string): Promise<string | null>;
38
+ /**
39
+ * 持久化到文件系统
40
+ */
41
+ private persistToFile;
42
+ /**
43
+ * 从文件系统加载
44
+ */
45
+ private loadFromFile;
46
+ /**
47
+ * 创建 ContextRef
48
+ */
49
+ createContextRef(spaceId: string): Promise<ContextRef>;
50
+ }
51
+ export declare const contextManager: ContextManager;
52
+ export {};
@@ -0,0 +1,165 @@
1
+ import { promises as fs } from 'fs';
2
+ import { join } from 'path';
3
+ import { v4 as uuidv4 } from 'uuid';
4
+ import { vectorStore } from './vector-store.js';
5
+ export class ContextManager {
6
+ memoryCache = new Map();
7
+ baseDir;
8
+ constructor(baseDir = './data/tasks') {
9
+ this.baseDir = baseDir;
10
+ }
11
+ /**
12
+ * 创建共享空间
13
+ */
14
+ async createSharedSpace(metadata = {}) {
15
+ const spaceId = uuidv4();
16
+ const context = {
17
+ shared_space_id: spaceId,
18
+ messages: [],
19
+ artifacts: new Map(),
20
+ metadata,
21
+ createdAt: Date.now(),
22
+ updatedAt: Date.now()
23
+ };
24
+ // L1: 内存缓存
25
+ this.memoryCache.set(spaceId, context);
26
+ // L2: 文件系统持久化
27
+ await this.persistToFile(spaceId, context);
28
+ return spaceId;
29
+ }
30
+ /**
31
+ * 获取共享空间
32
+ */
33
+ async getSharedSpace(spaceId) {
34
+ // L1: 先从内存获取
35
+ if (this.memoryCache.has(spaceId)) {
36
+ return this.memoryCache.get(spaceId);
37
+ }
38
+ // L2: 从文件系统加载
39
+ try {
40
+ const context = await this.loadFromFile(spaceId);
41
+ if (context) {
42
+ this.memoryCache.set(spaceId, context);
43
+ return context;
44
+ }
45
+ }
46
+ catch (error) {
47
+ console.error(`[ContextManager] Failed to load context: ${spaceId}`, error);
48
+ }
49
+ return null;
50
+ }
51
+ /**
52
+ * 添加消息到共享空间
53
+ */
54
+ async addMessage(spaceId, message) {
55
+ const context = await this.getSharedSpace(spaceId);
56
+ if (!context) {
57
+ throw new Error(`Shared space not found: ${spaceId}`);
58
+ }
59
+ context.messages.push(message);
60
+ context.updatedAt = Date.now();
61
+ // 更新内存缓存
62
+ this.memoryCache.set(spaceId, context);
63
+ // 持久化到文件系统
64
+ await this.persistToFile(spaceId, context);
65
+ // L3: 添加到向量数据库(异步,不阻塞)
66
+ if (vectorStore.isAvailable()) {
67
+ vectorStore.addMessage(spaceId, message).catch(err => {
68
+ console.error('[ContextManager] Vector store add failed:', err);
69
+ });
70
+ }
71
+ }
72
+ /**
73
+ * 获取消息历史
74
+ */
75
+ async getMessages(spaceId, limit) {
76
+ const context = await this.getSharedSpace(spaceId);
77
+ if (!context) {
78
+ return [];
79
+ }
80
+ const messages = context.messages;
81
+ return limit ? messages.slice(-limit) : messages;
82
+ }
83
+ /**
84
+ * 添加产物文件
85
+ */
86
+ async addArtifact(spaceId, filename, content) {
87
+ const context = await this.getSharedSpace(spaceId);
88
+ if (!context) {
89
+ throw new Error(`Shared space not found: ${spaceId}`);
90
+ }
91
+ const artifactsDir = join(this.baseDir, spaceId, 'artifacts');
92
+ await fs.mkdir(artifactsDir, { recursive: true });
93
+ const filePath = join(artifactsDir, filename);
94
+ await fs.writeFile(filePath, content, 'utf-8');
95
+ context.artifacts.set(filename, filePath);
96
+ context.updatedAt = Date.now();
97
+ // 更新内存缓存
98
+ this.memoryCache.set(spaceId, context);
99
+ // 持久化
100
+ await this.persistToFile(spaceId, context);
101
+ return filePath;
102
+ }
103
+ /**
104
+ * 获取产物文件
105
+ */
106
+ async getArtifact(spaceId, filename) {
107
+ const context = await this.getSharedSpace(spaceId);
108
+ if (!context) {
109
+ return null;
110
+ }
111
+ const filePath = context.artifacts.get(filename);
112
+ if (!filePath) {
113
+ return null;
114
+ }
115
+ try {
116
+ return await fs.readFile(filePath, 'utf-8');
117
+ }
118
+ catch {
119
+ return null;
120
+ }
121
+ }
122
+ /**
123
+ * 持久化到文件系统
124
+ */
125
+ async persistToFile(spaceId, context) {
126
+ const dir = join(this.baseDir, spaceId);
127
+ await fs.mkdir(dir, { recursive: true });
128
+ // 序列化 context(Map 需要转换)
129
+ const serialized = {
130
+ shared_space_id: context.shared_space_id,
131
+ messages: context.messages,
132
+ artifacts: Object.fromEntries(context.artifacts),
133
+ metadata: context.metadata,
134
+ createdAt: context.createdAt,
135
+ updatedAt: context.updatedAt
136
+ };
137
+ await fs.writeFile(join(dir, 'context.json'), JSON.stringify(serialized, null, 2), 'utf-8');
138
+ }
139
+ /**
140
+ * 从文件系统加载
141
+ */
142
+ async loadFromFile(spaceId) {
143
+ const filePath = join(this.baseDir, spaceId, 'context.json');
144
+ try {
145
+ const content = await fs.readFile(filePath, 'utf-8');
146
+ const parsed = JSON.parse(content);
147
+ return {
148
+ ...parsed,
149
+ artifacts: new Map(Object.entries(parsed.artifacts || {}))
150
+ };
151
+ }
152
+ catch {
153
+ return null;
154
+ }
155
+ }
156
+ /**
157
+ * 创建 ContextRef
158
+ */
159
+ async createContextRef(spaceId) {
160
+ return {
161
+ shared_space_id: spaceId
162
+ };
163
+ }
164
+ }
165
+ export const contextManager = new ContextManager();
@@ -0,0 +1,35 @@
1
+ import { EventEmitter } from 'events';
2
+ import type { AgentMessage, EventType } from '../types/index.js';
3
+ interface EventBusOptions {
4
+ logger?: Console;
5
+ }
6
+ export declare class EventBus extends EventEmitter {
7
+ private logger;
8
+ constructor(options?: EventBusOptions);
9
+ /**
10
+ * 发布事件
11
+ */
12
+ publish(eventType: EventType, data: AgentMessage): void;
13
+ /**
14
+ * 订阅事件
15
+ */
16
+ subscribe(eventType: EventType, handler: (event: {
17
+ type: EventType;
18
+ data: AgentMessage;
19
+ timestamp: number;
20
+ }) => void): () => void;
21
+ /**
22
+ * 发布任务事件
23
+ */
24
+ publishTaskEvent(eventType: Exclude<EventType, 'agent.registered' | 'agent.unregistered'>, message: AgentMessage): void;
25
+ /**
26
+ * 发布 Agent 事件
27
+ */
28
+ publishAgentEvent(eventType: 'agent.registered' | 'agent.unregistered', message: AgentMessage): void;
29
+ /**
30
+ * 获取所有事件类型
31
+ */
32
+ getEventTypes(): EventType[];
33
+ }
34
+ export declare const eventBus: EventBus;
35
+ export {};