@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.
- package/CHANGELOG.md +60 -41
- package/README.zh-CN.md +137 -167
- package/config/gateway.yaml +78 -0
- package/dist/src/adapters/base.d.ts +22 -0
- package/dist/src/adapters/base.js +10 -0
- package/dist/src/adapters/claude-code.d.ts +22 -0
- package/dist/src/adapters/claude-code.js +112 -0
- package/dist/src/adapters/openclaw.d.ts +22 -0
- package/dist/src/adapters/openclaw.js +110 -0
- package/dist/src/adapters/process.d.ts +28 -0
- package/dist/src/adapters/process.js +121 -0
- package/dist/src/cli/connect.d.ts +26 -0
- package/dist/src/cli/connect.js +544 -0
- package/dist/src/cli/setup.d.ts +2 -0
- package/dist/src/cli/setup.js +97 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +410 -0
- package/dist/src/core/agent-registry.d.ts +48 -0
- package/dist/src/core/agent-registry.js +295 -0
- package/dist/src/core/config.d.ts +59 -0
- package/dist/src/core/config.js +101 -0
- package/dist/src/core/context-manager.d.ts +52 -0
- package/dist/src/core/context-manager.js +165 -0
- package/dist/src/core/event-bus.d.ts +35 -0
- package/dist/src/core/event-bus.js +62 -0
- package/dist/src/core/logger.d.ts +14 -0
- package/dist/src/core/logger.js +57 -0
- package/dist/src/core/metrics.d.ts +87 -0
- package/dist/src/core/metrics.js +167 -0
- package/dist/src/core/router.d.ts +46 -0
- package/dist/src/core/router.js +90 -0
- package/dist/src/core/task-manager.d.ts +41 -0
- package/dist/src/core/task-manager.js +197 -0
- package/dist/src/core/vector-store.d.ts +37 -0
- package/dist/src/core/vector-store.js +175 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +105 -0
- package/dist/src/model-gateway/circuit-breaker.d.ts +21 -0
- package/dist/src/model-gateway/circuit-breaker.js +86 -0
- package/dist/src/model-gateway/health.d.ts +12 -0
- package/dist/src/model-gateway/health.js +80 -0
- package/dist/src/model-gateway/providers.d.ts +4 -0
- package/dist/src/model-gateway/providers.js +113 -0
- package/dist/src/model-gateway/quota.d.ts +4 -0
- package/dist/src/model-gateway/quota.js +107 -0
- package/dist/src/model-gateway/rate-limit.d.ts +12 -0
- package/dist/src/model-gateway/rate-limit.js +51 -0
- package/dist/src/model-gateway/retry.d.ts +14 -0
- package/dist/src/model-gateway/retry.js +48 -0
- package/dist/src/model-gateway/router.d.ts +4 -0
- package/dist/src/model-gateway/router.js +79 -0
- package/dist/src/model-gateway/routes.d.ts +2 -0
- package/dist/src/model-gateway/routes.js +172 -0
- package/dist/src/model-gateway/types.d.ts +47 -0
- package/dist/src/model-gateway/types.js +1 -0
- package/dist/src/routes/api.d.ts +2 -0
- package/dist/src/routes/api.js +128 -0
- package/dist/src/routes/websocket.d.ts +2 -0
- package/dist/src/routes/websocket.js +64 -0
- package/dist/src/types/index.d.ts +71 -0
- package/dist/src/types/index.js +1 -0
- package/dist/tests/core/context-manager.test.d.ts +1 -0
- package/dist/tests/core/context-manager.test.js +35 -0
- package/dist/tests/core/router.test.d.ts +1 -0
- package/dist/tests/core/router.test.js +79 -0
- package/dist/tests/model-gateway/circuit-breaker.test.d.ts +1 -0
- package/dist/tests/model-gateway/circuit-breaker.test.js +84 -0
- package/dist/tests/model-gateway/providers.test.d.ts +1 -0
- package/dist/tests/model-gateway/providers.test.js +80 -0
- package/dist/tests/model-gateway/quota.test.d.ts +1 -0
- package/dist/tests/model-gateway/quota.test.js +60 -0
- package/dist/tests/model-gateway/rate-limit.test.d.ts +1 -0
- package/dist/tests/model-gateway/rate-limit.test.js +42 -0
- package/dist/tests/model-gateway/retry.test.d.ts +1 -0
- package/dist/tests/model-gateway/retry.test.js +47 -0
- package/dist/tests/model-gateway/router.test.d.ts +1 -0
- package/dist/tests/model-gateway/router.test.js +108 -0
- package/dist/tests/model-gateway/routes.test.d.ts +1 -0
- package/dist/tests/model-gateway/routes.test.js +83 -0
- package/docs/api.md +187 -460
- package/docs/architecture.md +138 -0
- package/docs/configuration.md +188 -0
- package/package.json +3 -1
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Agent Mesh Gateway CLI
|
|
4
|
+
* 统一命令行接口 — start, setup, health, models, quota, config, doctor, help
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
7
|
+
import { resolve, dirname, join } from 'node:path';
|
|
8
|
+
import { initLogger } from './core/logger.js';
|
|
9
|
+
const PROJECT_ROOT = resolve(dirname(import.meta.dir), '..');
|
|
10
|
+
const VERSION = '1.1.0';
|
|
11
|
+
const BANNER = `
|
|
12
|
+
█████╗ ██████╗ ███████╗███╗ ██╗████████╗
|
|
13
|
+
██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝
|
|
14
|
+
███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║
|
|
15
|
+
██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║
|
|
16
|
+
██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║
|
|
17
|
+
╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝
|
|
18
|
+
𝙼 𝙴 𝚂 𝙷 𝙶 𝙰 𝚃 𝙴 𝚆 𝙰 𝚈 v${VERSION}
|
|
19
|
+
`;
|
|
20
|
+
const BASE_URL = () => {
|
|
21
|
+
const host = Bun.env.AGENT_GATEWAY_HOST || '127.0.0.1';
|
|
22
|
+
const port = Bun.env.AGENT_GATEWAY_PORT || '3000';
|
|
23
|
+
return `http://${host}:${port}`;
|
|
24
|
+
};
|
|
25
|
+
async function apiRequest(path, opts) {
|
|
26
|
+
const resp = await fetch(`${BASE_URL()}${path}`, {
|
|
27
|
+
...opts,
|
|
28
|
+
headers: { 'Content-Type': 'application/json', ...opts?.headers },
|
|
29
|
+
signal: AbortSignal.timeout(15_000),
|
|
30
|
+
});
|
|
31
|
+
if (!resp.ok) {
|
|
32
|
+
const err = (await resp.json().catch(() => ({ message: resp.statusText })));
|
|
33
|
+
throw new Error(`[${resp.status}] ${err.message || 'Unknown error'}`);
|
|
34
|
+
}
|
|
35
|
+
return resp.json();
|
|
36
|
+
}
|
|
37
|
+
// ===========================================================================
|
|
38
|
+
// Help
|
|
39
|
+
// ===========================================================================
|
|
40
|
+
function showHelp(topic) {
|
|
41
|
+
if (topic === 'start' || topic === 'run') {
|
|
42
|
+
console.log(`
|
|
43
|
+
agentmesh start — 启动网关服务
|
|
44
|
+
|
|
45
|
+
用法:
|
|
46
|
+
agentmesh start [--port PORT] [--host HOST]
|
|
47
|
+
|
|
48
|
+
选项:
|
|
49
|
+
--port 监听端口 (默认: 3000)
|
|
50
|
+
--host 监听地址 (默认: 0.0.0.0)
|
|
51
|
+
|
|
52
|
+
示例:
|
|
53
|
+
agentmesh start
|
|
54
|
+
agentmesh start --port 9400`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (topic === 'setup') {
|
|
58
|
+
console.log(` agentmesh setup — 交互式初始化向导
|
|
59
|
+
|
|
60
|
+
引导配置:
|
|
61
|
+
- API Key (DeepSeek, OpenAI, OpenRouter)
|
|
62
|
+
- 服务端口和日志级别
|
|
63
|
+
- 生成 .env 配置文件`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (topic === 'models' || topic === 'model') {
|
|
67
|
+
console.log(` agentmesh models — 列出可用模型`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (topic === 'quota') {
|
|
71
|
+
console.log(` agentmesh quota — 查看配额状态 (需 codexbar)
|
|
72
|
+
|
|
73
|
+
显示所有 Provider 的实时配额/余额信息。
|
|
74
|
+
首次调用可能较慢 (codexbar 数据采集)。`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (topic === 'config') {
|
|
78
|
+
console.log(` agentmesh config — 配置管理
|
|
79
|
+
|
|
80
|
+
用法:
|
|
81
|
+
agentmesh config show 显示当前配置
|
|
82
|
+
agentmesh config path 显示配置文件路径
|
|
83
|
+
agentmesh config edit 在编辑器中打开配置`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
console.log(`
|
|
87
|
+
${BANNER}
|
|
88
|
+
🤖 Agent Mesh Gateway CLI v${VERSION}
|
|
89
|
+
|
|
90
|
+
用法:
|
|
91
|
+
agentmesh <command> [options]
|
|
92
|
+
|
|
93
|
+
管理命令:
|
|
94
|
+
start 启动网关服务
|
|
95
|
+
setup 交互式初始化向导 (配置API Key等)
|
|
96
|
+
doctor 系统诊断检查
|
|
97
|
+
|
|
98
|
+
接入命令:
|
|
99
|
+
connect [tool] 一键接入 AI 工具 (--dry-run 预览)
|
|
100
|
+
disconnect [tool] 恢复工具配置到接入前状态
|
|
101
|
+
|
|
102
|
+
查询命令:
|
|
103
|
+
health, status 健康检查
|
|
104
|
+
models 列出可用模型
|
|
105
|
+
quota 查看配额状态
|
|
106
|
+
agents 列出已注册 Agent
|
|
107
|
+
tasks 列出任务列表
|
|
108
|
+
|
|
109
|
+
配置命令:
|
|
110
|
+
config show 显示当前配置
|
|
111
|
+
config path 显示配置文件路径
|
|
112
|
+
config edit 在编辑器中打开配置
|
|
113
|
+
|
|
114
|
+
获取帮助:
|
|
115
|
+
help 显示此帮助
|
|
116
|
+
help <command> 显示特定命令帮助
|
|
117
|
+
|
|
118
|
+
示例:
|
|
119
|
+
agentmesh start
|
|
120
|
+
agentmesh setup
|
|
121
|
+
agentmesh connect --dry-run # 预览接入变更
|
|
122
|
+
agentmesh connect all # 接入所有工具
|
|
123
|
+
agentmesh disconnect all # 恢复所有工具
|
|
124
|
+
|
|
125
|
+
文档: https://github.com/starlink-awaken/agentmesh
|
|
126
|
+
`);
|
|
127
|
+
}
|
|
128
|
+
// ===========================================================================
|
|
129
|
+
// Commands
|
|
130
|
+
// ===========================================================================
|
|
131
|
+
async function cmdStart(args) {
|
|
132
|
+
// 解析参数
|
|
133
|
+
const portArg = args.indexOf('--port');
|
|
134
|
+
const hostArg = args.indexOf('--host');
|
|
135
|
+
const port = portArg >= 0 ? args[portArg + 1] || '3000' : '3000';
|
|
136
|
+
const host = hostArg >= 0 ? args[hostArg + 1] || '0.0.0.0' : '0.0.0.0';
|
|
137
|
+
// 设置环境变量传递给服务器
|
|
138
|
+
Bun.env.AGENT_GATEWAY_PORT = port;
|
|
139
|
+
Bun.env.AGENT_GATEWAY_HOST = host;
|
|
140
|
+
console.log(`${BANNER}
|
|
141
|
+
🚀 Starting Agent Mesh Gateway...
|
|
142
|
+
═══════════════════════════════════════
|
|
143
|
+
HTTP: http://${host}:${port}
|
|
144
|
+
Health: http://${host}:${port}/health
|
|
145
|
+
Models: http://${host}:${port}/v1/models
|
|
146
|
+
Quota: http://${host}:${port}/model-gateway/quota
|
|
147
|
+
Docs: http://${host}:${port}/docs
|
|
148
|
+
═══════════════════════════════════════
|
|
149
|
+
`);
|
|
150
|
+
// 动态导入并启动服务器
|
|
151
|
+
await import('./index.js');
|
|
152
|
+
// 服务器会在导入时启动
|
|
153
|
+
}
|
|
154
|
+
async function cmdHealth() {
|
|
155
|
+
try {
|
|
156
|
+
const data = await apiRequest('/health');
|
|
157
|
+
console.log(`\n ✅ Gateway Running`);
|
|
158
|
+
console.log(` Status: ${data.status}`);
|
|
159
|
+
console.log(` Agents: ${data.agents?.length || 0}`);
|
|
160
|
+
console.log(` Timestamp: ${new Date(data.timestamp).toISOString()}\n`);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
console.error(`\n ❌ Gateway not reachable at ${BASE_URL()}`);
|
|
164
|
+
console.error(` Error: ${err.message}`);
|
|
165
|
+
console.log(`\n Start it with: agentmesh start\n`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async function cmdModels() {
|
|
169
|
+
try {
|
|
170
|
+
const data = await apiRequest('/v1/models');
|
|
171
|
+
console.log('\n 📋 Available Models:\n');
|
|
172
|
+
const byProvider = {};
|
|
173
|
+
for (const m of data.data || []) {
|
|
174
|
+
(byProvider[m.owned_by] ??= []).push(m.id);
|
|
175
|
+
}
|
|
176
|
+
for (const [provider, models] of Object.entries(byProvider)) {
|
|
177
|
+
console.log(` ${provider}:`);
|
|
178
|
+
models.forEach(m => console.log(` - ${m}`));
|
|
179
|
+
console.log('');
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
console.error(`\n ❌ ${err.message}\n`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async function cmdQuota() {
|
|
187
|
+
try {
|
|
188
|
+
console.log('\n ⏳ Fetching quota data (may take ~15s)...');
|
|
189
|
+
const data = await apiRequest('/model-gateway/quota', { signal: AbortSignal.timeout(60_000) });
|
|
190
|
+
console.log('\n 📊 Provider Quota Status:\n');
|
|
191
|
+
if (!data || Object.keys(data).length === 0) {
|
|
192
|
+
console.log(' No quota data available. Is codexbar installed?\n');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
for (const [name, info] of Object.entries(data)) {
|
|
196
|
+
const icon = info.available ? '🟢' : '🔴';
|
|
197
|
+
console.log(` ${icon} ${name.padEnd(15)} ${info.summary}`);
|
|
198
|
+
}
|
|
199
|
+
console.log('');
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
console.error(`\n ❌ ${err.message}\n`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
async function cmdAgents() {
|
|
206
|
+
try {
|
|
207
|
+
const data = await apiRequest('/agents');
|
|
208
|
+
console.log('\n 📋 Registered Agents:\n');
|
|
209
|
+
data.forEach(a => console.log(` ${a.status === 'online' ? '🟢' : '⚫'} ${a.id.padEnd(18)} ${a.name.padEnd(22)} [${a.status}]\n ${(a.capabilities || []).join(', ')}\n`));
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
console.error(`\n ❌ ${err.message}\n`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
async function cmdTasks() {
|
|
216
|
+
try {
|
|
217
|
+
const tasks = await apiRequest('/tasks');
|
|
218
|
+
console.log('\n 📋 Tasks:\n');
|
|
219
|
+
if (!tasks.length) {
|
|
220
|
+
console.log(' (none)\n');
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
tasks.forEach(t => console.log(` ${t.id?.slice(0, 8)}... ${t.status?.padEnd(10)} ${new Date(t.created_at).toLocaleString()}`));
|
|
224
|
+
console.log('');
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
console.error(`\n ❌ ${err.message}\n`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
async function cmdConfig(args) {
|
|
231
|
+
const configPath = join(PROJECT_ROOT, 'config', 'gateway.yaml');
|
|
232
|
+
const sub = args[0];
|
|
233
|
+
if (sub === 'path') {
|
|
234
|
+
console.log(`\n Config: ${configPath}\n`);
|
|
235
|
+
}
|
|
236
|
+
else if (sub === 'edit') {
|
|
237
|
+
const editor = Bun.env.EDITOR || Bun.env.VISUAL || 'vim';
|
|
238
|
+
console.log(` Opening ${configPath} with ${editor}...`);
|
|
239
|
+
Bun.spawnSync([editor, configPath], { stdio: ['inherit', 'inherit', 'inherit'] });
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
// show
|
|
243
|
+
try {
|
|
244
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
245
|
+
console.log(`\n ── ${configPath} ──\n`);
|
|
246
|
+
console.log(content.split('\n').map(l => ` ${l}`).join('\n'));
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
console.error(`\n ❌ Config not found: ${configPath}\n`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
async function cmdDoctor() {
|
|
254
|
+
console.log('\n 🔍 Agent Mesh Gateway Diagnostics\n');
|
|
255
|
+
const checks = [];
|
|
256
|
+
// bun
|
|
257
|
+
try {
|
|
258
|
+
const proc = Bun.spawnSync({ cmd: ['bun', '--version'], stdout: 'pipe' });
|
|
259
|
+
const ver = new TextDecoder().decode(proc.stdout).trim();
|
|
260
|
+
checks.push(['Bun Runtime', true, ver]);
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
checks.push(['Bun Runtime', false, 'Not found']);
|
|
264
|
+
}
|
|
265
|
+
// codexbar
|
|
266
|
+
try {
|
|
267
|
+
const proc = Bun.spawnSync({ cmd: ['codexbar', '--version'], stdout: 'pipe', stderr: 'pipe' });
|
|
268
|
+
checks.push(['codexbar', proc.exitCode === 0, proc.exitCode === 0 ? 'OK' : 'Warning']);
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
checks.push(['codexbar', false, 'Install for quota tracking']);
|
|
272
|
+
}
|
|
273
|
+
// API keys
|
|
274
|
+
for (const [name, env] of [['DeepSeek', 'DEEPSEEK_API_KEY'], ['OpenAI', 'OPENAI_API_KEY'], ['OpenRouter', 'OPENROUTER_API_KEY']]) {
|
|
275
|
+
checks.push([`${name} API Key`, !!Bun.env[env], Bun.env[env] ? 'Configured (env)' : 'Not set']);
|
|
276
|
+
}
|
|
277
|
+
// .env file
|
|
278
|
+
const envPath = join(PROJECT_ROOT, '.env');
|
|
279
|
+
checks.push(['.env file', existsSync(envPath), existsSync(envPath) ? 'Exists' : 'Run: agentmesh setup']);
|
|
280
|
+
// docker
|
|
281
|
+
try {
|
|
282
|
+
const proc = Bun.spawnSync({ cmd: ['docker', '--version'], stdout: 'pipe' });
|
|
283
|
+
checks.push(['Docker', true, new TextDecoder().decode(proc.stdout).trim()]);
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
checks.push(['Docker', false, 'Not required']);
|
|
287
|
+
}
|
|
288
|
+
// config
|
|
289
|
+
const configPath = join(PROJECT_ROOT, 'config', 'gateway.yaml');
|
|
290
|
+
checks.push(['Config file', existsSync(configPath), existsSync(configPath) ? 'OK' : 'Missing!']);
|
|
291
|
+
// Print
|
|
292
|
+
for (const [name, ok, detail] of checks) {
|
|
293
|
+
console.log(` ${ok ? '✅' : '⚠️'} ${name.padEnd(20)} ${detail}`);
|
|
294
|
+
}
|
|
295
|
+
// Gateway status
|
|
296
|
+
try {
|
|
297
|
+
await apiRequest('/health');
|
|
298
|
+
console.log(` ✅ Gateway Running at ${BASE_URL()}`);
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
console.log(' ⚠️ Gateway Not running (start: agentmesh start)');
|
|
302
|
+
}
|
|
303
|
+
console.log('');
|
|
304
|
+
}
|
|
305
|
+
// ===========================================================================
|
|
306
|
+
// Main
|
|
307
|
+
// ===========================================================================
|
|
308
|
+
async function main() {
|
|
309
|
+
const args = Bun.argv.slice(2);
|
|
310
|
+
initLogger({ level: Bun.env.LOG_LEVEL || 'info', dir: join(PROJECT_ROOT, 'logs') });
|
|
311
|
+
if (args.length === 0 || args[0] === 'help' || args[0] === '--help' || args[0] === '-h') {
|
|
312
|
+
showHelp(args[1]);
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
const cmd = args[0];
|
|
316
|
+
const rest = args.slice(1);
|
|
317
|
+
try {
|
|
318
|
+
switch (cmd) {
|
|
319
|
+
case 'start':
|
|
320
|
+
case 'run':
|
|
321
|
+
await cmdStart(rest);
|
|
322
|
+
break;
|
|
323
|
+
case 'setup':
|
|
324
|
+
case 'init':
|
|
325
|
+
const { runSetup } = await import('./cli/setup.js');
|
|
326
|
+
await runSetup();
|
|
327
|
+
break;
|
|
328
|
+
case 'health':
|
|
329
|
+
case 'status':
|
|
330
|
+
await cmdHealth();
|
|
331
|
+
break;
|
|
332
|
+
case 'models':
|
|
333
|
+
case 'model':
|
|
334
|
+
await cmdModels();
|
|
335
|
+
break;
|
|
336
|
+
case 'quota':
|
|
337
|
+
await cmdQuota();
|
|
338
|
+
break;
|
|
339
|
+
case 'agents':
|
|
340
|
+
case 'ls':
|
|
341
|
+
await cmdAgents();
|
|
342
|
+
break;
|
|
343
|
+
case 'tasks':
|
|
344
|
+
await cmdTasks();
|
|
345
|
+
break;
|
|
346
|
+
case 'config':
|
|
347
|
+
await cmdConfig(rest);
|
|
348
|
+
break;
|
|
349
|
+
case 'connect': {
|
|
350
|
+
// 子命令: connect list
|
|
351
|
+
if (rest[0] === 'list') {
|
|
352
|
+
const { listDetectedTools } = await import('./cli/connect.js');
|
|
353
|
+
const tools = listDetectedTools();
|
|
354
|
+
console.log('\n 🔍 检测到的 AI 工具:\n');
|
|
355
|
+
for (const t of tools) {
|
|
356
|
+
console.log(` ${t.installed ? '🟢' : '⚫'} ${t.name.padEnd(18)} ${t.description}`);
|
|
357
|
+
if (t.configPath)
|
|
358
|
+
console.log(` Config: ${t.configPath}`);
|
|
359
|
+
}
|
|
360
|
+
console.log(`\n 执行 \`agentmesh connect\` 进入交互式选择`);
|
|
361
|
+
console.log(` 执行 \`agentmesh connect all --dry-run\` 预览接入变更\n`);
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
// 无参数或 -i → 交互式选择
|
|
365
|
+
const hasTargets = rest.some(a => !a.startsWith('--'));
|
|
366
|
+
const isInteractive = rest.includes('-i') || rest.includes('--interactive') || !hasTargets;
|
|
367
|
+
if (isInteractive && !rest.includes('--dry-run')) {
|
|
368
|
+
const { interactiveConnect } = await import('./cli/connect.js');
|
|
369
|
+
await interactiveConnect();
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
const { connectTools } = await import('./cli/connect.js');
|
|
373
|
+
const dryRun = rest.includes('--dry-run');
|
|
374
|
+
const targets = rest.filter(a => !a.startsWith('--') && a !== '-i' && a !== '--interactive');
|
|
375
|
+
const results = await connectTools(targets.length ? targets : ['all'], { dryRun });
|
|
376
|
+
console.log('\n 接入结果:\n');
|
|
377
|
+
for (const r of results) {
|
|
378
|
+
const icon = r.status === 'ok' ? '✅' : r.status === 'skipped' ? '⏭️' : '❌';
|
|
379
|
+
console.log(` ${icon} ${r.tool.padEnd(16)} ${r.detail}`);
|
|
380
|
+
}
|
|
381
|
+
if (dryRun)
|
|
382
|
+
console.log('\n ⚠️ DRY-RUN 模式,未实际修改文件');
|
|
383
|
+
else
|
|
384
|
+
console.log(`\n 💡 使用 \`agentmesh disconnect\` 恢复配置`);
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
case 'disconnect': {
|
|
388
|
+
const { disconnectTools } = await import('./cli/connect.js');
|
|
389
|
+
const targets = rest.filter(a => !a.startsWith('--'));
|
|
390
|
+
const results = await disconnectTools(targets.length ? targets : ['all']);
|
|
391
|
+
console.log('\n 断开结果:\n');
|
|
392
|
+
for (const r of results) {
|
|
393
|
+
const icon = r.status === 'ok' ? '✅' : '❌';
|
|
394
|
+
console.log(` ${icon} ${r.tool.padEnd(16)} ${r.detail}`);
|
|
395
|
+
}
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
case 'doctor':
|
|
399
|
+
case 'check':
|
|
400
|
+
await cmdDoctor();
|
|
401
|
+
break;
|
|
402
|
+
default:
|
|
403
|
+
console.error(`\n ❌ Unknown command: ${cmd}\n Run 'agentmesh help' for available commands.\n`);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
catch (err) {
|
|
407
|
+
console.error(`\n ❌ Error: ${err.message}\n`);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
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;
|