@truefoundry/trueforge-core 0.1.0-rc.0 → 0.1.1

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.
Files changed (184) hide show
  1. package/README.md +27 -0
  2. package/dist/agent-session/TurnResourceResolver.d.ts.map +1 -1
  3. package/dist/agent-session/TurnResourceResolver.js +6 -2
  4. package/dist/agent-session/TurnResourceResolver.js.map +1 -1
  5. package/dist/agent-session/TurnResourceResolver.mjs +6 -2
  6. package/dist/agent-session/TurnResourceResolver.mjs.map +1 -1
  7. package/dist/agent-session/schemas/turn.d.ts.map +1 -1
  8. package/dist/agent-session/schemas/turn.js +3 -1
  9. package/dist/agent-session/schemas/turn.js.map +1 -1
  10. package/dist/agent-session/schemas/turn.mjs +3 -1
  11. package/dist/agent-session/schemas/turn.mjs.map +1 -1
  12. package/dist/agent-session/store/InMemorySessionStore.d.ts.map +1 -1
  13. package/dist/agent-session/store/InMemorySessionStore.js +24 -8
  14. package/dist/agent-session/store/InMemorySessionStore.js.map +1 -1
  15. package/dist/agent-session/store/InMemorySessionStore.mjs +24 -8
  16. package/dist/agent-session/store/InMemorySessionStore.mjs.map +1 -1
  17. package/dist/agent-session/store/OffsetPageToken.d.ts.map +1 -1
  18. package/dist/agent-session/store/OffsetPageToken.js +3 -1
  19. package/dist/agent-session/store/OffsetPageToken.js.map +1 -1
  20. package/dist/agent-session/store/OffsetPageToken.mjs +3 -1
  21. package/dist/agent-session/store/OffsetPageToken.mjs.map +1 -1
  22. package/dist/agent-session/store/SessionListPageToken.d.ts.map +1 -1
  23. package/dist/agent-session/store/SessionListPageToken.js +3 -1
  24. package/dist/agent-session/store/SessionListPageToken.js.map +1 -1
  25. package/dist/agent-session/store/SessionListPageToken.mjs +3 -1
  26. package/dist/agent-session/store/SessionListPageToken.mjs.map +1 -1
  27. package/dist/core/InstructionBuilder.d.ts.map +1 -1
  28. package/dist/core/InstructionBuilder.js +12 -4
  29. package/dist/core/InstructionBuilder.js.map +1 -1
  30. package/dist/core/InstructionBuilder.mjs +12 -4
  31. package/dist/core/InstructionBuilder.mjs.map +1 -1
  32. package/dist/core/capabilities/builtins/AskUserQuestion.d.ts.map +1 -1
  33. package/dist/core/capabilities/builtins/AskUserQuestion.js +5 -0
  34. package/dist/core/capabilities/builtins/AskUserQuestion.js.map +1 -1
  35. package/dist/core/capabilities/builtins/AskUserQuestion.mjs +5 -0
  36. package/dist/core/capabilities/builtins/AskUserQuestion.mjs.map +1 -1
  37. package/dist/core/capabilities/builtins/LargeToolResponse.d.ts.map +1 -1
  38. package/dist/core/capabilities/builtins/LargeToolResponse.js +6 -2
  39. package/dist/core/capabilities/builtins/LargeToolResponse.js.map +1 -1
  40. package/dist/core/capabilities/builtins/LargeToolResponse.mjs +6 -2
  41. package/dist/core/capabilities/builtins/LargeToolResponse.mjs.map +1 -1
  42. package/dist/core/index.d.ts +9 -3
  43. package/dist/core/index.d.ts.map +1 -1
  44. package/dist/core/index.js +25 -0
  45. package/dist/core/index.js.map +1 -1
  46. package/dist/core/index.mjs +24 -2
  47. package/dist/core/index.mjs.map +1 -1
  48. package/dist/core/llm/VercelAILLM.d.ts +1 -0
  49. package/dist/core/llm/VercelAILLM.d.ts.map +1 -1
  50. package/dist/core/llm/VercelAILLM.js +13 -14
  51. package/dist/core/llm/VercelAILLM.js.map +1 -1
  52. package/dist/core/llm/VercelAILLM.mjs +13 -15
  53. package/dist/core/llm/VercelAILLM.mjs.map +1 -1
  54. package/dist/core/mcp/RemoteMCP.d.ts.map +1 -1
  55. package/dist/core/mcp/RemoteMCP.js +15 -5
  56. package/dist/core/mcp/RemoteMCP.js.map +1 -1
  57. package/dist/core/mcp/RemoteMCP.mjs +15 -5
  58. package/dist/core/mcp/RemoteMCP.mjs.map +1 -1
  59. package/dist/core/mcp/ToolSelectorPolicy.d.ts.map +1 -1
  60. package/dist/core/mcp/ToolSelectorPolicy.js +3 -1
  61. package/dist/core/mcp/ToolSelectorPolicy.js.map +1 -1
  62. package/dist/core/mcp/ToolSelectorPolicy.mjs +3 -1
  63. package/dist/core/mcp/ToolSelectorPolicy.mjs.map +1 -1
  64. package/dist/core/mcp/ToolSet.d.ts.map +1 -1
  65. package/dist/core/mcp/ToolSet.js +9 -3
  66. package/dist/core/mcp/ToolSet.js.map +1 -1
  67. package/dist/core/mcp/ToolSet.mjs +9 -3
  68. package/dist/core/mcp/ToolSet.mjs.map +1 -1
  69. package/dist/core/mcp/convertMCPServers.d.ts.map +1 -1
  70. package/dist/core/mcp/convertMCPServers.js +6 -2
  71. package/dist/core/mcp/convertMCPServers.js.map +1 -1
  72. package/dist/core/mcp/convertMCPServers.mjs +6 -2
  73. package/dist/core/mcp/convertMCPServers.mjs.map +1 -1
  74. package/dist/core/mcp/remoteMcpClient.d.ts.map +1 -1
  75. package/dist/core/mcp/remoteMcpClient.js +21 -7
  76. package/dist/core/mcp/remoteMcpClient.js.map +1 -1
  77. package/dist/core/mcp/remoteMcpClient.mjs +21 -7
  78. package/dist/core/mcp/remoteMcpClient.mjs.map +1 -1
  79. package/dist/core/mcp/toolSelectors.d.ts.map +1 -1
  80. package/dist/core/mcp/toolSelectors.js +18 -6
  81. package/dist/core/mcp/toolSelectors.js.map +1 -1
  82. package/dist/core/mcp/toolSelectors.mjs +18 -6
  83. package/dist/core/mcp/toolSelectors.mjs.map +1 -1
  84. package/dist/core/runtime/AgentThread.d.ts.map +1 -1
  85. package/dist/core/runtime/AgentThread.js +45 -15
  86. package/dist/core/runtime/AgentThread.js.map +1 -1
  87. package/dist/core/runtime/AgentThread.mjs +45 -15
  88. package/dist/core/runtime/AgentThread.mjs.map +1 -1
  89. package/dist/core/runtime/AgentThreadOrchestrator.d.ts.map +1 -1
  90. package/dist/core/runtime/AgentThreadOrchestrator.js +27 -9
  91. package/dist/core/runtime/AgentThreadOrchestrator.js.map +1 -1
  92. package/dist/core/runtime/AgentThreadOrchestrator.mjs +27 -9
  93. package/dist/core/runtime/AgentThreadOrchestrator.mjs.map +1 -1
  94. package/dist/core/runtime/DeferredTool.d.ts.map +1 -1
  95. package/dist/core/runtime/DeferredTool.js +15 -5
  96. package/dist/core/runtime/DeferredTool.js.map +1 -1
  97. package/dist/core/runtime/DeferredTool.mjs +15 -5
  98. package/dist/core/runtime/DeferredTool.mjs.map +1 -1
  99. package/dist/core/runtime/contextUtils.d.ts.map +1 -1
  100. package/dist/core/runtime/contextUtils.js +3 -1
  101. package/dist/core/runtime/contextUtils.js.map +1 -1
  102. package/dist/core/runtime/contextUtils.mjs +3 -1
  103. package/dist/core/runtime/contextUtils.mjs.map +1 -1
  104. package/dist/core/sandbox/Sandbox.d.ts +7 -9
  105. package/dist/core/sandbox/Sandbox.d.ts.map +1 -1
  106. package/dist/core/sandbox/Sandbox.js +55 -63
  107. package/dist/core/sandbox/Sandbox.js.map +1 -1
  108. package/dist/core/sandbox/Sandbox.mjs +56 -64
  109. package/dist/core/sandbox/Sandbox.mjs.map +1 -1
  110. package/dist/core/sandbox/codeMode/CodeModeDispatcher.d.ts +29 -0
  111. package/dist/core/sandbox/codeMode/CodeModeDispatcher.d.ts.map +1 -0
  112. package/dist/core/sandbox/codeMode/CodeModeDispatcher.js +134 -0
  113. package/dist/core/sandbox/codeMode/CodeModeDispatcher.js.map +1 -0
  114. package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs +113 -0
  115. package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs.map +1 -0
  116. package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts +21 -0
  117. package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts.map +1 -0
  118. package/dist/core/sandbox/codeMode/CodeModeTransport.js +19 -0
  119. package/dist/core/sandbox/codeMode/CodeModeTransport.js.map +1 -0
  120. package/dist/core/sandbox/codeMode/CodeModeTransport.mjs +1 -0
  121. package/dist/core/sandbox/codeMode/CodeModeTransport.mjs.map +1 -0
  122. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts +34 -0
  123. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts.map +1 -0
  124. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js +193 -0
  125. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js.map +1 -0
  126. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs +168 -0
  127. package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs.map +1 -0
  128. package/dist/core/sandbox/codeMode/types.d.ts +34 -0
  129. package/dist/core/sandbox/codeMode/types.d.ts.map +1 -0
  130. package/dist/core/sandbox/codeMode/types.js +59 -0
  131. package/dist/core/sandbox/codeMode/types.js.map +1 -0
  132. package/dist/core/sandbox/codeMode/types.mjs +32 -0
  133. package/dist/core/sandbox/codeMode/types.mjs.map +1 -0
  134. package/dist/core/sandbox/provider/DaytonaProvider.d.ts +19 -1
  135. package/dist/core/sandbox/provider/DaytonaProvider.d.ts.map +1 -1
  136. package/dist/core/sandbox/provider/DaytonaProvider.js +96 -23
  137. package/dist/core/sandbox/provider/DaytonaProvider.js.map +1 -1
  138. package/dist/core/sandbox/provider/DaytonaProvider.mjs +96 -23
  139. package/dist/core/sandbox/provider/DaytonaProvider.mjs.map +1 -1
  140. package/dist/core/sandbox/provider/Provider.d.ts +4 -3
  141. package/dist/core/sandbox/provider/Provider.d.ts.map +1 -1
  142. package/dist/core/sandbox/provider/Provider.js.map +1 -1
  143. package/dist/core/sandbox/provider/Provider.mjs.map +1 -1
  144. package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts +2 -1
  145. package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts.map +1 -1
  146. package/dist/core/sandbox/provider/TFYSandboxProvider.js +20 -6
  147. package/dist/core/sandbox/provider/TFYSandboxProvider.js.map +1 -1
  148. package/dist/core/sandbox/provider/TFYSandboxProvider.mjs +20 -6
  149. package/dist/core/sandbox/provider/TFYSandboxProvider.mjs.map +1 -1
  150. package/dist/core/sandbox/sandboxImage.d.ts +1 -1
  151. package/dist/core/sandbox/sandboxImage.d.ts.map +1 -1
  152. package/dist/core/sandbox/sandboxImage.js +1 -1
  153. package/dist/core/sandbox/sandboxImage.js.map +1 -1
  154. package/dist/core/sandbox/sandboxImage.mjs +1 -1
  155. package/dist/core/sandbox/sandboxImage.mjs.map +1 -1
  156. package/dist/core/sandbox/sandboxScripts.gen.d.ts +1 -1
  157. package/dist/core/sandbox/sandboxScripts.gen.d.ts.map +1 -1
  158. package/dist/core/sandbox/sandboxScripts.gen.js +8 -8
  159. package/dist/core/sandbox/sandboxScripts.gen.js.map +1 -1
  160. package/dist/core/sandbox/sandboxScripts.gen.mjs +8 -8
  161. package/dist/core/sandbox/sandboxScripts.gen.mjs.map +1 -1
  162. package/dist/core/sandbox/skills/SkillMounter.d.ts.map +1 -1
  163. package/dist/core/sandbox/skills/SkillMounter.js +3 -1
  164. package/dist/core/sandbox/skills/SkillMounter.js.map +1 -1
  165. package/dist/core/sandbox/skills/SkillMounter.mjs +3 -1
  166. package/dist/core/sandbox/skills/SkillMounter.mjs.map +1 -1
  167. package/dist/core/util/abort.d.ts.map +1 -1
  168. package/dist/core/util/abort.js +3 -1
  169. package/dist/core/util/abort.js.map +1 -1
  170. package/dist/core/util/abort.mjs +3 -1
  171. package/dist/core/util/abort.mjs.map +1 -1
  172. package/dist/core/util/errorLogFields.d.ts +5 -0
  173. package/dist/core/util/errorLogFields.d.ts.map +1 -1
  174. package/dist/core/util/errorLogFields.js +38 -2
  175. package/dist/core/util/errorLogFields.js.map +1 -1
  176. package/dist/core/util/errorLogFields.mjs +37 -2
  177. package/dist/core/util/errorLogFields.mjs.map +1 -1
  178. package/package.json +10 -6
  179. package/dist/core/sandbox/SandboxNatsBridge.d.ts +0 -33
  180. package/dist/core/sandbox/SandboxNatsBridge.d.ts.map +0 -1
  181. package/dist/core/sandbox/SandboxNatsBridge.js +0 -222
  182. package/dist/core/sandbox/SandboxNatsBridge.js.map +0 -1
  183. package/dist/core/sandbox/SandboxNatsBridge.mjs +0 -201
  184. package/dist/core/sandbox/SandboxNatsBridge.mjs.map +0 -1
@@ -27,13 +27,21 @@ function createTransport(type, url, headers, sessionId) {
27
27
  return new SSEClientTransport(url, { requestInit });
28
28
  }
29
29
  function isSessionExpiredError(error) {
30
- if (!(error instanceof Error)) return false;
31
- if ("code" in error && error.code === 404) return true;
30
+ if (!(error instanceof Error)) {
31
+ return false;
32
+ }
33
+ if ("code" in error && error.code === 404) {
34
+ return true;
35
+ }
32
36
  return error.message.includes("HTTP 404") || error.message.toLowerCase().includes("session");
33
37
  }
34
38
  function isAuthError(error) {
35
- if (!(error instanceof Error)) return false;
36
- if ("code" in error && error.code === 401) return true;
39
+ if (!(error instanceof Error)) {
40
+ return false;
41
+ }
42
+ if ("code" in error && error.code === 401) {
43
+ return true;
44
+ }
37
45
  return error.message.includes("HTTP 401");
38
46
  }
39
47
  function stampTraceHeaders(headers) {
@@ -43,7 +51,9 @@ function getTransportSessionId(transport) {
43
51
  return transport instanceof StreamableHTTPClientTransport ? transport.sessionId ?? null : null;
44
52
  }
45
53
  function toConnectError(error) {
46
- if (error instanceof McpConnectionError) return error;
54
+ if (error instanceof McpConnectionError) {
55
+ return error;
56
+ }
47
57
  if (isAuthError(error)) {
48
58
  return new McpConnectionError("upstream returned 401 Unauthorized (check x-tfy-mcp-headers credentials)", 401, {
49
59
  cause: error
@@ -94,8 +104,12 @@ async function connectRemoteMcp(params) {
94
104
  } catch (error) {
95
105
  await client.close().catch(() => {
96
106
  });
97
- if (isAuthError(error)) throw toConnectError(error);
98
- if (params.sessionId && isSessionExpiredError(error)) throw toConnectError(error);
107
+ if (isAuthError(error)) {
108
+ throw toConnectError(error);
109
+ }
110
+ if (params.sessionId && isSessionExpiredError(error)) {
111
+ throw toConnectError(error);
112
+ }
99
113
  failures.push({ transport: transportType, error: error instanceof Error ? error.message.trim() : String(error) });
100
114
  continue;
101
115
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/mcp/remoteMcpClient.ts"],"sourcesContent":["import { Client } from '@modelcontextprotocol/sdk/client/index.js';\n// SSE remains required during the Streamable HTTP migration (some servers still speak SSE only).\n\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport type { CallToolRequest, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { context, propagation } from '@opentelemetry/api';\nimport { McpConnectionError } from '../errors';\nimport { withTimeout } from '../util/promiseUtils';\nimport type { ToolSchema } from './IMCPServer';\n\n/** Networking for remote (url-based) MCP servers, kept separate so it can be mocked in tests. */\n\nexport type RemoteMcpTransportType = 'streamable-http' | 'sse';\n\nexport interface RemoteMcpConnection {\n readonly transportType: RemoteMcpTransportType;\n /** Session id for a stateful server, or null for a stateless one. */\n readonly sessionId: string | null;\n listTools(cursor?: string): Promise<{ tools: ToolSchema[]; nextCursor?: string | undefined }>;\n callTool(params: CallToolRequest['params']): Promise<CallToolResult>;\n close(): Promise<void>;\n}\n\n// SSE transport type kept for dual-probe support during migration.\n// eslint-disable-next-line @typescript-eslint/no-deprecated -- see TRANSPORT_PROBE_ORDER\ntype McpTransport = StreamableHTTPClientTransport | SSEClientTransport;\n\nconst CLIENT_INFO = { name: 'tfy-agent-mcp-client', version: '1.0.0' } as const;\nconst TRANSPORT_PROBE_ORDER: RemoteMcpTransportType[] = ['streamable-http', 'sse'];\n\nclass McpClientWithTimeout extends Client {\n constructor(private readonly requestTimeoutMs: number) {\n super(CLIENT_INFO, { capabilities: {} });\n }\n\n // SDK Client.request is loosely typed; forward with an explicit timeout.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- MCP SDK request typing\n override request(req: any, schema: any, options?: any): Promise<any> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- MCP SDK request typing\n return super.request(req, schema, { ...options, timeout: this.requestTimeoutMs });\n }\n}\n\nfunction createTransport(\n type: RemoteMcpTransportType,\n url: URL,\n headers: Record<string, string>,\n sessionId?: string,\n): McpTransport {\n const requestInit = { headers };\n if (type === 'streamable-http') {\n return new StreamableHTTPClientTransport(url, { requestInit, ...(sessionId !== undefined ? { sessionId } : {}) });\n }\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- dual-transport probe; see TRANSPORT_PROBE_ORDER\n return new SSEClientTransport(url, { requestInit });\n}\n\nexport function isSessionExpiredError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n if ('code' in error && error.code === 404) return true;\n return error.message.includes('HTTP 404') || error.message.toLowerCase().includes('session');\n}\n\nfunction isAuthError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n if ('code' in error && error.code === 401) return true;\n return error.message.includes('HTTP 401');\n}\n\n/** Inject the active otel trace context so each request propagates its span. */\nfunction stampTraceHeaders(headers: Record<string, string>): void {\n propagation.inject(context.active(), headers);\n}\n\nfunction getTransportSessionId(transport: McpTransport): string | null {\n return transport instanceof StreamableHTTPClientTransport ? (transport.sessionId ?? null) : null;\n}\n\nfunction toConnectError(error: unknown): McpConnectionError {\n if (error instanceof McpConnectionError) return error;\n if (isAuthError(error)) {\n return new McpConnectionError('upstream returned 401 Unauthorized (check x-tfy-mcp-headers credentials)', 401, {\n cause: error,\n });\n }\n const message = error instanceof Error ? error.message : String(error);\n return new McpConnectionError(message, 502, { cause: error });\n}\n\nfunction buildConnection(\n client: McpClientWithTimeout,\n transport: McpTransport,\n transportType: RemoteMcpTransportType,\n headers: Record<string, string>,\n requestOptions: { signal: AbortSignal },\n): RemoteMcpConnection {\n return {\n transportType,\n sessionId: getTransportSessionId(transport),\n listTools: async (cursor?: string) => {\n stampTraceHeaders(headers);\n const response = await client.listTools(cursor ? { cursor } : undefined, requestOptions);\n return {\n tools: response.tools,\n nextCursor: response.nextCursor,\n };\n },\n callTool: async (callParams: CallToolRequest['params']): Promise<CallToolResult> => {\n stampTraceHeaders(headers);\n return (await client.callTool(callParams, undefined, requestOptions)) as CallToolResult;\n },\n close: async (): Promise<void> => {\n await client.close().catch(() => {\n /* no-op */\n });\n },\n };\n}\n\n/**\n * Connect to a remote MCP server, keeping the first transport that connects. `sessionId` is passed to\n * every attempt so a stateful session resumes in place instead of opening a throwaway one.\n *\n * `knownTransportType` is a hint (from a prior connect / persisted state): it's tried first for a fast\n * path, but on failure we still fall back to probing the remaining transports, so a stale or wrong\n * hint (server switched transports, bad resume data) self-heals instead of failing every turn.\n */\nexport async function connectRemoteMcp(params: {\n url: string;\n headers: Record<string, string>;\n sessionId?: string | undefined;\n knownTransportType?: RemoteMcpTransportType | undefined;\n requestTimeoutMs: number;\n connectTimeoutMs: number;\n signal: AbortSignal;\n onClose?: (() => void) | undefined;\n onError?: ((error: Error) => void) | undefined;\n}): Promise<RemoteMcpConnection> {\n const url = new URL(params.url);\n const requestOptions = { signal: params.signal };\n const candidates = params.knownTransportType\n ? [params.knownTransportType, ...TRANSPORT_PROBE_ORDER.filter(t => t !== params.knownTransportType)]\n : TRANSPORT_PROBE_ORDER;\n const failures: { transport: RemoteMcpTransportType; error: string }[] = [];\n\n for (const transportType of candidates) {\n const transport = createTransport(transportType, url, params.headers, params.sessionId);\n const client = new McpClientWithTimeout(params.requestTimeoutMs);\n try {\n stampTraceHeaders(params.headers);\n await withTimeout(\n // Concrete transports use sessionId: string|undefined; Transport uses an optional\n // property — exactOptionalPropertyTypes rejects assignability without this cast.\n client.connect(transport as Parameters<Client['connect']>[0], requestOptions),\n params.connectTimeoutMs,\n transportType,\n );\n } catch (error) {\n await client.close().catch(() => {\n /* no-op */\n });\n if (isAuthError(error)) throw toConnectError(error);\n // A session-expired error means the transport is right but the session is stale: surface it so\n // the caller reconnects fresh instead of falling through to a different transport.\n if (params.sessionId && isSessionExpiredError(error)) throw toConnectError(error);\n failures.push({ transport: transportType, error: error instanceof Error ? error.message.trim() : String(error) });\n continue;\n }\n\n // Set on the client (not the transport) so the SDK's own onclose/onerror cleanup still runs; the\n // SDK invokes these from inside it. Only wired on the kept connection, so failed attempts stay quiet.\n client.onclose = () => params.onClose?.();\n client.onerror = error => params.onError?.(error);\n return buildConnection(client, transport, transportType, params.headers, requestOptions);\n }\n\n throw new McpConnectionError(`failed to connect (tried ${candidates.join(', ')}): ${JSON.stringify(failures)}`, 502);\n}\n"],"mappings":";AAAA,SAAS,cAAc;AAGvB,SAAS,0BAA0B;AACnC,SAAS,qCAAqC;AAE9C,SAAS,SAAS,mBAAmB;AACrC,SAAS,0BAA0B;AACnC,SAAS,mBAAmB;AAoB5B,IAAM,cAAc,EAAE,MAAM,wBAAwB,SAAS,QAAQ;AACrE,IAAM,wBAAkD,CAAC,mBAAmB,KAAK;AAEjF,IAAM,uBAAN,cAAmC,OAAO;AAAA,EACxC,YAA6B,kBAA0B;AACrD,UAAM,aAAa,EAAE,cAAc,CAAC,EAAE,CAAC;AADZ;AAAA,EAE7B;AAAA,EAF6B;AAAA;AAAA;AAAA,EAMpB,QAAQ,KAAU,QAAa,SAA6B;AAEnE,WAAO,MAAM,QAAQ,KAAK,QAAQ,EAAE,GAAG,SAAS,SAAS,KAAK,iBAAiB,CAAC;AAAA,EAClF;AACF;AAEA,SAAS,gBACP,MACA,KACA,SACA,WACc;AACd,QAAM,cAAc,EAAE,QAAQ;AAC9B,MAAI,SAAS,mBAAmB;AAC9B,WAAO,IAAI,8BAA8B,KAAK,EAAE,aAAa,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC,EAAG,CAAC;AAAA,EAClH;AAEA,SAAO,IAAI,mBAAmB,KAAK,EAAE,YAAY,CAAC;AACpD;AAEO,SAAS,sBAAsB,OAAyB;AAC7D,MAAI,EAAE,iBAAiB,OAAQ,QAAO;AACtC,MAAI,UAAU,SAAS,MAAM,SAAS,IAAK,QAAO;AAClD,SAAO,MAAM,QAAQ,SAAS,UAAU,KAAK,MAAM,QAAQ,YAAY,EAAE,SAAS,SAAS;AAC7F;AAEA,SAAS,YAAY,OAAyB;AAC5C,MAAI,EAAE,iBAAiB,OAAQ,QAAO;AACtC,MAAI,UAAU,SAAS,MAAM,SAAS,IAAK,QAAO;AAClD,SAAO,MAAM,QAAQ,SAAS,UAAU;AAC1C;AAGA,SAAS,kBAAkB,SAAuC;AAChE,cAAY,OAAO,QAAQ,OAAO,GAAG,OAAO;AAC9C;AAEA,SAAS,sBAAsB,WAAwC;AACrE,SAAO,qBAAqB,gCAAiC,UAAU,aAAa,OAAQ;AAC9F;AAEA,SAAS,eAAe,OAAoC;AAC1D,MAAI,iBAAiB,mBAAoB,QAAO;AAChD,MAAI,YAAY,KAAK,GAAG;AACtB,WAAO,IAAI,mBAAmB,4EAA4E,KAAK;AAAA,MAC7G,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,SAAO,IAAI,mBAAmB,SAAS,KAAK,EAAE,OAAO,MAAM,CAAC;AAC9D;AAEA,SAAS,gBACP,QACA,WACA,eACA,SACA,gBACqB;AACrB,SAAO;AAAA,IACL;AAAA,IACA,WAAW,sBAAsB,SAAS;AAAA,IAC1C,WAAW,OAAO,WAAoB;AACpC,wBAAkB,OAAO;AACzB,YAAM,WAAW,MAAM,OAAO,UAAU,SAAS,EAAE,OAAO,IAAI,QAAW,cAAc;AACvF,aAAO;AAAA,QACL,OAAO,SAAS;AAAA,QAChB,YAAY,SAAS;AAAA,MACvB;AAAA,IACF;AAAA,IACA,UAAU,OAAO,eAAmE;AAClF,wBAAkB,OAAO;AACzB,aAAQ,MAAM,OAAO,SAAS,YAAY,QAAW,cAAc;AAAA,IACrE;AAAA,IACA,OAAO,YAA2B;AAChC,YAAM,OAAO,MAAM,EAAE,MAAM,MAAM;AAAA,MAEjC,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAUA,eAAsB,iBAAiB,QAUN;AAC/B,QAAM,MAAM,IAAI,IAAI,OAAO,GAAG;AAC9B,QAAM,iBAAiB,EAAE,QAAQ,OAAO,OAAO;AAC/C,QAAM,aAAa,OAAO,qBACtB,CAAC,OAAO,oBAAoB,GAAG,sBAAsB,OAAO,OAAK,MAAM,OAAO,kBAAkB,CAAC,IACjG;AACJ,QAAM,WAAmE,CAAC;AAE1E,aAAW,iBAAiB,YAAY;AACtC,UAAM,YAAY,gBAAgB,eAAe,KAAK,OAAO,SAAS,OAAO,SAAS;AACtF,UAAM,SAAS,IAAI,qBAAqB,OAAO,gBAAgB;AAC/D,QAAI;AACF,wBAAkB,OAAO,OAAO;AAChC,YAAM;AAAA;AAAA;AAAA,QAGJ,OAAO,QAAQ,WAA+C,cAAc;AAAA,QAC5E,OAAO;AAAA,QACP;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,OAAO,MAAM,EAAE,MAAM,MAAM;AAAA,MAEjC,CAAC;AACD,UAAI,YAAY,KAAK,EAAG,OAAM,eAAe,KAAK;AAGlD,UAAI,OAAO,aAAa,sBAAsB,KAAK,EAAG,OAAM,eAAe,KAAK;AAChF,eAAS,KAAK,EAAE,WAAW,eAAe,OAAO,iBAAiB,QAAQ,MAAM,QAAQ,KAAK,IAAI,OAAO,KAAK,EAAE,CAAC;AAChH;AAAA,IACF;AAIA,WAAO,UAAU,MAAM,OAAO,UAAU;AACxC,WAAO,UAAU,WAAS,OAAO,UAAU,KAAK;AAChD,WAAO,gBAAgB,QAAQ,WAAW,eAAe,OAAO,SAAS,cAAc;AAAA,EACzF;AAEA,QAAM,IAAI,mBAAmB,4BAA4B,WAAW,KAAK,IAAI,CAAC,MAAM,KAAK,UAAU,QAAQ,CAAC,IAAI,GAAG;AACrH;","names":[]}
1
+ {"version":3,"sources":["../../../src/core/mcp/remoteMcpClient.ts"],"sourcesContent":["import { Client } from '@modelcontextprotocol/sdk/client/index.js';\n// SSE remains required during the Streamable HTTP migration (some servers still speak SSE only).\n\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport type { CallToolRequest, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { context, propagation } from '@opentelemetry/api';\nimport { McpConnectionError } from '../errors';\nimport { withTimeout } from '../util/promiseUtils';\nimport type { ToolSchema } from './IMCPServer';\n\n/** Networking for remote (url-based) MCP servers, kept separate so it can be mocked in tests. */\n\nexport type RemoteMcpTransportType = 'streamable-http' | 'sse';\n\nexport interface RemoteMcpConnection {\n readonly transportType: RemoteMcpTransportType;\n /** Session id for a stateful server, or null for a stateless one. */\n readonly sessionId: string | null;\n listTools(cursor?: string): Promise<{ tools: ToolSchema[]; nextCursor?: string | undefined }>;\n callTool(params: CallToolRequest['params']): Promise<CallToolResult>;\n close(): Promise<void>;\n}\n\n// SSE transport type kept for dual-probe support during migration.\n// eslint-disable-next-line @typescript-eslint/no-deprecated -- see TRANSPORT_PROBE_ORDER\ntype McpTransport = StreamableHTTPClientTransport | SSEClientTransport;\n\nconst CLIENT_INFO = { name: 'tfy-agent-mcp-client', version: '1.0.0' } as const;\nconst TRANSPORT_PROBE_ORDER: RemoteMcpTransportType[] = ['streamable-http', 'sse'];\n\nclass McpClientWithTimeout extends Client {\n constructor(private readonly requestTimeoutMs: number) {\n super(CLIENT_INFO, { capabilities: {} });\n }\n\n // SDK Client.request is loosely typed; forward with an explicit timeout.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- MCP SDK request typing\n override request(req: any, schema: any, options?: any): Promise<any> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- MCP SDK request typing\n return super.request(req, schema, { ...options, timeout: this.requestTimeoutMs });\n }\n}\n\nfunction createTransport(\n type: RemoteMcpTransportType,\n url: URL,\n headers: Record<string, string>,\n sessionId?: string,\n): McpTransport {\n const requestInit = { headers };\n if (type === 'streamable-http') {\n return new StreamableHTTPClientTransport(url, { requestInit, ...(sessionId !== undefined ? { sessionId } : {}) });\n }\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- dual-transport probe; see TRANSPORT_PROBE_ORDER\n return new SSEClientTransport(url, { requestInit });\n}\n\nexport function isSessionExpiredError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n if ('code' in error && error.code === 404) {\n return true;\n }\n return error.message.includes('HTTP 404') || error.message.toLowerCase().includes('session');\n}\n\nfunction isAuthError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n if ('code' in error && error.code === 401) {\n return true;\n }\n return error.message.includes('HTTP 401');\n}\n\n/** Inject the active otel trace context so each request propagates its span. */\nfunction stampTraceHeaders(headers: Record<string, string>): void {\n propagation.inject(context.active(), headers);\n}\n\nfunction getTransportSessionId(transport: McpTransport): string | null {\n return transport instanceof StreamableHTTPClientTransport ? (transport.sessionId ?? null) : null;\n}\n\nfunction toConnectError(error: unknown): McpConnectionError {\n if (error instanceof McpConnectionError) {\n return error;\n }\n if (isAuthError(error)) {\n return new McpConnectionError('upstream returned 401 Unauthorized (check x-tfy-mcp-headers credentials)', 401, {\n cause: error,\n });\n }\n const message = error instanceof Error ? error.message : String(error);\n return new McpConnectionError(message, 502, { cause: error });\n}\n\nfunction buildConnection(\n client: McpClientWithTimeout,\n transport: McpTransport,\n transportType: RemoteMcpTransportType,\n headers: Record<string, string>,\n requestOptions: { signal: AbortSignal },\n): RemoteMcpConnection {\n return {\n transportType,\n sessionId: getTransportSessionId(transport),\n listTools: async (cursor?: string) => {\n stampTraceHeaders(headers);\n const response = await client.listTools(cursor ? { cursor } : undefined, requestOptions);\n return {\n tools: response.tools,\n nextCursor: response.nextCursor,\n };\n },\n callTool: async (callParams: CallToolRequest['params']): Promise<CallToolResult> => {\n stampTraceHeaders(headers);\n return (await client.callTool(callParams, undefined, requestOptions)) as CallToolResult;\n },\n close: async (): Promise<void> => {\n await client.close().catch(() => {\n /* no-op */\n });\n },\n };\n}\n\n/**\n * Connect to a remote MCP server, keeping the first transport that connects. `sessionId` is passed to\n * every attempt so a stateful session resumes in place instead of opening a throwaway one.\n *\n * `knownTransportType` is a hint (from a prior connect / persisted state): it's tried first for a fast\n * path, but on failure we still fall back to probing the remaining transports, so a stale or wrong\n * hint (server switched transports, bad resume data) self-heals instead of failing every turn.\n */\nexport async function connectRemoteMcp(params: {\n url: string;\n headers: Record<string, string>;\n sessionId?: string | undefined;\n knownTransportType?: RemoteMcpTransportType | undefined;\n requestTimeoutMs: number;\n connectTimeoutMs: number;\n signal: AbortSignal;\n onClose?: (() => void) | undefined;\n onError?: ((error: Error) => void) | undefined;\n}): Promise<RemoteMcpConnection> {\n const url = new URL(params.url);\n const requestOptions = { signal: params.signal };\n const candidates = params.knownTransportType\n ? [params.knownTransportType, ...TRANSPORT_PROBE_ORDER.filter(t => t !== params.knownTransportType)]\n : TRANSPORT_PROBE_ORDER;\n const failures: { transport: RemoteMcpTransportType; error: string }[] = [];\n\n for (const transportType of candidates) {\n const transport = createTransport(transportType, url, params.headers, params.sessionId);\n const client = new McpClientWithTimeout(params.requestTimeoutMs);\n try {\n stampTraceHeaders(params.headers);\n await withTimeout(\n // Concrete transports use sessionId: string|undefined; Transport uses an optional\n // property — exactOptionalPropertyTypes rejects assignability without this cast.\n client.connect(transport as Parameters<Client['connect']>[0], requestOptions),\n params.connectTimeoutMs,\n transportType,\n );\n } catch (error) {\n await client.close().catch(() => {\n /* no-op */\n });\n if (isAuthError(error)) {\n throw toConnectError(error);\n }\n // A session-expired error means the transport is right but the session is stale: surface it so\n // the caller reconnects fresh instead of falling through to a different transport.\n if (params.sessionId && isSessionExpiredError(error)) {\n throw toConnectError(error);\n }\n failures.push({ transport: transportType, error: error instanceof Error ? error.message.trim() : String(error) });\n continue;\n }\n\n // Set on the client (not the transport) so the SDK's own onclose/onerror cleanup still runs; the\n // SDK invokes these from inside it. Only wired on the kept connection, so failed attempts stay quiet.\n client.onclose = () => params.onClose?.();\n client.onerror = error => params.onError?.(error);\n return buildConnection(client, transport, transportType, params.headers, requestOptions);\n }\n\n throw new McpConnectionError(`failed to connect (tried ${candidates.join(', ')}): ${JSON.stringify(failures)}`, 502);\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"toolSelectors.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/toolSelectors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAkB1E,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,iCAA8C,CAAC;AAE/E,oDAAoD;AACpD,eAAO,MAAM,oCAAoC,6CAAgE,CAAC;AAElH,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAAmB,CAAC;AAC7D,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAAO,CAAC;AAClD,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAAO,CAAC;AAClD,eAAO,MAAM,kCAAkC,EAAE,MAAM,EAA2C,CAAC;AA+BnG,mEAAmE;AACnE,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,eAAe,GAAG,SAAS,EACxC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACvC,OAAO,CAWT;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,eAAe,GAAG,SAAS,EACxC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACvC,OAAO,CAGT;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,MAAM,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,eAAe,GAAG,SAAS,CAAC;IACzC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,GAAG,OAAO,CAKV;AAED,yFAAyF;AACzF,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,EAAE,CAGnF;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,OAAO,CAErF"}
1
+ {"version":3,"file":"toolSelectors.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/toolSelectors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAkB1E,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,iCAA8C,CAAC;AAE/E,oDAAoD;AACpD,eAAO,MAAM,oCAAoC,6CAAgE,CAAC;AAElH,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAAmB,CAAC;AAC7D,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAAO,CAAC;AAClD,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAAO,CAAC;AAClD,eAAO,MAAM,kCAAkC,EAAE,MAAM,EAA2C,CAAC;AA+BnG,mEAAmE;AACnE,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,eAAe,GAAG,SAAS,EACxC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACvC,OAAO,CAeT;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,eAAe,GAAG,SAAS,EACxC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACvC,OAAO,CAKT;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,MAAM,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,eAAe,GAAG,SAAS,CAAC;IACzC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,GAAG,OAAO,CASV;AAED,yFAAyF;AACzF,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,EAAE,CAKnF;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,OAAO,CAErF"}
@@ -69,10 +69,14 @@ function toolMatchesTag(tag, annotations) {
69
69
  }
70
70
  }
71
71
  function toolMatchesAnySelector(toolName, annotations, selectors) {
72
- if (!selectors?.length) return false;
72
+ if (!selectors?.length) {
73
+ return false;
74
+ }
73
75
  for (const selector of selectors) {
74
76
  if (isToolTag(selector)) {
75
- if (toolMatchesTag(selector, annotations)) return true;
77
+ if (toolMatchesTag(selector, annotations)) {
78
+ return true;
79
+ }
76
80
  } else if (selector === toolName) {
77
81
  return true;
78
82
  }
@@ -80,17 +84,25 @@ function toolMatchesAnySelector(toolName, annotations, selectors) {
80
84
  return false;
81
85
  }
82
86
  function toolRequiresApproval(toolName, annotations, selectors) {
83
- if (!selectors?.length) return false;
87
+ if (!selectors?.length) {
88
+ return false;
89
+ }
84
90
  return toolMatchesAnySelector(toolName, annotations, selectors);
85
91
  }
86
92
  function isToolAllowed(params) {
87
93
  const { toolName, annotations, enableSelectors, disableSelectors } = params;
88
- if (!toolMatchesAnySelector(toolName, annotations, enableSelectors)) return false;
89
- if (toolMatchesAnySelector(toolName, annotations, disableSelectors)) return false;
94
+ if (!toolMatchesAnySelector(toolName, annotations, enableSelectors)) {
95
+ return false;
96
+ }
97
+ if (toolMatchesAnySelector(toolName, annotations, disableSelectors)) {
98
+ return false;
99
+ }
90
100
  return true;
91
101
  }
92
102
  function literalToolNames(selectors) {
93
- if (!selectors) return [];
103
+ if (!selectors) {
104
+ return [];
105
+ }
94
106
  return selectors.filter((s) => !isToolTag(s));
95
107
  }
96
108
  function selectorsIncludeAll(selectors) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/mcp/toolSelectors.ts"],"sourcesContent":["import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * MCP server tool selectors are either a special tag or a literal tool name.\n *\n * @all — every tool on the server\n * @read-only — readOnlyHint === true\n * @write — readOnlyHint === false and not destructive\n * @destructive — destructiveHint === true\n */\nconst TOOL_TAG_ALL = '@all';\nconst TOOL_TAG_READ_ONLY = '@read-only';\nconst TOOL_TAG_WRITE = '@write';\nconst TOOL_TAG_DESTRUCTIVE = '@destructive';\n\nconst TOOL_TAGS = [TOOL_TAG_ALL, TOOL_TAG_READ_ONLY, TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE] as const;\ntype ToolTag = (typeof TOOL_TAGS)[number];\n\n/** Tags allowed on `enable_tools`, `disable_tools`, and `preload_tools`. */\nexport const TOOLS_SELECTOR_TAGS = [TOOL_TAG_ALL, TOOL_TAG_READ_ONLY] as const;\n\n/** Tags allowed on `require_approval_for_tools`. */\nexport const REQUIRE_APPROVAL_TOOLS_SELECTOR_TAGS = [TOOL_TAG_ALL, TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE] as const;\n\nexport const DEFAULT_ENABLE_TOOLS: string[] = [TOOL_TAG_ALL];\nexport const DEFAULT_DISABLE_TOOLS: string[] = [];\nexport const DEFAULT_PRELOAD_TOOLS: string[] = [];\nexport const DEFAULT_REQUIRE_APPROVAL_FOR_TOOLS: string[] = [TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE];\n\nfunction isToolTag(selector: string): selector is ToolTag {\n return TOOL_TAGS.includes(selector as ToolTag);\n}\n\nfunction isReadOnly(annotations?: ToolAnnotations): boolean {\n return annotations?.readOnlyHint === true;\n}\n\nfunction isWrite(annotations?: ToolAnnotations): boolean {\n return annotations?.readOnlyHint === false && annotations.destructiveHint !== true;\n}\n\nfunction isDestructive(annotations?: ToolAnnotations): boolean {\n return annotations?.destructiveHint === true;\n}\n\nfunction toolMatchesTag(tag: ToolTag, annotations: ToolAnnotations | undefined): boolean {\n switch (tag) {\n case TOOL_TAG_ALL:\n return true;\n case TOOL_TAG_READ_ONLY:\n return isReadOnly(annotations);\n case TOOL_TAG_WRITE:\n return isWrite(annotations);\n case TOOL_TAG_DESTRUCTIVE:\n return isDestructive(annotations);\n }\n}\n\n/** True if the tool matches any selector (tag or literal name). */\nexport function toolMatchesAnySelector(\n toolName: string,\n annotations: ToolAnnotations | undefined,\n selectors: readonly string[] | undefined,\n): boolean {\n if (!selectors?.length) return false;\n\n for (const selector of selectors) {\n if (isToolTag(selector)) {\n if (toolMatchesTag(selector, annotations)) return true;\n } else if (selector === toolName) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Whether the tool requires human approval before execution.\n * Matches `@write`, `@destructive`, `@all`, or explicit tool names against annotations.\n * Unannotated tools are exempt unless named in `require_approval_for_tools` or covered by `@all`.\n */\nexport function toolRequiresApproval(\n toolName: string,\n annotations: ToolAnnotations | undefined,\n selectors: readonly string[] | undefined,\n): boolean {\n if (!selectors?.length) return false;\n return toolMatchesAnySelector(toolName, annotations, selectors);\n}\n\n/** True if the tool is enabled and not disabled. */\nexport function isToolAllowed(params: {\n toolName: string;\n annotations: ToolAnnotations | undefined;\n enableSelectors: readonly string[];\n disableSelectors: readonly string[];\n}): boolean {\n const { toolName, annotations, enableSelectors, disableSelectors } = params;\n if (!toolMatchesAnySelector(toolName, annotations, enableSelectors)) return false;\n if (toolMatchesAnySelector(toolName, annotations, disableSelectors)) return false;\n return true;\n}\n\n/** Non-tag names from a selector list (for upfront validation / sandbox allow-lists). */\nexport function literalToolNames(selectors: readonly string[] | undefined): string[] {\n if (!selectors) return [];\n return selectors.filter(s => !isToolTag(s));\n}\n\nexport function selectorsIncludeAll(selectors: readonly string[] | undefined): boolean {\n return !!selectors?.includes(TOOL_TAG_ALL);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,IAAM,eAAe;AACrB,IAAM,qBAAqB;AAC3B,IAAM,iBAAiB;AACvB,IAAM,uBAAuB;AAE7B,IAAM,YAAY,CAAC,cAAc,oBAAoB,gBAAgB,oBAAoB;AAIlF,IAAM,sBAAsB,CAAC,cAAc,kBAAkB;AAG7D,IAAM,uCAAuC,CAAC,cAAc,gBAAgB,oBAAoB;AAEhG,IAAM,uBAAiC,CAAC,YAAY;AACpD,IAAM,wBAAkC,CAAC;AACzC,IAAM,wBAAkC,CAAC;AACzC,IAAM,qCAA+C,CAAC,gBAAgB,oBAAoB;AAEjG,SAAS,UAAU,UAAuC;AACxD,SAAO,UAAU,SAAS,QAAmB;AAC/C;AAEA,SAAS,WAAW,aAAwC;AAC1D,SAAO,aAAa,iBAAiB;AACvC;AAEA,SAAS,QAAQ,aAAwC;AACvD,SAAO,aAAa,iBAAiB,SAAS,YAAY,oBAAoB;AAChF;AAEA,SAAS,cAAc,aAAwC;AAC7D,SAAO,aAAa,oBAAoB;AAC1C;AAEA,SAAS,eAAe,KAAc,aAAmD;AACvF,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,WAAW,WAAW;AAAA,IAC/B,KAAK;AACH,aAAO,QAAQ,WAAW;AAAA,IAC5B,KAAK;AACH,aAAO,cAAc,WAAW;AAAA,EACpC;AACF;AAGO,SAAS,uBACd,UACA,aACA,WACS;AACT,MAAI,CAAC,WAAW,OAAQ,QAAO;AAE/B,aAAW,YAAY,WAAW;AAChC,QAAI,UAAU,QAAQ,GAAG;AACvB,UAAI,eAAe,UAAU,WAAW,EAAG,QAAO;AAAA,IACpD,WAAW,aAAa,UAAU;AAChC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,qBACd,UACA,aACA,WACS;AACT,MAAI,CAAC,WAAW,OAAQ,QAAO;AAC/B,SAAO,uBAAuB,UAAU,aAAa,SAAS;AAChE;AAGO,SAAS,cAAc,QAKlB;AACV,QAAM,EAAE,UAAU,aAAa,iBAAiB,iBAAiB,IAAI;AACrE,MAAI,CAAC,uBAAuB,UAAU,aAAa,eAAe,EAAG,QAAO;AAC5E,MAAI,uBAAuB,UAAU,aAAa,gBAAgB,EAAG,QAAO;AAC5E,SAAO;AACT;AAGO,SAAS,iBAAiB,WAAoD;AACnF,MAAI,CAAC,UAAW,QAAO,CAAC;AACxB,SAAO,UAAU,OAAO,OAAK,CAAC,UAAU,CAAC,CAAC;AAC5C;AAEO,SAAS,oBAAoB,WAAmD;AACrF,SAAO,CAAC,CAAC,WAAW,SAAS,YAAY;AAC3C;","names":[]}
1
+ {"version":3,"sources":["../../../src/core/mcp/toolSelectors.ts"],"sourcesContent":["import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * MCP server tool selectors are either a special tag or a literal tool name.\n *\n * @all — every tool on the server\n * @read-only — readOnlyHint === true\n * @write — readOnlyHint === false and not destructive\n * @destructive — destructiveHint === true\n */\nconst TOOL_TAG_ALL = '@all';\nconst TOOL_TAG_READ_ONLY = '@read-only';\nconst TOOL_TAG_WRITE = '@write';\nconst TOOL_TAG_DESTRUCTIVE = '@destructive';\n\nconst TOOL_TAGS = [TOOL_TAG_ALL, TOOL_TAG_READ_ONLY, TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE] as const;\ntype ToolTag = (typeof TOOL_TAGS)[number];\n\n/** Tags allowed on `enable_tools`, `disable_tools`, and `preload_tools`. */\nexport const TOOLS_SELECTOR_TAGS = [TOOL_TAG_ALL, TOOL_TAG_READ_ONLY] as const;\n\n/** Tags allowed on `require_approval_for_tools`. */\nexport const REQUIRE_APPROVAL_TOOLS_SELECTOR_TAGS = [TOOL_TAG_ALL, TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE] as const;\n\nexport const DEFAULT_ENABLE_TOOLS: string[] = [TOOL_TAG_ALL];\nexport const DEFAULT_DISABLE_TOOLS: string[] = [];\nexport const DEFAULT_PRELOAD_TOOLS: string[] = [];\nexport const DEFAULT_REQUIRE_APPROVAL_FOR_TOOLS: string[] = [TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE];\n\nfunction isToolTag(selector: string): selector is ToolTag {\n return TOOL_TAGS.includes(selector as ToolTag);\n}\n\nfunction isReadOnly(annotations?: ToolAnnotations): boolean {\n return annotations?.readOnlyHint === true;\n}\n\nfunction isWrite(annotations?: ToolAnnotations): boolean {\n return annotations?.readOnlyHint === false && annotations.destructiveHint !== true;\n}\n\nfunction isDestructive(annotations?: ToolAnnotations): boolean {\n return annotations?.destructiveHint === true;\n}\n\nfunction toolMatchesTag(tag: ToolTag, annotations: ToolAnnotations | undefined): boolean {\n switch (tag) {\n case TOOL_TAG_ALL:\n return true;\n case TOOL_TAG_READ_ONLY:\n return isReadOnly(annotations);\n case TOOL_TAG_WRITE:\n return isWrite(annotations);\n case TOOL_TAG_DESTRUCTIVE:\n return isDestructive(annotations);\n }\n}\n\n/** True if the tool matches any selector (tag or literal name). */\nexport function toolMatchesAnySelector(\n toolName: string,\n annotations: ToolAnnotations | undefined,\n selectors: readonly string[] | undefined,\n): boolean {\n if (!selectors?.length) {\n return false;\n }\n\n for (const selector of selectors) {\n if (isToolTag(selector)) {\n if (toolMatchesTag(selector, annotations)) {\n return true;\n }\n } else if (selector === toolName) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Whether the tool requires human approval before execution.\n * Matches `@write`, `@destructive`, `@all`, or explicit tool names against annotations.\n * Unannotated tools are exempt unless named in `require_approval_for_tools` or covered by `@all`.\n */\nexport function toolRequiresApproval(\n toolName: string,\n annotations: ToolAnnotations | undefined,\n selectors: readonly string[] | undefined,\n): boolean {\n if (!selectors?.length) {\n return false;\n }\n return toolMatchesAnySelector(toolName, annotations, selectors);\n}\n\n/** True if the tool is enabled and not disabled. */\nexport function isToolAllowed(params: {\n toolName: string;\n annotations: ToolAnnotations | undefined;\n enableSelectors: readonly string[];\n disableSelectors: readonly string[];\n}): boolean {\n const { toolName, annotations, enableSelectors, disableSelectors } = params;\n if (!toolMatchesAnySelector(toolName, annotations, enableSelectors)) {\n return false;\n }\n if (toolMatchesAnySelector(toolName, annotations, disableSelectors)) {\n return false;\n }\n return true;\n}\n\n/** Non-tag names from a selector list (for upfront validation / sandbox allow-lists). */\nexport function literalToolNames(selectors: readonly string[] | undefined): string[] {\n if (!selectors) {\n return [];\n }\n return selectors.filter(s => !isToolTag(s));\n}\n\nexport function selectorsIncludeAll(selectors: readonly string[] | undefined): boolean {\n return !!selectors?.includes(TOOL_TAG_ALL);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,IAAM,eAAe;AACrB,IAAM,qBAAqB;AAC3B,IAAM,iBAAiB;AACvB,IAAM,uBAAuB;AAE7B,IAAM,YAAY,CAAC,cAAc,oBAAoB,gBAAgB,oBAAoB;AAIlF,IAAM,sBAAsB,CAAC,cAAc,kBAAkB;AAG7D,IAAM,uCAAuC,CAAC,cAAc,gBAAgB,oBAAoB;AAEhG,IAAM,uBAAiC,CAAC,YAAY;AACpD,IAAM,wBAAkC,CAAC;AACzC,IAAM,wBAAkC,CAAC;AACzC,IAAM,qCAA+C,CAAC,gBAAgB,oBAAoB;AAEjG,SAAS,UAAU,UAAuC;AACxD,SAAO,UAAU,SAAS,QAAmB;AAC/C;AAEA,SAAS,WAAW,aAAwC;AAC1D,SAAO,aAAa,iBAAiB;AACvC;AAEA,SAAS,QAAQ,aAAwC;AACvD,SAAO,aAAa,iBAAiB,SAAS,YAAY,oBAAoB;AAChF;AAEA,SAAS,cAAc,aAAwC;AAC7D,SAAO,aAAa,oBAAoB;AAC1C;AAEA,SAAS,eAAe,KAAc,aAAmD;AACvF,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,WAAW,WAAW;AAAA,IAC/B,KAAK;AACH,aAAO,QAAQ,WAAW;AAAA,IAC5B,KAAK;AACH,aAAO,cAAc,WAAW;AAAA,EACpC;AACF;AAGO,SAAS,uBACd,UACA,aACA,WACS;AACT,MAAI,CAAC,WAAW,QAAQ;AACtB,WAAO;AAAA,EACT;AAEA,aAAW,YAAY,WAAW;AAChC,QAAI,UAAU,QAAQ,GAAG;AACvB,UAAI,eAAe,UAAU,WAAW,GAAG;AACzC,eAAO;AAAA,MACT;AAAA,IACF,WAAW,aAAa,UAAU;AAChC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,qBACd,UACA,aACA,WACS;AACT,MAAI,CAAC,WAAW,QAAQ;AACtB,WAAO;AAAA,EACT;AACA,SAAO,uBAAuB,UAAU,aAAa,SAAS;AAChE;AAGO,SAAS,cAAc,QAKlB;AACV,QAAM,EAAE,UAAU,aAAa,iBAAiB,iBAAiB,IAAI;AACrE,MAAI,CAAC,uBAAuB,UAAU,aAAa,eAAe,GAAG;AACnE,WAAO;AAAA,EACT;AACA,MAAI,uBAAuB,UAAU,aAAa,gBAAgB,GAAG;AACnE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGO,SAAS,iBAAiB,WAAoD;AACnF,MAAI,CAAC,WAAW;AACd,WAAO,CAAC;AAAA,EACV;AACA,SAAO,UAAU,OAAO,OAAK,CAAC,UAAU,CAAC,CAAC;AAC5C;AAEO,SAAS,oBAAoB,WAAmD;AACrF,SAAO,CAAC,CAAC,WAAW,SAAS,YAAY;AAC3C;","names":[]}
@@ -35,10 +35,14 @@ function toolMatchesTag(tag, annotations) {
35
35
  }
36
36
  }
37
37
  function toolMatchesAnySelector(toolName, annotations, selectors) {
38
- if (!selectors?.length) return false;
38
+ if (!selectors?.length) {
39
+ return false;
40
+ }
39
41
  for (const selector of selectors) {
40
42
  if (isToolTag(selector)) {
41
- if (toolMatchesTag(selector, annotations)) return true;
43
+ if (toolMatchesTag(selector, annotations)) {
44
+ return true;
45
+ }
42
46
  } else if (selector === toolName) {
43
47
  return true;
44
48
  }
@@ -46,17 +50,25 @@ function toolMatchesAnySelector(toolName, annotations, selectors) {
46
50
  return false;
47
51
  }
48
52
  function toolRequiresApproval(toolName, annotations, selectors) {
49
- if (!selectors?.length) return false;
53
+ if (!selectors?.length) {
54
+ return false;
55
+ }
50
56
  return toolMatchesAnySelector(toolName, annotations, selectors);
51
57
  }
52
58
  function isToolAllowed(params) {
53
59
  const { toolName, annotations, enableSelectors, disableSelectors } = params;
54
- if (!toolMatchesAnySelector(toolName, annotations, enableSelectors)) return false;
55
- if (toolMatchesAnySelector(toolName, annotations, disableSelectors)) return false;
60
+ if (!toolMatchesAnySelector(toolName, annotations, enableSelectors)) {
61
+ return false;
62
+ }
63
+ if (toolMatchesAnySelector(toolName, annotations, disableSelectors)) {
64
+ return false;
65
+ }
56
66
  return true;
57
67
  }
58
68
  function literalToolNames(selectors) {
59
- if (!selectors) return [];
69
+ if (!selectors) {
70
+ return [];
71
+ }
60
72
  return selectors.filter((s) => !isToolTag(s));
61
73
  }
62
74
  function selectorsIncludeAll(selectors) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/mcp/toolSelectors.ts"],"sourcesContent":["import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * MCP server tool selectors are either a special tag or a literal tool name.\n *\n * @all — every tool on the server\n * @read-only — readOnlyHint === true\n * @write — readOnlyHint === false and not destructive\n * @destructive — destructiveHint === true\n */\nconst TOOL_TAG_ALL = '@all';\nconst TOOL_TAG_READ_ONLY = '@read-only';\nconst TOOL_TAG_WRITE = '@write';\nconst TOOL_TAG_DESTRUCTIVE = '@destructive';\n\nconst TOOL_TAGS = [TOOL_TAG_ALL, TOOL_TAG_READ_ONLY, TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE] as const;\ntype ToolTag = (typeof TOOL_TAGS)[number];\n\n/** Tags allowed on `enable_tools`, `disable_tools`, and `preload_tools`. */\nexport const TOOLS_SELECTOR_TAGS = [TOOL_TAG_ALL, TOOL_TAG_READ_ONLY] as const;\n\n/** Tags allowed on `require_approval_for_tools`. */\nexport const REQUIRE_APPROVAL_TOOLS_SELECTOR_TAGS = [TOOL_TAG_ALL, TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE] as const;\n\nexport const DEFAULT_ENABLE_TOOLS: string[] = [TOOL_TAG_ALL];\nexport const DEFAULT_DISABLE_TOOLS: string[] = [];\nexport const DEFAULT_PRELOAD_TOOLS: string[] = [];\nexport const DEFAULT_REQUIRE_APPROVAL_FOR_TOOLS: string[] = [TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE];\n\nfunction isToolTag(selector: string): selector is ToolTag {\n return TOOL_TAGS.includes(selector as ToolTag);\n}\n\nfunction isReadOnly(annotations?: ToolAnnotations): boolean {\n return annotations?.readOnlyHint === true;\n}\n\nfunction isWrite(annotations?: ToolAnnotations): boolean {\n return annotations?.readOnlyHint === false && annotations.destructiveHint !== true;\n}\n\nfunction isDestructive(annotations?: ToolAnnotations): boolean {\n return annotations?.destructiveHint === true;\n}\n\nfunction toolMatchesTag(tag: ToolTag, annotations: ToolAnnotations | undefined): boolean {\n switch (tag) {\n case TOOL_TAG_ALL:\n return true;\n case TOOL_TAG_READ_ONLY:\n return isReadOnly(annotations);\n case TOOL_TAG_WRITE:\n return isWrite(annotations);\n case TOOL_TAG_DESTRUCTIVE:\n return isDestructive(annotations);\n }\n}\n\n/** True if the tool matches any selector (tag or literal name). */\nexport function toolMatchesAnySelector(\n toolName: string,\n annotations: ToolAnnotations | undefined,\n selectors: readonly string[] | undefined,\n): boolean {\n if (!selectors?.length) return false;\n\n for (const selector of selectors) {\n if (isToolTag(selector)) {\n if (toolMatchesTag(selector, annotations)) return true;\n } else if (selector === toolName) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Whether the tool requires human approval before execution.\n * Matches `@write`, `@destructive`, `@all`, or explicit tool names against annotations.\n * Unannotated tools are exempt unless named in `require_approval_for_tools` or covered by `@all`.\n */\nexport function toolRequiresApproval(\n toolName: string,\n annotations: ToolAnnotations | undefined,\n selectors: readonly string[] | undefined,\n): boolean {\n if (!selectors?.length) return false;\n return toolMatchesAnySelector(toolName, annotations, selectors);\n}\n\n/** True if the tool is enabled and not disabled. */\nexport function isToolAllowed(params: {\n toolName: string;\n annotations: ToolAnnotations | undefined;\n enableSelectors: readonly string[];\n disableSelectors: readonly string[];\n}): boolean {\n const { toolName, annotations, enableSelectors, disableSelectors } = params;\n if (!toolMatchesAnySelector(toolName, annotations, enableSelectors)) return false;\n if (toolMatchesAnySelector(toolName, annotations, disableSelectors)) return false;\n return true;\n}\n\n/** Non-tag names from a selector list (for upfront validation / sandbox allow-lists). */\nexport function literalToolNames(selectors: readonly string[] | undefined): string[] {\n if (!selectors) return [];\n return selectors.filter(s => !isToolTag(s));\n}\n\nexport function selectorsIncludeAll(selectors: readonly string[] | undefined): boolean {\n return !!selectors?.includes(TOOL_TAG_ALL);\n}\n"],"mappings":";AAUA,IAAM,eAAe;AACrB,IAAM,qBAAqB;AAC3B,IAAM,iBAAiB;AACvB,IAAM,uBAAuB;AAE7B,IAAM,YAAY,CAAC,cAAc,oBAAoB,gBAAgB,oBAAoB;AAIlF,IAAM,sBAAsB,CAAC,cAAc,kBAAkB;AAG7D,IAAM,uCAAuC,CAAC,cAAc,gBAAgB,oBAAoB;AAEhG,IAAM,uBAAiC,CAAC,YAAY;AACpD,IAAM,wBAAkC,CAAC;AACzC,IAAM,wBAAkC,CAAC;AACzC,IAAM,qCAA+C,CAAC,gBAAgB,oBAAoB;AAEjG,SAAS,UAAU,UAAuC;AACxD,SAAO,UAAU,SAAS,QAAmB;AAC/C;AAEA,SAAS,WAAW,aAAwC;AAC1D,SAAO,aAAa,iBAAiB;AACvC;AAEA,SAAS,QAAQ,aAAwC;AACvD,SAAO,aAAa,iBAAiB,SAAS,YAAY,oBAAoB;AAChF;AAEA,SAAS,cAAc,aAAwC;AAC7D,SAAO,aAAa,oBAAoB;AAC1C;AAEA,SAAS,eAAe,KAAc,aAAmD;AACvF,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,WAAW,WAAW;AAAA,IAC/B,KAAK;AACH,aAAO,QAAQ,WAAW;AAAA,IAC5B,KAAK;AACH,aAAO,cAAc,WAAW;AAAA,EACpC;AACF;AAGO,SAAS,uBACd,UACA,aACA,WACS;AACT,MAAI,CAAC,WAAW,OAAQ,QAAO;AAE/B,aAAW,YAAY,WAAW;AAChC,QAAI,UAAU,QAAQ,GAAG;AACvB,UAAI,eAAe,UAAU,WAAW,EAAG,QAAO;AAAA,IACpD,WAAW,aAAa,UAAU;AAChC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,qBACd,UACA,aACA,WACS;AACT,MAAI,CAAC,WAAW,OAAQ,QAAO;AAC/B,SAAO,uBAAuB,UAAU,aAAa,SAAS;AAChE;AAGO,SAAS,cAAc,QAKlB;AACV,QAAM,EAAE,UAAU,aAAa,iBAAiB,iBAAiB,IAAI;AACrE,MAAI,CAAC,uBAAuB,UAAU,aAAa,eAAe,EAAG,QAAO;AAC5E,MAAI,uBAAuB,UAAU,aAAa,gBAAgB,EAAG,QAAO;AAC5E,SAAO;AACT;AAGO,SAAS,iBAAiB,WAAoD;AACnF,MAAI,CAAC,UAAW,QAAO,CAAC;AACxB,SAAO,UAAU,OAAO,OAAK,CAAC,UAAU,CAAC,CAAC;AAC5C;AAEO,SAAS,oBAAoB,WAAmD;AACrF,SAAO,CAAC,CAAC,WAAW,SAAS,YAAY;AAC3C;","names":[]}
1
+ {"version":3,"sources":["../../../src/core/mcp/toolSelectors.ts"],"sourcesContent":["import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * MCP server tool selectors are either a special tag or a literal tool name.\n *\n * @all — every tool on the server\n * @read-only — readOnlyHint === true\n * @write — readOnlyHint === false and not destructive\n * @destructive — destructiveHint === true\n */\nconst TOOL_TAG_ALL = '@all';\nconst TOOL_TAG_READ_ONLY = '@read-only';\nconst TOOL_TAG_WRITE = '@write';\nconst TOOL_TAG_DESTRUCTIVE = '@destructive';\n\nconst TOOL_TAGS = [TOOL_TAG_ALL, TOOL_TAG_READ_ONLY, TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE] as const;\ntype ToolTag = (typeof TOOL_TAGS)[number];\n\n/** Tags allowed on `enable_tools`, `disable_tools`, and `preload_tools`. */\nexport const TOOLS_SELECTOR_TAGS = [TOOL_TAG_ALL, TOOL_TAG_READ_ONLY] as const;\n\n/** Tags allowed on `require_approval_for_tools`. */\nexport const REQUIRE_APPROVAL_TOOLS_SELECTOR_TAGS = [TOOL_TAG_ALL, TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE] as const;\n\nexport const DEFAULT_ENABLE_TOOLS: string[] = [TOOL_TAG_ALL];\nexport const DEFAULT_DISABLE_TOOLS: string[] = [];\nexport const DEFAULT_PRELOAD_TOOLS: string[] = [];\nexport const DEFAULT_REQUIRE_APPROVAL_FOR_TOOLS: string[] = [TOOL_TAG_WRITE, TOOL_TAG_DESTRUCTIVE];\n\nfunction isToolTag(selector: string): selector is ToolTag {\n return TOOL_TAGS.includes(selector as ToolTag);\n}\n\nfunction isReadOnly(annotations?: ToolAnnotations): boolean {\n return annotations?.readOnlyHint === true;\n}\n\nfunction isWrite(annotations?: ToolAnnotations): boolean {\n return annotations?.readOnlyHint === false && annotations.destructiveHint !== true;\n}\n\nfunction isDestructive(annotations?: ToolAnnotations): boolean {\n return annotations?.destructiveHint === true;\n}\n\nfunction toolMatchesTag(tag: ToolTag, annotations: ToolAnnotations | undefined): boolean {\n switch (tag) {\n case TOOL_TAG_ALL:\n return true;\n case TOOL_TAG_READ_ONLY:\n return isReadOnly(annotations);\n case TOOL_TAG_WRITE:\n return isWrite(annotations);\n case TOOL_TAG_DESTRUCTIVE:\n return isDestructive(annotations);\n }\n}\n\n/** True if the tool matches any selector (tag or literal name). */\nexport function toolMatchesAnySelector(\n toolName: string,\n annotations: ToolAnnotations | undefined,\n selectors: readonly string[] | undefined,\n): boolean {\n if (!selectors?.length) {\n return false;\n }\n\n for (const selector of selectors) {\n if (isToolTag(selector)) {\n if (toolMatchesTag(selector, annotations)) {\n return true;\n }\n } else if (selector === toolName) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Whether the tool requires human approval before execution.\n * Matches `@write`, `@destructive`, `@all`, or explicit tool names against annotations.\n * Unannotated tools are exempt unless named in `require_approval_for_tools` or covered by `@all`.\n */\nexport function toolRequiresApproval(\n toolName: string,\n annotations: ToolAnnotations | undefined,\n selectors: readonly string[] | undefined,\n): boolean {\n if (!selectors?.length) {\n return false;\n }\n return toolMatchesAnySelector(toolName, annotations, selectors);\n}\n\n/** True if the tool is enabled and not disabled. */\nexport function isToolAllowed(params: {\n toolName: string;\n annotations: ToolAnnotations | undefined;\n enableSelectors: readonly string[];\n disableSelectors: readonly string[];\n}): boolean {\n const { toolName, annotations, enableSelectors, disableSelectors } = params;\n if (!toolMatchesAnySelector(toolName, annotations, enableSelectors)) {\n return false;\n }\n if (toolMatchesAnySelector(toolName, annotations, disableSelectors)) {\n return false;\n }\n return true;\n}\n\n/** Non-tag names from a selector list (for upfront validation / sandbox allow-lists). */\nexport function literalToolNames(selectors: readonly string[] | undefined): string[] {\n if (!selectors) {\n return [];\n }\n return selectors.filter(s => !isToolTag(s));\n}\n\nexport function selectorsIncludeAll(selectors: readonly string[] | undefined): boolean {\n return !!selectors?.includes(TOOL_TAG_ALL);\n}\n"],"mappings":";AAUA,IAAM,eAAe;AACrB,IAAM,qBAAqB;AAC3B,IAAM,iBAAiB;AACvB,IAAM,uBAAuB;AAE7B,IAAM,YAAY,CAAC,cAAc,oBAAoB,gBAAgB,oBAAoB;AAIlF,IAAM,sBAAsB,CAAC,cAAc,kBAAkB;AAG7D,IAAM,uCAAuC,CAAC,cAAc,gBAAgB,oBAAoB;AAEhG,IAAM,uBAAiC,CAAC,YAAY;AACpD,IAAM,wBAAkC,CAAC;AACzC,IAAM,wBAAkC,CAAC;AACzC,IAAM,qCAA+C,CAAC,gBAAgB,oBAAoB;AAEjG,SAAS,UAAU,UAAuC;AACxD,SAAO,UAAU,SAAS,QAAmB;AAC/C;AAEA,SAAS,WAAW,aAAwC;AAC1D,SAAO,aAAa,iBAAiB;AACvC;AAEA,SAAS,QAAQ,aAAwC;AACvD,SAAO,aAAa,iBAAiB,SAAS,YAAY,oBAAoB;AAChF;AAEA,SAAS,cAAc,aAAwC;AAC7D,SAAO,aAAa,oBAAoB;AAC1C;AAEA,SAAS,eAAe,KAAc,aAAmD;AACvF,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,WAAW,WAAW;AAAA,IAC/B,KAAK;AACH,aAAO,QAAQ,WAAW;AAAA,IAC5B,KAAK;AACH,aAAO,cAAc,WAAW;AAAA,EACpC;AACF;AAGO,SAAS,uBACd,UACA,aACA,WACS;AACT,MAAI,CAAC,WAAW,QAAQ;AACtB,WAAO;AAAA,EACT;AAEA,aAAW,YAAY,WAAW;AAChC,QAAI,UAAU,QAAQ,GAAG;AACvB,UAAI,eAAe,UAAU,WAAW,GAAG;AACzC,eAAO;AAAA,MACT;AAAA,IACF,WAAW,aAAa,UAAU;AAChC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,qBACd,UACA,aACA,WACS;AACT,MAAI,CAAC,WAAW,QAAQ;AACtB,WAAO;AAAA,EACT;AACA,SAAO,uBAAuB,UAAU,aAAa,SAAS;AAChE;AAGO,SAAS,cAAc,QAKlB;AACV,QAAM,EAAE,UAAU,aAAa,iBAAiB,iBAAiB,IAAI;AACrE,MAAI,CAAC,uBAAuB,UAAU,aAAa,eAAe,GAAG;AACnE,WAAO;AAAA,EACT;AACA,MAAI,uBAAuB,UAAU,aAAa,gBAAgB,GAAG;AACnE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGO,SAAS,iBAAiB,WAAoD;AACnF,MAAI,CAAC,WAAW;AACd,WAAO,CAAC;AAAA,EACV;AACA,SAAO,UAAU,OAAO,OAAK,CAAC,UAAU,CAAC,CAAC;AAC5C;AAEO,SAAS,oBAAoB,WAAmD;AACrF,SAAO,CAAC,CAAC,WAAW,SAAS,YAAY;AAC3C;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"AgentThread.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/AgentThread.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AgentThread.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/AgentThread.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,7 @@ var import_toOpenAIChatMessage = require("../llm/toOpenAIChatMessage.js");
33
33
  var import_usage = require("../llm/usage.js");
34
34
  var import_convertMCPServers = require("../mcp/convertMCPServers.js");
35
35
  var import_executeToolCalls = require("../mcp/executeToolCalls.js");
36
+ var import_errorLogFields = require("../util/errorLogFields.js");
36
37
  var import_AgentThread = require("./AgentThread.types.js");
37
38
  var import_contextUsage = require("./contextUsage.js");
38
39
  var import_contextUtils = require("./contextUtils.js");
@@ -56,7 +57,9 @@ function assertValidTransition(from, to) {
56
57
  }
57
58
  function deriveAgentThreadState(context) {
58
59
  const openToolCallIds = getOpenToolCallIds(context);
59
- if (openToolCallIds.size === 0) return "llm-call-required";
60
+ if (openToolCallIds.size === 0) {
61
+ return "llm-call-required";
62
+ }
60
63
  const assistant = lastAssistantInContext(context);
61
64
  const decisions = (0, import_contextUtils.scanApprovalDecisions)(context);
62
65
  const hasPendingApproval = assistant?.tool_calls?.some(
@@ -75,15 +78,23 @@ function getOpenToolCallIds(context) {
75
78
  const openToolCallIds = /* @__PURE__ */ new Set();
76
79
  for (let i = context.length - 1; i >= 0; i--) {
77
80
  const msg = context[i];
78
- if (msg === void 0) continue;
79
- if (!(0, import_contextUtils.isLLMContextMessage)(msg)) continue;
81
+ if (msg === void 0) {
82
+ continue;
83
+ }
84
+ if (!(0, import_contextUtils.isLLMContextMessage)(msg)) {
85
+ continue;
86
+ }
80
87
  if (msg.role === "tool") {
81
88
  resolvedToolCallIds.add(msg.tool_call_id);
82
89
  continue;
83
90
  }
84
91
  if (msg.role === "assistant") {
85
- for (const tc of msg.tool_calls ?? []) openToolCallIds.add(tc.id);
86
- for (const id of resolvedToolCallIds) openToolCallIds.delete(id);
92
+ for (const tc of msg.tool_calls ?? []) {
93
+ openToolCallIds.add(tc.id);
94
+ }
95
+ for (const id of resolvedToolCallIds) {
96
+ openToolCallIds.delete(id);
97
+ }
87
98
  break;
88
99
  }
89
100
  }
@@ -195,7 +206,9 @@ function validateInputMessageTypesGivenContext(context, messages) {
195
206
  const pendingClientSideIds = new Set(getPendingClientSideToolCalls(context).map((tc) => tc.id));
196
207
  for (let i = 0; i < messages.length; i++) {
197
208
  const m = messages[i];
198
- if (m === void 0) continue;
209
+ if (m === void 0) {
210
+ continue;
211
+ }
199
212
  if ((0, import_contextUtils.isApprovalDecisionMessage)(m)) {
200
213
  validateApprovalMessage(m, pendingApprovalIds, i);
201
214
  pendingApprovalIds.delete(m.tool_call_id);
@@ -298,7 +311,9 @@ function isJsonObject(value) {
298
311
  return typeof value === "object" && value !== null && !Array.isArray(value);
299
312
  }
300
313
  function tryParseToolArgs(args) {
301
- if (!args) return {};
314
+ if (!args) {
315
+ return {};
316
+ }
302
317
  try {
303
318
  const parsed = JSON.parse(args);
304
319
  return isJsonObject(parsed) ? parsed : {};
@@ -365,7 +380,9 @@ var AgentThread = class {
365
380
  capabilities.map((c) => c.state?.key).filter((k) => typeof k === "string")
366
381
  );
367
382
  for (const capability of capabilities) {
368
- if (!capability.state) continue;
383
+ if (!capability.state) {
384
+ continue;
385
+ }
369
386
  const value = claimed[capability.state.key];
370
387
  if (value !== void 0) {
371
388
  capability.state.load(value);
@@ -989,14 +1006,18 @@ var AgentThread = class {
989
1006
  for (; ; ) {
990
1007
  for (; ; ) {
991
1008
  const sandboxCreatedEvent = this.pendingSandboxCreatedEvents.shift();
992
- if (sandboxCreatedEvent === void 0) break;
1009
+ if (sandboxCreatedEvent === void 0) {
1010
+ break;
1011
+ }
993
1012
  yield sandboxCreatedEvent;
994
1013
  }
995
1014
  const state = this.deriveState();
996
1015
  let outcome;
997
1016
  switch (state) {
998
1017
  case "llm-call-required": {
999
- if (signal?.aborted) return;
1018
+ if (signal?.aborted) {
1019
+ return;
1020
+ }
1000
1021
  if (this.metrics.iterations >= iterationLimit) {
1001
1022
  yield this.generateErrorEvent(
1002
1023
  `You have reached iteration limit of ${String(iterationLimit)}, please request again`
@@ -1010,7 +1031,9 @@ var AgentThread = class {
1010
1031
  break;
1011
1032
  }
1012
1033
  case "tool-response-required": {
1013
- if (signal?.aborted) return;
1034
+ if (signal?.aborted) {
1035
+ return;
1036
+ }
1014
1037
  outcome = yield* this.stepToolResponse(toolMapping);
1015
1038
  break;
1016
1039
  }
@@ -1022,10 +1045,13 @@ var AgentThread = class {
1022
1045
  throw new Error("unreachable");
1023
1046
  }
1024
1047
  }
1025
- if (outcome === "exit") return;
1048
+ if (outcome === "exit") {
1049
+ return;
1050
+ }
1026
1051
  }
1027
1052
  } catch (error) {
1028
- yield this.generateErrorEvent(error instanceof Error ? error.message : "Unknown error occurred");
1053
+ this.logger.error("Agent thread execution failed", (0, import_errorLogFields.extractErrorLogFields)(error));
1054
+ yield this.generateErrorEvent((0, import_errorLogFields.describeUnknownError)(error));
1029
1055
  } finally {
1030
1056
  this.contextBusy = false;
1031
1057
  }
@@ -1035,7 +1061,9 @@ function assertUniqueStateKeys(capabilities) {
1035
1061
  const seen = /* @__PURE__ */ new Set();
1036
1062
  for (const capability of capabilities) {
1037
1063
  const key = capability.state?.key;
1038
- if (!key) continue;
1064
+ if (!key) {
1065
+ continue;
1066
+ }
1039
1067
  if (seen.has(key)) {
1040
1068
  throw new import_errors.AgentHarnessError(
1041
1069
  "capability_state_error",
@@ -1046,7 +1074,9 @@ function assertUniqueStateKeys(capabilities) {
1046
1074
  }
1047
1075
  }
1048
1076
  function claimCapabilityState(capabilities, input, logger) {
1049
- if (!input) return {};
1077
+ if (!input) {
1078
+ return {};
1079
+ }
1050
1080
  const claimedKeys = new Set(capabilities.map((c) => c.state?.key).filter((k) => typeof k === "string"));
1051
1081
  const claimed = {};
1052
1082
  for (const [key, value] of Object.entries(input)) {