@starlink-awaken/agentmesh 1.0.2 → 1.0.3
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.
- package/dist/adapters/base.d.ts +22 -0
- package/dist/adapters/base.js +10 -0
- package/dist/adapters/claude-code.d.ts +22 -0
- package/dist/adapters/claude-code.js +112 -0
- package/dist/adapters/openclaw.d.ts +22 -0
- package/dist/adapters/openclaw.js +110 -0
- package/dist/adapters/process.d.ts +28 -0
- package/dist/adapters/process.js +121 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +246 -0
- package/dist/core/agent-registry.d.ts +48 -0
- package/dist/core/agent-registry.js +295 -0
- package/dist/core/config.d.ts +59 -0
- package/dist/core/config.js +101 -0
- package/dist/core/context-manager.d.ts +52 -0
- package/dist/core/context-manager.js +165 -0
- package/dist/core/event-bus.d.ts +35 -0
- package/dist/core/event-bus.js +62 -0
- package/dist/core/metrics.d.ts +87 -0
- package/dist/core/metrics.js +167 -0
- package/dist/core/router.d.ts +46 -0
- package/dist/core/router.js +90 -0
- package/dist/core/task-manager.d.ts +41 -0
- package/dist/core/task-manager.js +197 -0
- package/dist/core/vector-store.d.ts +37 -0
- package/dist/core/vector-store.js +175 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +73 -0
- package/dist/routes/api.d.ts +2 -0
- package/dist/routes/api.js +128 -0
- package/dist/routes/websocket.d.ts +2 -0
- package/dist/routes/websocket.js +64 -0
- package/dist/types/index.d.ts +71 -0
- package/dist/types/index.js +1 -0
- package/package.json +1 -1
package/dist/cli.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
const BASE_URL = process.env.AGENT_GATEWAY_URL || 'http://localhost:3000';
|
|
3
|
+
async function request(path, options) {
|
|
4
|
+
const response = await fetch(`${BASE_URL}${path}`, {
|
|
5
|
+
...options,
|
|
6
|
+
headers: {
|
|
7
|
+
'Content-Type': 'application/json',
|
|
8
|
+
...options?.headers
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
if (!response.ok) {
|
|
12
|
+
const error = await response.json().catch(() => ({ message: 'Unknown error' }));
|
|
13
|
+
throw new Error(`HTTP ${response.status}: ${JSON.stringify(error)}`);
|
|
14
|
+
}
|
|
15
|
+
return response.json();
|
|
16
|
+
}
|
|
17
|
+
// 命令
|
|
18
|
+
const commands = {
|
|
19
|
+
// 列出所有 Agent
|
|
20
|
+
async listAgents() {
|
|
21
|
+
const agents = await request('/agents');
|
|
22
|
+
console.log('\n📋 可用 Agent:\n');
|
|
23
|
+
agents.forEach(agent => {
|
|
24
|
+
console.log(` ${agent.id.padEnd(15)} ${agent.name.padEnd(20)} [${agent.status}]`);
|
|
25
|
+
console.log(` 能力: ${agent.capabilities.join(', ')}\n`);
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
// 提交任务
|
|
29
|
+
async submitTask(args) {
|
|
30
|
+
const task = args.join(' ');
|
|
31
|
+
if (!task) {
|
|
32
|
+
console.error('❌ 请提供任务描述');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
console.log(`\n📤 提交任务: ${task}\n`);
|
|
36
|
+
const message = {
|
|
37
|
+
type: 'request',
|
|
38
|
+
source: 'cli',
|
|
39
|
+
target: 'gateway',
|
|
40
|
+
payload: {
|
|
41
|
+
task,
|
|
42
|
+
options: {
|
|
43
|
+
stream: false,
|
|
44
|
+
timeout: 300
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const result = await request('/tasks', {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
body: JSON.stringify(message)
|
|
51
|
+
});
|
|
52
|
+
console.log(`✅ 任务已提交: ${result.task_id}`);
|
|
53
|
+
console.log(` 状态: ${result.status}\n`);
|
|
54
|
+
// 轮询获取结果
|
|
55
|
+
console.log('Waiting for result...\n');
|
|
56
|
+
let completed = false;
|
|
57
|
+
let attempts = 0;
|
|
58
|
+
const maxAttempts = 60;
|
|
59
|
+
while (!completed && attempts < maxAttempts) {
|
|
60
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
61
|
+
const taskResult = await request(`/tasks/${result.task_id}`);
|
|
62
|
+
if (taskResult.status === 'completed') {
|
|
63
|
+
completed = true;
|
|
64
|
+
console.log('✅ 任务完成!\n');
|
|
65
|
+
console.log('📊 结果:');
|
|
66
|
+
if (typeof taskResult.result === 'object') {
|
|
67
|
+
Object.entries(taskResult.result).forEach(([agent, res]) => {
|
|
68
|
+
console.log(`\n--- ${agent} ---`);
|
|
69
|
+
console.log(res);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
console.log(taskResult.result);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else if (taskResult.status === 'failed') {
|
|
77
|
+
completed = true;
|
|
78
|
+
console.log('❌ 任务失败!');
|
|
79
|
+
console.log('错误:', taskResult.error);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
attempts++;
|
|
83
|
+
process.stdout.write('.');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (!completed) {
|
|
87
|
+
console.log('\n⚠️ 任务超时\n');
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
// 提交到指定 Agent
|
|
91
|
+
async submitToAgent(agentId, args) {
|
|
92
|
+
const task = args.join(' ');
|
|
93
|
+
if (!task) {
|
|
94
|
+
console.error('❌ 请提供任务描述');
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
console.log(`\n📤 提交任务到 ${agentId}: ${task}\n`);
|
|
98
|
+
const message = {
|
|
99
|
+
type: 'request',
|
|
100
|
+
source: 'cli',
|
|
101
|
+
target: agentId,
|
|
102
|
+
payload: {
|
|
103
|
+
task,
|
|
104
|
+
options: {
|
|
105
|
+
stream: false,
|
|
106
|
+
timeout: 300
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
const result = await request('/tasks', {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
body: JSON.stringify(message)
|
|
113
|
+
});
|
|
114
|
+
console.log(`✅ 任务已提交: ${result.task_id}`);
|
|
115
|
+
console.log(` 状态: ${result.status}\n`);
|
|
116
|
+
// 轮询获取结果
|
|
117
|
+
console.log('⏳ 等待执行结果...\n');
|
|
118
|
+
let completed = false;
|
|
119
|
+
let attempts = 0;
|
|
120
|
+
const maxAttempts = 60;
|
|
121
|
+
while (!completed && attempts < maxAttempts) {
|
|
122
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
123
|
+
const taskResult = await request(`/tasks/${result.task_id}`);
|
|
124
|
+
if (taskResult.status === 'completed') {
|
|
125
|
+
completed = true;
|
|
126
|
+
console.log('\n✅ 任务完成!\n');
|
|
127
|
+
console.log('📊 结果:');
|
|
128
|
+
console.log(taskResult.result);
|
|
129
|
+
}
|
|
130
|
+
else if (taskResult.status === 'failed') {
|
|
131
|
+
completed = true;
|
|
132
|
+
console.log('\n❌ 任务失败!');
|
|
133
|
+
console.log('错误:', taskResult.error);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
attempts++;
|
|
137
|
+
process.stdout.write('.');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (!completed) {
|
|
141
|
+
console.log('\n⚠️ 任务超时\n');
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
// 创建共享空间
|
|
145
|
+
async createSpace() {
|
|
146
|
+
const result = await request('/spaces', {
|
|
147
|
+
method: 'POST',
|
|
148
|
+
body: JSON.stringify({ metadata: { createdBy: 'cli' } })
|
|
149
|
+
});
|
|
150
|
+
console.log(`\n✅ 共享空间已创建: ${result.space_id}\n`);
|
|
151
|
+
return result.space_id;
|
|
152
|
+
},
|
|
153
|
+
// 列出任务
|
|
154
|
+
async listTasks() {
|
|
155
|
+
const tasks = await request('/tasks');
|
|
156
|
+
console.log('\n📋 任务列表:\n');
|
|
157
|
+
if (tasks.length === 0) {
|
|
158
|
+
console.log(' (无任务)\n');
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
tasks.forEach(task => {
|
|
162
|
+
console.log(` ${task.id?.slice(0, 8) || 'unknown'}... ${task.status?.padEnd(10) || 'unknown'} ${new Date(task.created_at).toLocaleString()}`);
|
|
163
|
+
});
|
|
164
|
+
console.log('');
|
|
165
|
+
},
|
|
166
|
+
// 健康检查
|
|
167
|
+
async health() {
|
|
168
|
+
const result = await request('/health');
|
|
169
|
+
console.log('\n🔍 Gateway 状态:\n');
|
|
170
|
+
console.log(` 状态: ${result.status}`);
|
|
171
|
+
console.log(` Agent 数量: ${result.agents?.length || 0}`);
|
|
172
|
+
console.log(` 时间: ${new Date(result.timestamp).toLocaleString()}\n`);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
// 主入口
|
|
176
|
+
async function main() {
|
|
177
|
+
const args = process.argv.slice(2);
|
|
178
|
+
if (args.length === 0) {
|
|
179
|
+
console.log(`
|
|
180
|
+
🤖 Agent Gateway CLI
|
|
181
|
+
|
|
182
|
+
用法:
|
|
183
|
+
agent-gateway <command> [options]
|
|
184
|
+
|
|
185
|
+
命令:
|
|
186
|
+
agents, list 列出所有可用 Agent
|
|
187
|
+
task <description> 提交通用任务(自动路由)
|
|
188
|
+
to <agent> <task> 提交任务到指定 Agent
|
|
189
|
+
space, create-space 创建共享空间
|
|
190
|
+
tasks, list-tasks 列出所有任务
|
|
191
|
+
health, status 检查 Gateway 状态
|
|
192
|
+
|
|
193
|
+
示例:
|
|
194
|
+
agent-gateway agents
|
|
195
|
+
agent-gateway task 帮我写一个排序算法
|
|
196
|
+
agent-gateway to claude-code 帮我review这段代码
|
|
197
|
+
agent-gateway health
|
|
198
|
+
`);
|
|
199
|
+
process.exit(0);
|
|
200
|
+
}
|
|
201
|
+
const command = args[0];
|
|
202
|
+
const commandArgs = args.slice(1);
|
|
203
|
+
try {
|
|
204
|
+
switch (command) {
|
|
205
|
+
case 'agents':
|
|
206
|
+
case 'list':
|
|
207
|
+
case 'ls':
|
|
208
|
+
await commands.listAgents();
|
|
209
|
+
break;
|
|
210
|
+
case 'task':
|
|
211
|
+
await commands.submitTask(commandArgs);
|
|
212
|
+
break;
|
|
213
|
+
case 'to':
|
|
214
|
+
if (commandArgs.length < 2) {
|
|
215
|
+
console.error('用法: agent-gateway to <agent> <task>');
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
const agentId = commandArgs[0];
|
|
219
|
+
if (agentId) {
|
|
220
|
+
await commands.submitToAgent(agentId, commandArgs.slice(1));
|
|
221
|
+
}
|
|
222
|
+
break;
|
|
223
|
+
case 'space':
|
|
224
|
+
case 'create-space':
|
|
225
|
+
await commands.createSpace();
|
|
226
|
+
break;
|
|
227
|
+
case 'tasks':
|
|
228
|
+
case 'list-tasks':
|
|
229
|
+
await commands.listTasks();
|
|
230
|
+
break;
|
|
231
|
+
case 'health':
|
|
232
|
+
case 'status':
|
|
233
|
+
await commands.health();
|
|
234
|
+
break;
|
|
235
|
+
default:
|
|
236
|
+
console.error(`❌ 未知命令: ${command}`);
|
|
237
|
+
console.log('运行 agent-gateway 查看帮助');
|
|
238
|
+
process.exit(1);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
console.error(`\n❌ 错误: ${error.message}\n`);
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
main();
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { AgentAdapter } from '../adapters/base.js';
|
|
2
|
+
import type { Agent } from '../types/index.js';
|
|
3
|
+
export declare class AgentRegistry {
|
|
4
|
+
private adapters;
|
|
5
|
+
private initialized;
|
|
6
|
+
constructor();
|
|
7
|
+
/**
|
|
8
|
+
* 初始化注册表
|
|
9
|
+
*/
|
|
10
|
+
initialize(): void;
|
|
11
|
+
/**
|
|
12
|
+
* 从配置注册所有 Agent
|
|
13
|
+
*/
|
|
14
|
+
private registerAllFromConfig;
|
|
15
|
+
/**
|
|
16
|
+
* 注册自定义适配器
|
|
17
|
+
*/
|
|
18
|
+
register(adapter: AgentAdapter): void;
|
|
19
|
+
/**
|
|
20
|
+
* 获取适配器
|
|
21
|
+
*/
|
|
22
|
+
get(agentId: string): AgentAdapter | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* 获取所有适配器
|
|
25
|
+
*/
|
|
26
|
+
getAll(): AgentAdapter[];
|
|
27
|
+
/**
|
|
28
|
+
* 获取所有 Agent 信息
|
|
29
|
+
*/
|
|
30
|
+
getAgents(): Agent[];
|
|
31
|
+
/**
|
|
32
|
+
* 根据能力查找 Agent
|
|
33
|
+
*/
|
|
34
|
+
findByCapability(capability: string): Agent[];
|
|
35
|
+
/**
|
|
36
|
+
* 检查适配器是否存在
|
|
37
|
+
*/
|
|
38
|
+
has(agentId: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* 检查适配器是否健康
|
|
41
|
+
*/
|
|
42
|
+
checkHealth(agentId: string): Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* 获取可用 Agent 列表(健康检查)
|
|
45
|
+
*/
|
|
46
|
+
getAvailableAgents(): Promise<Agent[]>;
|
|
47
|
+
}
|
|
48
|
+
export declare const agentRegistry: AgentRegistry;
|
|
@@ -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;
|