@next-open-ai/openbot 0.6.8 → 0.6.66
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/LICENSE +21 -0
- package/README.md +155 -136
- package/apps/desktop/renderer/dist/assets/index-CxDZnMBH.css +10 -0
- package/apps/desktop/renderer/dist/assets/index-k47Qiokg.js +93 -0
- package/apps/desktop/renderer/dist/index.html +2 -2
- package/dist/cli/cli.js +136 -0
- package/dist/cli/extension-cmd.d.ts +15 -0
- package/dist/cli/extension-cmd.js +107 -0
- package/dist/core/agent/agent-dir.d.ts +6 -0
- package/dist/core/agent/agent-dir.js +8 -0
- package/dist/core/agent/agent-manager.d.ts +27 -6
- package/dist/core/agent/agent-manager.js +147 -26
- package/dist/core/agent/proxy/adapters/claude-code-adapter.d.ts +2 -0
- package/dist/core/agent/proxy/adapters/claude-code-adapter.js +186 -0
- package/dist/core/agent/proxy/adapters/coze-adapter.d.ts +2 -0
- package/dist/core/agent/proxy/adapters/coze-adapter.js +406 -0
- package/dist/core/agent/proxy/adapters/local-adapter.d.ts +2 -0
- package/dist/core/agent/proxy/adapters/local-adapter.js +95 -0
- package/dist/core/agent/proxy/adapters/openclawx-adapter.d.ts +2 -0
- package/dist/core/agent/proxy/adapters/openclawx-adapter.js +115 -0
- package/dist/core/agent/proxy/adapters/opencode-adapter.d.ts +11 -0
- package/dist/core/agent/proxy/adapters/opencode-adapter.js +786 -0
- package/dist/core/agent/proxy/adapters/opencode-free-models.d.ts +20 -0
- package/dist/core/agent/proxy/adapters/opencode-free-models.js +14 -0
- package/dist/core/agent/proxy/adapters/opencode-local-runner.d.ts +5 -0
- package/dist/core/agent/proxy/adapters/opencode-local-runner.js +95 -0
- package/dist/core/agent/proxy/index.d.ts +3 -0
- package/dist/core/agent/proxy/index.js +18 -0
- package/dist/core/agent/proxy/registry.d.ts +7 -0
- package/dist/core/agent/proxy/registry.js +13 -0
- package/dist/core/agent/proxy/run-for-channel.d.ts +3 -0
- package/dist/core/agent/proxy/run-for-channel.js +31 -0
- package/dist/core/agent/proxy/types.d.ts +30 -0
- package/dist/core/agent/proxy/types.js +1 -0
- package/dist/core/agent/run.js +1 -1
- package/dist/core/agent/token-usage-log-extension.d.ts +14 -0
- package/dist/core/agent/token-usage-log-extension.js +61 -0
- package/dist/core/config/agent-reload-pending.d.ts +9 -0
- package/dist/core/config/agent-reload-pending.js +67 -0
- package/dist/core/config/desktop-config.d.ts +136 -5
- package/dist/core/config/desktop-config.js +470 -46
- package/dist/core/config/provider-support-default.js +27 -0
- package/dist/core/extensions/index.d.ts +1 -0
- package/dist/core/extensions/index.js +1 -0
- package/dist/core/extensions/load.d.ts +11 -0
- package/dist/core/extensions/load.js +101 -0
- package/dist/core/inbound-message-preprocess.d.ts +27 -0
- package/dist/core/inbound-message-preprocess.js +96 -0
- package/dist/core/local-llm-server/download-model.d.ts +16 -0
- package/dist/core/local-llm-server/download-model.js +37 -0
- package/dist/core/local-llm-server/index.d.ts +32 -0
- package/dist/core/local-llm-server/index.js +152 -0
- package/dist/core/local-llm-server/llm-context.d.ts +66 -0
- package/dist/core/local-llm-server/llm-context.js +270 -0
- package/dist/core/local-llm-server/model-resolve.d.ts +27 -0
- package/dist/core/local-llm-server/model-resolve.js +90 -0
- package/dist/core/local-llm-server/server.d.ts +1 -0
- package/dist/core/local-llm-server/server.js +234 -0
- package/dist/core/local-llm-server/start-from-config.d.ts +5 -0
- package/dist/core/local-llm-server/start-from-config.js +50 -0
- package/dist/core/mcp/adapter.d.ts +4 -2
- package/dist/core/mcp/adapter.js +10 -4
- package/dist/core/mcp/client.d.ts +4 -0
- package/dist/core/mcp/client.js +2 -0
- package/dist/core/mcp/config.d.ts +14 -3
- package/dist/core/mcp/config.js +68 -3
- package/dist/core/mcp/index.d.ts +10 -6
- package/dist/core/mcp/index.js +7 -3
- package/dist/core/mcp/operator.d.ts +28 -2
- package/dist/core/mcp/operator.js +131 -30
- package/dist/core/mcp/transport/index.d.ts +4 -0
- package/dist/core/mcp/transport/index.js +6 -1
- package/dist/core/mcp/transport/stdio.d.ts +12 -0
- package/dist/core/mcp/transport/stdio.js +147 -29
- package/dist/core/mcp/types.d.ts +18 -0
- package/dist/core/memory/compaction-extension.d.ts +4 -3
- package/dist/core/memory/compaction-extension.js +6 -14
- package/dist/core/memory/embedding-types.d.ts +10 -0
- package/dist/core/memory/embedding-types.js +5 -0
- package/dist/core/memory/embedding.d.ts +2 -1
- package/dist/core/memory/embedding.js +38 -6
- package/dist/core/memory/index.js +3 -0
- package/dist/core/memory/local-embedding-llama.d.ts +13 -0
- package/dist/core/memory/local-embedding-llama.js +78 -0
- package/dist/core/memory/local-embedding.d.ts +11 -0
- package/dist/core/memory/local-embedding.js +69 -0
- package/dist/core/memory/persist-compaction-on-close.d.ts +14 -0
- package/dist/core/memory/persist-compaction-on-close.js +32 -0
- package/dist/core/session-outlet/index.d.ts +19 -0
- package/dist/core/session-outlet/index.js +33 -0
- package/dist/core/session-outlet/outlet.d.ts +15 -0
- package/dist/core/session-outlet/outlet.js +49 -0
- package/dist/core/session-outlet/types.d.ts +35 -0
- package/dist/core/session-outlet/types.js +5 -0
- package/dist/core/tools/bookmark-tool.d.ts +4 -0
- package/dist/core/tools/bookmark-tool.js +59 -3
- package/dist/core/tools/index.d.ts +3 -1
- package/dist/core/tools/index.js +3 -1
- package/dist/core/tools/memory-recall-tool.d.ts +6 -0
- package/dist/core/tools/memory-recall-tool.js +77 -0
- package/dist/core/tools/truncate-result.d.ts +14 -0
- package/dist/core/tools/truncate-result.js +27 -0
- package/dist/core/tools/web-search/create-web-search-tool.d.ts +17 -0
- package/dist/core/tools/web-search/create-web-search-tool.js +87 -0
- package/dist/core/tools/web-search/index.d.ts +4 -0
- package/dist/core/tools/web-search/index.js +2 -0
- package/dist/core/tools/web-search/providers/brave.d.ts +2 -0
- package/dist/core/tools/web-search/providers/brave.js +87 -0
- package/dist/core/tools/web-search/providers/duck-duck-scrape.d.ts +2 -0
- package/dist/core/tools/web-search/providers/duck-duck-scrape.js +47 -0
- package/dist/core/tools/web-search/providers/index.d.ts +5 -0
- package/dist/core/tools/web-search/providers/index.js +13 -0
- package/dist/core/tools/web-search/types.d.ts +35 -0
- package/dist/core/tools/web-search/types.js +4 -0
- package/dist/gateway/channel/adapters/telegram.js +13 -2
- package/dist/gateway/channel/adapters/wechat.d.ts +24 -0
- package/dist/gateway/channel/adapters/wechat.js +205 -0
- package/dist/gateway/channel/channel-core.d.ts +1 -0
- package/dist/gateway/channel/channel-core.js +101 -59
- package/dist/gateway/channel/run-agent.d.ts +2 -4
- package/dist/gateway/channel/run-agent.js +13 -125
- package/dist/gateway/methods/agent-cancel.d.ts +3 -1
- package/dist/gateway/methods/agent-cancel.js +16 -2
- package/dist/gateway/methods/agent-chat.d.ts +4 -0
- package/dist/gateway/methods/agent-chat.js +377 -118
- package/dist/gateway/methods/run-scheduled-task.js +9 -7
- package/dist/gateway/proxy-run-abort.d.ts +6 -0
- package/dist/gateway/proxy-run-abort.js +39 -0
- package/dist/gateway/server.js +123 -19
- package/dist/server/agent-config/agent-config.controller.d.ts +10 -2
- package/dist/server/agent-config/agent-config.controller.js +19 -4
- package/dist/server/agent-config/agent-config.module.js +3 -1
- package/dist/server/agent-config/agent-config.service.d.ts +91 -6
- package/dist/server/agent-config/agent-config.service.js +115 -3
- package/dist/server/agents/agents.controller.d.ts +16 -0
- package/dist/server/agents/agents.controller.js +62 -1
- package/dist/server/agents/agents.gateway.js +1 -1
- package/dist/server/agents/agents.service.js +1 -1
- package/dist/server/bootstrap.d.ts +1 -0
- package/dist/server/bootstrap.js +28 -4
- package/dist/server/config/config.controller.d.ts +134 -2
- package/dist/server/config/config.controller.js +199 -3
- package/dist/server/config/config.module.js +5 -4
- package/dist/server/config/config.service.d.ts +32 -2
- package/dist/server/config/config.service.js +69 -9
- package/dist/server/config/local-models.service.d.ts +67 -0
- package/dist/server/config/local-models.service.js +242 -0
- package/dist/server/workspace/workspace.service.d.ts +7 -0
- package/dist/server/workspace/workspace.service.js +16 -0
- package/package.json +10 -2
- package/presets/preset-agents.json +128 -0
- package/presets/preset-config.json +29 -0
- package/presets/preset-providers.json +180 -0
- package/presets/recommended-local-models.json +36 -0
- package/presets/workspaces/code-assistant/skills/code-review/SKILL.md +19 -0
- package/presets/workspaces/code-assistant/skills/code-runner/SKILL.md +21 -0
- package/presets/workspaces/code-assistant/skills/git-helper/SKILL.md +29 -0
- package/presets/workspaces/creator-assistant/skills/.gitkeep +0 -0
- package/presets/workspaces/creator-assistant/skills/creator-tools/SKILL.md +15 -0
- package/presets/workspaces/doc-assistant/skills/doc-processor/SKILL.md +21 -0
- package/presets/workspaces/download-assistant/skills/downloader/SKILL.md +20 -0
- package/presets/workspaces/file-assistant/skills/file-converter/SKILL.md +21 -0
- package/presets/workspaces/file-assistant/skills/file-organizer/SKILL.md +17 -0
- package/presets/workspaces/file-assistant/skills/file-search/SKILL.md +22 -0
- package/presets/workspaces/morning-briefing/skills/news-fetcher/SKILL.md +16 -0
- package/presets/workspaces/morning-briefing/skills/web-summarizer/SKILL.md +20 -0
- package/presets/workspaces/news-assistant/skills/news-fetcher/SKILL.md +16 -0
- package/presets/workspaces/news-assistant/skills/web-summarizer/SKILL.md +20 -0
- package/presets/workspaces/office-automation/skills/rpa-helper/SKILL.md +9 -0
- package/presets/workspaces/self-media-bot/skills/self-media-tools/SKILL.md +9 -0
- package/skills/url-bookmark/SKILL.md +12 -12
- package/apps/desktop/renderer/dist/assets/index-LCp1YPVA.css +0 -10
- package/apps/desktop/renderer/dist/assets/index-l5fpDsHs.js +0 -89
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 通用「按当前已保存配置启动本地模型服务」逻辑。
|
|
3
|
+
* 供网关启动与 API 复用:读取默认智能体配置,尝试启动;失败只设 env 与日志,不抛错、不影响主进程。
|
|
4
|
+
* LLM/Embedding 任一存在即可启动,只提示不报错。
|
|
5
|
+
*/
|
|
6
|
+
import { loadDesktopAgentConfig } from "../config/desktop-config.js";
|
|
7
|
+
import { startLocalLlmServer } from "./index.js";
|
|
8
|
+
import { resolveModelPathInCache, LOCAL_LLM_CACHE_DIR } from "./model-resolve.js";
|
|
9
|
+
/**
|
|
10
|
+
* 按已保存的配置(默认智能体的 local 模型与上下文长度)尝试启动本地模型服务。
|
|
11
|
+
* 仅当已下载的模型文件存在时才启动;不抛错;失败时设置 process.env.LOCAL_LLM_START_FAILED 并打日志。
|
|
12
|
+
*/
|
|
13
|
+
export async function tryStartLocalModelFromSavedConfig() {
|
|
14
|
+
try {
|
|
15
|
+
const agent = await loadDesktopAgentConfig("default");
|
|
16
|
+
if (!agent || agent.provider !== "local" || !agent.model?.trim()) {
|
|
17
|
+
// 默认智能体未使用 local 时仅跳过启动,不设置 LOCAL_LLM_START_FAILED,避免 Ollama/openai-custom 等连接失败时被误报为「未配置本地模型」
|
|
18
|
+
delete process.env.LOCAL_LLM_START_FAILED;
|
|
19
|
+
console.log("[local-llm] 提示:未配置默认本地模型,跳过启动。");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const llmResolved = resolveModelPathInCache(agent.model.trim(), LOCAL_LLM_CACHE_DIR);
|
|
23
|
+
if (!llmResolved) {
|
|
24
|
+
process.env.LOCAL_LLM_START_FAILED =
|
|
25
|
+
"缺省模型文件未下载,请先在「模型管理」中下载后点击「启动本地模型服务」";
|
|
26
|
+
console.log("[local-llm] 提示:缺省模型文件未下载,跳过启动。");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const contextSize = process.env.LOCAL_LLM_CONTEXT_MAX != null && String(process.env.LOCAL_LLM_CONTEXT_MAX).trim() !== ""
|
|
30
|
+
? parseInt(process.env.LOCAL_LLM_CONTEXT_MAX, 10) || 32768
|
|
31
|
+
: (agent.contextSize ?? 32768);
|
|
32
|
+
const opts = { llmModelPath: llmResolved, contextSize };
|
|
33
|
+
startLocalLlmServer(opts)
|
|
34
|
+
.then((handle) => {
|
|
35
|
+
process.env.LOCAL_LLM_BASE_URL = handle.baseUrl;
|
|
36
|
+
delete process.env.LOCAL_LLM_START_FAILED;
|
|
37
|
+
console.log("[local-llm] 已就绪:", handle.baseUrl);
|
|
38
|
+
})
|
|
39
|
+
.catch((e) => {
|
|
40
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
41
|
+
process.env.LOCAL_LLM_START_FAILED = msg;
|
|
42
|
+
console.log("[local-llm] 提示:启动未成功(如模型未下载请先在「模型管理」中下载)。", msg);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
47
|
+
process.env.LOCAL_LLM_START_FAILED = msg;
|
|
48
|
+
console.log("[local-llm] 提示:启动时发生异常,已跳过。", msg);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -9,9 +9,11 @@ import type { McpClient } from "./client.js";
|
|
|
9
9
|
* @param tool MCP tools/list 返回的项
|
|
10
10
|
* @param client 已连接的 McpClient,用于 callTool
|
|
11
11
|
* @param serverId 可选前缀,用于避免多 MCP 时工具名冲突
|
|
12
|
+
* @param maxResultTokens 可选,单次返回最大 token;超过则从尾部裁剪并打日志;不配置则不限制
|
|
12
13
|
*/
|
|
13
|
-
export declare function mcpToolToToolDefinition(tool: McpTool, client: McpClient, serverId?: string): ToolDefinition;
|
|
14
|
+
export declare function mcpToolToToolDefinition(tool: McpTool, client: McpClient, serverId?: string, maxResultTokens?: number): ToolDefinition;
|
|
14
15
|
/**
|
|
15
16
|
* 将某 MCP 客户端的全部工具转为 ToolDefinition 数组。
|
|
17
|
+
* @param maxResultTokens 可选,单次返回最大 token;不配置则不限制
|
|
16
18
|
*/
|
|
17
|
-
export declare function mcpToolsToToolDefinitions(tools: McpTool[], client: McpClient, serverId?: string): ToolDefinition[];
|
|
19
|
+
export declare function mcpToolsToToolDefinitions(tools: McpTool[], client: McpClient, serverId?: string, maxResultTokens?: number): ToolDefinition[];
|
package/dist/core/mcp/adapter.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* MCP Tool 转为 pi-coding-agent ToolDefinition 的适配层。
|
|
3
3
|
*/
|
|
4
4
|
import { Type } from "@sinclair/typebox";
|
|
5
|
+
import { truncateTextToMaxTokens } from "../tools/truncate-result.js";
|
|
5
6
|
/** 通用参数:MCP 工具接受任意 JSON 对象作为 arguments */
|
|
6
7
|
const McpToolParamsSchema = Type.Record(Type.String(), Type.Any());
|
|
7
8
|
/**
|
|
@@ -9,8 +10,9 @@ const McpToolParamsSchema = Type.Record(Type.String(), Type.Any());
|
|
|
9
10
|
* @param tool MCP tools/list 返回的项
|
|
10
11
|
* @param client 已连接的 McpClient,用于 callTool
|
|
11
12
|
* @param serverId 可选前缀,用于避免多 MCP 时工具名冲突
|
|
13
|
+
* @param maxResultTokens 可选,单次返回最大 token;超过则从尾部裁剪并打日志;不配置则不限制
|
|
12
14
|
*/
|
|
13
|
-
export function mcpToolToToolDefinition(tool, client, serverId) {
|
|
15
|
+
export function mcpToolToToolDefinition(tool, client, serverId, maxResultTokens) {
|
|
14
16
|
const name = serverId ? `${serverId}_${tool.name}` : tool.name;
|
|
15
17
|
const description = (tool.description ?? "").trim() || `MCP tool: ${tool.name}`;
|
|
16
18
|
return {
|
|
@@ -22,10 +24,13 @@ export function mcpToolToToolDefinition(tool, client, serverId) {
|
|
|
22
24
|
const args = params && typeof params === "object" ? params : {};
|
|
23
25
|
try {
|
|
24
26
|
const result = await client.callTool(tool.name, args);
|
|
25
|
-
|
|
27
|
+
let text = result.content
|
|
26
28
|
?.filter((c) => c.type === "text")
|
|
27
29
|
.map((c) => c.text)
|
|
28
30
|
.join("\n") ?? (result.isError ? "MCP 调用返回错误" : "");
|
|
31
|
+
if (typeof maxResultTokens === "number" && maxResultTokens > 0) {
|
|
32
|
+
text = truncateTextToMaxTokens(text, maxResultTokens, `MCP ${name}`);
|
|
33
|
+
}
|
|
29
34
|
return {
|
|
30
35
|
content: [{ type: "text", text }],
|
|
31
36
|
details: result.isError ? { isError: true } : undefined,
|
|
@@ -43,7 +48,8 @@ export function mcpToolToToolDefinition(tool, client, serverId) {
|
|
|
43
48
|
}
|
|
44
49
|
/**
|
|
45
50
|
* 将某 MCP 客户端的全部工具转为 ToolDefinition 数组。
|
|
51
|
+
* @param maxResultTokens 可选,单次返回最大 token;不配置则不限制
|
|
46
52
|
*/
|
|
47
|
-
export function mcpToolsToToolDefinitions(tools, client, serverId) {
|
|
48
|
-
return tools.map((t) => mcpToolToToolDefinition(t, client, serverId));
|
|
53
|
+
export function mcpToolsToToolDefinitions(tools, client, serverId, maxResultTokens) {
|
|
54
|
+
return tools.map((t) => mcpToolToToolDefinition(t, client, serverId, maxResultTokens));
|
|
49
55
|
}
|
|
@@ -7,6 +7,10 @@ import type { McpServerConfig } from "./types.js";
|
|
|
7
7
|
export interface McpClientOptions {
|
|
8
8
|
initTimeoutMs?: number;
|
|
9
9
|
requestTimeoutMs?: number;
|
|
10
|
+
/** stdio:初始化失败时的重试次数(默认 1) */
|
|
11
|
+
initRetries?: number;
|
|
12
|
+
/** stdio:初始化重试间隔毫秒(默认 3000) */
|
|
13
|
+
initRetryDelayMs?: number;
|
|
10
14
|
}
|
|
11
15
|
export declare class McpClient {
|
|
12
16
|
private transport;
|
package/dist/core/mcp/client.js
CHANGED
|
@@ -16,6 +16,8 @@ export class McpClient {
|
|
|
16
16
|
this.transport = createTransport(configOrTransport, {
|
|
17
17
|
initTimeoutMs: options.initTimeoutMs,
|
|
18
18
|
requestTimeoutMs: options.requestTimeoutMs,
|
|
19
|
+
initRetries: options.initRetries,
|
|
20
|
+
initRetryDelayMs: options.initRetryDelayMs,
|
|
19
21
|
});
|
|
20
22
|
}
|
|
21
23
|
}
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP 配置解析与校验。
|
|
3
3
|
* 从 getOrCreateSession 的 options.mcpServers 中取出并规范化,支持 stdio 与 sse。
|
|
4
|
+
* 支持两种输入:数组(含 transport)或标准 JSON 对象(key 为名称,由 command/url 推断 transport)。
|
|
4
5
|
*/
|
|
5
|
-
import type { McpServerConfig, McpServerConfigStdio, McpServerConfigSse } from "./types.js";
|
|
6
|
+
import type { McpServerConfig, McpServerConfigStdio, McpServerConfigSse, McpServersStandardFormat } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* 将标准格式(mcpServers 对象)转为内部数组格式。
|
|
9
|
+
* 有 command 视为 stdio,有 url 视为 sse;无效项跳过。
|
|
10
|
+
*/
|
|
11
|
+
export declare function standardFormatToArray(mcpServers: McpServersStandardFormat): McpServerConfig[];
|
|
12
|
+
/**
|
|
13
|
+
* 将内部数组格式转为标准 JSON 对象(用于展示/编辑)。
|
|
14
|
+
* 无名称的项使用 "MCP Server 1"、"MCP Server 2" 等占位 key。
|
|
15
|
+
*/
|
|
16
|
+
export declare function arrayToStandardFormat(mcpServers: McpServerConfig[]): McpServersStandardFormat;
|
|
6
17
|
/**
|
|
7
18
|
* 从会话选项里解析出本会话启用的 MCP 服务器配置列表。
|
|
8
|
-
*
|
|
19
|
+
* 支持:数组(含 transport)、标准 JSON 对象(key 为名称,由 command/url 推断)。
|
|
9
20
|
*/
|
|
10
|
-
export declare function resolveMcpServersForSession(mcpServers: McpServerConfig[] | undefined): McpServerConfig[];
|
|
21
|
+
export declare function resolveMcpServersForSession(mcpServers: McpServerConfig[] | McpServersStandardFormat | undefined): McpServerConfig[];
|
|
11
22
|
/**
|
|
12
23
|
* 为 stdio 配置生成缓存键(用于 Operator 复用同一进程连接)
|
|
13
24
|
*/
|
package/dist/core/mcp/config.js
CHANGED
|
@@ -1,15 +1,80 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP 配置解析与校验。
|
|
3
3
|
* 从 getOrCreateSession 的 options.mcpServers 中取出并规范化,支持 stdio 与 sse。
|
|
4
|
+
* 支持两种输入:数组(含 transport)或标准 JSON 对象(key 为名称,由 command/url 推断 transport)。
|
|
4
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* 将标准格式(mcpServers 对象)转为内部数组格式。
|
|
8
|
+
* 有 command 视为 stdio,有 url 视为 sse;无效项跳过。
|
|
9
|
+
*/
|
|
10
|
+
export function standardFormatToArray(mcpServers) {
|
|
11
|
+
const result = [];
|
|
12
|
+
for (const [_, entry] of Object.entries(mcpServers)) {
|
|
13
|
+
if (!entry || typeof entry !== "object")
|
|
14
|
+
continue;
|
|
15
|
+
const cmd = typeof entry.command === "string" ? entry.command.trim() : "";
|
|
16
|
+
const url = typeof entry.url === "string" ? entry.url.trim() : "";
|
|
17
|
+
if (cmd) {
|
|
18
|
+
result.push({
|
|
19
|
+
transport: "stdio",
|
|
20
|
+
command: cmd,
|
|
21
|
+
args: Array.isArray(entry.args) ? entry.args : undefined,
|
|
22
|
+
env: entry.env && typeof entry.env === "object" ? entry.env : undefined,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
else if (url) {
|
|
26
|
+
result.push({
|
|
27
|
+
transport: "sse",
|
|
28
|
+
url,
|
|
29
|
+
headers: entry.headers && typeof entry.headers === "object" ? entry.headers : undefined,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
console.warn("[mcp] 跳过无效标准格式项:需 command(stdio)或 url(sse)");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 将内部数组格式转为标准 JSON 对象(用于展示/编辑)。
|
|
40
|
+
* 无名称的项使用 "MCP Server 1"、"MCP Server 2" 等占位 key。
|
|
41
|
+
*/
|
|
42
|
+
export function arrayToStandardFormat(mcpServers) {
|
|
43
|
+
const out = {};
|
|
44
|
+
mcpServers.forEach((s, i) => {
|
|
45
|
+
const name = `MCP Server ${i + 1}`;
|
|
46
|
+
if (s.transport === "stdio") {
|
|
47
|
+
const e = {
|
|
48
|
+
command: s.command,
|
|
49
|
+
args: s.args,
|
|
50
|
+
env: s.env,
|
|
51
|
+
};
|
|
52
|
+
out[name] = e;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const e = {
|
|
56
|
+
url: s.url,
|
|
57
|
+
headers: s.headers,
|
|
58
|
+
};
|
|
59
|
+
out[name] = e;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
function isStandardFormat(obj) {
|
|
65
|
+
return obj !== null && typeof obj === "object" && !Array.isArray(obj);
|
|
66
|
+
}
|
|
5
67
|
/**
|
|
6
68
|
* 从会话选项里解析出本会话启用的 MCP 服务器配置列表。
|
|
7
|
-
*
|
|
69
|
+
* 支持:数组(含 transport)、标准 JSON 对象(key 为名称,由 command/url 推断)。
|
|
8
70
|
*/
|
|
9
71
|
export function resolveMcpServersForSession(mcpServers) {
|
|
10
|
-
if (
|
|
72
|
+
if (mcpServers == null)
|
|
73
|
+
return [];
|
|
74
|
+
if (isStandardFormat(mcpServers))
|
|
75
|
+
return standardFormatToArray(mcpServers);
|
|
76
|
+
if (!Array.isArray(mcpServers) || mcpServers.length === 0)
|
|
11
77
|
return [];
|
|
12
|
-
}
|
|
13
78
|
const result = [];
|
|
14
79
|
for (const s of mcpServers) {
|
|
15
80
|
if (!s || typeof s !== "object")
|
package/dist/core/mcp/index.d.ts
CHANGED
|
@@ -3,16 +3,20 @@
|
|
|
3
3
|
* 配置在创建 Session 时通过 options.mcpServers 传入,与 Skill 类似。
|
|
4
4
|
*/
|
|
5
5
|
import type { ToolDefinition } from "@mariozechner/pi-coding-agent";
|
|
6
|
-
import type { McpServerConfig } from "./types.js";
|
|
7
|
-
export type { McpServerConfig, McpServerConfigStdio, McpServerConfigSse, McpTool } from "./types.js";
|
|
8
|
-
export { resolveMcpServersForSession, stdioConfigKey, sseConfigKey, mcpConfigKey } from "./config.js";
|
|
6
|
+
import type { McpServerConfig, McpServersStandardFormat } from "./types.js";
|
|
7
|
+
export type { McpServerConfig, McpServerConfigStdio, McpServerConfigSse, McpServerConfigStandardEntry, McpServersStandardFormat, McpTool, } from "./types.js";
|
|
8
|
+
export { resolveMcpServersForSession, standardFormatToArray, arrayToStandardFormat, stdioConfigKey, sseConfigKey, mcpConfigKey, } from "./config.js";
|
|
9
9
|
export { McpClient } from "./client.js";
|
|
10
|
-
export { getMcpToolDefinitions, shutdownMcpClients } from "./operator.js";
|
|
10
|
+
export { getMcpToolDefinitions, shutdownMcpClients, type GetMcpToolDefinitionsOptions } from "./operator.js";
|
|
11
11
|
export { mcpToolToToolDefinition, mcpToolsToToolDefinitions } from "./adapter.js";
|
|
12
12
|
/**
|
|
13
13
|
* 根据会话选项中的 mcpServers 配置,返回该会话可用的 MCP 工具(ToolDefinition 数组)。
|
|
14
|
-
*
|
|
14
|
+
* 支持数组或标准 JSON 对象格式;在 AgentManager.getOrCreateSession 中调用,并入 customTools。
|
|
15
|
+
* 若提供 sessionId,MCP 连接/重试进度将经全局 sendSessionMessage 以系统消息推送。
|
|
15
16
|
*/
|
|
16
17
|
export declare function createMcpToolsForSession(options: {
|
|
17
|
-
mcpServers?: McpServerConfig[];
|
|
18
|
+
mcpServers?: McpServerConfig[] | McpServersStandardFormat;
|
|
19
|
+
sessionId?: string;
|
|
20
|
+
/** 单次 MCP 工具返回最大 token;不配置则不限制 */
|
|
21
|
+
mcpMaxResultTokens?: number;
|
|
18
22
|
}): Promise<ToolDefinition[]>;
|
package/dist/core/mcp/index.js
CHANGED
|
@@ -4,17 +4,21 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { resolveMcpServersForSession } from "./config.js";
|
|
6
6
|
import { getMcpToolDefinitions } from "./operator.js";
|
|
7
|
-
export { resolveMcpServersForSession, stdioConfigKey, sseConfigKey, mcpConfigKey } from "./config.js";
|
|
7
|
+
export { resolveMcpServersForSession, standardFormatToArray, arrayToStandardFormat, stdioConfigKey, sseConfigKey, mcpConfigKey, } from "./config.js";
|
|
8
8
|
export { McpClient } from "./client.js";
|
|
9
9
|
export { getMcpToolDefinitions, shutdownMcpClients } from "./operator.js";
|
|
10
10
|
export { mcpToolToToolDefinition, mcpToolsToToolDefinitions } from "./adapter.js";
|
|
11
11
|
/**
|
|
12
12
|
* 根据会话选项中的 mcpServers 配置,返回该会话可用的 MCP 工具(ToolDefinition 数组)。
|
|
13
|
-
*
|
|
13
|
+
* 支持数组或标准 JSON 对象格式;在 AgentManager.getOrCreateSession 中调用,并入 customTools。
|
|
14
|
+
* 若提供 sessionId,MCP 连接/重试进度将经全局 sendSessionMessage 以系统消息推送。
|
|
14
15
|
*/
|
|
15
16
|
export async function createMcpToolsForSession(options) {
|
|
16
17
|
const configs = resolveMcpServersForSession(options.mcpServers);
|
|
17
18
|
if (configs.length === 0)
|
|
18
19
|
return [];
|
|
19
|
-
return getMcpToolDefinitions(configs
|
|
20
|
+
return getMcpToolDefinitions(configs, {
|
|
21
|
+
sessionId: options.sessionId,
|
|
22
|
+
maxResultTokens: options.mcpMaxResultTokens,
|
|
23
|
+
});
|
|
20
24
|
}
|
|
@@ -4,12 +4,38 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { McpServerConfig } from "./types.js";
|
|
6
6
|
import type { ToolDefinition } from "@mariozechner/pi-coding-agent";
|
|
7
|
+
/** getMcpToolDefinitions 的可选参数:超时、重试与 sessionId(用于经 sendSessionMessage 推送进度) */
|
|
8
|
+
export interface GetMcpToolDefinitionsOptions {
|
|
9
|
+
/** 连接或 list_tools 失败时的重试次数(不含首次,默认 1) */
|
|
10
|
+
connectRetries?: number;
|
|
11
|
+
/** 重试间隔(毫秒,默认 3000) */
|
|
12
|
+
retryDelayMs?: number;
|
|
13
|
+
/** stdio 初始化超时(毫秒) */
|
|
14
|
+
initTimeoutMs?: number;
|
|
15
|
+
/** stdio 初始化重试次数(默认 1) */
|
|
16
|
+
initRetries?: number;
|
|
17
|
+
/** stdio 初始化重试间隔(毫秒,默认 3000) */
|
|
18
|
+
initRetryDelayMs?: number;
|
|
19
|
+
/** 会话 ID,用于经全局 sendSessionMessage 推送 MCP 进度系统消息 */
|
|
20
|
+
sessionId?: string;
|
|
21
|
+
/** 单次 MCP 工具返回最大 token;超过则从尾部裁剪并打日志;不配置则不限制 */
|
|
22
|
+
maxResultTokens?: number;
|
|
23
|
+
}
|
|
7
24
|
/**
|
|
8
25
|
* 为给定 MCP 服务器配置列表获取或创建客户端,并返回其工具对应的 ToolDefinition 数组。
|
|
9
|
-
* 连接失败或 list_tools 失败的 server
|
|
26
|
+
* 连接失败或 list_tools 失败的 server 会按 options 重试,仍失败则跳过并打日志,不阻塞整体。
|
|
10
27
|
*/
|
|
11
|
-
export declare function getMcpToolDefinitions(serverConfigs: McpServerConfig[]): Promise<ToolDefinition[]>;
|
|
28
|
+
export declare function getMcpToolDefinitions(serverConfigs: McpServerConfig[], options?: GetMcpToolDefinitionsOptions): Promise<ToolDefinition[]>;
|
|
12
29
|
/**
|
|
13
30
|
* 关闭并移除所有缓存的 MCP 客户端(进程退出或显式清理时调用)。
|
|
14
31
|
*/
|
|
15
32
|
export declare function shutdownMcpClients(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* 测试单条 MCP 配置是否可用:连接、拉取工具列表后断开。
|
|
35
|
+
* 不写入 clientCache,用于配置界面「测试」按钮,可提前触发 uvx/npx 依赖安装。
|
|
36
|
+
*/
|
|
37
|
+
export declare function testMcpConnection(config: McpServerConfig, options?: GetMcpToolDefinitionsOptions): Promise<{
|
|
38
|
+
success: boolean;
|
|
39
|
+
error?: string;
|
|
40
|
+
toolsCount?: number;
|
|
41
|
+
}>;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { mcpConfigKey } from "./config.js";
|
|
6
6
|
import { McpClient } from "./client.js";
|
|
7
7
|
import { mcpToolsToToolDefinitions } from "./adapter.js";
|
|
8
|
+
import { sendSessionMessage } from "../session-outlet/index.js";
|
|
8
9
|
/** 按配置键缓存的客户端 */
|
|
9
10
|
const clientCache = new Map();
|
|
10
11
|
function configLabel(config) {
|
|
@@ -12,53 +13,123 @@ function configLabel(config) {
|
|
|
12
13
|
return config.command;
|
|
13
14
|
return config.url;
|
|
14
15
|
}
|
|
16
|
+
/** 用于系统消息展示的 MCP 名称:stdio 优先用首个非选项参数(如 akshare-tools),否则 command;sse 用 URL 主机或路径末段 */
|
|
17
|
+
function mcpDisplayName(config) {
|
|
18
|
+
if (config.transport === "stdio") {
|
|
19
|
+
const args = config.args;
|
|
20
|
+
const nameArg = (args ?? []).find((a) => typeof a === "string" && a.trim() && !a.startsWith("-") && !a.includes("/") && !a.includes("\\"));
|
|
21
|
+
if (nameArg)
|
|
22
|
+
return nameArg.trim();
|
|
23
|
+
return config.command;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const u = new URL(config.url);
|
|
27
|
+
const host = u.hostname || u.pathname?.replace(/\/$/, "").split("/").pop() || "MCP";
|
|
28
|
+
return host;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return config.url;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function sleep(ms) {
|
|
35
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
36
|
+
}
|
|
15
37
|
/**
|
|
16
38
|
* 为给定 MCP 服务器配置列表获取或创建客户端,并返回其工具对应的 ToolDefinition 数组。
|
|
17
|
-
* 连接失败或 list_tools 失败的 server
|
|
39
|
+
* 连接失败或 list_tools 失败的 server 会按 options 重试,仍失败则跳过并打日志,不阻塞整体。
|
|
18
40
|
*/
|
|
19
|
-
export async function getMcpToolDefinitions(serverConfigs) {
|
|
41
|
+
export async function getMcpToolDefinitions(serverConfigs, options = {}) {
|
|
42
|
+
const connectRetries = options.connectRetries ?? 1;
|
|
43
|
+
const retryDelayMs = options.retryDelayMs ?? 3_000;
|
|
44
|
+
const sessionId = options.sessionId;
|
|
45
|
+
const clientOptions = {
|
|
46
|
+
initTimeoutMs: options.initTimeoutMs,
|
|
47
|
+
initRetries: options.initRetries,
|
|
48
|
+
initRetryDelayMs: options.initRetryDelayMs,
|
|
49
|
+
};
|
|
50
|
+
const emitProgress = (displayMessage, phase, detail) => {
|
|
51
|
+
if (sessionId) {
|
|
52
|
+
sendSessionMessage(sessionId, {
|
|
53
|
+
type: "system",
|
|
54
|
+
code: "mcp.progress",
|
|
55
|
+
payload: { phase, message: displayMessage, serverLabel: detail },
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
};
|
|
20
59
|
const allTools = [];
|
|
21
60
|
for (let i = 0; i < serverConfigs.length; i++) {
|
|
22
61
|
const config = serverConfigs[i];
|
|
23
62
|
const key = mcpConfigKey(config);
|
|
63
|
+
const label = configLabel(config);
|
|
64
|
+
const displayName = mcpDisplayName(config);
|
|
24
65
|
let client = clientCache.get(key);
|
|
25
|
-
if (!client) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
66
|
+
if (!client || !client.isConnected) {
|
|
67
|
+
if (client) {
|
|
68
|
+
clientCache.delete(key);
|
|
69
|
+
try {
|
|
70
|
+
await client.close();
|
|
71
|
+
}
|
|
72
|
+
catch { }
|
|
30
73
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
74
|
+
emitProgress(`${displayName} MCP connecting`, "connecting");
|
|
75
|
+
let connected = false;
|
|
76
|
+
for (let attempt = 0; attempt <= connectRetries; attempt++) {
|
|
77
|
+
if (attempt > 0) {
|
|
78
|
+
emitProgress(`${displayName} MCP retrying (${attempt + 1}/${connectRetries + 1})`, "retrying", "connect");
|
|
79
|
+
await sleep(retryDelayMs);
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
client = new McpClient(config, clientOptions);
|
|
83
|
+
await client.connect();
|
|
84
|
+
clientCache.set(key, client);
|
|
85
|
+
connected = true;
|
|
86
|
+
emitProgress(`${displayName} MCP ready`, "ready");
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
if (client)
|
|
91
|
+
try {
|
|
92
|
+
await client.close();
|
|
93
|
+
}
|
|
94
|
+
catch { }
|
|
95
|
+
if (attempt === connectRetries) {
|
|
96
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
97
|
+
console.warn(`[mcp] 连接失败 (${label}):`, errMsg);
|
|
98
|
+
const enoentHint = /ENOENT/.test(errMsg) && /uvx|npx/.test(errMsg)
|
|
99
|
+
? " 若在 Docker 中运行,请使用已安装 uv/npx 的镜像(Dockerfile 中需安装 uv 并设置 PATH=/root/.local/bin)并重新构建。"
|
|
100
|
+
: "";
|
|
101
|
+
if (enoentHint)
|
|
102
|
+
console.warn(`[mcp]`, enoentHint.trim());
|
|
103
|
+
emitProgress(`${displayName} MCP failed: ${errMsg}`, "skipped", errMsg);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
34
106
|
}
|
|
107
|
+
if (!connected)
|
|
108
|
+
continue;
|
|
35
109
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
110
|
+
client = clientCache.get(key);
|
|
111
|
+
let toolsListed = false;
|
|
112
|
+
for (let attempt = 0; attempt <= connectRetries; attempt++) {
|
|
113
|
+
if (attempt > 0) {
|
|
114
|
+
emitProgress(`${displayName} MCP retrying list tools (${attempt + 1}/${connectRetries + 1})`, "retrying", "list_tools");
|
|
115
|
+
await sleep(retryDelayMs);
|
|
40
116
|
}
|
|
41
|
-
catch { }
|
|
42
|
-
const newClient = new McpClient(config);
|
|
43
117
|
try {
|
|
44
|
-
await
|
|
45
|
-
|
|
46
|
-
|
|
118
|
+
const tools = await client.listTools();
|
|
119
|
+
const serverId = `mcp${i}`;
|
|
120
|
+
const definitions = mcpToolsToToolDefinitions(tools, client, serverId, options.maxResultTokens);
|
|
121
|
+
allTools.push(...definitions);
|
|
122
|
+
toolsListed = true;
|
|
123
|
+
break;
|
|
47
124
|
}
|
|
48
125
|
catch (err) {
|
|
49
|
-
|
|
50
|
-
|
|
126
|
+
if (attempt === connectRetries) {
|
|
127
|
+
console.warn(`[mcp] list_tools 失败 (${label}):`, err instanceof Error ? err.message : err);
|
|
128
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
129
|
+
emitProgress(`${displayName} MCP list tools failed: ${errMsg}`, "skipped", errMsg);
|
|
130
|
+
}
|
|
51
131
|
}
|
|
52
132
|
}
|
|
53
|
-
try {
|
|
54
|
-
const tools = await client.listTools();
|
|
55
|
-
const serverId = `mcp${i}`;
|
|
56
|
-
const definitions = mcpToolsToToolDefinitions(tools, client, serverId);
|
|
57
|
-
allTools.push(...definitions);
|
|
58
|
-
}
|
|
59
|
-
catch (err) {
|
|
60
|
-
console.warn(`[mcp] list_tools 失败 (${configLabel(config)}):`, err instanceof Error ? err.message : err);
|
|
61
|
-
}
|
|
62
133
|
}
|
|
63
134
|
return allTools;
|
|
64
135
|
}
|
|
@@ -70,3 +141,33 @@ export async function shutdownMcpClients() {
|
|
|
70
141
|
clientCache.clear();
|
|
71
142
|
await Promise.all(closeAll);
|
|
72
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* 测试单条 MCP 配置是否可用:连接、拉取工具列表后断开。
|
|
146
|
+
* 不写入 clientCache,用于配置界面「测试」按钮,可提前触发 uvx/npx 依赖安装。
|
|
147
|
+
*/
|
|
148
|
+
export async function testMcpConnection(config, options = {}) {
|
|
149
|
+
const clientOptions = {
|
|
150
|
+
initTimeoutMs: options.initTimeoutMs,
|
|
151
|
+
initRetries: options.initRetries ?? 1,
|
|
152
|
+
initRetryDelayMs: options.initRetryDelayMs,
|
|
153
|
+
};
|
|
154
|
+
let client = null;
|
|
155
|
+
try {
|
|
156
|
+
client = new McpClient(config, clientOptions);
|
|
157
|
+
await client.connect();
|
|
158
|
+
const tools = await client.listTools();
|
|
159
|
+
const count = Array.isArray(tools) ? tools.length : 0;
|
|
160
|
+
await client.close();
|
|
161
|
+
return { success: true, toolsCount: count };
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
if (client) {
|
|
165
|
+
try {
|
|
166
|
+
await client.close();
|
|
167
|
+
}
|
|
168
|
+
catch { }
|
|
169
|
+
}
|
|
170
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
171
|
+
return { success: false, error: message };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -2,6 +2,10 @@ import type { McpServerConfig, IMcpTransport } from "../types.js";
|
|
|
2
2
|
export interface TransportOptions {
|
|
3
3
|
initTimeoutMs?: number;
|
|
4
4
|
requestTimeoutMs?: number;
|
|
5
|
+
/** stdio:初始化失败时的重试次数(默认 1) */
|
|
6
|
+
initRetries?: number;
|
|
7
|
+
/** stdio:初始化重试间隔毫秒(默认 3000) */
|
|
8
|
+
initRetryDelayMs?: number;
|
|
5
9
|
}
|
|
6
10
|
/**
|
|
7
11
|
* 根据配置创建对应的传输层实例。
|
|
@@ -5,7 +5,12 @@ import { SseTransport } from "./sse.js";
|
|
|
5
5
|
*/
|
|
6
6
|
export function createTransport(config, options) {
|
|
7
7
|
if (config.transport === "stdio") {
|
|
8
|
-
return new StdioTransport(config,
|
|
8
|
+
return new StdioTransport(config, {
|
|
9
|
+
initTimeoutMs: options?.initTimeoutMs,
|
|
10
|
+
requestTimeoutMs: options?.requestTimeoutMs,
|
|
11
|
+
initRetries: options?.initRetries,
|
|
12
|
+
initRetryDelayMs: options?.initRetryDelayMs,
|
|
13
|
+
});
|
|
9
14
|
}
|
|
10
15
|
if (config.transport === "sse") {
|
|
11
16
|
return new SseTransport(config, options);
|
|
@@ -8,19 +8,31 @@ export interface StdioTransportOptions {
|
|
|
8
8
|
initTimeoutMs?: number;
|
|
9
9
|
/** 单次请求超时(毫秒) */
|
|
10
10
|
requestTimeoutMs?: number;
|
|
11
|
+
/** 初始化失败时的重试次数(不含首次,默认 1,即最多 2 次尝试) */
|
|
12
|
+
initRetries?: number;
|
|
13
|
+
/** 初始化重试间隔(毫秒,默认 3000) */
|
|
14
|
+
initRetryDelayMs?: number;
|
|
11
15
|
}
|
|
12
16
|
export declare class StdioTransport {
|
|
13
17
|
private process;
|
|
14
18
|
private config;
|
|
15
19
|
private initTimeoutMs;
|
|
16
20
|
private requestTimeoutMs;
|
|
21
|
+
private initRetries;
|
|
22
|
+
private initRetryDelayMs;
|
|
17
23
|
private nextId;
|
|
18
24
|
private pending;
|
|
19
25
|
private buffer;
|
|
26
|
+
private stderrBuffer;
|
|
27
|
+
private static pendingKey;
|
|
20
28
|
constructor(config: McpServerConfigStdio, options?: StdioTransportOptions);
|
|
21
29
|
/** 启动子进程并完成 MCP initialize 握手 */
|
|
22
30
|
start(): Promise<void>;
|
|
31
|
+
/** 从一行中解析 JSON-RPC 响应:整行即 JSON,或从第一个 { 开始提取到匹配的 }(兼容 npx/uvx 等前缀输出) */
|
|
32
|
+
private static parseJsonRpcResponse;
|
|
23
33
|
private flushLines;
|
|
34
|
+
private flushStderrLines;
|
|
35
|
+
private flushLinesFromBuffer;
|
|
24
36
|
private rejectAll;
|
|
25
37
|
private initialize;
|
|
26
38
|
private sendNotification;
|