@onesclawkolor/onesclaw 0.1.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/README.md +65 -0
- package/dist/agent/conversation.d.ts +34 -0
- package/dist/agent/conversation.js +61 -0
- package/dist/agent/conversation.js.map +1 -0
- package/dist/agent/loop.d.ts +40 -0
- package/dist/agent/loop.js +213 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/session.d.ts +73 -0
- package/dist/agent/session.js +225 -0
- package/dist/agent/session.js.map +1 -0
- package/dist/audit/file-sink.d.ts +6 -0
- package/dist/audit/file-sink.js +21 -0
- package/dist/audit/file-sink.js.map +1 -0
- package/dist/audit/ids.d.ts +3 -0
- package/dist/audit/ids.js +15 -0
- package/dist/audit/ids.js.map +1 -0
- package/dist/audit/types.d.ts +13 -0
- package/dist/audit/types.js +2 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/cli/commands.d.ts +31 -0
- package/dist/cli/commands.js +433 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/logger.d.ts +57 -0
- package/dist/cli/logger.js +79 -0
- package/dist/cli/logger.js.map +1 -0
- package/dist/cli/output.d.ts +59 -0
- package/dist/cli/output.js +306 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/prompt.d.ts +29 -0
- package/dist/cli/prompt.js +197 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/repl.d.ts +4 -0
- package/dist/cli/repl.js +486 -0
- package/dist/cli/repl.js.map +1 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +84 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/model.d.ts +3 -0
- package/dist/commands/model.js +178 -0
- package/dist/commands/model.js.map +1 -0
- package/dist/commands/plugin-init.d.ts +23 -0
- package/dist/commands/plugin-init.js +303 -0
- package/dist/commands/plugin-init.js.map +1 -0
- package/dist/commands/provider-auth.d.ts +14 -0
- package/dist/commands/provider-auth.js +153 -0
- package/dist/commands/provider-auth.js.map +1 -0
- package/dist/config/manager.d.ts +71 -0
- package/dist/config/manager.js +201 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/types.d.ts +43 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/errors.d.ts +37 -0
- package/dist/errors.js +55 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +207 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/anthropic.d.ts +83 -0
- package/dist/llm/anthropic.js +190 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/factory.d.ts +105 -0
- package/dist/llm/factory.js +164 -0
- package/dist/llm/factory.js.map +1 -0
- package/dist/llm/openai-codex.d.ts +102 -0
- package/dist/llm/openai-codex.js +445 -0
- package/dist/llm/openai-codex.js.map +1 -0
- package/dist/llm/openai.d.ts +71 -0
- package/dist/llm/openai.js +289 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/llm/provider.d.ts +1 -0
- package/dist/llm/provider.js +2 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/types.d.ts +72 -0
- package/dist/llm/types.js +2 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/mcp/bridge.d.ts +17 -0
- package/dist/mcp/bridge.js +74 -0
- package/dist/mcp/bridge.js.map +1 -0
- package/dist/mcp/config.d.ts +10 -0
- package/dist/mcp/config.js +27 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/manager.d.ts +67 -0
- package/dist/mcp/manager.js +207 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/memory/scope.d.ts +4 -0
- package/dist/memory/scope.js +14 -0
- package/dist/memory/scope.js.map +1 -0
- package/dist/memory/store.d.ts +28 -0
- package/dist/memory/store.js +126 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/prompts/system.d.ts +4 -0
- package/dist/prompts/system.js +197 -0
- package/dist/prompts/system.js.map +1 -0
- package/dist/skills/loader.d.ts +25 -0
- package/dist/skills/loader.js +98 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/registry.d.ts +57 -0
- package/dist/skills/registry.js +132 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/sync.d.ts +33 -0
- package/dist/skills/sync.js +180 -0
- package/dist/skills/sync.js.map +1 -0
- package/dist/skills/types.d.ts +1 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/tools/ask.d.ts +30 -0
- package/dist/tools/ask.js +60 -0
- package/dist/tools/ask.js.map +1 -0
- package/dist/tools/confirmation.d.ts +12 -0
- package/dist/tools/confirmation.js +75 -0
- package/dist/tools/confirmation.js.map +1 -0
- package/dist/tools/plugin-init.d.ts +29 -0
- package/dist/tools/plugin-init.js +47 -0
- package/dist/tools/plugin-init.js.map +1 -0
- package/dist/tools/registry.d.ts +56 -0
- package/dist/tools/registry.js +123 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/safety.d.ts +2 -0
- package/dist/tools/safety.js +30 -0
- package/dist/tools/safety.js.map +1 -0
- package/dist/tools/server.d.ts +91 -0
- package/dist/tools/server.js +149 -0
- package/dist/tools/server.js.map +1 -0
- package/dist/tools/shell.d.ts +11 -0
- package/dist/tools/shell.js +174 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/tools/skills-sync.d.ts +19 -0
- package/dist/tools/skills-sync.js +29 -0
- package/dist/tools/skills-sync.js.map +1 -0
- package/dist/tools/ssh.d.ts +62 -0
- package/dist/tools/ssh.js +343 -0
- package/dist/tools/ssh.js.map +1 -0
- package/dist/tools/types.d.ts +10 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/utils/retry.d.ts +7 -0
- package/dist/utils/retry.js +34 -0
- package/dist/utils/retry.js.map +1 -0
- package/install.sh +171 -0
- package/package.json +49 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import OpenAI from 'openai';
|
|
3
|
+
import { logger } from '../cli/logger.js';
|
|
4
|
+
import { LLMError } from '../errors.js';
|
|
5
|
+
import { withRetry } from '../utils/retry.js';
|
|
6
|
+
const DEFAULT_MODEL = 'gpt-4o';
|
|
7
|
+
const DEFAULT_MAX_TOKENS = 8192;
|
|
8
|
+
/**
|
|
9
|
+
* OpenAI LLM Provider
|
|
10
|
+
*
|
|
11
|
+
* 实现统一 LLMProvider 接口,内部将 Anthropic 格式的消息/工具转换为 OpenAI 格式,
|
|
12
|
+
* 并将 OpenAI 流式响应转换回统一的 StreamEvent。
|
|
13
|
+
*
|
|
14
|
+
* 同时支持 API Key 和 OAuth access_token(OpenAI SDK 的 apiKey 参数兼容两者)。
|
|
15
|
+
*/
|
|
16
|
+
export class OpenAIProvider {
|
|
17
|
+
name = 'openai';
|
|
18
|
+
client;
|
|
19
|
+
constructor(apiKeyOrToken, baseUrl) {
|
|
20
|
+
this.client = new OpenAI({
|
|
21
|
+
apiKey: apiKeyOrToken,
|
|
22
|
+
...(baseUrl ? { baseURL: baseUrl } : {}),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
async *chat(messages, tools, options) {
|
|
26
|
+
const model = options?.model || DEFAULT_MODEL;
|
|
27
|
+
const maxTokens = options?.maxTokens || DEFAULT_MAX_TOKENS;
|
|
28
|
+
// 构造请求参数
|
|
29
|
+
const openaiMessages = convertMessages(messages, options?.system);
|
|
30
|
+
const params = {
|
|
31
|
+
model,
|
|
32
|
+
max_tokens: maxTokens,
|
|
33
|
+
messages: openaiMessages,
|
|
34
|
+
stream: true,
|
|
35
|
+
stream_options: { include_usage: true },
|
|
36
|
+
};
|
|
37
|
+
if (options?.temperature !== undefined) {
|
|
38
|
+
params.temperature = options.temperature;
|
|
39
|
+
}
|
|
40
|
+
if (tools.length > 0) {
|
|
41
|
+
params.tools = convertTools(tools);
|
|
42
|
+
}
|
|
43
|
+
logger.debug('llm', `→ Request: model=${model}, tools=${tools.length}, messages=${messages.length}`);
|
|
44
|
+
// 创建流(带重试)
|
|
45
|
+
let stream;
|
|
46
|
+
try {
|
|
47
|
+
stream = await withRetry(() => this.client.chat.completions.create(params), {
|
|
48
|
+
maxRetries: 3,
|
|
49
|
+
baseDelayMs: 1000,
|
|
50
|
+
maxDelayMs: 8000,
|
|
51
|
+
shouldRetry: (e) => isRetryableError(e),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
yield { type: 'error', error: classifyError(error) };
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// 处理流式事件
|
|
59
|
+
try {
|
|
60
|
+
const activeToolCalls = new Map();
|
|
61
|
+
let inputTokens = 0;
|
|
62
|
+
for await (const chunk of stream) {
|
|
63
|
+
const choice = chunk.choices?.[0];
|
|
64
|
+
// usage chunk (最后一个 chunk,choices 为空)
|
|
65
|
+
if (chunk.usage) {
|
|
66
|
+
inputTokens = chunk.usage.prompt_tokens || 0;
|
|
67
|
+
}
|
|
68
|
+
if (!choice)
|
|
69
|
+
continue;
|
|
70
|
+
const delta = choice.delta;
|
|
71
|
+
// 文本内容
|
|
72
|
+
if (delta?.content) {
|
|
73
|
+
yield { type: 'text_delta', text: delta.content };
|
|
74
|
+
}
|
|
75
|
+
// tool_calls
|
|
76
|
+
if (delta?.tool_calls) {
|
|
77
|
+
for (const tc of delta.tool_calls) {
|
|
78
|
+
const idx = tc.index;
|
|
79
|
+
if (!activeToolCalls.has(idx)) {
|
|
80
|
+
// 新的 tool_call 开始
|
|
81
|
+
activeToolCalls.set(idx, {
|
|
82
|
+
id: tc.id || '',
|
|
83
|
+
name: tc.function?.name || '',
|
|
84
|
+
started: false,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
const state = activeToolCalls.get(idx);
|
|
88
|
+
// 更新 id/name(可能在后续 chunk 中到达)
|
|
89
|
+
if (tc.id)
|
|
90
|
+
state.id = tc.id;
|
|
91
|
+
if (tc.function?.name)
|
|
92
|
+
state.name = tc.function.name;
|
|
93
|
+
// 发送 tool_use_start(首次有足够信息时)
|
|
94
|
+
if (!state.started && state.id && state.name) {
|
|
95
|
+
state.started = true;
|
|
96
|
+
yield { type: 'tool_use_start', id: state.id, name: state.name };
|
|
97
|
+
}
|
|
98
|
+
// 发送参数增量
|
|
99
|
+
if (tc.function?.arguments) {
|
|
100
|
+
yield { type: 'tool_use_delta', input_json: tc.function.arguments };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// finish_reason
|
|
105
|
+
if (choice.finish_reason) {
|
|
106
|
+
// 结束所有活跃的 tool_calls
|
|
107
|
+
for (const [, state] of activeToolCalls) {
|
|
108
|
+
if (state.started) {
|
|
109
|
+
yield { type: 'tool_use_end' };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
activeToolCalls.clear();
|
|
113
|
+
const outputTokens = chunk.usage?.completion_tokens || 0;
|
|
114
|
+
const stopReason = mapFinishReason(choice.finish_reason);
|
|
115
|
+
logger.debug('llm', `← Response: stop=${stopReason}, in=${inputTokens}, out=${outputTokens}`);
|
|
116
|
+
yield {
|
|
117
|
+
type: 'message_end',
|
|
118
|
+
stop_reason: stopReason,
|
|
119
|
+
usage: { inputTokens, outputTokens },
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
yield {
|
|
126
|
+
type: 'error',
|
|
127
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 将 Anthropic 格式的 Message[] 转换为 OpenAI ChatCompletionMessageParam[]
|
|
134
|
+
*/
|
|
135
|
+
function convertMessages(messages, system) {
|
|
136
|
+
const result = [];
|
|
137
|
+
// system prompt
|
|
138
|
+
if (system) {
|
|
139
|
+
result.push({ role: 'system', content: system });
|
|
140
|
+
}
|
|
141
|
+
for (const msg of messages) {
|
|
142
|
+
if (typeof msg.content === 'string') {
|
|
143
|
+
result.push({ role: msg.role, content: msg.content });
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
// ContentBlock[] 消息需要拆分处理
|
|
147
|
+
if (msg.role === 'assistant') {
|
|
148
|
+
result.push(convertAssistantMessage(msg.content));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// user 消息可能包含 tool_result blocks
|
|
152
|
+
const toolResults = msg.content.filter((b) => b.type === 'tool_result');
|
|
153
|
+
const nonToolBlocks = msg.content.filter((b) => b.type !== 'tool_result');
|
|
154
|
+
// 先添加普通 user 内容
|
|
155
|
+
if (nonToolBlocks.length > 0) {
|
|
156
|
+
const text = nonToolBlocks
|
|
157
|
+
.filter((b) => b.type === 'text')
|
|
158
|
+
.map((b) => b.text)
|
|
159
|
+
.join('');
|
|
160
|
+
if (text) {
|
|
161
|
+
result.push({ role: 'user', content: text });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// tool_result → OpenAI tool role messages
|
|
165
|
+
for (const tr of toolResults) {
|
|
166
|
+
result.push({
|
|
167
|
+
role: 'tool',
|
|
168
|
+
tool_call_id: tr.tool_use_id,
|
|
169
|
+
content: tr.content,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* 将 assistant 消息的 ContentBlock[] 转换为 OpenAI assistant message
|
|
178
|
+
*/
|
|
179
|
+
function convertAssistantMessage(blocks) {
|
|
180
|
+
let textContent = '';
|
|
181
|
+
const toolCalls = [];
|
|
182
|
+
for (const block of blocks) {
|
|
183
|
+
if (block.type === 'text') {
|
|
184
|
+
textContent += block.text;
|
|
185
|
+
}
|
|
186
|
+
else if (block.type === 'tool_use') {
|
|
187
|
+
const toolUse = block;
|
|
188
|
+
toolCalls.push({
|
|
189
|
+
id: toolUse.id,
|
|
190
|
+
type: 'function',
|
|
191
|
+
function: {
|
|
192
|
+
name: toolUse.name,
|
|
193
|
+
arguments: JSON.stringify(toolUse.input),
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const msg = {
|
|
199
|
+
role: 'assistant',
|
|
200
|
+
content: textContent || null,
|
|
201
|
+
};
|
|
202
|
+
if (toolCalls.length > 0) {
|
|
203
|
+
msg.tool_calls = toolCalls;
|
|
204
|
+
}
|
|
205
|
+
return msg;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* 将 Anthropic 格式的 ToolDefinition[] 转换为 OpenAI 格式
|
|
209
|
+
*/
|
|
210
|
+
function convertTools(tools) {
|
|
211
|
+
return tools.map((tool) => ({
|
|
212
|
+
type: 'function',
|
|
213
|
+
function: {
|
|
214
|
+
name: tool.name,
|
|
215
|
+
description: tool.description,
|
|
216
|
+
parameters: tool.input_schema,
|
|
217
|
+
},
|
|
218
|
+
}));
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* 映射 OpenAI finish_reason 到统一的 stop_reason
|
|
222
|
+
*/
|
|
223
|
+
function mapFinishReason(reason) {
|
|
224
|
+
switch (reason) {
|
|
225
|
+
case 'stop':
|
|
226
|
+
return 'end_turn';
|
|
227
|
+
case 'tool_calls':
|
|
228
|
+
return 'tool_use';
|
|
229
|
+
case 'length':
|
|
230
|
+
return 'max_tokens';
|
|
231
|
+
default:
|
|
232
|
+
return reason;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* 判断 API 错误是否可重试
|
|
237
|
+
*/
|
|
238
|
+
function isRetryableError(error) {
|
|
239
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
240
|
+
const status = error?.status;
|
|
241
|
+
if (status === 429 || status === 500 || status === 502 || status === 503) {
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
245
|
+
if (message.includes('fetch') ||
|
|
246
|
+
message.includes('network') ||
|
|
247
|
+
message.includes('ECONNREFUSED') ||
|
|
248
|
+
message.includes('ETIMEDOUT')) {
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* 将原始错误转换为 LLMError
|
|
255
|
+
*/
|
|
256
|
+
function classifyError(error) {
|
|
257
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
258
|
+
const status = error?.status;
|
|
259
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
260
|
+
switch (status) {
|
|
261
|
+
case 401:
|
|
262
|
+
return new LLMError('API 认证失败,请检查 API Key 或 OAuth token 配置', 401, false);
|
|
263
|
+
case 400: {
|
|
264
|
+
if (message.includes('context') ||
|
|
265
|
+
message.includes('too long') ||
|
|
266
|
+
message.includes('max tokens') ||
|
|
267
|
+
message.includes('too many')) {
|
|
268
|
+
return new LLMError(message, 400, false);
|
|
269
|
+
}
|
|
270
|
+
return new LLMError(`请求参数错误: ${message}`, 400, false);
|
|
271
|
+
}
|
|
272
|
+
case 429:
|
|
273
|
+
return new LLMError('API 请求频率超限,已重试仍失败', 429, true);
|
|
274
|
+
case 500:
|
|
275
|
+
case 502:
|
|
276
|
+
case 503:
|
|
277
|
+
return new LLMError(`OpenAI API 服务暂时不可用 (${status}),已重试仍失败`, status, true);
|
|
278
|
+
default: {
|
|
279
|
+
if (message.includes('fetch') ||
|
|
280
|
+
message.includes('network') ||
|
|
281
|
+
message.includes('ECONNREFUSED') ||
|
|
282
|
+
message.includes('ETIMEDOUT')) {
|
|
283
|
+
return new LLMError('网络连接失败,请检查网络', undefined, true);
|
|
284
|
+
}
|
|
285
|
+
return new LLMError(message, status);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/llm/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/llm/provider.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export type Role = 'user' | 'assistant';
|
|
2
|
+
export interface TextBlock {
|
|
3
|
+
type: 'text';
|
|
4
|
+
text: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ToolUseBlock {
|
|
7
|
+
type: 'tool_use';
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
input: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
export interface ToolResultBlock {
|
|
13
|
+
type: 'tool_result';
|
|
14
|
+
tool_use_id: string;
|
|
15
|
+
content: string;
|
|
16
|
+
is_error?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock;
|
|
19
|
+
export interface Message {
|
|
20
|
+
role: Role;
|
|
21
|
+
content: string | ContentBlock[];
|
|
22
|
+
}
|
|
23
|
+
export interface ToolDefinition {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
input_schema: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
export interface TokenUsage {
|
|
29
|
+
inputTokens: number;
|
|
30
|
+
outputTokens: number;
|
|
31
|
+
}
|
|
32
|
+
export type StreamEvent = {
|
|
33
|
+
type: 'turn_start';
|
|
34
|
+
} | {
|
|
35
|
+
type: 'text_delta';
|
|
36
|
+
text: string;
|
|
37
|
+
} | {
|
|
38
|
+
type: 'tool_use_start';
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
} | {
|
|
42
|
+
type: 'tool_use_delta';
|
|
43
|
+
input_json: string;
|
|
44
|
+
} | {
|
|
45
|
+
type: 'tool_use_end';
|
|
46
|
+
} | {
|
|
47
|
+
type: 'tool_execute_start';
|
|
48
|
+
name: string;
|
|
49
|
+
args: Record<string, unknown>;
|
|
50
|
+
} | {
|
|
51
|
+
type: 'tool_execute_end';
|
|
52
|
+
name: string;
|
|
53
|
+
result: string;
|
|
54
|
+
isError?: boolean;
|
|
55
|
+
} | {
|
|
56
|
+
type: 'message_end';
|
|
57
|
+
stop_reason: string;
|
|
58
|
+
usage?: TokenUsage;
|
|
59
|
+
} | {
|
|
60
|
+
type: 'error';
|
|
61
|
+
error: Error;
|
|
62
|
+
};
|
|
63
|
+
export interface ChatOptions {
|
|
64
|
+
model?: string;
|
|
65
|
+
maxTokens?: number;
|
|
66
|
+
system?: string;
|
|
67
|
+
temperature?: number;
|
|
68
|
+
}
|
|
69
|
+
export interface LLMProvider {
|
|
70
|
+
name: string;
|
|
71
|
+
chat(messages: Message[], tools: ToolDefinition[], options?: ChatOptions): AsyncGenerator<StreamEvent, void, unknown>;
|
|
72
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/llm/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 将所有 MCP 工具转换为 Anthropic Tool 格式
|
|
3
|
+
* 工具名添加 {server}__ 前缀以区分来源
|
|
4
|
+
*/
|
|
5
|
+
export declare function getToolDefinitions(manager: any): any[];
|
|
6
|
+
/**
|
|
7
|
+
* 解析带命名空间前缀的工具名
|
|
8
|
+
* @returns [serverName, toolName] 或 null(如果不含前缀)
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseToolName(prefixedName: any): any[];
|
|
11
|
+
/**
|
|
12
|
+
* 根据带前缀的工具名路由到正确的 MCP Server 并调用
|
|
13
|
+
*/
|
|
14
|
+
export declare function callMcpTool(manager: any, prefixedName: any, args: any): Promise<{
|
|
15
|
+
content: any;
|
|
16
|
+
isError: any;
|
|
17
|
+
}>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/** 命名空间分隔符 */
|
|
3
|
+
const NAMESPACE_SEPARATOR = '__';
|
|
4
|
+
/**
|
|
5
|
+
* 将所有 MCP 工具转换为 Anthropic Tool 格式
|
|
6
|
+
* 工具名添加 {server}__ 前缀以区分来源
|
|
7
|
+
*/
|
|
8
|
+
export function getToolDefinitions(manager) {
|
|
9
|
+
const allTools = manager.getAllTools();
|
|
10
|
+
const definitions = [];
|
|
11
|
+
for (const [serverName, tools] of allTools) {
|
|
12
|
+
for (const tool of tools) {
|
|
13
|
+
definitions.push({
|
|
14
|
+
name: `${serverName}${NAMESPACE_SEPARATOR}${tool.name}`,
|
|
15
|
+
description: tool.description || '',
|
|
16
|
+
input_schema: tool.inputSchema || {
|
|
17
|
+
type: 'object',
|
|
18
|
+
properties: {},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return definitions;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 解析带命名空间前缀的工具名
|
|
27
|
+
* @returns [serverName, toolName] 或 null(如果不含前缀)
|
|
28
|
+
*/
|
|
29
|
+
export function parseToolName(prefixedName) {
|
|
30
|
+
const idx = prefixedName.indexOf(NAMESPACE_SEPARATOR);
|
|
31
|
+
if (idx === -1)
|
|
32
|
+
return null;
|
|
33
|
+
const serverName = prefixedName.slice(0, idx);
|
|
34
|
+
const toolName = prefixedName.slice(idx + NAMESPACE_SEPARATOR.length);
|
|
35
|
+
return [serverName, toolName];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 根据带前缀的工具名路由到正确的 MCP Server 并调用
|
|
39
|
+
*/
|
|
40
|
+
export async function callMcpTool(manager, prefixedName, args) {
|
|
41
|
+
const parsed = parseToolName(prefixedName);
|
|
42
|
+
if (!parsed) {
|
|
43
|
+
return {
|
|
44
|
+
content: `工具名格式错误,缺少服务器前缀: ${prefixedName}`,
|
|
45
|
+
isError: true,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const [serverName, toolName] = parsed;
|
|
49
|
+
try {
|
|
50
|
+
const result = await manager.callTool(serverName, toolName, args);
|
|
51
|
+
// 提取文本内容
|
|
52
|
+
const response = result;
|
|
53
|
+
if (response.content && Array.isArray(response.content)) {
|
|
54
|
+
const textParts = response.content
|
|
55
|
+
.filter((c) => c.type === 'text' && c.text)
|
|
56
|
+
.map((c) => c.text);
|
|
57
|
+
return {
|
|
58
|
+
content: textParts.join('\n') || JSON.stringify(result),
|
|
59
|
+
isError: response.isError || false,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
content: JSON.stringify(result),
|
|
64
|
+
isError: false,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
return {
|
|
69
|
+
content: `MCP 工具调用失败 [${serverName}/${toolName}]: ${error instanceof Error ? error.message : String(error)}`,
|
|
70
|
+
isError: true,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/mcp/bridge.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACjC;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAO;IACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,WAAW,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,WAAW,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,GAAG,UAAU,GAAG,mBAAmB,GAAG,IAAI,CAAC,IAAI,EAAE;gBACvD,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;gBACnC,YAAY,EAAE,IAAI,CAAC,WAAW,IAAI;oBAC9B,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE,EAAE;iBACjB;aACJ,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IACD,OAAO,WAAW,CAAC;AACvB,CAAC;AACD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,YAAY;IACtC,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACtD,IAAI,GAAG,KAAK,CAAC,CAAC;QACV,OAAO,IAAI,CAAC;IAChB,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACtE,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC;AACD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI;IACzD,MAAM,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO;YACH,OAAO,EAAE,oBAAoB,YAAY,EAAE;YAC3C,OAAO,EAAE,IAAI;SAChB,CAAC;IACN,CAAC;IACD,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC;IACtC,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAClE,SAAS;QACT,MAAM,QAAQ,GAAG,MAAM,CAAC;QACxB,IAAI,QAAQ,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACtD,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO;iBAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC;iBAC1C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;gBACH,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;gBACvD,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,KAAK;aACrC,CAAC;QACN,CAAC;QACD,OAAO;YACH,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;YAC/B,OAAO,EAAE,KAAK;SACjB,CAAC;IACN,CAAC;IACD,OAAO,KAAK,EAAE,CAAC;QACX,OAAO;YACH,OAAO,EAAE,eAAe,UAAU,IAAI,QAAQ,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YAC5G,OAAO,EAAE,IAAI;SAChB,CAAC;IACN,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* 根据用户配置生成 MCP Server 配置列表
|
|
4
|
+
* 内置 ONES MCP(必需)和 Context7 MCP(可选)
|
|
5
|
+
*/
|
|
6
|
+
export function getMcpServerConfigs(config) {
|
|
7
|
+
const servers = [
|
|
8
|
+
// ONES MCP Server(必需)
|
|
9
|
+
// 通过 mcp-remote 桥接远程服务器,自动处理 OAuth 认证
|
|
10
|
+
{
|
|
11
|
+
name: 'ones',
|
|
12
|
+
command: 'npx',
|
|
13
|
+
args: ['mcp-remote', config.ones_mcp_url],
|
|
14
|
+
required: true,
|
|
15
|
+
},
|
|
16
|
+
// Context7 MCP Server(可选)
|
|
17
|
+
// 提供第三方库文档搜索能力
|
|
18
|
+
{
|
|
19
|
+
name: 'context7',
|
|
20
|
+
command: 'npx',
|
|
21
|
+
args: ['-y', '@upstash/context7-mcp'],
|
|
22
|
+
required: false,
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
return servers;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/mcp/config.ts"],"names":[],"mappings":"AAAA,cAAc;AACd;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAM;IACtC,MAAM,OAAO,GAAG;QACZ,sBAAsB;QACtB,sCAAsC;QACtC;YACI,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC;YACzC,QAAQ,EAAE,IAAI;SACjB;QACD,0BAA0B;QAC1B,eAAe;QACf;YACI,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,CAAC,IAAI,EAAE,uBAAuB,CAAC;YACrC,QAAQ,EAAE,KAAK;SAClB;KACJ,CAAC;IACF,OAAO,OAAO,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
3
|
+
import type { McpServerConfig } from '../config/types.js';
|
|
4
|
+
interface UserInfo {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
email: string;
|
|
8
|
+
}
|
|
9
|
+
interface MCPConnection {
|
|
10
|
+
client: Client;
|
|
11
|
+
transport: StdioClientTransport;
|
|
12
|
+
tools: Array<any>;
|
|
13
|
+
config: McpServerConfig;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* MCP 多服务器连接管理器
|
|
17
|
+
* 管理多个 MCP Server 的生命周期:连接、工具发现、调用、断开
|
|
18
|
+
*/
|
|
19
|
+
export declare class MCPManager {
|
|
20
|
+
connections: Map<string, MCPConnection>;
|
|
21
|
+
_userInfo: UserInfo | null;
|
|
22
|
+
private readonly connectRetryTimes;
|
|
23
|
+
/**
|
|
24
|
+
* 当前用户信息(从 ONES MCP who_am_i 获取)
|
|
25
|
+
*/
|
|
26
|
+
get userInfo(): UserInfo;
|
|
27
|
+
/**
|
|
28
|
+
* 并行连接所有 MCP 服务器
|
|
29
|
+
* required 服务器连接失败会抛出错误
|
|
30
|
+
* optional 服务器连接失败仅输出警告
|
|
31
|
+
*/
|
|
32
|
+
connectAll(servers: McpServerConfig[]): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* 连接单个服务器,失败后自动重试一次
|
|
35
|
+
*/
|
|
36
|
+
connectServerWithRetry(server: McpServerConfig): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* 连接单个 MCP 服务器
|
|
39
|
+
*/
|
|
40
|
+
connectServer(server: McpServerConfig): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* 通过 ONES MCP 的 who_am_i 获取用户身份
|
|
43
|
+
*/
|
|
44
|
+
fetchUserInfo(): Promise<UserInfo>;
|
|
45
|
+
/**
|
|
46
|
+
* 获取指定服务器的工具列表
|
|
47
|
+
*/
|
|
48
|
+
getTools(serverName: string): Array<any>;
|
|
49
|
+
/**
|
|
50
|
+
* 获取所有已连接服务器的工具列表
|
|
51
|
+
*/
|
|
52
|
+
getAllTools(): Map<string, Array<any>>;
|
|
53
|
+
/**
|
|
54
|
+
* 获取所有已连接的服务器名称
|
|
55
|
+
*/
|
|
56
|
+
getConnectedServers(): string[];
|
|
57
|
+
/**
|
|
58
|
+
* 调用指定服务器的工具
|
|
59
|
+
* 调用失败时尝试断开重连一次
|
|
60
|
+
*/
|
|
61
|
+
callTool(serverName: string, toolName: string, args: Record<string, unknown>): Promise<any>;
|
|
62
|
+
/**
|
|
63
|
+
* 断开所有 MCP 连接,清理子进程
|
|
64
|
+
*/
|
|
65
|
+
disconnectAll(): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
export {};
|