@dyyz1993/pi-coding-agent 0.74.9 → 0.74.11
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 +19 -0
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +3 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session.d.ts +9 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +51 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/mcp/mcp-manager.d.ts +1 -0
- package/dist/core/mcp/mcp-manager.d.ts.map +1 -1
- package/dist/core/mcp/mcp-manager.js +36 -0
- package/dist/core/mcp/mcp-manager.js.map +1 -1
- package/dist/core/sdk.d.ts +2 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +41 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +3 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/rpc/rpc-client-types.d.ts +4 -1
- package/dist/modes/rpc/rpc-client-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client-types.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +3 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +10 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +18 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +21 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +4 -4
|
@@ -25,6 +25,7 @@ export declare class McpManager {
|
|
|
25
25
|
private scheduleReconnect;
|
|
26
26
|
private reconnectServer;
|
|
27
27
|
addServer(name: string, config: McpServerConfig): Promise<void>;
|
|
28
|
+
restartServer(name: string): Promise<void>;
|
|
28
29
|
removeServer(name: string): Promise<void>;
|
|
29
30
|
setServerEnabled(name: string, enabled: boolean): Promise<void>;
|
|
30
31
|
refreshTools(serverName?: string): Promise<DiscoveredTool[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-manager.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/mcp-manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACX,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EAEf,MAAM,YAAY,CAAC;AAYpB,qBAAa,UAAU;IACtB,OAAO,CAAC,WAAW,CAAwC;IAC3D,OAAO,CAAC,OAAO,CAA+D;IAC9E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwB;IAEtD,OAAO,CAAC,eAAe,CAAoD;IAC3E,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,iBAAiB,CAAS;IAElC,OAAO,CAAC,cAAc,CAA2B;IAEjD,YACC,eAAe,CAAC,EACb,gBAAgB,GAChB,CAAC,iBAAiB,GAAG;QAAE,kBAAkB,CAAC,EAAE,gBAAgB,CAAC,oBAAoB,CAAC,CAAA;KAAE,CAAC,EAuBxF;IAED,OAAO,CAAC,eAAe;IASvB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAUvB;IAED,OAAO,CAAC,YAAY;IAId,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CASxE;IAEK,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBxE;YAEa,oBAAoB;YAmBpB,eAAe;IAuD7B,OAAO,CAAC,iBAAiB;YAoBX,eAAe;IAyBvB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpE;IAEK,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB9C;IAEK,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBpE;IAEK,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA2DjE;IAED,cAAc,IAAI,aAAa,EAAE,CAEhC;IAED,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAErD;IAED,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE,CAErD;IAEK,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,SAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CAoChH;IAED,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,eAAe;IAOvB,WAAW,IAAI,cAAc,EAAE,CAM9B;IAEK,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAYnC;YAEa,eAAe;IAsC7B,OAAO,CAAC,aAAa;CAGrB","sourcesContent":["import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { McpConnectionError, McpError, McpTimeoutError, McpToolCallError } from \"./errors.js\";\nimport { McpLogger } from \"./logger.js\";\nimport type {\n\tDiscoveredTool,\n\tMcpConnection,\n\tMcpManagerEvents,\n\tMcpManagerOptions,\n\tMcpServerConfig,\n\tMcpStdioServerConfig,\n} from \"./types.js\";\n\ninterface ManagedConnection extends McpConnection {\n\tclient?: Client;\n}\n\ninterface Semaphore {\n\tcurrent: number;\n\tmax: number;\n\tqueue: Array<() => void>;\n}\n\nexport class McpManager {\n\tprivate connections = new Map<string, ManagedConnection>();\n\tprivate toolMap = new Map<string, { serverName: string; toolName: string }>();\n\tprivate readonly logger: McpLogger;\n\tprivate readonly events: McpManagerEvents;\n\tprivate readonly connectTimeoutMs: number;\n\tprivate readonly callTimeoutMs: number;\n\tprivate readonly maxReconnectAttempts: number;\n\tprivate readonly callSemaphore: Semaphore | undefined;\n\n\tprivate reconnectTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\tprivate baseReconnectDelay = 1000;\n\tprivate maxReconnectDelay = 30000;\n\n\tprivate cleanupHandler: (() => void) | undefined;\n\n\tconstructor(\n\t\toptionsOrEvents?:\n\t\t\t| McpManagerEvents\n\t\t\t| (McpManagerOptions & { onConnectionChange?: McpManagerEvents[\"onConnectionChange\"] }),\n\t) {\n\t\tconst hasOptions =\n\t\t\toptionsOrEvents &&\n\t\t\t(\"logLevel\" in optionsOrEvents ||\n\t\t\t\t\"connectTimeoutMs\" in optionsOrEvents ||\n\t\t\t\t\"callTimeoutMs\" in optionsOrEvents ||\n\t\t\t\t\"maxReconnectAttempts\" in optionsOrEvents ||\n\t\t\t\t\"maxConcurrentCalls\" in optionsOrEvents);\n\t\tconst opts = hasOptions ? (optionsOrEvents as McpManagerOptions) : undefined;\n\t\tconst eventsCallback = (optionsOrEvents as Record<string, unknown>)?.onConnectionChange as\n\t\t\t| McpManagerEvents[\"onConnectionChange\"]\n\t\t\t| undefined;\n\n\t\tthis.events = eventsCallback ? { onConnectionChange: eventsCallback } : {};\n\t\tthis.logger = new McpLogger(opts?.logLevel ?? \"info\");\n\t\tthis.connectTimeoutMs = opts?.connectTimeoutMs ?? 30_000;\n\t\tthis.callTimeoutMs = opts?.callTimeoutMs ?? 60_000;\n\t\tthis.maxReconnectAttempts = opts?.maxReconnectAttempts ?? 3;\n\t\tif (opts?.maxConcurrentCalls) {\n\t\t\tthis.callSemaphore = { current: 0, max: opts.maxConcurrentCalls, queue: [] };\n\t\t}\n\t\tthis.registerCleanup();\n\t}\n\n\tprivate registerCleanup() {\n\t\tthis.cleanupHandler = () => {\n\t\t\tthis.disconnectAll().catch(() => {});\n\t\t};\n\t\tprocess.on(\"beforeExit\", this.cleanupHandler);\n\t\tprocess.on(\"SIGTERM\", this.cleanupHandler);\n\t\tprocess.on(\"SIGINT\", this.cleanupHandler);\n\t}\n\n\tdispose(): Promise<void> {\n\t\tif (this.cleanupHandler) {\n\t\t\tprocess.off(\"beforeExit\", this.cleanupHandler);\n\t\t\tprocess.off(\"SIGTERM\", this.cleanupHandler);\n\t\t\tprocess.off(\"SIGINT\", this.cleanupHandler);\n\t\t\tthis.cleanupHandler = undefined;\n\t\t}\n\t\tfor (const timer of this.reconnectTimers.values()) clearTimeout(timer);\n\t\tthis.reconnectTimers.clear();\n\t\treturn this.disconnectAll();\n\t}\n\n\tprivate notifyChange(conn: McpConnection) {\n\t\tthis.events.onConnectionChange?.(conn);\n\t}\n\n\tasync connectAll(servers: Record<string, McpServerConfig>): Promise<void> {\n\t\tconst entries = Object.entries(servers).filter(([_, c]) => !c.disabled);\n\t\tif (entries.length === 0) return;\n\n\t\tconst results = await Promise.allSettled(entries.map(([name, config]) => this.connectServer(name, config)));\n\n\t\tconst succeeded = results.filter((r) => r.status === \"fulfilled\").length;\n\t\tconst failed = results.filter((r) => r.status === \"rejected\").length;\n\t\tthis.logger.info(\"*\", `${succeeded} server(s) connected${failed > 0 ? `, ${failed} failed` : \"\"}`);\n\t}\n\n\tasync connectServer(name: string, config: McpServerConfig): Promise<void> {\n\t\tconst existing = this.connections.get(name);\n\t\tif (existing?.client) {\n\t\t\ttry {\n\t\t\t\tawait existing.client.close();\n\t\t\t} catch {}\n\t\t}\n\n\t\tconst entry: ManagedConnection = { name, config, status: \"connecting\", tools: [] };\n\t\tthis.connections.set(name, entry);\n\t\tthis.notifyChange(entry);\n\n\t\ttry {\n\t\t\tawait this.doConnectWithTimeout(name, config);\n\t\t} catch (e) {\n\t\t\tentry.status = \"error\";\n\t\t\tentry.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.logger.error(name, `Connection failed: ${entry.error}`);\n\t\t\tthis.notifyChange(entry);\n\t\t\tthrow e instanceof McpError ? e : new McpConnectionError(name, entry.error);\n\t\t}\n\t}\n\n\tprivate async doConnectWithTimeout(\n\t\tname: string,\n\t\tconfig: McpServerConfig,\n\t\ttimeoutMs = this.connectTimeoutMs,\n\t): Promise<void> {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\ttry {\n\t\t\tawait this.doConnectServer(name, config, controller.signal);\n\t\t} catch (e) {\n\t\t\tif (controller.signal.aborted) {\n\t\t\t\tthrow new McpTimeoutError(\"connect\", name, timeoutMs);\n\t\t\t}\n\t\t\tthrow e;\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n\n\tprivate async doConnectServer(name: string, config: McpServerConfig, signal?: AbortSignal): Promise<void> {\n\t\tconst entry = this.connections.get(name);\n\t\tif (!entry) return;\n\n\t\tconst transport = await this.createTransport(config);\n\t\tconst client = new Client({ name: \"pi-mcp\", version: \"1.0.0\" }, { capabilities: {} });\n\n\t\tawait client.connect(transport, { signal });\n\t\tconst { tools } = await client.listTools();\n\n\t\tentry.client = client;\n\t\tentry.status = \"connected\";\n\t\tentry.error = undefined;\n\n\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t}\n\t\t}\n\n\t\tentry.tools = (tools ?? []).map((tool) => {\n\t\t\tconst fullName = `mcp__${name}__${tool.name}`;\n\t\t\tthis.toolMap.set(fullName, { serverName: name, toolName: tool.name });\n\t\t\treturn {\n\t\t\t\tserverName: name,\n\t\t\t\toriginalName: tool.name,\n\t\t\t\tfullName,\n\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t};\n\t\t});\n\n\t\tthis.logger.info(name, `${entry.tools.length} tool(s) discovered`);\n\t\tthis.notifyChange(entry);\n\n\t\tclient.onclose = () => {\n\t\t\tconst conn = this.connections.get(name);\n\t\t\tif (!conn || conn.status === \"disconnected\") return;\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = \"Connection closed unexpectedly\";\n\t\t\tthis.logger.warn(name, \"Connection closed unexpectedly\");\n\t\t\tthis.notifyChange(conn);\n\t\t\tthis.scheduleReconnect(name, 0);\n\t\t};\n\n\t\tclient.onerror = (err: Error) => {\n\t\t\tconst conn = this.connections.get(name);\n\t\t\tif (!conn) return;\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = err.message;\n\t\t\tthis.logger.error(name, `Client error: ${err.message}`);\n\t\t\tthis.notifyChange(conn);\n\t\t};\n\t}\n\n\tprivate scheduleReconnect(name: string, attempt: number) {\n\t\tif (attempt >= this.maxReconnectAttempts) {\n\t\t\tthis.logger.warn(name, `Max reconnect attempts (${this.maxReconnectAttempts}) reached`);\n\t\t\treturn;\n\t\t}\n\t\tconst existing = this.reconnectTimers.get(name);\n\t\tif (existing) {\n\t\t\tclearTimeout(existing);\n\t\t}\n\n\t\tconst delay = Math.min(this.baseReconnectDelay * 2 ** attempt, this.maxReconnectDelay);\n\t\tthis.logger.info(name, `Reconnecting in ${delay}ms (attempt ${attempt + 1}/${this.maxReconnectAttempts})`);\n\n\t\tconst timer = setTimeout(() => {\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t\tthis.reconnectServer(name, attempt + 1);\n\t\t}, delay);\n\t\tthis.reconnectTimers.set(name, timer);\n\t}\n\n\tprivate async reconnectServer(name: string, attempt: number): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn || conn.config.disabled) return;\n\n\t\tconn.status = \"connecting\";\n\t\tconn.error = undefined;\n\t\tthis.notifyChange(conn);\n\n\t\ttry {\n\t\t\tif (conn.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait conn.client.close();\n\t\t\t\t} catch {}\n\t\t\t\tconn.client = undefined;\n\t\t\t}\n\t\t\tawait this.doConnectServer(name, conn.config);\n\t\t\tthis.logger.info(name, \"Reconnected successfully\");\n\t\t} catch (e) {\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.notifyChange(conn);\n\t\t\tthis.scheduleReconnect(name, attempt);\n\t\t}\n\t}\n\n\tasync addServer(name: string, config: McpServerConfig): Promise<void> {\n\t\tawait this.connectServer(name, config);\n\t}\n\n\tasync removeServer(name: string): Promise<void> {\n\t\tconst timer = this.reconnectTimers.get(name);\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t}\n\n\t\tconst conn = this.connections.get(name);\n\t\tif (conn?.client) {\n\t\t\ttry {\n\t\t\t\tawait conn.client.close();\n\t\t\t} catch {}\n\t\t}\n\n\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t}\n\t\t}\n\n\t\tthis.connections.delete(name);\n\t}\n\n\tasync setServerEnabled(name: string, enabled: boolean): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn) return;\n\n\t\tconn.config = { ...conn.config, disabled: !enabled } as McpServerConfig;\n\n\t\tif (!enabled) {\n\t\t\tconst timer = this.reconnectTimers.get(name);\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis.reconnectTimers.delete(name);\n\t\t\t}\n\t\t\tif (conn.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait conn.client.close();\n\t\t\t\t} catch {}\n\t\t\t\tconn.client = undefined;\n\t\t\t}\n\t\t\tconn.status = \"disconnected\";\n\t\t\tthis.notifyChange(conn);\n\t\t} else {\n\t\t\tawait this.connectServer(name, conn.config);\n\t\t}\n\t}\n\n\tasync refreshTools(serverName?: string): Promise<DiscoveredTool[]> {\n\t\tif (serverName) {\n\t\t\tconst conn = this.connections.get(serverName);\n\t\t\tif (!conn?.client) return [];\n\t\t\ttry {\n\t\t\t\tconst { tools } = await conn.client.listTools();\n\t\t\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\t\t\tif (this.toolMap.get(oldKey)?.serverName === serverName) {\n\t\t\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconn.tools = (tools ?? []).map((tool) => {\n\t\t\t\t\tconst fullName = `mcp__${serverName}__${tool.name}`;\n\t\t\t\t\tthis.toolMap.set(fullName, { serverName, toolName: tool.name });\n\t\t\t\t\treturn {\n\t\t\t\t\t\tserverName,\n\t\t\t\t\t\toriginalName: tool.name,\n\t\t\t\t\t\tfullName,\n\t\t\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t\tthis.logger.info(serverName, `Refreshed: ${conn.tools.length} tool(s)`);\n\t\t\t\tthis.notifyChange(conn);\n\t\t\t} catch (e) {\n\t\t\t\tthis.logger.error(serverName, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);\n\t\t\t}\n\t\t\treturn conn.tools;\n\t\t}\n\n\t\tconst allTools: DiscoveredTool[] = [];\n\t\tfor (const [name, conn] of this.connections) {\n\t\t\tif (conn.client && conn.status === \"connected\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst { tools } = await conn.client.listTools();\n\t\t\t\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\t\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconn.tools = (tools ?? []).map((tool) => {\n\t\t\t\t\t\tconst fullName = `mcp__${name}__${tool.name}`;\n\t\t\t\t\t\tthis.toolMap.set(fullName, { serverName: name, toolName: tool.name });\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tserverName: name,\n\t\t\t\t\t\t\toriginalName: tool.name,\n\t\t\t\t\t\t\tfullName,\n\t\t\t\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t\tallTools.push(...conn.tools);\n\t\t\t\t\tthis.notifyChange(conn);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.logger.error(name, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn allTools;\n\t}\n\n\tgetConnections(): McpConnection[] {\n\t\treturn [...this.connections.values()];\n\t}\n\n\tgetConnection(name: string): McpConnection | undefined {\n\t\treturn this.connections.get(name);\n\t}\n\n\tgetToolsByServer(serverName: string): DiscoveredTool[] {\n\t\treturn this.connections.get(serverName)?.tools ?? [];\n\t}\n\n\tasync callTool(fullName: string, args: Record<string, unknown>, timeoutMs = this.callTimeoutMs): Promise<unknown> {\n\t\tconst slotPromise = this.acquireCallSlot();\n\t\tif (slotPromise) await slotPromise;\n\t\ttry {\n\t\t\tconst mapping = this.toolMap.get(fullName);\n\t\t\tif (!mapping) throw new McpToolCallError(\"\", fullName, `Unknown MCP tool: ${fullName}`);\n\n\t\t\tconst connection = this.connections.get(mapping.serverName);\n\t\t\tif (!connection?.client)\n\t\t\t\tthrow new McpToolCallError(\n\t\t\t\t\tmapping.serverName,\n\t\t\t\t\tmapping.toolName,\n\t\t\t\t\t`MCP server \"${mapping.serverName}\" not connected`,\n\t\t\t\t);\n\n\t\t\tconst controller = new AbortController();\n\t\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\t\ttry {\n\t\t\t\treturn await connection.client.callTool({ name: mapping.toolName, arguments: args }, undefined, {\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tif (controller.signal.aborted) {\n\t\t\t\t\tthrow new McpTimeoutError(`callTool(${fullName})`, mapping.serverName, timeoutMs);\n\t\t\t\t}\n\t\t\t\tthrow new McpToolCallError(\n\t\t\t\t\tmapping.serverName,\n\t\t\t\t\tmapping.toolName,\n\t\t\t\t\te instanceof Error ? e.message : String(e),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.releaseCallSlot();\n\t\t}\n\t}\n\n\tprivate acquireCallSlot(): Promise<void> | undefined {\n\t\tif (!this.callSemaphore) return undefined;\n\t\tif (this.callSemaphore.current < this.callSemaphore.max) {\n\t\t\tthis.callSemaphore.current++;\n\t\t\treturn undefined;\n\t\t}\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tthis.callSemaphore!.queue.push(() => {\n\t\t\t\tthis.callSemaphore!.current++;\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate releaseCallSlot(): void {\n\t\tif (!this.callSemaphore) return;\n\t\tthis.callSemaphore.current--;\n\t\tconst next = this.callSemaphore.queue.shift();\n\t\tif (next) next();\n\t}\n\n\tgetAllTools(): DiscoveredTool[] {\n\t\tconst tools: DiscoveredTool[] = [];\n\t\tfor (const connection of this.connections.values()) {\n\t\t\tif (connection.status === \"connected\") tools.push(...connection.tools);\n\t\t}\n\t\treturn tools;\n\t}\n\n\tasync disconnectAll(): Promise<void> {\n\t\tfor (const timer of this.reconnectTimers.values()) clearTimeout(timer);\n\t\tthis.reconnectTimers.clear();\n\n\t\tfor (const connection of this.connections.values()) {\n\t\t\ttry {\n\t\t\t\tif (connection.client) await connection.client.close();\n\t\t\t\tconnection.status = \"disconnected\";\n\t\t\t} catch {}\n\t\t}\n\t\tthis.connections.clear();\n\t\tthis.toolMap.clear();\n\t}\n\n\tprivate async createTransport(config: McpServerConfig) {\n\t\tif (this.isStdioConfig(config)) {\n\t\t\treturn new StdioClientTransport({\n\t\t\t\tcommand: config.command,\n\t\t\t\targs: config.args,\n\t\t\t\tenv: config.env\n\t\t\t\t\t? (Object.fromEntries(\n\t\t\t\t\t\t\tObject.entries({ ...process.env, ...config.env }).filter(([, v]) => v !== undefined),\n\t\t\t\t\t\t) as Record<string, string>)\n\t\t\t\t\t: undefined,\n\t\t\t\tstderr: \"pipe\",\n\t\t\t});\n\t\t}\n\t\tif (config.type === \"sse\") {\n\t\t\tconst { SSEClientTransport } = await import(\"@modelcontextprotocol/sdk/client/sse.js\");\n\t\t\treturn new SSEClientTransport(\n\t\t\t\tnew URL(config.url),\n\t\t\t\tconfig.headers\n\t\t\t\t\t? {\n\t\t\t\t\t\t\trequestInit: { headers: config.headers },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\t\tif (config.type === \"streamable-http\") {\n\t\t\tconst { StreamableHTTPClientTransport } = await import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\");\n\t\t\treturn new StreamableHTTPClientTransport(\n\t\t\t\tnew URL(config.url),\n\t\t\t\tconfig.headers\n\t\t\t\t\t? {\n\t\t\t\t\t\t\trequestInit: { headers: config.headers },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\t\tthrow new Error(`Unknown MCP transport type: ${(config as { type: string }).type}`);\n\t}\n\n\tprivate isStdioConfig(config: McpServerConfig): config is McpStdioServerConfig {\n\t\treturn \"command\" in config;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mcp-manager.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/mcp-manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACX,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EAEf,MAAM,YAAY,CAAC;AAYpB,qBAAa,UAAU;IACtB,OAAO,CAAC,WAAW,CAAwC;IAC3D,OAAO,CAAC,OAAO,CAA+D;IAC9E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwB;IAEtD,OAAO,CAAC,eAAe,CAAoD;IAC3E,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,iBAAiB,CAAS;IAElC,OAAO,CAAC,cAAc,CAA2B;IAEjD,YACC,eAAe,CAAC,EACb,gBAAgB,GAChB,CAAC,iBAAiB,GAAG;QAAE,kBAAkB,CAAC,EAAE,gBAAgB,CAAC,oBAAoB,CAAC,CAAA;KAAE,CAAC,EAuBxF;IAED,OAAO,CAAC,eAAe;IASvB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAUvB;IAED,OAAO,CAAC,YAAY;IAId,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CASxE;IAEK,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBxE;YAEa,oBAAoB;YAmBpB,eAAe;IAuD7B,OAAO,CAAC,iBAAiB;YAoBX,eAAe;IAyBvB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpE;IAEK,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8B/C;IAEK,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0B9C;IAEK,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBpE;IAEK,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA2DjE;IAED,cAAc,IAAI,aAAa,EAAE,CAEhC;IAED,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAErD;IAED,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE,CAErD;IAEK,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,SAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CAoChH;IAED,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,eAAe;IAOvB,WAAW,IAAI,cAAc,EAAE,CAM9B;IAEK,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAYnC;YAEa,eAAe;IAsC7B,OAAO,CAAC,aAAa;CAGrB","sourcesContent":["import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { McpConnectionError, McpError, McpTimeoutError, McpToolCallError } from \"./errors.js\";\nimport { McpLogger } from \"./logger.js\";\nimport type {\n\tDiscoveredTool,\n\tMcpConnection,\n\tMcpManagerEvents,\n\tMcpManagerOptions,\n\tMcpServerConfig,\n\tMcpStdioServerConfig,\n} from \"./types.js\";\n\ninterface ManagedConnection extends McpConnection {\n\tclient?: Client;\n}\n\ninterface Semaphore {\n\tcurrent: number;\n\tmax: number;\n\tqueue: Array<() => void>;\n}\n\nexport class McpManager {\n\tprivate connections = new Map<string, ManagedConnection>();\n\tprivate toolMap = new Map<string, { serverName: string; toolName: string }>();\n\tprivate readonly logger: McpLogger;\n\tprivate readonly events: McpManagerEvents;\n\tprivate readonly connectTimeoutMs: number;\n\tprivate readonly callTimeoutMs: number;\n\tprivate readonly maxReconnectAttempts: number;\n\tprivate readonly callSemaphore: Semaphore | undefined;\n\n\tprivate reconnectTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\tprivate baseReconnectDelay = 1000;\n\tprivate maxReconnectDelay = 30000;\n\n\tprivate cleanupHandler: (() => void) | undefined;\n\n\tconstructor(\n\t\toptionsOrEvents?:\n\t\t\t| McpManagerEvents\n\t\t\t| (McpManagerOptions & { onConnectionChange?: McpManagerEvents[\"onConnectionChange\"] }),\n\t) {\n\t\tconst hasOptions =\n\t\t\toptionsOrEvents &&\n\t\t\t(\"logLevel\" in optionsOrEvents ||\n\t\t\t\t\"connectTimeoutMs\" in optionsOrEvents ||\n\t\t\t\t\"callTimeoutMs\" in optionsOrEvents ||\n\t\t\t\t\"maxReconnectAttempts\" in optionsOrEvents ||\n\t\t\t\t\"maxConcurrentCalls\" in optionsOrEvents);\n\t\tconst opts = hasOptions ? (optionsOrEvents as McpManagerOptions) : undefined;\n\t\tconst eventsCallback = (optionsOrEvents as Record<string, unknown>)?.onConnectionChange as\n\t\t\t| McpManagerEvents[\"onConnectionChange\"]\n\t\t\t| undefined;\n\n\t\tthis.events = eventsCallback ? { onConnectionChange: eventsCallback } : {};\n\t\tthis.logger = new McpLogger(opts?.logLevel ?? \"info\");\n\t\tthis.connectTimeoutMs = opts?.connectTimeoutMs ?? 30_000;\n\t\tthis.callTimeoutMs = opts?.callTimeoutMs ?? 60_000;\n\t\tthis.maxReconnectAttempts = opts?.maxReconnectAttempts ?? 3;\n\t\tif (opts?.maxConcurrentCalls) {\n\t\t\tthis.callSemaphore = { current: 0, max: opts.maxConcurrentCalls, queue: [] };\n\t\t}\n\t\tthis.registerCleanup();\n\t}\n\n\tprivate registerCleanup() {\n\t\tthis.cleanupHandler = () => {\n\t\t\tthis.disconnectAll().catch(() => {});\n\t\t};\n\t\tprocess.on(\"beforeExit\", this.cleanupHandler);\n\t\tprocess.on(\"SIGTERM\", this.cleanupHandler);\n\t\tprocess.on(\"SIGINT\", this.cleanupHandler);\n\t}\n\n\tdispose(): Promise<void> {\n\t\tif (this.cleanupHandler) {\n\t\t\tprocess.off(\"beforeExit\", this.cleanupHandler);\n\t\t\tprocess.off(\"SIGTERM\", this.cleanupHandler);\n\t\t\tprocess.off(\"SIGINT\", this.cleanupHandler);\n\t\t\tthis.cleanupHandler = undefined;\n\t\t}\n\t\tfor (const timer of this.reconnectTimers.values()) clearTimeout(timer);\n\t\tthis.reconnectTimers.clear();\n\t\treturn this.disconnectAll();\n\t}\n\n\tprivate notifyChange(conn: McpConnection) {\n\t\tthis.events.onConnectionChange?.(conn);\n\t}\n\n\tasync connectAll(servers: Record<string, McpServerConfig>): Promise<void> {\n\t\tconst entries = Object.entries(servers).filter(([_, c]) => !c.disabled);\n\t\tif (entries.length === 0) return;\n\n\t\tconst results = await Promise.allSettled(entries.map(([name, config]) => this.connectServer(name, config)));\n\n\t\tconst succeeded = results.filter((r) => r.status === \"fulfilled\").length;\n\t\tconst failed = results.filter((r) => r.status === \"rejected\").length;\n\t\tthis.logger.info(\"*\", `${succeeded} server(s) connected${failed > 0 ? `, ${failed} failed` : \"\"}`);\n\t}\n\n\tasync connectServer(name: string, config: McpServerConfig): Promise<void> {\n\t\tconst existing = this.connections.get(name);\n\t\tif (existing?.client) {\n\t\t\ttry {\n\t\t\t\tawait existing.client.close();\n\t\t\t} catch {}\n\t\t}\n\n\t\tconst entry: ManagedConnection = { name, config, status: \"connecting\", tools: [] };\n\t\tthis.connections.set(name, entry);\n\t\tthis.notifyChange(entry);\n\n\t\ttry {\n\t\t\tawait this.doConnectWithTimeout(name, config);\n\t\t} catch (e) {\n\t\t\tentry.status = \"error\";\n\t\t\tentry.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.logger.error(name, `Connection failed: ${entry.error}`);\n\t\t\tthis.notifyChange(entry);\n\t\t\tthrow e instanceof McpError ? e : new McpConnectionError(name, entry.error);\n\t\t}\n\t}\n\n\tprivate async doConnectWithTimeout(\n\t\tname: string,\n\t\tconfig: McpServerConfig,\n\t\ttimeoutMs = this.connectTimeoutMs,\n\t): Promise<void> {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\ttry {\n\t\t\tawait this.doConnectServer(name, config, controller.signal);\n\t\t} catch (e) {\n\t\t\tif (controller.signal.aborted) {\n\t\t\t\tthrow new McpTimeoutError(\"connect\", name, timeoutMs);\n\t\t\t}\n\t\t\tthrow e;\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n\n\tprivate async doConnectServer(name: string, config: McpServerConfig, signal?: AbortSignal): Promise<void> {\n\t\tconst entry = this.connections.get(name);\n\t\tif (!entry) return;\n\n\t\tconst transport = await this.createTransport(config);\n\t\tconst client = new Client({ name: \"pi-mcp\", version: \"1.0.0\" }, { capabilities: {} });\n\n\t\tawait client.connect(transport, { signal });\n\t\tconst { tools } = await client.listTools();\n\n\t\tentry.client = client;\n\t\tentry.status = \"connected\";\n\t\tentry.error = undefined;\n\n\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t}\n\t\t}\n\n\t\tentry.tools = (tools ?? []).map((tool) => {\n\t\t\tconst fullName = `mcp__${name}__${tool.name}`;\n\t\t\tthis.toolMap.set(fullName, { serverName: name, toolName: tool.name });\n\t\t\treturn {\n\t\t\t\tserverName: name,\n\t\t\t\toriginalName: tool.name,\n\t\t\t\tfullName,\n\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t};\n\t\t});\n\n\t\tthis.logger.info(name, `${entry.tools.length} tool(s) discovered`);\n\t\tthis.notifyChange(entry);\n\n\t\tclient.onclose = () => {\n\t\t\tconst conn = this.connections.get(name);\n\t\t\tif (!conn || conn.status === \"disconnected\") return;\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = \"Connection closed unexpectedly\";\n\t\t\tthis.logger.warn(name, \"Connection closed unexpectedly\");\n\t\t\tthis.notifyChange(conn);\n\t\t\tthis.scheduleReconnect(name, 0);\n\t\t};\n\n\t\tclient.onerror = (err: Error) => {\n\t\t\tconst conn = this.connections.get(name);\n\t\t\tif (!conn) return;\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = err.message;\n\t\t\tthis.logger.error(name, `Client error: ${err.message}`);\n\t\t\tthis.notifyChange(conn);\n\t\t};\n\t}\n\n\tprivate scheduleReconnect(name: string, attempt: number) {\n\t\tif (attempt >= this.maxReconnectAttempts) {\n\t\t\tthis.logger.warn(name, `Max reconnect attempts (${this.maxReconnectAttempts}) reached`);\n\t\t\treturn;\n\t\t}\n\t\tconst existing = this.reconnectTimers.get(name);\n\t\tif (existing) {\n\t\t\tclearTimeout(existing);\n\t\t}\n\n\t\tconst delay = Math.min(this.baseReconnectDelay * 2 ** attempt, this.maxReconnectDelay);\n\t\tthis.logger.info(name, `Reconnecting in ${delay}ms (attempt ${attempt + 1}/${this.maxReconnectAttempts})`);\n\n\t\tconst timer = setTimeout(() => {\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t\tthis.reconnectServer(name, attempt + 1);\n\t\t}, delay);\n\t\tthis.reconnectTimers.set(name, timer);\n\t}\n\n\tprivate async reconnectServer(name: string, attempt: number): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn || conn.config.disabled) return;\n\n\t\tconn.status = \"connecting\";\n\t\tconn.error = undefined;\n\t\tthis.notifyChange(conn);\n\n\t\ttry {\n\t\t\tif (conn.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait conn.client.close();\n\t\t\t\t} catch {}\n\t\t\t\tconn.client = undefined;\n\t\t\t}\n\t\t\tawait this.doConnectServer(name, conn.config);\n\t\t\tthis.logger.info(name, \"Reconnected successfully\");\n\t\t} catch (e) {\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.notifyChange(conn);\n\t\t\tthis.scheduleReconnect(name, attempt);\n\t\t}\n\t}\n\n\tasync addServer(name: string, config: McpServerConfig): Promise<void> {\n\t\tawait this.connectServer(name, config);\n\t}\n\n\tasync restartServer(name: string): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn) throw new Error(`MCP server \"${name}\" not found`);\n\t\tif (conn.config.disabled) throw new Error(`MCP server \"${name}\" is disabled, enable it first`);\n\n\t\tconst timer = this.reconnectTimers.get(name);\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t}\n\n\t\tif (conn.client) {\n\t\t\ttry {\n\t\t\t\tawait conn.client.close();\n\t\t\t} catch {}\n\t\t\tconn.client = undefined;\n\t\t}\n\n\t\tconn.status = \"connecting\";\n\t\tconn.error = undefined;\n\t\tthis.notifyChange(conn);\n\n\t\ttry {\n\t\t\tawait this.doConnectWithTimeout(name, conn.config);\n\t\t} catch (e) {\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.notifyChange(conn);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tasync removeServer(name: string): Promise<void> {\n\t\tconst timer = this.reconnectTimers.get(name);\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t}\n\n\t\tconst conn = this.connections.get(name);\n\t\tif (conn?.client) {\n\t\t\ttry {\n\t\t\t\tawait conn.client.close();\n\t\t\t} catch {}\n\t\t}\n\n\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t}\n\t\t}\n\n\t\tif (conn) {\n\t\t\tconn.status = \"disconnected\";\n\t\t\tconn.tools = [];\n\t\t\tthis.notifyChange(conn);\n\t\t}\n\t\tthis.connections.delete(name);\n\t}\n\n\tasync setServerEnabled(name: string, enabled: boolean): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn) return;\n\n\t\tconn.config = { ...conn.config, disabled: !enabled } as McpServerConfig;\n\n\t\tif (!enabled) {\n\t\t\tconst timer = this.reconnectTimers.get(name);\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis.reconnectTimers.delete(name);\n\t\t\t}\n\t\t\tif (conn.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait conn.client.close();\n\t\t\t\t} catch {}\n\t\t\t\tconn.client = undefined;\n\t\t\t}\n\t\t\tconn.status = \"disconnected\";\n\t\t\tthis.notifyChange(conn);\n\t\t} else {\n\t\t\tawait this.connectServer(name, conn.config);\n\t\t}\n\t}\n\n\tasync refreshTools(serverName?: string): Promise<DiscoveredTool[]> {\n\t\tif (serverName) {\n\t\t\tconst conn = this.connections.get(serverName);\n\t\t\tif (!conn?.client) return [];\n\t\t\ttry {\n\t\t\t\tconst { tools } = await conn.client.listTools();\n\t\t\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\t\t\tif (this.toolMap.get(oldKey)?.serverName === serverName) {\n\t\t\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconn.tools = (tools ?? []).map((tool) => {\n\t\t\t\t\tconst fullName = `mcp__${serverName}__${tool.name}`;\n\t\t\t\t\tthis.toolMap.set(fullName, { serverName, toolName: tool.name });\n\t\t\t\t\treturn {\n\t\t\t\t\t\tserverName,\n\t\t\t\t\t\toriginalName: tool.name,\n\t\t\t\t\t\tfullName,\n\t\t\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t\tthis.logger.info(serverName, `Refreshed: ${conn.tools.length} tool(s)`);\n\t\t\t\tthis.notifyChange(conn);\n\t\t\t} catch (e) {\n\t\t\t\tthis.logger.error(serverName, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);\n\t\t\t}\n\t\t\treturn conn.tools;\n\t\t}\n\n\t\tconst allTools: DiscoveredTool[] = [];\n\t\tfor (const [name, conn] of this.connections) {\n\t\t\tif (conn.client && conn.status === \"connected\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst { tools } = await conn.client.listTools();\n\t\t\t\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\t\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconn.tools = (tools ?? []).map((tool) => {\n\t\t\t\t\t\tconst fullName = `mcp__${name}__${tool.name}`;\n\t\t\t\t\t\tthis.toolMap.set(fullName, { serverName: name, toolName: tool.name });\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tserverName: name,\n\t\t\t\t\t\t\toriginalName: tool.name,\n\t\t\t\t\t\t\tfullName,\n\t\t\t\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t\tallTools.push(...conn.tools);\n\t\t\t\t\tthis.notifyChange(conn);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.logger.error(name, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn allTools;\n\t}\n\n\tgetConnections(): McpConnection[] {\n\t\treturn [...this.connections.values()];\n\t}\n\n\tgetConnection(name: string): McpConnection | undefined {\n\t\treturn this.connections.get(name);\n\t}\n\n\tgetToolsByServer(serverName: string): DiscoveredTool[] {\n\t\treturn this.connections.get(serverName)?.tools ?? [];\n\t}\n\n\tasync callTool(fullName: string, args: Record<string, unknown>, timeoutMs = this.callTimeoutMs): Promise<unknown> {\n\t\tconst slotPromise = this.acquireCallSlot();\n\t\tif (slotPromise) await slotPromise;\n\t\ttry {\n\t\t\tconst mapping = this.toolMap.get(fullName);\n\t\t\tif (!mapping) throw new McpToolCallError(\"\", fullName, `Unknown MCP tool: ${fullName}`);\n\n\t\t\tconst connection = this.connections.get(mapping.serverName);\n\t\t\tif (!connection?.client)\n\t\t\t\tthrow new McpToolCallError(\n\t\t\t\t\tmapping.serverName,\n\t\t\t\t\tmapping.toolName,\n\t\t\t\t\t`MCP server \"${mapping.serverName}\" not connected`,\n\t\t\t\t);\n\n\t\t\tconst controller = new AbortController();\n\t\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\t\ttry {\n\t\t\t\treturn await connection.client.callTool({ name: mapping.toolName, arguments: args }, undefined, {\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tif (controller.signal.aborted) {\n\t\t\t\t\tthrow new McpTimeoutError(`callTool(${fullName})`, mapping.serverName, timeoutMs);\n\t\t\t\t}\n\t\t\t\tthrow new McpToolCallError(\n\t\t\t\t\tmapping.serverName,\n\t\t\t\t\tmapping.toolName,\n\t\t\t\t\te instanceof Error ? e.message : String(e),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.releaseCallSlot();\n\t\t}\n\t}\n\n\tprivate acquireCallSlot(): Promise<void> | undefined {\n\t\tif (!this.callSemaphore) return undefined;\n\t\tif (this.callSemaphore.current < this.callSemaphore.max) {\n\t\t\tthis.callSemaphore.current++;\n\t\t\treturn undefined;\n\t\t}\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tthis.callSemaphore!.queue.push(() => {\n\t\t\t\tthis.callSemaphore!.current++;\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate releaseCallSlot(): void {\n\t\tif (!this.callSemaphore) return;\n\t\tthis.callSemaphore.current--;\n\t\tconst next = this.callSemaphore.queue.shift();\n\t\tif (next) next();\n\t}\n\n\tgetAllTools(): DiscoveredTool[] {\n\t\tconst tools: DiscoveredTool[] = [];\n\t\tfor (const connection of this.connections.values()) {\n\t\t\tif (connection.status === \"connected\") tools.push(...connection.tools);\n\t\t}\n\t\treturn tools;\n\t}\n\n\tasync disconnectAll(): Promise<void> {\n\t\tfor (const timer of this.reconnectTimers.values()) clearTimeout(timer);\n\t\tthis.reconnectTimers.clear();\n\n\t\tfor (const connection of this.connections.values()) {\n\t\t\ttry {\n\t\t\t\tif (connection.client) await connection.client.close();\n\t\t\t\tconnection.status = \"disconnected\";\n\t\t\t} catch {}\n\t\t}\n\t\tthis.connections.clear();\n\t\tthis.toolMap.clear();\n\t}\n\n\tprivate async createTransport(config: McpServerConfig) {\n\t\tif (this.isStdioConfig(config)) {\n\t\t\treturn new StdioClientTransport({\n\t\t\t\tcommand: config.command,\n\t\t\t\targs: config.args,\n\t\t\t\tenv: config.env\n\t\t\t\t\t? (Object.fromEntries(\n\t\t\t\t\t\t\tObject.entries({ ...process.env, ...config.env }).filter(([, v]) => v !== undefined),\n\t\t\t\t\t\t) as Record<string, string>)\n\t\t\t\t\t: undefined,\n\t\t\t\tstderr: \"pipe\",\n\t\t\t});\n\t\t}\n\t\tif (config.type === \"sse\") {\n\t\t\tconst { SSEClientTransport } = await import(\"@modelcontextprotocol/sdk/client/sse.js\");\n\t\t\treturn new SSEClientTransport(\n\t\t\t\tnew URL(config.url),\n\t\t\t\tconfig.headers\n\t\t\t\t\t? {\n\t\t\t\t\t\t\trequestInit: { headers: config.headers },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\t\tif (config.type === \"streamable-http\") {\n\t\t\tconst { StreamableHTTPClientTransport } = await import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\");\n\t\t\treturn new StreamableHTTPClientTransport(\n\t\t\t\tnew URL(config.url),\n\t\t\t\tconfig.headers\n\t\t\t\t\t? {\n\t\t\t\t\t\t\trequestInit: { headers: config.headers },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\t\tthrow new Error(`Unknown MCP transport type: ${(config as { type: string }).type}`);\n\t}\n\n\tprivate isStdioConfig(config: McpServerConfig): config is McpStdioServerConfig {\n\t\treturn \"command\" in config;\n\t}\n}\n"]}
|
|
@@ -198,6 +198,37 @@ export class McpManager {
|
|
|
198
198
|
async addServer(name, config) {
|
|
199
199
|
await this.connectServer(name, config);
|
|
200
200
|
}
|
|
201
|
+
async restartServer(name) {
|
|
202
|
+
const conn = this.connections.get(name);
|
|
203
|
+
if (!conn)
|
|
204
|
+
throw new Error(`MCP server "${name}" not found`);
|
|
205
|
+
if (conn.config.disabled)
|
|
206
|
+
throw new Error(`MCP server "${name}" is disabled, enable it first`);
|
|
207
|
+
const timer = this.reconnectTimers.get(name);
|
|
208
|
+
if (timer) {
|
|
209
|
+
clearTimeout(timer);
|
|
210
|
+
this.reconnectTimers.delete(name);
|
|
211
|
+
}
|
|
212
|
+
if (conn.client) {
|
|
213
|
+
try {
|
|
214
|
+
await conn.client.close();
|
|
215
|
+
}
|
|
216
|
+
catch { }
|
|
217
|
+
conn.client = undefined;
|
|
218
|
+
}
|
|
219
|
+
conn.status = "connecting";
|
|
220
|
+
conn.error = undefined;
|
|
221
|
+
this.notifyChange(conn);
|
|
222
|
+
try {
|
|
223
|
+
await this.doConnectWithTimeout(name, conn.config);
|
|
224
|
+
}
|
|
225
|
+
catch (e) {
|
|
226
|
+
conn.status = "error";
|
|
227
|
+
conn.error = e instanceof Error ? e.message : String(e);
|
|
228
|
+
this.notifyChange(conn);
|
|
229
|
+
throw e;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
201
232
|
async removeServer(name) {
|
|
202
233
|
const timer = this.reconnectTimers.get(name);
|
|
203
234
|
if (timer) {
|
|
@@ -216,6 +247,11 @@ export class McpManager {
|
|
|
216
247
|
this.toolMap.delete(oldKey);
|
|
217
248
|
}
|
|
218
249
|
}
|
|
250
|
+
if (conn) {
|
|
251
|
+
conn.status = "disconnected";
|
|
252
|
+
conn.tools = [];
|
|
253
|
+
this.notifyChange(conn);
|
|
254
|
+
}
|
|
219
255
|
this.connections.delete(name);
|
|
220
256
|
}
|
|
221
257
|
async setServerEnabled(name, enabled) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-manager.js","sourceRoot":"","sources":["../../../src/core/mcp/mcp-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { McpConnectionError, McpError, McpTimeoutError, McpToolCallError } from \"./errors.js\";\nimport { McpLogger } from \"./logger.js\";\nimport type {\n\tDiscoveredTool,\n\tMcpConnection,\n\tMcpManagerEvents,\n\tMcpManagerOptions,\n\tMcpServerConfig,\n\tMcpStdioServerConfig,\n} from \"./types.js\";\n\ninterface ManagedConnection extends McpConnection {\n\tclient?: Client;\n}\n\ninterface Semaphore {\n\tcurrent: number;\n\tmax: number;\n\tqueue: Array<() => void>;\n}\n\nexport class McpManager {\n\tprivate connections = new Map<string, ManagedConnection>();\n\tprivate toolMap = new Map<string, { serverName: string; toolName: string }>();\n\tprivate readonly logger: McpLogger;\n\tprivate readonly events: McpManagerEvents;\n\tprivate readonly connectTimeoutMs: number;\n\tprivate readonly callTimeoutMs: number;\n\tprivate readonly maxReconnectAttempts: number;\n\tprivate readonly callSemaphore: Semaphore | undefined;\n\n\tprivate reconnectTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\tprivate baseReconnectDelay = 1000;\n\tprivate maxReconnectDelay = 30000;\n\n\tprivate cleanupHandler: (() => void) | undefined;\n\n\tconstructor(\n\t\toptionsOrEvents?:\n\t\t\t| McpManagerEvents\n\t\t\t| (McpManagerOptions & { onConnectionChange?: McpManagerEvents[\"onConnectionChange\"] }),\n\t) {\n\t\tconst hasOptions =\n\t\t\toptionsOrEvents &&\n\t\t\t(\"logLevel\" in optionsOrEvents ||\n\t\t\t\t\"connectTimeoutMs\" in optionsOrEvents ||\n\t\t\t\t\"callTimeoutMs\" in optionsOrEvents ||\n\t\t\t\t\"maxReconnectAttempts\" in optionsOrEvents ||\n\t\t\t\t\"maxConcurrentCalls\" in optionsOrEvents);\n\t\tconst opts = hasOptions ? (optionsOrEvents as McpManagerOptions) : undefined;\n\t\tconst eventsCallback = (optionsOrEvents as Record<string, unknown>)?.onConnectionChange as\n\t\t\t| McpManagerEvents[\"onConnectionChange\"]\n\t\t\t| undefined;\n\n\t\tthis.events = eventsCallback ? { onConnectionChange: eventsCallback } : {};\n\t\tthis.logger = new McpLogger(opts?.logLevel ?? \"info\");\n\t\tthis.connectTimeoutMs = opts?.connectTimeoutMs ?? 30_000;\n\t\tthis.callTimeoutMs = opts?.callTimeoutMs ?? 60_000;\n\t\tthis.maxReconnectAttempts = opts?.maxReconnectAttempts ?? 3;\n\t\tif (opts?.maxConcurrentCalls) {\n\t\t\tthis.callSemaphore = { current: 0, max: opts.maxConcurrentCalls, queue: [] };\n\t\t}\n\t\tthis.registerCleanup();\n\t}\n\n\tprivate registerCleanup() {\n\t\tthis.cleanupHandler = () => {\n\t\t\tthis.disconnectAll().catch(() => {});\n\t\t};\n\t\tprocess.on(\"beforeExit\", this.cleanupHandler);\n\t\tprocess.on(\"SIGTERM\", this.cleanupHandler);\n\t\tprocess.on(\"SIGINT\", this.cleanupHandler);\n\t}\n\n\tdispose(): Promise<void> {\n\t\tif (this.cleanupHandler) {\n\t\t\tprocess.off(\"beforeExit\", this.cleanupHandler);\n\t\t\tprocess.off(\"SIGTERM\", this.cleanupHandler);\n\t\t\tprocess.off(\"SIGINT\", this.cleanupHandler);\n\t\t\tthis.cleanupHandler = undefined;\n\t\t}\n\t\tfor (const timer of this.reconnectTimers.values()) clearTimeout(timer);\n\t\tthis.reconnectTimers.clear();\n\t\treturn this.disconnectAll();\n\t}\n\n\tprivate notifyChange(conn: McpConnection) {\n\t\tthis.events.onConnectionChange?.(conn);\n\t}\n\n\tasync connectAll(servers: Record<string, McpServerConfig>): Promise<void> {\n\t\tconst entries = Object.entries(servers).filter(([_, c]) => !c.disabled);\n\t\tif (entries.length === 0) return;\n\n\t\tconst results = await Promise.allSettled(entries.map(([name, config]) => this.connectServer(name, config)));\n\n\t\tconst succeeded = results.filter((r) => r.status === \"fulfilled\").length;\n\t\tconst failed = results.filter((r) => r.status === \"rejected\").length;\n\t\tthis.logger.info(\"*\", `${succeeded} server(s) connected${failed > 0 ? `, ${failed} failed` : \"\"}`);\n\t}\n\n\tasync connectServer(name: string, config: McpServerConfig): Promise<void> {\n\t\tconst existing = this.connections.get(name);\n\t\tif (existing?.client) {\n\t\t\ttry {\n\t\t\t\tawait existing.client.close();\n\t\t\t} catch {}\n\t\t}\n\n\t\tconst entry: ManagedConnection = { name, config, status: \"connecting\", tools: [] };\n\t\tthis.connections.set(name, entry);\n\t\tthis.notifyChange(entry);\n\n\t\ttry {\n\t\t\tawait this.doConnectWithTimeout(name, config);\n\t\t} catch (e) {\n\t\t\tentry.status = \"error\";\n\t\t\tentry.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.logger.error(name, `Connection failed: ${entry.error}`);\n\t\t\tthis.notifyChange(entry);\n\t\t\tthrow e instanceof McpError ? e : new McpConnectionError(name, entry.error);\n\t\t}\n\t}\n\n\tprivate async doConnectWithTimeout(\n\t\tname: string,\n\t\tconfig: McpServerConfig,\n\t\ttimeoutMs = this.connectTimeoutMs,\n\t): Promise<void> {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\ttry {\n\t\t\tawait this.doConnectServer(name, config, controller.signal);\n\t\t} catch (e) {\n\t\t\tif (controller.signal.aborted) {\n\t\t\t\tthrow new McpTimeoutError(\"connect\", name, timeoutMs);\n\t\t\t}\n\t\t\tthrow e;\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n\n\tprivate async doConnectServer(name: string, config: McpServerConfig, signal?: AbortSignal): Promise<void> {\n\t\tconst entry = this.connections.get(name);\n\t\tif (!entry) return;\n\n\t\tconst transport = await this.createTransport(config);\n\t\tconst client = new Client({ name: \"pi-mcp\", version: \"1.0.0\" }, { capabilities: {} });\n\n\t\tawait client.connect(transport, { signal });\n\t\tconst { tools } = await client.listTools();\n\n\t\tentry.client = client;\n\t\tentry.status = \"connected\";\n\t\tentry.error = undefined;\n\n\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t}\n\t\t}\n\n\t\tentry.tools = (tools ?? []).map((tool) => {\n\t\t\tconst fullName = `mcp__${name}__${tool.name}`;\n\t\t\tthis.toolMap.set(fullName, { serverName: name, toolName: tool.name });\n\t\t\treturn {\n\t\t\t\tserverName: name,\n\t\t\t\toriginalName: tool.name,\n\t\t\t\tfullName,\n\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t};\n\t\t});\n\n\t\tthis.logger.info(name, `${entry.tools.length} tool(s) discovered`);\n\t\tthis.notifyChange(entry);\n\n\t\tclient.onclose = () => {\n\t\t\tconst conn = this.connections.get(name);\n\t\t\tif (!conn || conn.status === \"disconnected\") return;\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = \"Connection closed unexpectedly\";\n\t\t\tthis.logger.warn(name, \"Connection closed unexpectedly\");\n\t\t\tthis.notifyChange(conn);\n\t\t\tthis.scheduleReconnect(name, 0);\n\t\t};\n\n\t\tclient.onerror = (err: Error) => {\n\t\t\tconst conn = this.connections.get(name);\n\t\t\tif (!conn) return;\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = err.message;\n\t\t\tthis.logger.error(name, `Client error: ${err.message}`);\n\t\t\tthis.notifyChange(conn);\n\t\t};\n\t}\n\n\tprivate scheduleReconnect(name: string, attempt: number) {\n\t\tif (attempt >= this.maxReconnectAttempts) {\n\t\t\tthis.logger.warn(name, `Max reconnect attempts (${this.maxReconnectAttempts}) reached`);\n\t\t\treturn;\n\t\t}\n\t\tconst existing = this.reconnectTimers.get(name);\n\t\tif (existing) {\n\t\t\tclearTimeout(existing);\n\t\t}\n\n\t\tconst delay = Math.min(this.baseReconnectDelay * 2 ** attempt, this.maxReconnectDelay);\n\t\tthis.logger.info(name, `Reconnecting in ${delay}ms (attempt ${attempt + 1}/${this.maxReconnectAttempts})`);\n\n\t\tconst timer = setTimeout(() => {\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t\tthis.reconnectServer(name, attempt + 1);\n\t\t}, delay);\n\t\tthis.reconnectTimers.set(name, timer);\n\t}\n\n\tprivate async reconnectServer(name: string, attempt: number): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn || conn.config.disabled) return;\n\n\t\tconn.status = \"connecting\";\n\t\tconn.error = undefined;\n\t\tthis.notifyChange(conn);\n\n\t\ttry {\n\t\t\tif (conn.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait conn.client.close();\n\t\t\t\t} catch {}\n\t\t\t\tconn.client = undefined;\n\t\t\t}\n\t\t\tawait this.doConnectServer(name, conn.config);\n\t\t\tthis.logger.info(name, \"Reconnected successfully\");\n\t\t} catch (e) {\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.notifyChange(conn);\n\t\t\tthis.scheduleReconnect(name, attempt);\n\t\t}\n\t}\n\n\tasync addServer(name: string, config: McpServerConfig): Promise<void> {\n\t\tawait this.connectServer(name, config);\n\t}\n\n\tasync removeServer(name: string): Promise<void> {\n\t\tconst timer = this.reconnectTimers.get(name);\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t}\n\n\t\tconst conn = this.connections.get(name);\n\t\tif (conn?.client) {\n\t\t\ttry {\n\t\t\t\tawait conn.client.close();\n\t\t\t} catch {}\n\t\t}\n\n\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t}\n\t\t}\n\n\t\tthis.connections.delete(name);\n\t}\n\n\tasync setServerEnabled(name: string, enabled: boolean): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn) return;\n\n\t\tconn.config = { ...conn.config, disabled: !enabled } as McpServerConfig;\n\n\t\tif (!enabled) {\n\t\t\tconst timer = this.reconnectTimers.get(name);\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis.reconnectTimers.delete(name);\n\t\t\t}\n\t\t\tif (conn.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait conn.client.close();\n\t\t\t\t} catch {}\n\t\t\t\tconn.client = undefined;\n\t\t\t}\n\t\t\tconn.status = \"disconnected\";\n\t\t\tthis.notifyChange(conn);\n\t\t} else {\n\t\t\tawait this.connectServer(name, conn.config);\n\t\t}\n\t}\n\n\tasync refreshTools(serverName?: string): Promise<DiscoveredTool[]> {\n\t\tif (serverName) {\n\t\t\tconst conn = this.connections.get(serverName);\n\t\t\tif (!conn?.client) return [];\n\t\t\ttry {\n\t\t\t\tconst { tools } = await conn.client.listTools();\n\t\t\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\t\t\tif (this.toolMap.get(oldKey)?.serverName === serverName) {\n\t\t\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconn.tools = (tools ?? []).map((tool) => {\n\t\t\t\t\tconst fullName = `mcp__${serverName}__${tool.name}`;\n\t\t\t\t\tthis.toolMap.set(fullName, { serverName, toolName: tool.name });\n\t\t\t\t\treturn {\n\t\t\t\t\t\tserverName,\n\t\t\t\t\t\toriginalName: tool.name,\n\t\t\t\t\t\tfullName,\n\t\t\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t\tthis.logger.info(serverName, `Refreshed: ${conn.tools.length} tool(s)`);\n\t\t\t\tthis.notifyChange(conn);\n\t\t\t} catch (e) {\n\t\t\t\tthis.logger.error(serverName, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);\n\t\t\t}\n\t\t\treturn conn.tools;\n\t\t}\n\n\t\tconst allTools: DiscoveredTool[] = [];\n\t\tfor (const [name, conn] of this.connections) {\n\t\t\tif (conn.client && conn.status === \"connected\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst { tools } = await conn.client.listTools();\n\t\t\t\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\t\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconn.tools = (tools ?? []).map((tool) => {\n\t\t\t\t\t\tconst fullName = `mcp__${name}__${tool.name}`;\n\t\t\t\t\t\tthis.toolMap.set(fullName, { serverName: name, toolName: tool.name });\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tserverName: name,\n\t\t\t\t\t\t\toriginalName: tool.name,\n\t\t\t\t\t\t\tfullName,\n\t\t\t\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t\tallTools.push(...conn.tools);\n\t\t\t\t\tthis.notifyChange(conn);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.logger.error(name, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn allTools;\n\t}\n\n\tgetConnections(): McpConnection[] {\n\t\treturn [...this.connections.values()];\n\t}\n\n\tgetConnection(name: string): McpConnection | undefined {\n\t\treturn this.connections.get(name);\n\t}\n\n\tgetToolsByServer(serverName: string): DiscoveredTool[] {\n\t\treturn this.connections.get(serverName)?.tools ?? [];\n\t}\n\n\tasync callTool(fullName: string, args: Record<string, unknown>, timeoutMs = this.callTimeoutMs): Promise<unknown> {\n\t\tconst slotPromise = this.acquireCallSlot();\n\t\tif (slotPromise) await slotPromise;\n\t\ttry {\n\t\t\tconst mapping = this.toolMap.get(fullName);\n\t\t\tif (!mapping) throw new McpToolCallError(\"\", fullName, `Unknown MCP tool: ${fullName}`);\n\n\t\t\tconst connection = this.connections.get(mapping.serverName);\n\t\t\tif (!connection?.client)\n\t\t\t\tthrow new McpToolCallError(\n\t\t\t\t\tmapping.serverName,\n\t\t\t\t\tmapping.toolName,\n\t\t\t\t\t`MCP server \"${mapping.serverName}\" not connected`,\n\t\t\t\t);\n\n\t\t\tconst controller = new AbortController();\n\t\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\t\ttry {\n\t\t\t\treturn await connection.client.callTool({ name: mapping.toolName, arguments: args }, undefined, {\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tif (controller.signal.aborted) {\n\t\t\t\t\tthrow new McpTimeoutError(`callTool(${fullName})`, mapping.serverName, timeoutMs);\n\t\t\t\t}\n\t\t\t\tthrow new McpToolCallError(\n\t\t\t\t\tmapping.serverName,\n\t\t\t\t\tmapping.toolName,\n\t\t\t\t\te instanceof Error ? e.message : String(e),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.releaseCallSlot();\n\t\t}\n\t}\n\n\tprivate acquireCallSlot(): Promise<void> | undefined {\n\t\tif (!this.callSemaphore) return undefined;\n\t\tif (this.callSemaphore.current < this.callSemaphore.max) {\n\t\t\tthis.callSemaphore.current++;\n\t\t\treturn undefined;\n\t\t}\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tthis.callSemaphore!.queue.push(() => {\n\t\t\t\tthis.callSemaphore!.current++;\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate releaseCallSlot(): void {\n\t\tif (!this.callSemaphore) return;\n\t\tthis.callSemaphore.current--;\n\t\tconst next = this.callSemaphore.queue.shift();\n\t\tif (next) next();\n\t}\n\n\tgetAllTools(): DiscoveredTool[] {\n\t\tconst tools: DiscoveredTool[] = [];\n\t\tfor (const connection of this.connections.values()) {\n\t\t\tif (connection.status === \"connected\") tools.push(...connection.tools);\n\t\t}\n\t\treturn tools;\n\t}\n\n\tasync disconnectAll(): Promise<void> {\n\t\tfor (const timer of this.reconnectTimers.values()) clearTimeout(timer);\n\t\tthis.reconnectTimers.clear();\n\n\t\tfor (const connection of this.connections.values()) {\n\t\t\ttry {\n\t\t\t\tif (connection.client) await connection.client.close();\n\t\t\t\tconnection.status = \"disconnected\";\n\t\t\t} catch {}\n\t\t}\n\t\tthis.connections.clear();\n\t\tthis.toolMap.clear();\n\t}\n\n\tprivate async createTransport(config: McpServerConfig) {\n\t\tif (this.isStdioConfig(config)) {\n\t\t\treturn new StdioClientTransport({\n\t\t\t\tcommand: config.command,\n\t\t\t\targs: config.args,\n\t\t\t\tenv: config.env\n\t\t\t\t\t? (Object.fromEntries(\n\t\t\t\t\t\t\tObject.entries({ ...process.env, ...config.env }).filter(([, v]) => v !== undefined),\n\t\t\t\t\t\t) as Record<string, string>)\n\t\t\t\t\t: undefined,\n\t\t\t\tstderr: \"pipe\",\n\t\t\t});\n\t\t}\n\t\tif (config.type === \"sse\") {\n\t\t\tconst { SSEClientTransport } = await import(\"@modelcontextprotocol/sdk/client/sse.js\");\n\t\t\treturn new SSEClientTransport(\n\t\t\t\tnew URL(config.url),\n\t\t\t\tconfig.headers\n\t\t\t\t\t? {\n\t\t\t\t\t\t\trequestInit: { headers: config.headers },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\t\tif (config.type === \"streamable-http\") {\n\t\t\tconst { StreamableHTTPClientTransport } = await import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\");\n\t\t\treturn new StreamableHTTPClientTransport(\n\t\t\t\tnew URL(config.url),\n\t\t\t\tconfig.headers\n\t\t\t\t\t? {\n\t\t\t\t\t\t\trequestInit: { headers: config.headers },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\t\tthrow new Error(`Unknown MCP transport type: ${(config as { type: string }).type}`);\n\t}\n\n\tprivate isStdioConfig(config: McpServerConfig): config is McpStdioServerConfig {\n\t\treturn \"command\" in config;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mcp-manager.js","sourceRoot":"","sources":["../../../src/core/mcp/mcp-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { McpConnectionError, McpError, McpTimeoutError, McpToolCallError } from \"./errors.js\";\nimport { McpLogger } from \"./logger.js\";\nimport type {\n\tDiscoveredTool,\n\tMcpConnection,\n\tMcpManagerEvents,\n\tMcpManagerOptions,\n\tMcpServerConfig,\n\tMcpStdioServerConfig,\n} from \"./types.js\";\n\ninterface ManagedConnection extends McpConnection {\n\tclient?: Client;\n}\n\ninterface Semaphore {\n\tcurrent: number;\n\tmax: number;\n\tqueue: Array<() => void>;\n}\n\nexport class McpManager {\n\tprivate connections = new Map<string, ManagedConnection>();\n\tprivate toolMap = new Map<string, { serverName: string; toolName: string }>();\n\tprivate readonly logger: McpLogger;\n\tprivate readonly events: McpManagerEvents;\n\tprivate readonly connectTimeoutMs: number;\n\tprivate readonly callTimeoutMs: number;\n\tprivate readonly maxReconnectAttempts: number;\n\tprivate readonly callSemaphore: Semaphore | undefined;\n\n\tprivate reconnectTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\tprivate baseReconnectDelay = 1000;\n\tprivate maxReconnectDelay = 30000;\n\n\tprivate cleanupHandler: (() => void) | undefined;\n\n\tconstructor(\n\t\toptionsOrEvents?:\n\t\t\t| McpManagerEvents\n\t\t\t| (McpManagerOptions & { onConnectionChange?: McpManagerEvents[\"onConnectionChange\"] }),\n\t) {\n\t\tconst hasOptions =\n\t\t\toptionsOrEvents &&\n\t\t\t(\"logLevel\" in optionsOrEvents ||\n\t\t\t\t\"connectTimeoutMs\" in optionsOrEvents ||\n\t\t\t\t\"callTimeoutMs\" in optionsOrEvents ||\n\t\t\t\t\"maxReconnectAttempts\" in optionsOrEvents ||\n\t\t\t\t\"maxConcurrentCalls\" in optionsOrEvents);\n\t\tconst opts = hasOptions ? (optionsOrEvents as McpManagerOptions) : undefined;\n\t\tconst eventsCallback = (optionsOrEvents as Record<string, unknown>)?.onConnectionChange as\n\t\t\t| McpManagerEvents[\"onConnectionChange\"]\n\t\t\t| undefined;\n\n\t\tthis.events = eventsCallback ? { onConnectionChange: eventsCallback } : {};\n\t\tthis.logger = new McpLogger(opts?.logLevel ?? \"info\");\n\t\tthis.connectTimeoutMs = opts?.connectTimeoutMs ?? 30_000;\n\t\tthis.callTimeoutMs = opts?.callTimeoutMs ?? 60_000;\n\t\tthis.maxReconnectAttempts = opts?.maxReconnectAttempts ?? 3;\n\t\tif (opts?.maxConcurrentCalls) {\n\t\t\tthis.callSemaphore = { current: 0, max: opts.maxConcurrentCalls, queue: [] };\n\t\t}\n\t\tthis.registerCleanup();\n\t}\n\n\tprivate registerCleanup() {\n\t\tthis.cleanupHandler = () => {\n\t\t\tthis.disconnectAll().catch(() => {});\n\t\t};\n\t\tprocess.on(\"beforeExit\", this.cleanupHandler);\n\t\tprocess.on(\"SIGTERM\", this.cleanupHandler);\n\t\tprocess.on(\"SIGINT\", this.cleanupHandler);\n\t}\n\n\tdispose(): Promise<void> {\n\t\tif (this.cleanupHandler) {\n\t\t\tprocess.off(\"beforeExit\", this.cleanupHandler);\n\t\t\tprocess.off(\"SIGTERM\", this.cleanupHandler);\n\t\t\tprocess.off(\"SIGINT\", this.cleanupHandler);\n\t\t\tthis.cleanupHandler = undefined;\n\t\t}\n\t\tfor (const timer of this.reconnectTimers.values()) clearTimeout(timer);\n\t\tthis.reconnectTimers.clear();\n\t\treturn this.disconnectAll();\n\t}\n\n\tprivate notifyChange(conn: McpConnection) {\n\t\tthis.events.onConnectionChange?.(conn);\n\t}\n\n\tasync connectAll(servers: Record<string, McpServerConfig>): Promise<void> {\n\t\tconst entries = Object.entries(servers).filter(([_, c]) => !c.disabled);\n\t\tif (entries.length === 0) return;\n\n\t\tconst results = await Promise.allSettled(entries.map(([name, config]) => this.connectServer(name, config)));\n\n\t\tconst succeeded = results.filter((r) => r.status === \"fulfilled\").length;\n\t\tconst failed = results.filter((r) => r.status === \"rejected\").length;\n\t\tthis.logger.info(\"*\", `${succeeded} server(s) connected${failed > 0 ? `, ${failed} failed` : \"\"}`);\n\t}\n\n\tasync connectServer(name: string, config: McpServerConfig): Promise<void> {\n\t\tconst existing = this.connections.get(name);\n\t\tif (existing?.client) {\n\t\t\ttry {\n\t\t\t\tawait existing.client.close();\n\t\t\t} catch {}\n\t\t}\n\n\t\tconst entry: ManagedConnection = { name, config, status: \"connecting\", tools: [] };\n\t\tthis.connections.set(name, entry);\n\t\tthis.notifyChange(entry);\n\n\t\ttry {\n\t\t\tawait this.doConnectWithTimeout(name, config);\n\t\t} catch (e) {\n\t\t\tentry.status = \"error\";\n\t\t\tentry.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.logger.error(name, `Connection failed: ${entry.error}`);\n\t\t\tthis.notifyChange(entry);\n\t\t\tthrow e instanceof McpError ? e : new McpConnectionError(name, entry.error);\n\t\t}\n\t}\n\n\tprivate async doConnectWithTimeout(\n\t\tname: string,\n\t\tconfig: McpServerConfig,\n\t\ttimeoutMs = this.connectTimeoutMs,\n\t): Promise<void> {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\ttry {\n\t\t\tawait this.doConnectServer(name, config, controller.signal);\n\t\t} catch (e) {\n\t\t\tif (controller.signal.aborted) {\n\t\t\t\tthrow new McpTimeoutError(\"connect\", name, timeoutMs);\n\t\t\t}\n\t\t\tthrow e;\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n\n\tprivate async doConnectServer(name: string, config: McpServerConfig, signal?: AbortSignal): Promise<void> {\n\t\tconst entry = this.connections.get(name);\n\t\tif (!entry) return;\n\n\t\tconst transport = await this.createTransport(config);\n\t\tconst client = new Client({ name: \"pi-mcp\", version: \"1.0.0\" }, { capabilities: {} });\n\n\t\tawait client.connect(transport, { signal });\n\t\tconst { tools } = await client.listTools();\n\n\t\tentry.client = client;\n\t\tentry.status = \"connected\";\n\t\tentry.error = undefined;\n\n\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t}\n\t\t}\n\n\t\tentry.tools = (tools ?? []).map((tool) => {\n\t\t\tconst fullName = `mcp__${name}__${tool.name}`;\n\t\t\tthis.toolMap.set(fullName, { serverName: name, toolName: tool.name });\n\t\t\treturn {\n\t\t\t\tserverName: name,\n\t\t\t\toriginalName: tool.name,\n\t\t\t\tfullName,\n\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t};\n\t\t});\n\n\t\tthis.logger.info(name, `${entry.tools.length} tool(s) discovered`);\n\t\tthis.notifyChange(entry);\n\n\t\tclient.onclose = () => {\n\t\t\tconst conn = this.connections.get(name);\n\t\t\tif (!conn || conn.status === \"disconnected\") return;\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = \"Connection closed unexpectedly\";\n\t\t\tthis.logger.warn(name, \"Connection closed unexpectedly\");\n\t\t\tthis.notifyChange(conn);\n\t\t\tthis.scheduleReconnect(name, 0);\n\t\t};\n\n\t\tclient.onerror = (err: Error) => {\n\t\t\tconst conn = this.connections.get(name);\n\t\t\tif (!conn) return;\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = err.message;\n\t\t\tthis.logger.error(name, `Client error: ${err.message}`);\n\t\t\tthis.notifyChange(conn);\n\t\t};\n\t}\n\n\tprivate scheduleReconnect(name: string, attempt: number) {\n\t\tif (attempt >= this.maxReconnectAttempts) {\n\t\t\tthis.logger.warn(name, `Max reconnect attempts (${this.maxReconnectAttempts}) reached`);\n\t\t\treturn;\n\t\t}\n\t\tconst existing = this.reconnectTimers.get(name);\n\t\tif (existing) {\n\t\t\tclearTimeout(existing);\n\t\t}\n\n\t\tconst delay = Math.min(this.baseReconnectDelay * 2 ** attempt, this.maxReconnectDelay);\n\t\tthis.logger.info(name, `Reconnecting in ${delay}ms (attempt ${attempt + 1}/${this.maxReconnectAttempts})`);\n\n\t\tconst timer = setTimeout(() => {\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t\tthis.reconnectServer(name, attempt + 1);\n\t\t}, delay);\n\t\tthis.reconnectTimers.set(name, timer);\n\t}\n\n\tprivate async reconnectServer(name: string, attempt: number): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn || conn.config.disabled) return;\n\n\t\tconn.status = \"connecting\";\n\t\tconn.error = undefined;\n\t\tthis.notifyChange(conn);\n\n\t\ttry {\n\t\t\tif (conn.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait conn.client.close();\n\t\t\t\t} catch {}\n\t\t\t\tconn.client = undefined;\n\t\t\t}\n\t\t\tawait this.doConnectServer(name, conn.config);\n\t\t\tthis.logger.info(name, \"Reconnected successfully\");\n\t\t} catch (e) {\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.notifyChange(conn);\n\t\t\tthis.scheduleReconnect(name, attempt);\n\t\t}\n\t}\n\n\tasync addServer(name: string, config: McpServerConfig): Promise<void> {\n\t\tawait this.connectServer(name, config);\n\t}\n\n\tasync restartServer(name: string): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn) throw new Error(`MCP server \"${name}\" not found`);\n\t\tif (conn.config.disabled) throw new Error(`MCP server \"${name}\" is disabled, enable it first`);\n\n\t\tconst timer = this.reconnectTimers.get(name);\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t}\n\n\t\tif (conn.client) {\n\t\t\ttry {\n\t\t\t\tawait conn.client.close();\n\t\t\t} catch {}\n\t\t\tconn.client = undefined;\n\t\t}\n\n\t\tconn.status = \"connecting\";\n\t\tconn.error = undefined;\n\t\tthis.notifyChange(conn);\n\n\t\ttry {\n\t\t\tawait this.doConnectWithTimeout(name, conn.config);\n\t\t} catch (e) {\n\t\t\tconn.status = \"error\";\n\t\t\tconn.error = e instanceof Error ? e.message : String(e);\n\t\t\tthis.notifyChange(conn);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tasync removeServer(name: string): Promise<void> {\n\t\tconst timer = this.reconnectTimers.get(name);\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t\tthis.reconnectTimers.delete(name);\n\t\t}\n\n\t\tconst conn = this.connections.get(name);\n\t\tif (conn?.client) {\n\t\t\ttry {\n\t\t\t\tawait conn.client.close();\n\t\t\t} catch {}\n\t\t}\n\n\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t}\n\t\t}\n\n\t\tif (conn) {\n\t\t\tconn.status = \"disconnected\";\n\t\t\tconn.tools = [];\n\t\t\tthis.notifyChange(conn);\n\t\t}\n\t\tthis.connections.delete(name);\n\t}\n\n\tasync setServerEnabled(name: string, enabled: boolean): Promise<void> {\n\t\tconst conn = this.connections.get(name);\n\t\tif (!conn) return;\n\n\t\tconn.config = { ...conn.config, disabled: !enabled } as McpServerConfig;\n\n\t\tif (!enabled) {\n\t\t\tconst timer = this.reconnectTimers.get(name);\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis.reconnectTimers.delete(name);\n\t\t\t}\n\t\t\tif (conn.client) {\n\t\t\t\ttry {\n\t\t\t\t\tawait conn.client.close();\n\t\t\t\t} catch {}\n\t\t\t\tconn.client = undefined;\n\t\t\t}\n\t\t\tconn.status = \"disconnected\";\n\t\t\tthis.notifyChange(conn);\n\t\t} else {\n\t\t\tawait this.connectServer(name, conn.config);\n\t\t}\n\t}\n\n\tasync refreshTools(serverName?: string): Promise<DiscoveredTool[]> {\n\t\tif (serverName) {\n\t\t\tconst conn = this.connections.get(serverName);\n\t\t\tif (!conn?.client) return [];\n\t\t\ttry {\n\t\t\t\tconst { tools } = await conn.client.listTools();\n\t\t\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\t\t\tif (this.toolMap.get(oldKey)?.serverName === serverName) {\n\t\t\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconn.tools = (tools ?? []).map((tool) => {\n\t\t\t\t\tconst fullName = `mcp__${serverName}__${tool.name}`;\n\t\t\t\t\tthis.toolMap.set(fullName, { serverName, toolName: tool.name });\n\t\t\t\t\treturn {\n\t\t\t\t\t\tserverName,\n\t\t\t\t\t\toriginalName: tool.name,\n\t\t\t\t\t\tfullName,\n\t\t\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t\tthis.logger.info(serverName, `Refreshed: ${conn.tools.length} tool(s)`);\n\t\t\t\tthis.notifyChange(conn);\n\t\t\t} catch (e) {\n\t\t\t\tthis.logger.error(serverName, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);\n\t\t\t}\n\t\t\treturn conn.tools;\n\t\t}\n\n\t\tconst allTools: DiscoveredTool[] = [];\n\t\tfor (const [name, conn] of this.connections) {\n\t\t\tif (conn.client && conn.status === \"connected\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst { tools } = await conn.client.listTools();\n\t\t\t\t\tfor (const oldKey of [...this.toolMap.keys()]) {\n\t\t\t\t\t\tif (this.toolMap.get(oldKey)?.serverName === name) {\n\t\t\t\t\t\t\tthis.toolMap.delete(oldKey);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconn.tools = (tools ?? []).map((tool) => {\n\t\t\t\t\t\tconst fullName = `mcp__${name}__${tool.name}`;\n\t\t\t\t\t\tthis.toolMap.set(fullName, { serverName: name, toolName: tool.name });\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tserverName: name,\n\t\t\t\t\t\t\toriginalName: tool.name,\n\t\t\t\t\t\t\tfullName,\n\t\t\t\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\t\t\t\tinputSchema: (tool.inputSchema as Record<string, unknown>) ?? { type: \"object\", properties: {} },\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t\tallTools.push(...conn.tools);\n\t\t\t\t\tthis.notifyChange(conn);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthis.logger.error(name, `Refresh failed: ${e instanceof Error ? e.message : String(e)}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn allTools;\n\t}\n\n\tgetConnections(): McpConnection[] {\n\t\treturn [...this.connections.values()];\n\t}\n\n\tgetConnection(name: string): McpConnection | undefined {\n\t\treturn this.connections.get(name);\n\t}\n\n\tgetToolsByServer(serverName: string): DiscoveredTool[] {\n\t\treturn this.connections.get(serverName)?.tools ?? [];\n\t}\n\n\tasync callTool(fullName: string, args: Record<string, unknown>, timeoutMs = this.callTimeoutMs): Promise<unknown> {\n\t\tconst slotPromise = this.acquireCallSlot();\n\t\tif (slotPromise) await slotPromise;\n\t\ttry {\n\t\t\tconst mapping = this.toolMap.get(fullName);\n\t\t\tif (!mapping) throw new McpToolCallError(\"\", fullName, `Unknown MCP tool: ${fullName}`);\n\n\t\t\tconst connection = this.connections.get(mapping.serverName);\n\t\t\tif (!connection?.client)\n\t\t\t\tthrow new McpToolCallError(\n\t\t\t\t\tmapping.serverName,\n\t\t\t\t\tmapping.toolName,\n\t\t\t\t\t`MCP server \"${mapping.serverName}\" not connected`,\n\t\t\t\t);\n\n\t\t\tconst controller = new AbortController();\n\t\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\t\ttry {\n\t\t\t\treturn await connection.client.callTool({ name: mapping.toolName, arguments: args }, undefined, {\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tif (controller.signal.aborted) {\n\t\t\t\t\tthrow new McpTimeoutError(`callTool(${fullName})`, mapping.serverName, timeoutMs);\n\t\t\t\t}\n\t\t\t\tthrow new McpToolCallError(\n\t\t\t\t\tmapping.serverName,\n\t\t\t\t\tmapping.toolName,\n\t\t\t\t\te instanceof Error ? e.message : String(e),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.releaseCallSlot();\n\t\t}\n\t}\n\n\tprivate acquireCallSlot(): Promise<void> | undefined {\n\t\tif (!this.callSemaphore) return undefined;\n\t\tif (this.callSemaphore.current < this.callSemaphore.max) {\n\t\t\tthis.callSemaphore.current++;\n\t\t\treturn undefined;\n\t\t}\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tthis.callSemaphore!.queue.push(() => {\n\t\t\t\tthis.callSemaphore!.current++;\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate releaseCallSlot(): void {\n\t\tif (!this.callSemaphore) return;\n\t\tthis.callSemaphore.current--;\n\t\tconst next = this.callSemaphore.queue.shift();\n\t\tif (next) next();\n\t}\n\n\tgetAllTools(): DiscoveredTool[] {\n\t\tconst tools: DiscoveredTool[] = [];\n\t\tfor (const connection of this.connections.values()) {\n\t\t\tif (connection.status === \"connected\") tools.push(...connection.tools);\n\t\t}\n\t\treturn tools;\n\t}\n\n\tasync disconnectAll(): Promise<void> {\n\t\tfor (const timer of this.reconnectTimers.values()) clearTimeout(timer);\n\t\tthis.reconnectTimers.clear();\n\n\t\tfor (const connection of this.connections.values()) {\n\t\t\ttry {\n\t\t\t\tif (connection.client) await connection.client.close();\n\t\t\t\tconnection.status = \"disconnected\";\n\t\t\t} catch {}\n\t\t}\n\t\tthis.connections.clear();\n\t\tthis.toolMap.clear();\n\t}\n\n\tprivate async createTransport(config: McpServerConfig) {\n\t\tif (this.isStdioConfig(config)) {\n\t\t\treturn new StdioClientTransport({\n\t\t\t\tcommand: config.command,\n\t\t\t\targs: config.args,\n\t\t\t\tenv: config.env\n\t\t\t\t\t? (Object.fromEntries(\n\t\t\t\t\t\t\tObject.entries({ ...process.env, ...config.env }).filter(([, v]) => v !== undefined),\n\t\t\t\t\t\t) as Record<string, string>)\n\t\t\t\t\t: undefined,\n\t\t\t\tstderr: \"pipe\",\n\t\t\t});\n\t\t}\n\t\tif (config.type === \"sse\") {\n\t\t\tconst { SSEClientTransport } = await import(\"@modelcontextprotocol/sdk/client/sse.js\");\n\t\t\treturn new SSEClientTransport(\n\t\t\t\tnew URL(config.url),\n\t\t\t\tconfig.headers\n\t\t\t\t\t? {\n\t\t\t\t\t\t\trequestInit: { headers: config.headers },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\t\tif (config.type === \"streamable-http\") {\n\t\t\tconst { StreamableHTTPClientTransport } = await import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\");\n\t\t\treturn new StreamableHTTPClientTransport(\n\t\t\t\tnew URL(config.url),\n\t\t\t\tconfig.headers\n\t\t\t\t\t? {\n\t\t\t\t\t\t\trequestInit: { headers: config.headers },\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t}\n\t\tthrow new Error(`Unknown MCP transport type: ${(config as { type: string }).type}`);\n\t}\n\n\tprivate isStdioConfig(config: McpServerConfig): config is McpStdioServerConfig {\n\t\treturn \"command\" in config;\n\t}\n}\n"]}
|
package/dist/core/sdk.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ export interface CreateAgentSessionOptions {
|
|
|
44
44
|
tools?: string[];
|
|
45
45
|
/** Custom tools to register (in addition to built-in tools). */
|
|
46
46
|
customTools?: ToolDefinition[];
|
|
47
|
+
/** Skip MCP server initialization entirely. */
|
|
48
|
+
noMcp?: boolean;
|
|
47
49
|
/** Resource loader. When omitted, DefaultResourceLoader is used. */
|
|
48
50
|
resourceLoader?: ResourceLoader;
|
|
49
51
|
/** Session manager. Default: SessionManager.create(cwd) */
|
package/dist/core/sdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { Agent, type AgentMessage, type ThinkingLevel } from \"@dyyz1993/pi-agent-core\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple } from \"@dyyz1993/pi-ai\";\nimport { getAgentDir } from \"../config.js\";\nimport { AgentSession } from \"./agent-session.js\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.js\";\nimport { AuthStorage } from \"./auth-storage.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.js\";\nimport { convertToLlm } from \"./messages.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { findInitialModel } from \"./model-resolver.js\";\nimport type { ResourceLoader } from \"./resource-loader.js\";\nimport { DefaultResourceLoader } from \"./resource-loader.js\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.js\";\nimport { SettingsManager } from \"./settings-manager.js\";\nimport { isInstallTelemetryEnabled } from \"./telemetry.js\";\nimport { time } from \"./timings.js\";\nimport {\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.js\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.pi/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, pi enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.js\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.js\";\nexport type { PromptTemplate } from \"./prompt-templates.js\";\nexport type { Skill } from \"./skills.js\";\nexport type { Tool } from \"./tools/index.js\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\nfunction getAttributionHeaders(\n\tmodel: Model<any>,\n\tsettingsManager: SettingsManager,\n): Record<string, string> | undefined {\n\tif (!isInstallTelemetryEnabled(settingsManager)) {\n\t\treturn undefined;\n\t}\n\n\tif (model.provider === \"openrouter\" || model.baseUrl.includes(\"openrouter.ai\")) {\n\t\treturn {\n\t\t\t\"HTTP-Referer\": \"https://pi.dev\",\n\t\t\t\"X-OpenRouter-Title\": \"pi\",\n\t\t\t\"X-OpenRouter-Categories\": \"cli-agent\",\n\t\t};\n\t}\n\n\tif (\n\t\tmodel.provider === \"cloudflare-workers-ai\" ||\n\t\tmodel.provider === \"cloudflare-ai-gateway\" ||\n\t\tmodel.baseUrl.includes(\"api.cloudflare.com\") ||\n\t\tmodel.baseUrl.includes(\"gateway.ai.cloudflare.com\")\n\t) {\n\t\treturn {\n\t\t\t\"User-Agent\": \"pi-coding-agent\",\n\t\t};\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@dyyz1993/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [readTool, bashTool],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd();\n\tconst agentDir = options.agentDir ?? getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst initialActiveToolNames: string[] = options.tools\n\t\t? [...options.tools]\n\t\t: options.noTools\n\t\t\t? []\n\t\t\t: defaultActiveToolNames;\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst auth = await modelRegistry.getApiKeyAndHeaders(model);\n\t\t\tif (!auth.ok) {\n\t\t\t\tthrow new Error(auth.error);\n\t\t\t}\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst attributionHeaders = getAttributionHeaders(model, settingsManager);\n\t\t\treturn streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\ttimeoutMs: options?.timeoutMs ?? providerRetrySettings.timeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\theaders:\n\t\t\t\t\tattributionHeaders || auth.headers || options?.headers\n\t\t\t\t\t\t? { ...attributionHeaders, ...auth.headers, ...options?.headers }\n\t\t\t\t\t\t: undefined,\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = existingSession.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\textensionRunnerRef,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { Agent, type AgentMessage, type ThinkingLevel } from \"@dyyz1993/pi-agent-core\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple } from \"@dyyz1993/pi-ai\";\nimport { getAgentDir } from \"../config.js\";\nimport { AgentSession } from \"./agent-session.js\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.js\";\nimport { AuthStorage } from \"./auth-storage.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.js\";\nimport { convertToLlm } from \"./messages.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { findInitialModel } from \"./model-resolver.js\";\nimport type { ResourceLoader } from \"./resource-loader.js\";\nimport { DefaultResourceLoader } from \"./resource-loader.js\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.js\";\nimport { SettingsManager } from \"./settings-manager.js\";\nimport { isInstallTelemetryEnabled } from \"./telemetry.js\";\nimport { time } from \"./timings.js\";\nimport {\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.js\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.pi/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, pi enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Skip MCP server initialization entirely. */\n\tnoMcp?: boolean;\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.js\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.js\";\nexport type { PromptTemplate } from \"./prompt-templates.js\";\nexport type { Skill } from \"./skills.js\";\nexport type { Tool } from \"./tools/index.js\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\nfunction getAttributionHeaders(\n\tmodel: Model<any>,\n\tsettingsManager: SettingsManager,\n): Record<string, string> | undefined {\n\tif (!isInstallTelemetryEnabled(settingsManager)) {\n\t\treturn undefined;\n\t}\n\n\tif (model.provider === \"openrouter\" || model.baseUrl.includes(\"openrouter.ai\")) {\n\t\treturn {\n\t\t\t\"HTTP-Referer\": \"https://pi.dev\",\n\t\t\t\"X-OpenRouter-Title\": \"pi\",\n\t\t\t\"X-OpenRouter-Categories\": \"cli-agent\",\n\t\t};\n\t}\n\n\tif (\n\t\tmodel.provider === \"cloudflare-workers-ai\" ||\n\t\tmodel.provider === \"cloudflare-ai-gateway\" ||\n\t\tmodel.baseUrl.includes(\"api.cloudflare.com\") ||\n\t\tmodel.baseUrl.includes(\"gateway.ai.cloudflare.com\")\n\t) {\n\t\treturn {\n\t\t\t\"User-Agent\": \"pi-coding-agent\",\n\t\t};\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@dyyz1993/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [readTool, bashTool],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd();\n\tconst agentDir = options.agentDir ?? getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst initialActiveToolNames: string[] = options.tools\n\t\t? [...options.tools]\n\t\t: options.noTools\n\t\t\t? []\n\t\t\t: defaultActiveToolNames;\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst auth = await modelRegistry.getApiKeyAndHeaders(model);\n\t\t\tif (!auth.ok) {\n\t\t\t\tthrow new Error(auth.error);\n\t\t\t}\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst attributionHeaders = getAttributionHeaders(model, settingsManager);\n\t\t\treturn streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\ttimeoutMs: options?.timeoutMs ?? providerRetrySettings.timeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\theaders:\n\t\t\t\t\tattributionHeaders || auth.headers || options?.headers\n\t\t\t\t\t\t? { ...attributionHeaders, ...auth.headers, ...options?.headers }\n\t\t\t\t\t\t: undefined,\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = existingSession.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\textensionRunnerRef,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tnoMcp: options.noMcp,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
|
package/dist/core/sdk.js
CHANGED
|
@@ -271,6 +271,7 @@ export async function createAgentSession(options = {}) {
|
|
|
271
271
|
allowedToolNames,
|
|
272
272
|
extensionRunnerRef,
|
|
273
273
|
sessionStartEvent: options.sessionStartEvent,
|
|
274
|
+
noMcp: options.noMcp,
|
|
274
275
|
});
|
|
275
276
|
const extensionsResult = resourceLoader.getExtensions();
|
|
276
277
|
return {
|
package/dist/core/sdk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { Agent, type AgentMessage, type ThinkingLevel } from \"@dyyz1993/pi-agent-core\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple } from \"@dyyz1993/pi-ai\";\nimport { getAgentDir } from \"../config.js\";\nimport { AgentSession } from \"./agent-session.js\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.js\";\nimport { AuthStorage } from \"./auth-storage.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.js\";\nimport { convertToLlm } from \"./messages.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { findInitialModel } from \"./model-resolver.js\";\nimport type { ResourceLoader } from \"./resource-loader.js\";\nimport { DefaultResourceLoader } from \"./resource-loader.js\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.js\";\nimport { SettingsManager } from \"./settings-manager.js\";\nimport { isInstallTelemetryEnabled } from \"./telemetry.js\";\nimport { time } from \"./timings.js\";\nimport {\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.js\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.pi/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, pi enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.js\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.js\";\nexport type { PromptTemplate } from \"./prompt-templates.js\";\nexport type { Skill } from \"./skills.js\";\nexport type { Tool } from \"./tools/index.js\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\nfunction getAttributionHeaders(\n\tmodel: Model<any>,\n\tsettingsManager: SettingsManager,\n): Record<string, string> | undefined {\n\tif (!isInstallTelemetryEnabled(settingsManager)) {\n\t\treturn undefined;\n\t}\n\n\tif (model.provider === \"openrouter\" || model.baseUrl.includes(\"openrouter.ai\")) {\n\t\treturn {\n\t\t\t\"HTTP-Referer\": \"https://pi.dev\",\n\t\t\t\"X-OpenRouter-Title\": \"pi\",\n\t\t\t\"X-OpenRouter-Categories\": \"cli-agent\",\n\t\t};\n\t}\n\n\tif (\n\t\tmodel.provider === \"cloudflare-workers-ai\" ||\n\t\tmodel.provider === \"cloudflare-ai-gateway\" ||\n\t\tmodel.baseUrl.includes(\"api.cloudflare.com\") ||\n\t\tmodel.baseUrl.includes(\"gateway.ai.cloudflare.com\")\n\t) {\n\t\treturn {\n\t\t\t\"User-Agent\": \"pi-coding-agent\",\n\t\t};\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@dyyz1993/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [readTool, bashTool],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd();\n\tconst agentDir = options.agentDir ?? getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst initialActiveToolNames: string[] = options.tools\n\t\t? [...options.tools]\n\t\t: options.noTools\n\t\t\t? []\n\t\t\t: defaultActiveToolNames;\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst auth = await modelRegistry.getApiKeyAndHeaders(model);\n\t\t\tif (!auth.ok) {\n\t\t\t\tthrow new Error(auth.error);\n\t\t\t}\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst attributionHeaders = getAttributionHeaders(model, settingsManager);\n\t\t\treturn streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\ttimeoutMs: options?.timeoutMs ?? providerRetrySettings.timeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\theaders:\n\t\t\t\t\tattributionHeaders || auth.headers || options?.headers\n\t\t\t\t\t\t? { ...attributionHeaders, ...auth.headers, ...options?.headers }\n\t\t\t\t\t\t: undefined,\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = existingSession.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\textensionRunnerRef,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { Agent, type AgentMessage, type ThinkingLevel } from \"@dyyz1993/pi-agent-core\";\nimport { clampThinkingLevel, type Message, type Model, streamSimple } from \"@dyyz1993/pi-ai\";\nimport { getAgentDir } from \"../config.js\";\nimport { AgentSession } from \"./agent-session.js\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.js\";\nimport { AuthStorage } from \"./auth-storage.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.js\";\nimport { convertToLlm } from \"./messages.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { findInitialModel } from \"./model-resolver.js\";\nimport type { ResourceLoader } from \"./resource-loader.js\";\nimport { DefaultResourceLoader } from \"./resource-loader.js\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.js\";\nimport { SettingsManager } from \"./settings-manager.js\";\nimport { isInstallTelemetryEnabled } from \"./telemetry.js\";\nimport { time } from \"./timings.js\";\nimport {\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.js\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.pi/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, pi enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Skip MCP server initialization entirely. */\n\tnoMcp?: boolean;\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.js\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.js\";\nexport type { PromptTemplate } from \"./prompt-templates.js\";\nexport type { Skill } from \"./skills.js\";\nexport type { Tool } from \"./tools/index.js\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\nfunction getAttributionHeaders(\n\tmodel: Model<any>,\n\tsettingsManager: SettingsManager,\n): Record<string, string> | undefined {\n\tif (!isInstallTelemetryEnabled(settingsManager)) {\n\t\treturn undefined;\n\t}\n\n\tif (model.provider === \"openrouter\" || model.baseUrl.includes(\"openrouter.ai\")) {\n\t\treturn {\n\t\t\t\"HTTP-Referer\": \"https://pi.dev\",\n\t\t\t\"X-OpenRouter-Title\": \"pi\",\n\t\t\t\"X-OpenRouter-Categories\": \"cli-agent\",\n\t\t};\n\t}\n\n\tif (\n\t\tmodel.provider === \"cloudflare-workers-ai\" ||\n\t\tmodel.provider === \"cloudflare-ai-gateway\" ||\n\t\tmodel.baseUrl.includes(\"api.cloudflare.com\") ||\n\t\tmodel.baseUrl.includes(\"gateway.ai.cloudflare.com\")\n\t) {\n\t\treturn {\n\t\t\t\"User-Agent\": \"pi-coding-agent\",\n\t\t};\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@dyyz1993/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [readTool, bashTool],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd();\n\tconst agentDir = options.agentDir ?? getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst initialActiveToolNames: string[] = options.tools\n\t\t? [...options.tools]\n\t\t: options.noTools\n\t\t\t? []\n\t\t\t: defaultActiveToolNames;\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tstreamFn: async (model, context, options) => {\n\t\t\tconst auth = await modelRegistry.getApiKeyAndHeaders(model);\n\t\t\tif (!auth.ok) {\n\t\t\t\tthrow new Error(auth.error);\n\t\t\t}\n\t\t\tconst providerRetrySettings = settingsManager.getProviderRetrySettings();\n\t\t\tconst attributionHeaders = getAttributionHeaders(model, settingsManager);\n\t\t\treturn streamSimple(model, context, {\n\t\t\t\t...options,\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\ttimeoutMs: options?.timeoutMs ?? providerRetrySettings.timeoutMs,\n\t\t\t\tmaxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries,\n\t\t\t\tmaxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs,\n\t\t\t\theaders:\n\t\t\t\t\tattributionHeaders || auth.headers || options?.headers\n\t\t\t\t\t\t? { ...attributionHeaders, ...auth.headers, ...options?.headers }\n\t\t\t\t\t\t: undefined,\n\t\t\t});\n\t\t},\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = existingSession.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\textensionRunnerRef,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tnoMcp: options.noMcp,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
|
|
@@ -54,7 +54,7 @@ export type PackageSource = string | {
|
|
|
54
54
|
prompts?: string[];
|
|
55
55
|
themes?: string[];
|
|
56
56
|
};
|
|
57
|
-
import type { McpSettings } from "./mcp/types.js";
|
|
57
|
+
import type { McpServerConfig, McpSettings } from "./mcp/types.js";
|
|
58
58
|
export type { McpManagerOptions, McpServerConfig, McpSettings, McpSseServerConfig, McpStdioServerConfig, McpStreamableHttpServerConfig, } from "./mcp/types.js";
|
|
59
59
|
export interface Settings {
|
|
60
60
|
lastChangelogVersion?: string;
|
|
@@ -263,5 +263,7 @@ export declare class SettingsManager {
|
|
|
263
263
|
getWarnings(): WarningSettings;
|
|
264
264
|
setWarnings(warnings: WarningSettings): void;
|
|
265
265
|
getTierModels(): Record<string, string>;
|
|
266
|
+
setMcpServerDisabled(name: string, disabled: boolean, scope: "global" | "project"): void;
|
|
267
|
+
getMcpServers(scope: "global" | "project"): Record<string, McpServerConfig>;
|
|
266
268
|
}
|
|
267
269
|
//# sourceMappingURL=settings-manager.d.ts.map
|