@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
@@ -22,8 +22,12 @@ var MAX_PARALLEL_SUB_AGENTS = 5;
22
22
  function agentThreadEventToTerminalFields(event) {
23
23
  switch (event.type) {
24
24
  case InternalEventType.AGENT_DONE: {
25
- if ("parent" in event && event.parent) return {};
26
- if (event.status === "error") return {};
25
+ if ("parent" in event && event.parent) {
26
+ return {};
27
+ }
28
+ if (event.status === "error") {
29
+ return {};
30
+ }
27
31
  return { output: event.output };
28
32
  }
29
33
  case EventType.TOOL_APPROVAL_REQUIRED:
@@ -39,7 +43,9 @@ function isUserToolApprovalOrResponseBatch(messages) {
39
43
  }
40
44
  function getMainThreadId(agentThreads) {
41
45
  for (const thread of agentThreads.values()) {
42
- if (!thread.parent) return thread.threadId;
46
+ if (!thread.parent) {
47
+ return thread.threadId;
48
+ }
43
49
  }
44
50
  throw new Error("Unreachable: no root thread found");
45
51
  }
@@ -54,7 +60,9 @@ function getActiveAgentThreads(agentThreads) {
54
60
  }
55
61
  return leaves.map((id) => {
56
62
  const agentThread = agentThreads.get(id);
57
- if (!agentThread) throw new Error("unreachable");
63
+ if (!agentThread) {
64
+ throw new Error("unreachable");
65
+ }
58
66
  return agentThread;
59
67
  });
60
68
  }
@@ -269,9 +277,13 @@ var AgentThreadOrchestrator = class {
269
277
  return { shouldStopExecution: true };
270
278
  case InternalEventType.AGENT_DONE: {
271
279
  if (chunk.parent) {
272
- if (!chunk.send_to_parent) throw new Error("unreachable");
280
+ if (!chunk.send_to_parent) {
281
+ throw new Error("unreachable");
282
+ }
273
283
  const parentThread = this.agentThreads.get(chunk.parent.thread_id);
274
- if (!parentThread) throw new Error("unreachable: parent thread missing");
284
+ if (!parentThread) {
285
+ throw new Error("unreachable: parent thread missing");
286
+ }
275
287
  const subAgentToolIsOpen = parentThread.hasOpenToolCallId(chunk.parent.tool_call_id);
276
288
  if (subAgentToolIsOpen) {
277
289
  const parentToolResponse = {
@@ -348,7 +360,9 @@ var AgentThreadOrchestrator = class {
348
360
  });
349
361
  try {
350
362
  while (agentThreads.size > 0) {
351
- if (shouldStopExecution) break;
363
+ if (shouldStopExecution) {
364
+ break;
365
+ }
352
366
  const activeThreads = getActiveAgentThreads(agentThreads);
353
367
  for (let i = 0; i < activeThreads.length && !shouldStopExecution; i += MAX_PARALLEL_SUB_AGENTS) {
354
368
  const batch = activeThreads.slice(i, i + MAX_PARALLEL_SUB_AGENTS);
@@ -375,8 +389,12 @@ var AgentThreadOrchestrator = class {
375
389
  }
376
390
  if (chunk.type !== InternalEventType.PASSTHROUGH) {
377
391
  const { output: outputContribution, requiredAction } = agentThreadEventToTerminalFields(chunk);
378
- if (outputContribution) output = outputContribution;
379
- if (requiredAction) requiredActions.push(requiredAction);
392
+ if (outputContribution) {
393
+ output = outputContribution;
394
+ }
395
+ if (requiredAction) {
396
+ requiredActions.push(requiredAction);
397
+ }
380
398
  }
381
399
  }
382
400
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/runtime/AgentThreadOrchestrator.ts"],"sourcesContent":["import type { Logger } from 'winston';\nimport { AgentHarnessError, InvalidAgentSendInputError } from '../errors';\nimport {\n EventType,\n newEventId,\n type ActionRequiredEvent,\n type ModelMessageEvent,\n type ToolResponseEvent,\n type UserToolApprovalMessage,\n type UserToolResponseMessage,\n} from '../events/schema';\nimport type { AgentExecutionTrace, AgentTracing } from '../tracing/AgentTracing';\nimport { onSignalAbort } from '../util/abort';\nimport { mergeAsyncGenerators } from '../util/promiseUtils';\nimport { AgentThread } from './AgentThread';\nimport type { AgentThreadRuntimeSendBatch } from './AgentThread.types';\nimport {\n InternalEventType,\n type AgentThreadAppendContext,\n type AgentThreadEvent,\n type AgentThreadExecutionEvent,\n type AgentThreadExecutionResult,\n type AgentThreadSendBatch,\n type InternalMCPAuthRequiredEvent,\n type InternalMCPServerAuthInfo,\n} from './AgentThread.types';\nimport {\n assistantMessageContentToStringForSubAgent,\n getThreadId,\n isApprovalDecisionMessage,\n isClientSideToolResponseMessage,\n isInternalThreadDoneError,\n} from './contextUtils';\nimport type { CreateDynamicSubAgentThread } from './CreateDynamicSubAgentThread';\nimport { addAgentThreadMetrics, createEmptyAgentThreadMetrics, type AgentThreadMetrics } from './metrics';\n\nconst MAX_PARALLEL_SUB_AGENTS = 5;\n\nfunction agentThreadEventToTerminalFields(event: AgentThreadExecutionEvent): {\n output?: ModelMessageEvent | undefined;\n requiredAction?: ActionRequiredEvent | undefined;\n} {\n switch (event.type) {\n case InternalEventType.AGENT_DONE: {\n if ('parent' in event && event.parent) return {};\n if (event.status === 'error') return {};\n return { output: event.output };\n }\n case EventType.TOOL_APPROVAL_REQUIRED:\n case EventType.TOOL_RESPONSE_REQUIRED:\n return { requiredAction: event };\n default:\n return {};\n }\n}\n\ntype UserToolApprovalOrResponseBatch = (UserToolApprovalMessage | UserToolResponseMessage)[];\n\nfunction isUserToolApprovalOrResponseBatch(\n messages: AgentThreadSendBatch,\n): messages is UserToolApprovalOrResponseBatch {\n const first = messages[0];\n return first !== undefined && (isApprovalDecisionMessage(first) || isClientSideToolResponseMessage(first));\n}\n\nfunction getMainThreadId(agentThreads: Map<string, AgentThread>): string {\n for (const thread of agentThreads.values()) {\n if (!thread.parent) return thread.threadId;\n }\n throw new Error('Unreachable: no root thread found');\n}\n\nfunction getActiveAgentThreads(agentThreads: Map<string, AgentThread>): AgentThread[] {\n const nodes = new Set(agentThreads.keys());\n const parentNodes = new Set(\n [...agentThreads.values()].map(a => a.parent?.thread_id).filter((a): a is string => Boolean(a)),\n );\n const leaves = [...nodes].filter(id => !parentNodes.has(id));\n if (leaves.length === 0) {\n throw new Error('We cannot have zero leave agents');\n }\n return leaves.map(id => {\n const agentThread = agentThreads.get(id);\n if (!agentThread) throw new Error('unreachable');\n return agentThread;\n });\n}\n\nfunction mergeAuthEvents(events: InternalMCPAuthRequiredEvent[]): InternalMCPAuthRequiredEvent {\n const serverMap = new Map<string, InternalMCPServerAuthInfo>();\n for (const event of events) {\n for (const entry of event.mcp_servers) {\n const existing = serverMap.get(entry.id);\n if (existing) {\n existing.thread_ids.push(...entry.thread_ids);\n } else {\n serverMap.set(entry.id, { ...entry, thread_ids: [...entry.thread_ids] });\n }\n }\n }\n return {\n type: InternalEventType.MCP_AUTH_REQUIRED,\n id: newEventId(),\n created_at: new Date().toISOString(),\n thread_id: null,\n mcp_servers: [...serverMap.values()],\n };\n}\n\nfunction wrapGeneratorWithTrace<T, TReturn = void, TNext = unknown>(\n trace: AgentExecutionTrace,\n generator: AsyncGenerator<T, TReturn, TNext>,\n): AsyncGenerator<T, TReturn, TNext> {\n const wrapped: AsyncGenerator<T, TReturn, TNext> = {\n [Symbol.asyncIterator]() {\n return this;\n },\n next(...[value]: [] | [TNext]) {\n return trace.runInContext(() => (value === undefined ? generator.next() : generator.next(value)));\n },\n return(value: TReturn | PromiseLike<TReturn>) {\n return trace.runInContext(() => generator.return(value));\n },\n throw(e: unknown) {\n return trace.runInContext(() => generator.throw(e));\n },\n [Symbol.asyncDispose]() {\n return generator[Symbol.asyncDispose]();\n },\n };\n return wrapped;\n}\n\ninterface RootAgentSpanHandle {\n trace: AgentExecutionTrace;\n wrapThreadWithContext(thread: AgentThread, signal?: AbortSignal): AsyncGenerator<AgentThreadEvent>;\n setOutputFromEvent(chunk: AgentThreadEvent): void;\n finalize(thread: AgentThread, error?: unknown): void;\n end(): void;\n}\n\nfunction createRootAgentSpan(mainThread: AgentThread, tracing: AgentTracing): RootAgentSpanHandle {\n const trace = tracing.startRootSpan(\n JSON.stringify({ instructions: mainThread.definition.instruction, messages: mainThread.definition.messages }),\n );\n let rootAgentErrorMessage: string | undefined;\n let rootAgentCompleted = false;\n\n return {\n trace,\n wrapThreadWithContext(thread: AgentThread, signal?: AbortSignal) {\n return wrapGeneratorWithTrace(trace, thread.execute({ signal }));\n },\n setOutputFromEvent(chunk: AgentThreadEvent) {\n rootAgentCompleted = true;\n if (chunk.type === InternalEventType.AGENT_DONE) {\n if (isInternalThreadDoneError(chunk)) {\n rootAgentErrorMessage = chunk.error;\n trace.setOutput(JSON.stringify({ error: chunk.error }));\n } else {\n const content = assistantMessageContentToStringForSubAgent(chunk.output.content);\n trace.setOutput(JSON.stringify({ result: content }));\n }\n }\n },\n finalize(thread: AgentThread, error?: unknown) {\n trace.setMetrics(thread.getAgentThreadMetrics());\n if (error) {\n trace.setError(error);\n } else if (rootAgentErrorMessage || !rootAgentCompleted) {\n trace.setError(rootAgentErrorMessage ?? 'Agent execution interrupted');\n } else {\n trace.setSuccess();\n }\n },\n end() {\n trace.end();\n },\n };\n}\n\n/** @internal Exported for sub-agent span finalization tests. */\nexport async function* wrapWithSubAgentSpan(\n parentTrace: AgentExecutionTrace,\n currentThread: AgentThread,\n signal?: AbortSignal,\n): AsyncGenerator<AgentThreadEvent> {\n const agentInfo = currentThread.agentInfo;\n if (!agentInfo) {\n throw new Error('Sub-agent thread is missing agentInfo');\n }\n const subTrace = parentTrace.startSubAgent(agentInfo.name, JSON.stringify({ instructions: agentInfo.input }));\n const generator = wrapGeneratorWithTrace(subTrace, currentThread.execute({ signal }));\n\n try {\n for await (const event of generator) {\n if (event.type === InternalEventType.AGENT_DONE) {\n if (isInternalThreadDoneError(event)) {\n subTrace.setOutput(JSON.stringify({ error: event.error }));\n subTrace.setMetrics(currentThread.getAgentThreadMetrics());\n subTrace.setError(event.error);\n } else {\n const content = assistantMessageContentToStringForSubAgent(event.output.content);\n subTrace.setOutput(JSON.stringify({ result: content }));\n subTrace.setMetrics(currentThread.getAgentThreadMetrics());\n subTrace.setSuccess();\n }\n // end() only in finally so every path finalizes exactly once\n }\n yield event;\n }\n } catch (error) {\n subTrace.setError(error);\n throw error;\n } finally {\n subTrace.end();\n }\n}\n\nexport interface AgentThreadOrchestratorInput {\n agentThreads: Map<string, AgentThread>;\n createDynamicSubAgentThread: CreateDynamicSubAgentThread;\n tracing: AgentTracing;\n logger: Logger;\n}\n\nexport class AgentThreadOrchestrator {\n private readonly agentThreads: Map<string, AgentThread>;\n private readonly createDynamicSubAgentThread: CreateDynamicSubAgentThread;\n private readonly tracing: AgentTracing;\n private readonly logger: Logger;\n // Finished sub-agents removed from `agentThreads`; kept so totals still include them.\n private finishedSubAgentMetrics: AgentThreadMetrics = createEmptyAgentThreadMetrics();\n\n constructor(params: AgentThreadOrchestratorInput) {\n this.agentThreads = params.agentThreads;\n this.createDynamicSubAgentThread = params.createDynamicSubAgentThread;\n this.tracing = params.tracing;\n this.logger = params.logger.child({ module: 'AgentThreadOrchestrator' });\n }\n\n /**\n * Turn-wide metrics so far: live threads plus finished sub-agents.\n * Safe mid-flight and after cancel/error (`execute()` may not return).\n * Each thread is counted once — a sub-agent moves from live → finished atomically.\n */\n public getMetrics(): AgentThreadMetrics {\n const total = createEmptyAgentThreadMetrics();\n addAgentThreadMetrics(total, this.finishedSubAgentMetrics);\n for (const thread of this.agentThreads.values()) {\n addAgentThreadMetrics(total, thread.getAgentThreadMetrics());\n }\n return total;\n }\n\n public async *send(messages: AgentThreadSendBatch): AsyncGenerator<AgentThreadAppendContext, void, unknown> {\n const byThread = new Map<string, AgentThreadRuntimeSendBatch>();\n for (const thread of this.agentThreads.values()) {\n byThread.set(thread.threadId, []);\n }\n\n if (isUserToolApprovalOrResponseBatch(messages)) {\n const grouped = new Map<string, UserToolApprovalOrResponseBatch[number][]>();\n for (const msg of messages) {\n const threadId = msg.thread_id;\n if (!byThread.has(threadId)) {\n throw new InvalidAgentSendInputError(`unknown thread_id: ${threadId}`);\n }\n const batch = grouped.get(threadId) ?? [];\n batch.push(msg);\n grouped.set(threadId, batch);\n }\n for (const [threadId, batch] of grouped) {\n byThread.set(threadId, batch);\n }\n } else if (messages.length > 0) {\n if (this.agentThreads.size > 1) {\n throw new InvalidAgentSendInputError(\n 'Cannot process user messages while sub agents are running, please send empty input for previous conversation to complete',\n );\n }\n byThread.set(getMainThreadId(this.agentThreads), messages);\n }\n\n const validationErrors: string[] = [];\n for (const [threadId, batch] of byThread) {\n const thread = this.agentThreads.get(threadId);\n if (!thread) {\n throw new Error(`AgentThreadOrchestrator.send: unknown threadId ${threadId}`);\n }\n try {\n thread.validateSendInput(batch);\n } catch (e) {\n if (e instanceof AgentHarnessError && e.code === 'invalid_send_input') {\n validationErrors.push(`thread ${threadId}: ${e.message}`);\n } else {\n throw e;\n }\n }\n }\n if (validationErrors.length > 0) {\n throw new InvalidAgentSendInputError(validationErrors.join('; '));\n }\n\n for (const [threadId, batch] of byThread) {\n yield* this.sendToThread(threadId, batch);\n }\n }\n\n private async *sendToThread(\n threadId: string,\n messages: AgentThreadRuntimeSendBatch,\n ): AsyncGenerator<AgentThreadAppendContext, void, unknown> {\n const thread = this.agentThreads.get(threadId);\n if (!thread) {\n throw new Error(`AgentThreadOrchestrator.sendToThread: unknown threadId ${threadId}`);\n }\n yield* thread.send(messages);\n }\n\n private async *processAgentStreamChunk(\n chunk: Exclude<AgentThreadEvent, InternalMCPAuthRequiredEvent>,\n signal: AbortSignal,\n ): AsyncGenerator<AgentThreadExecutionEvent, { shouldStopExecution: boolean }, unknown> {\n if (chunk.type === InternalEventType.PASSTHROUGH) {\n yield chunk.event;\n return { shouldStopExecution: false };\n }\n\n if (!('thread_id' in chunk) || chunk.thread_id == null) {\n yield chunk;\n return { shouldStopExecution: false };\n }\n\n const currentThread = this.agentThreads.get(chunk.thread_id);\n if (!currentThread) {\n throw new Error('unreachable');\n }\n\n switch (chunk.type) {\n case EventType.TOOL_APPROVAL_REQUIRED:\n case EventType.TOOL_RESPONSE_REQUIRED:\n yield chunk;\n return { shouldStopExecution: true };\n case InternalEventType.AGENT_DONE: {\n if (chunk.parent) {\n if (!chunk.send_to_parent) throw new Error('unreachable');\n const parentThread = this.agentThreads.get(chunk.parent.thread_id);\n if (!parentThread) throw new Error('unreachable: parent thread missing');\n const subAgentToolIsOpen = parentThread.hasOpenToolCallId(chunk.parent.tool_call_id);\n if (subAgentToolIsOpen) {\n const parentToolResponse: ToolResponseEvent = {\n type: EventType.TOOL_RESPONSE,\n id: newEventId(),\n created_at: new Date().toISOString(),\n thread_id: chunk.parent.thread_id,\n tool_call_id: chunk.send_to_parent.tool_call_id,\n content: '',\n };\n yield parentToolResponse;\n yield* this.sendToThread(chunk.parent.thread_id, [chunk.send_to_parent]);\n }\n yield chunk;\n // Move metrics to the finished bucket and drop the live entry with no `yield` between,\n // so getMetrics() counts this sub-agent once. After `yield chunk` per durable-state.\n addAgentThreadMetrics(this.finishedSubAgentMetrics, currentThread.getAgentThreadMetrics());\n this.agentThreads.delete(chunk.thread_id);\n return { shouldStopExecution: false };\n }\n yield chunk;\n return { shouldStopExecution: true };\n }\n case InternalEventType.AGENT_CREATE_SUBAGENT: {\n const parent = {\n tool_call_id: chunk.tool_call_id,\n thread_id: chunk.thread_id,\n };\n const subAgentThreadId = getThreadId();\n const subAgentThread = await this.createDynamicSubAgentThread({\n parentDefinition: currentThread.definition,\n request: chunk.agent_info,\n threadId: subAgentThreadId,\n parent,\n signal,\n });\n\n yield {\n type: EventType.THREAD_CREATED,\n id: newEventId(),\n agent_info: {\n type: 'dynamic',\n name: chunk.agent_info.name,\n input: chunk.agent_info.input,\n model: chunk.agent_info.model,\n },\n created_at: new Date().toISOString(),\n parent,\n title: chunk.agent_info.name,\n thread_id: subAgentThreadId,\n };\n this.agentThreads.set(subAgentThreadId, subAgentThread);\n return { shouldStopExecution: false };\n }\n default:\n yield chunk;\n return { shouldStopExecution: false };\n }\n }\n\n public async *execute({\n signal,\n }: {\n signal: AbortSignal;\n }): AsyncGenerator<AgentThreadExecutionEvent, AgentThreadExecutionResult, unknown> {\n const { agentThreads } = this;\n\n let shouldStopExecution = false;\n let caughtError: unknown;\n let output: ModelMessageEvent | null = null;\n const requiredActions: ActionRequiredEvent[] = [];\n let rootAgentError: AgentThreadExecutionResult['root_agent_error'];\n const pendingAuthEvents: InternalMCPAuthRequiredEvent[] = [];\n const mainThread = [...agentThreads.values()].find(e => !e.parent);\n if (!mainThread) {\n throw new Error('Unreachable: no root thread found');\n }\n const rootSpan = createRootAgentSpan(mainThread, this.tracing);\n\n onSignalAbort(signal, () => {\n shouldStopExecution = true;\n });\n\n try {\n while (agentThreads.size > 0) {\n if (shouldStopExecution) break;\n\n const activeThreads = getActiveAgentThreads(agentThreads);\n\n for (let i = 0; i < activeThreads.length && !shouldStopExecution; i += MAX_PARALLEL_SUB_AGENTS) {\n const batch = activeThreads.slice(i, i + MAX_PARALLEL_SUB_AGENTS);\n const generators = batch.map(thread => {\n if (!thread.parent) {\n return rootSpan.wrapThreadWithContext(thread, signal);\n }\n return wrapWithSubAgentSpan(rootSpan.trace, thread, signal);\n });\n\n for await (const chunk of mergeAsyncGenerators(generators, this.logger)) {\n if (chunk.type === InternalEventType.MCP_AUTH_REQUIRED) {\n pendingAuthEvents.push(chunk);\n shouldStopExecution = true;\n continue;\n }\n if (chunk.type === InternalEventType.AGENT_DONE && !chunk.parent) {\n // Root-thread only — sub-agent AGENT_DONE would overwrite root trace output /\n // leave a stale error; sub-agent spans finalize in wrapWithSubAgentSpan.\n rootSpan.setOutputFromEvent(chunk);\n }\n\n const result = yield* this.processAgentStreamChunk(chunk, signal);\n if (result.shouldStopExecution) {\n shouldStopExecution = true;\n if (\n !rootAgentError &&\n chunk.type === InternalEventType.AGENT_DONE &&\n isInternalThreadDoneError(chunk) &&\n !chunk.parent\n ) {\n rootAgentError = { error: chunk.error, output: chunk.output };\n }\n if (chunk.type !== InternalEventType.PASSTHROUGH) {\n const { output: outputContribution, requiredAction } = agentThreadEventToTerminalFields(chunk);\n if (outputContribution) output = outputContribution;\n if (requiredAction) requiredActions.push(requiredAction);\n }\n }\n }\n }\n }\n } catch (error) {\n caughtError = error;\n throw error;\n } finally {\n rootSpan.finalize(mainThread, caughtError);\n rootSpan.end();\n }\n\n if (pendingAuthEvents.length > 0) {\n const authEvent = mergeAuthEvents(pendingAuthEvents);\n yield authEvent;\n const authRequiredAction: ActionRequiredEvent = {\n type: EventType.MCP_AUTH_REQUIRED,\n id: authEvent.id,\n created_at: authEvent.created_at,\n thread_id: authEvent.thread_id,\n mcp_servers: authEvent.mcp_servers.map(({ thread_ids, ...s }) => {\n void thread_ids;\n return s;\n }),\n };\n requiredActions.push(authRequiredAction);\n }\n\n return {\n output,\n required_actions: requiredActions,\n root_agent_error: rootAgentError,\n };\n }\n}\n"],"mappings":";AACA,SAAS,mBAAmB,kCAAkC;AAC9D;AAAA,EACE;AAAA,EACA;AAAA,OAMK;AAEP,SAAS,qBAAqB;AAC9B,SAAS,4BAA4B;AACrC,OAA4B;AAE5B;AAAA,EACE;AAAA,OAQK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,uBAAuB,qCAA8D;AAE9F,IAAM,0BAA0B;AAEhC,SAAS,iCAAiC,OAGxC;AACA,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK,kBAAkB,YAAY;AACjC,UAAI,YAAY,SAAS,MAAM,OAAQ,QAAO,CAAC;AAC/C,UAAI,MAAM,WAAW,QAAS,QAAO,CAAC;AACtC,aAAO,EAAE,QAAQ,MAAM,OAAO;AAAA,IAChC;AAAA,IACA,KAAK,UAAU;AAAA,IACf,KAAK,UAAU;AACb,aAAO,EAAE,gBAAgB,MAAM;AAAA,IACjC;AACE,aAAO,CAAC;AAAA,EACZ;AACF;AAIA,SAAS,kCACP,UAC6C;AAC7C,QAAM,QAAQ,SAAS,CAAC;AACxB,SAAO,UAAU,WAAc,0BAA0B,KAAK,KAAK,gCAAgC,KAAK;AAC1G;AAEA,SAAS,gBAAgB,cAAgD;AACvE,aAAW,UAAU,aAAa,OAAO,GAAG;AAC1C,QAAI,CAAC,OAAO,OAAQ,QAAO,OAAO;AAAA,EACpC;AACA,QAAM,IAAI,MAAM,mCAAmC;AACrD;AAEA,SAAS,sBAAsB,cAAuD;AACpF,QAAM,QAAQ,IAAI,IAAI,aAAa,KAAK,CAAC;AACzC,QAAM,cAAc,IAAI;AAAA,IACtB,CAAC,GAAG,aAAa,OAAO,CAAC,EAAE,IAAI,OAAK,EAAE,QAAQ,SAAS,EAAE,OAAO,CAAC,MAAmB,QAAQ,CAAC,CAAC;AAAA,EAChG;AACA,QAAM,SAAS,CAAC,GAAG,KAAK,EAAE,OAAO,QAAM,CAAC,YAAY,IAAI,EAAE,CAAC;AAC3D,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AACA,SAAO,OAAO,IAAI,QAAM;AACtB,UAAM,cAAc,aAAa,IAAI,EAAE;AACvC,QAAI,CAAC,YAAa,OAAM,IAAI,MAAM,aAAa;AAC/C,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,gBAAgB,QAAsE;AAC7F,QAAM,YAAY,oBAAI,IAAuC;AAC7D,aAAW,SAAS,QAAQ;AAC1B,eAAW,SAAS,MAAM,aAAa;AACrC,YAAM,WAAW,UAAU,IAAI,MAAM,EAAE;AACvC,UAAI,UAAU;AACZ,iBAAS,WAAW,KAAK,GAAG,MAAM,UAAU;AAAA,MAC9C,OAAO;AACL,kBAAU,IAAI,MAAM,IAAI,EAAE,GAAG,OAAO,YAAY,CAAC,GAAG,MAAM,UAAU,EAAE,CAAC;AAAA,MACzE;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM,kBAAkB;AAAA,IACxB,IAAI,WAAW;AAAA,IACf,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,IACnC,WAAW;AAAA,IACX,aAAa,CAAC,GAAG,UAAU,OAAO,CAAC;AAAA,EACrC;AACF;AAEA,SAAS,uBACP,OACA,WACmC;AACnC,QAAM,UAA6C;AAAA,IACjD,CAAC,OAAO,aAAa,IAAI;AACvB,aAAO;AAAA,IACT;AAAA,IACA,QAAQ,CAAC,KAAK,GAAiB;AAC7B,aAAO,MAAM,aAAa,MAAO,UAAU,SAAY,UAAU,KAAK,IAAI,UAAU,KAAK,KAAK,CAAE;AAAA,IAClG;AAAA,IACA,OAAO,OAAuC;AAC5C,aAAO,MAAM,aAAa,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IACzD;AAAA,IACA,MAAM,GAAY;AAChB,aAAO,MAAM,aAAa,MAAM,UAAU,MAAM,CAAC,CAAC;AAAA,IACpD;AAAA,IACA,CAAC,OAAO,YAAY,IAAI;AACtB,aAAO,UAAU,OAAO,YAAY,EAAE;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AACT;AAUA,SAAS,oBAAoB,YAAyB,SAA4C;AAChG,QAAM,QAAQ,QAAQ;AAAA,IACpB,KAAK,UAAU,EAAE,cAAc,WAAW,WAAW,aAAa,UAAU,WAAW,WAAW,SAAS,CAAC;AAAA,EAC9G;AACA,MAAI;AACJ,MAAI,qBAAqB;AAEzB,SAAO;AAAA,IACL;AAAA,IACA,sBAAsB,QAAqB,QAAsB;AAC/D,aAAO,uBAAuB,OAAO,OAAO,QAAQ,EAAE,OAAO,CAAC,CAAC;AAAA,IACjE;AAAA,IACA,mBAAmB,OAAyB;AAC1C,2BAAqB;AACrB,UAAI,MAAM,SAAS,kBAAkB,YAAY;AAC/C,YAAI,0BAA0B,KAAK,GAAG;AACpC,kCAAwB,MAAM;AAC9B,gBAAM,UAAU,KAAK,UAAU,EAAE,OAAO,MAAM,MAAM,CAAC,CAAC;AAAA,QACxD,OAAO;AACL,gBAAM,UAAU,2CAA2C,MAAM,OAAO,OAAO;AAC/E,gBAAM,UAAU,KAAK,UAAU,EAAE,QAAQ,QAAQ,CAAC,CAAC;AAAA,QACrD;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS,QAAqB,OAAiB;AAC7C,YAAM,WAAW,OAAO,sBAAsB,CAAC;AAC/C,UAAI,OAAO;AACT,cAAM,SAAS,KAAK;AAAA,MACtB,WAAW,yBAAyB,CAAC,oBAAoB;AACvD,cAAM,SAAS,yBAAyB,6BAA6B;AAAA,MACvE,OAAO;AACL,cAAM,WAAW;AAAA,MACnB;AAAA,IACF;AAAA,IACA,MAAM;AACJ,YAAM,IAAI;AAAA,IACZ;AAAA,EACF;AACF;AAGA,gBAAuB,qBACrB,aACA,eACA,QACkC;AAClC,QAAM,YAAY,cAAc;AAChC,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AACA,QAAM,WAAW,YAAY,cAAc,UAAU,MAAM,KAAK,UAAU,EAAE,cAAc,UAAU,MAAM,CAAC,CAAC;AAC5G,QAAM,YAAY,uBAAuB,UAAU,cAAc,QAAQ,EAAE,OAAO,CAAC,CAAC;AAEpF,MAAI;AACF,qBAAiB,SAAS,WAAW;AACnC,UAAI,MAAM,SAAS,kBAAkB,YAAY;AAC/C,YAAI,0BAA0B,KAAK,GAAG;AACpC,mBAAS,UAAU,KAAK,UAAU,EAAE,OAAO,MAAM,MAAM,CAAC,CAAC;AACzD,mBAAS,WAAW,cAAc,sBAAsB,CAAC;AACzD,mBAAS,SAAS,MAAM,KAAK;AAAA,QAC/B,OAAO;AACL,gBAAM,UAAU,2CAA2C,MAAM,OAAO,OAAO;AAC/E,mBAAS,UAAU,KAAK,UAAU,EAAE,QAAQ,QAAQ,CAAC,CAAC;AACtD,mBAAS,WAAW,cAAc,sBAAsB,CAAC;AACzD,mBAAS,WAAW;AAAA,QACtB;AAAA,MAEF;AACA,YAAM;AAAA,IACR;AAAA,EACF,SAAS,OAAO;AACd,aAAS,SAAS,KAAK;AACvB,UAAM;AAAA,EACR,UAAE;AACA,aAAS,IAAI;AAAA,EACf;AACF;AASO,IAAM,0BAAN,MAA8B;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAET,0BAA8C,8BAA8B;AAAA,EAEpF,YAAY,QAAsC;AAChD,SAAK,eAAe,OAAO;AAC3B,SAAK,8BAA8B,OAAO;AAC1C,SAAK,UAAU,OAAO;AACtB,SAAK,SAAS,OAAO,OAAO,MAAM,EAAE,QAAQ,0BAA0B,CAAC;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,aAAiC;AACtC,UAAM,QAAQ,8BAA8B;AAC5C,0BAAsB,OAAO,KAAK,uBAAuB;AACzD,eAAW,UAAU,KAAK,aAAa,OAAO,GAAG;AAC/C,4BAAsB,OAAO,OAAO,sBAAsB,CAAC;AAAA,IAC7D;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAc,KAAK,UAAyF;AAC1G,UAAM,WAAW,oBAAI,IAAyC;AAC9D,eAAW,UAAU,KAAK,aAAa,OAAO,GAAG;AAC/C,eAAS,IAAI,OAAO,UAAU,CAAC,CAAC;AAAA,IAClC;AAEA,QAAI,kCAAkC,QAAQ,GAAG;AAC/C,YAAM,UAAU,oBAAI,IAAuD;AAC3E,iBAAW,OAAO,UAAU;AAC1B,cAAM,WAAW,IAAI;AACrB,YAAI,CAAC,SAAS,IAAI,QAAQ,GAAG;AAC3B,gBAAM,IAAI,2BAA2B,sBAAsB,QAAQ,EAAE;AAAA,QACvE;AACA,cAAM,QAAQ,QAAQ,IAAI,QAAQ,KAAK,CAAC;AACxC,cAAM,KAAK,GAAG;AACd,gBAAQ,IAAI,UAAU,KAAK;AAAA,MAC7B;AACA,iBAAW,CAAC,UAAU,KAAK,KAAK,SAAS;AACvC,iBAAS,IAAI,UAAU,KAAK;AAAA,MAC9B;AAAA,IACF,WAAW,SAAS,SAAS,GAAG;AAC9B,UAAI,KAAK,aAAa,OAAO,GAAG;AAC9B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,eAAS,IAAI,gBAAgB,KAAK,YAAY,GAAG,QAAQ;AAAA,IAC3D;AAEA,UAAM,mBAA6B,CAAC;AACpC,eAAW,CAAC,UAAU,KAAK,KAAK,UAAU;AACxC,YAAM,SAAS,KAAK,aAAa,IAAI,QAAQ;AAC7C,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,kDAAkD,QAAQ,EAAE;AAAA,MAC9E;AACA,UAAI;AACF,eAAO,kBAAkB,KAAK;AAAA,MAChC,SAAS,GAAG;AACV,YAAI,aAAa,qBAAqB,EAAE,SAAS,sBAAsB;AACrE,2BAAiB,KAAK,UAAU,QAAQ,KAAK,EAAE,OAAO,EAAE;AAAA,QAC1D,OAAO;AACL,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,QAAI,iBAAiB,SAAS,GAAG;AAC/B,YAAM,IAAI,2BAA2B,iBAAiB,KAAK,IAAI,CAAC;AAAA,IAClE;AAEA,eAAW,CAAC,UAAU,KAAK,KAAK,UAAU;AACxC,aAAO,KAAK,aAAa,UAAU,KAAK;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,OAAe,aACb,UACA,UACyD;AACzD,UAAM,SAAS,KAAK,aAAa,IAAI,QAAQ;AAC7C,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,0DAA0D,QAAQ,EAAE;AAAA,IACtF;AACA,WAAO,OAAO,KAAK,QAAQ;AAAA,EAC7B;AAAA,EAEA,OAAe,wBACb,OACA,QACsF;AACtF,QAAI,MAAM,SAAS,kBAAkB,aAAa;AAChD,YAAM,MAAM;AACZ,aAAO,EAAE,qBAAqB,MAAM;AAAA,IACtC;AAEA,QAAI,EAAE,eAAe,UAAU,MAAM,aAAa,MAAM;AACtD,YAAM;AACN,aAAO,EAAE,qBAAqB,MAAM;AAAA,IACtC;AAEA,UAAM,gBAAgB,KAAK,aAAa,IAAI,MAAM,SAAS;AAC3D,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI,MAAM,aAAa;AAAA,IAC/B;AAEA,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK,UAAU;AAAA,MACf,KAAK,UAAU;AACb,cAAM;AACN,eAAO,EAAE,qBAAqB,KAAK;AAAA,MACrC,KAAK,kBAAkB,YAAY;AACjC,YAAI,MAAM,QAAQ;AAChB,cAAI,CAAC,MAAM,eAAgB,OAAM,IAAI,MAAM,aAAa;AACxD,gBAAM,eAAe,KAAK,aAAa,IAAI,MAAM,OAAO,SAAS;AACjE,cAAI,CAAC,aAAc,OAAM,IAAI,MAAM,oCAAoC;AACvE,gBAAM,qBAAqB,aAAa,kBAAkB,MAAM,OAAO,YAAY;AACnF,cAAI,oBAAoB;AACtB,kBAAM,qBAAwC;AAAA,cAC5C,MAAM,UAAU;AAAA,cAChB,IAAI,WAAW;AAAA,cACf,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,cACnC,WAAW,MAAM,OAAO;AAAA,cACxB,cAAc,MAAM,eAAe;AAAA,cACnC,SAAS;AAAA,YACX;AACA,kBAAM;AACN,mBAAO,KAAK,aAAa,MAAM,OAAO,WAAW,CAAC,MAAM,cAAc,CAAC;AAAA,UACzE;AACA,gBAAM;AAGN,gCAAsB,KAAK,yBAAyB,cAAc,sBAAsB,CAAC;AACzF,eAAK,aAAa,OAAO,MAAM,SAAS;AACxC,iBAAO,EAAE,qBAAqB,MAAM;AAAA,QACtC;AACA,cAAM;AACN,eAAO,EAAE,qBAAqB,KAAK;AAAA,MACrC;AAAA,MACA,KAAK,kBAAkB,uBAAuB;AAC5C,cAAM,SAAS;AAAA,UACb,cAAc,MAAM;AAAA,UACpB,WAAW,MAAM;AAAA,QACnB;AACA,cAAM,mBAAmB,YAAY;AACrC,cAAM,iBAAiB,MAAM,KAAK,4BAA4B;AAAA,UAC5D,kBAAkB,cAAc;AAAA,UAChC,SAAS,MAAM;AAAA,UACf,UAAU;AAAA,UACV;AAAA,UACA;AAAA,QACF,CAAC;AAED,cAAM;AAAA,UACJ,MAAM,UAAU;AAAA,UAChB,IAAI,WAAW;AAAA,UACf,YAAY;AAAA,YACV,MAAM;AAAA,YACN,MAAM,MAAM,WAAW;AAAA,YACvB,OAAO,MAAM,WAAW;AAAA,YACxB,OAAO,MAAM,WAAW;AAAA,UAC1B;AAAA,UACA,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,UACnC;AAAA,UACA,OAAO,MAAM,WAAW;AAAA,UACxB,WAAW;AAAA,QACb;AACA,aAAK,aAAa,IAAI,kBAAkB,cAAc;AACtD,eAAO,EAAE,qBAAqB,MAAM;AAAA,MACtC;AAAA,MACA;AACE,cAAM;AACN,eAAO,EAAE,qBAAqB,MAAM;AAAA,IACxC;AAAA,EACF;AAAA,EAEA,OAAc,QAAQ;AAAA,IACpB;AAAA,EACF,GAEmF;AACjF,UAAM,EAAE,aAAa,IAAI;AAEzB,QAAI,sBAAsB;AAC1B,QAAI;AACJ,QAAI,SAAmC;AACvC,UAAM,kBAAyC,CAAC;AAChD,QAAI;AACJ,UAAM,oBAAoD,CAAC;AAC3D,UAAM,aAAa,CAAC,GAAG,aAAa,OAAO,CAAC,EAAE,KAAK,OAAK,CAAC,EAAE,MAAM;AACjE,QAAI,CAAC,YAAY;AACf,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AACA,UAAM,WAAW,oBAAoB,YAAY,KAAK,OAAO;AAE7D,kBAAc,QAAQ,MAAM;AAC1B,4BAAsB;AAAA,IACxB,CAAC;AAED,QAAI;AACF,aAAO,aAAa,OAAO,GAAG;AAC5B,YAAI,oBAAqB;AAEzB,cAAM,gBAAgB,sBAAsB,YAAY;AAExD,iBAAS,IAAI,GAAG,IAAI,cAAc,UAAU,CAAC,qBAAqB,KAAK,yBAAyB;AAC9F,gBAAM,QAAQ,cAAc,MAAM,GAAG,IAAI,uBAAuB;AAChE,gBAAM,aAAa,MAAM,IAAI,YAAU;AACrC,gBAAI,CAAC,OAAO,QAAQ;AAClB,qBAAO,SAAS,sBAAsB,QAAQ,MAAM;AAAA,YACtD;AACA,mBAAO,qBAAqB,SAAS,OAAO,QAAQ,MAAM;AAAA,UAC5D,CAAC;AAED,2BAAiB,SAAS,qBAAqB,YAAY,KAAK,MAAM,GAAG;AACvE,gBAAI,MAAM,SAAS,kBAAkB,mBAAmB;AACtD,gCAAkB,KAAK,KAAK;AAC5B,oCAAsB;AACtB;AAAA,YACF;AACA,gBAAI,MAAM,SAAS,kBAAkB,cAAc,CAAC,MAAM,QAAQ;AAGhE,uBAAS,mBAAmB,KAAK;AAAA,YACnC;AAEA,kBAAM,SAAS,OAAO,KAAK,wBAAwB,OAAO,MAAM;AAChE,gBAAI,OAAO,qBAAqB;AAC9B,oCAAsB;AACtB,kBACE,CAAC,kBACD,MAAM,SAAS,kBAAkB,cACjC,0BAA0B,KAAK,KAC/B,CAAC,MAAM,QACP;AACA,iCAAiB,EAAE,OAAO,MAAM,OAAO,QAAQ,MAAM,OAAO;AAAA,cAC9D;AACA,kBAAI,MAAM,SAAS,kBAAkB,aAAa;AAChD,sBAAM,EAAE,QAAQ,oBAAoB,eAAe,IAAI,iCAAiC,KAAK;AAC7F,oBAAI,mBAAoB,UAAS;AACjC,oBAAI,eAAgB,iBAAgB,KAAK,cAAc;AAAA,cACzD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,oBAAc;AACd,YAAM;AAAA,IACR,UAAE;AACA,eAAS,SAAS,YAAY,WAAW;AACzC,eAAS,IAAI;AAAA,IACf;AAEA,QAAI,kBAAkB,SAAS,GAAG;AAChC,YAAM,YAAY,gBAAgB,iBAAiB;AACnD,YAAM;AACN,YAAM,qBAA0C;AAAA,QAC9C,MAAM,UAAU;AAAA,QAChB,IAAI,UAAU;AAAA,QACd,YAAY,UAAU;AAAA,QACtB,WAAW,UAAU;AAAA,QACrB,aAAa,UAAU,YAAY,IAAI,CAAC,EAAE,YAAY,GAAG,EAAE,MAAM;AAC/D,eAAK;AACL,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AACA,sBAAgB,KAAK,kBAAkB;AAAA,IACzC;AAEA,WAAO;AAAA,MACL;AAAA,MACA,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/core/runtime/AgentThreadOrchestrator.ts"],"sourcesContent":["import type { Logger } from 'winston';\nimport { AgentHarnessError, InvalidAgentSendInputError } from '../errors';\nimport {\n EventType,\n newEventId,\n type ActionRequiredEvent,\n type ModelMessageEvent,\n type ToolResponseEvent,\n type UserToolApprovalMessage,\n type UserToolResponseMessage,\n} from '../events/schema';\nimport type { AgentExecutionTrace, AgentTracing } from '../tracing/AgentTracing';\nimport { onSignalAbort } from '../util/abort';\nimport { mergeAsyncGenerators } from '../util/promiseUtils';\nimport { AgentThread } from './AgentThread';\nimport type { AgentThreadRuntimeSendBatch } from './AgentThread.types';\nimport {\n InternalEventType,\n type AgentThreadAppendContext,\n type AgentThreadEvent,\n type AgentThreadExecutionEvent,\n type AgentThreadExecutionResult,\n type AgentThreadSendBatch,\n type InternalMCPAuthRequiredEvent,\n type InternalMCPServerAuthInfo,\n} from './AgentThread.types';\nimport {\n assistantMessageContentToStringForSubAgent,\n getThreadId,\n isApprovalDecisionMessage,\n isClientSideToolResponseMessage,\n isInternalThreadDoneError,\n} from './contextUtils';\nimport type { CreateDynamicSubAgentThread } from './CreateDynamicSubAgentThread';\nimport { addAgentThreadMetrics, createEmptyAgentThreadMetrics, type AgentThreadMetrics } from './metrics';\n\nconst MAX_PARALLEL_SUB_AGENTS = 5;\n\nfunction agentThreadEventToTerminalFields(event: AgentThreadExecutionEvent): {\n output?: ModelMessageEvent | undefined;\n requiredAction?: ActionRequiredEvent | undefined;\n} {\n switch (event.type) {\n case InternalEventType.AGENT_DONE: {\n if ('parent' in event && event.parent) {\n return {};\n }\n if (event.status === 'error') {\n return {};\n }\n return { output: event.output };\n }\n case EventType.TOOL_APPROVAL_REQUIRED:\n case EventType.TOOL_RESPONSE_REQUIRED:\n return { requiredAction: event };\n default:\n return {};\n }\n}\n\ntype UserToolApprovalOrResponseBatch = (UserToolApprovalMessage | UserToolResponseMessage)[];\n\nfunction isUserToolApprovalOrResponseBatch(\n messages: AgentThreadSendBatch,\n): messages is UserToolApprovalOrResponseBatch {\n const first = messages[0];\n return first !== undefined && (isApprovalDecisionMessage(first) || isClientSideToolResponseMessage(first));\n}\n\nfunction getMainThreadId(agentThreads: Map<string, AgentThread>): string {\n for (const thread of agentThreads.values()) {\n if (!thread.parent) {\n return thread.threadId;\n }\n }\n throw new Error('Unreachable: no root thread found');\n}\n\nfunction getActiveAgentThreads(agentThreads: Map<string, AgentThread>): AgentThread[] {\n const nodes = new Set(agentThreads.keys());\n const parentNodes = new Set(\n [...agentThreads.values()].map(a => a.parent?.thread_id).filter((a): a is string => Boolean(a)),\n );\n const leaves = [...nodes].filter(id => !parentNodes.has(id));\n if (leaves.length === 0) {\n throw new Error('We cannot have zero leave agents');\n }\n return leaves.map(id => {\n const agentThread = agentThreads.get(id);\n if (!agentThread) {\n throw new Error('unreachable');\n }\n return agentThread;\n });\n}\n\nfunction mergeAuthEvents(events: InternalMCPAuthRequiredEvent[]): InternalMCPAuthRequiredEvent {\n const serverMap = new Map<string, InternalMCPServerAuthInfo>();\n for (const event of events) {\n for (const entry of event.mcp_servers) {\n const existing = serverMap.get(entry.id);\n if (existing) {\n existing.thread_ids.push(...entry.thread_ids);\n } else {\n serverMap.set(entry.id, { ...entry, thread_ids: [...entry.thread_ids] });\n }\n }\n }\n return {\n type: InternalEventType.MCP_AUTH_REQUIRED,\n id: newEventId(),\n created_at: new Date().toISOString(),\n thread_id: null,\n mcp_servers: [...serverMap.values()],\n };\n}\n\nfunction wrapGeneratorWithTrace<T, TReturn = void, TNext = unknown>(\n trace: AgentExecutionTrace,\n generator: AsyncGenerator<T, TReturn, TNext>,\n): AsyncGenerator<T, TReturn, TNext> {\n const wrapped: AsyncGenerator<T, TReturn, TNext> = {\n [Symbol.asyncIterator]() {\n return this;\n },\n next(...[value]: [] | [TNext]) {\n return trace.runInContext(() => (value === undefined ? generator.next() : generator.next(value)));\n },\n return(value: TReturn | PromiseLike<TReturn>) {\n return trace.runInContext(() => generator.return(value));\n },\n throw(e: unknown) {\n return trace.runInContext(() => generator.throw(e));\n },\n [Symbol.asyncDispose]() {\n return generator[Symbol.asyncDispose]();\n },\n };\n return wrapped;\n}\n\ninterface RootAgentSpanHandle {\n trace: AgentExecutionTrace;\n wrapThreadWithContext(thread: AgentThread, signal?: AbortSignal): AsyncGenerator<AgentThreadEvent>;\n setOutputFromEvent(chunk: AgentThreadEvent): void;\n finalize(thread: AgentThread, error?: unknown): void;\n end(): void;\n}\n\nfunction createRootAgentSpan(mainThread: AgentThread, tracing: AgentTracing): RootAgentSpanHandle {\n const trace = tracing.startRootSpan(\n JSON.stringify({ instructions: mainThread.definition.instruction, messages: mainThread.definition.messages }),\n );\n let rootAgentErrorMessage: string | undefined;\n let rootAgentCompleted = false;\n\n return {\n trace,\n wrapThreadWithContext(thread: AgentThread, signal?: AbortSignal) {\n return wrapGeneratorWithTrace(trace, thread.execute({ signal }));\n },\n setOutputFromEvent(chunk: AgentThreadEvent) {\n rootAgentCompleted = true;\n if (chunk.type === InternalEventType.AGENT_DONE) {\n if (isInternalThreadDoneError(chunk)) {\n rootAgentErrorMessage = chunk.error;\n trace.setOutput(JSON.stringify({ error: chunk.error }));\n } else {\n const content = assistantMessageContentToStringForSubAgent(chunk.output.content);\n trace.setOutput(JSON.stringify({ result: content }));\n }\n }\n },\n finalize(thread: AgentThread, error?: unknown) {\n trace.setMetrics(thread.getAgentThreadMetrics());\n if (error) {\n trace.setError(error);\n } else if (rootAgentErrorMessage || !rootAgentCompleted) {\n trace.setError(rootAgentErrorMessage ?? 'Agent execution interrupted');\n } else {\n trace.setSuccess();\n }\n },\n end() {\n trace.end();\n },\n };\n}\n\n/** @internal Exported for sub-agent span finalization tests. */\nexport async function* wrapWithSubAgentSpan(\n parentTrace: AgentExecutionTrace,\n currentThread: AgentThread,\n signal?: AbortSignal,\n): AsyncGenerator<AgentThreadEvent> {\n const agentInfo = currentThread.agentInfo;\n if (!agentInfo) {\n throw new Error('Sub-agent thread is missing agentInfo');\n }\n const subTrace = parentTrace.startSubAgent(agentInfo.name, JSON.stringify({ instructions: agentInfo.input }));\n const generator = wrapGeneratorWithTrace(subTrace, currentThread.execute({ signal }));\n\n try {\n for await (const event of generator) {\n if (event.type === InternalEventType.AGENT_DONE) {\n if (isInternalThreadDoneError(event)) {\n subTrace.setOutput(JSON.stringify({ error: event.error }));\n subTrace.setMetrics(currentThread.getAgentThreadMetrics());\n subTrace.setError(event.error);\n } else {\n const content = assistantMessageContentToStringForSubAgent(event.output.content);\n subTrace.setOutput(JSON.stringify({ result: content }));\n subTrace.setMetrics(currentThread.getAgentThreadMetrics());\n subTrace.setSuccess();\n }\n // end() only in finally so every path finalizes exactly once\n }\n yield event;\n }\n } catch (error) {\n subTrace.setError(error);\n throw error;\n } finally {\n subTrace.end();\n }\n}\n\nexport interface AgentThreadOrchestratorInput {\n agentThreads: Map<string, AgentThread>;\n createDynamicSubAgentThread: CreateDynamicSubAgentThread;\n tracing: AgentTracing;\n logger: Logger;\n}\n\nexport class AgentThreadOrchestrator {\n private readonly agentThreads: Map<string, AgentThread>;\n private readonly createDynamicSubAgentThread: CreateDynamicSubAgentThread;\n private readonly tracing: AgentTracing;\n private readonly logger: Logger;\n // Finished sub-agents removed from `agentThreads`; kept so totals still include them.\n private finishedSubAgentMetrics: AgentThreadMetrics = createEmptyAgentThreadMetrics();\n\n constructor(params: AgentThreadOrchestratorInput) {\n this.agentThreads = params.agentThreads;\n this.createDynamicSubAgentThread = params.createDynamicSubAgentThread;\n this.tracing = params.tracing;\n this.logger = params.logger.child({ module: 'AgentThreadOrchestrator' });\n }\n\n /**\n * Turn-wide metrics so far: live threads plus finished sub-agents.\n * Safe mid-flight and after cancel/error (`execute()` may not return).\n * Each thread is counted once — a sub-agent moves from live → finished atomically.\n */\n public getMetrics(): AgentThreadMetrics {\n const total = createEmptyAgentThreadMetrics();\n addAgentThreadMetrics(total, this.finishedSubAgentMetrics);\n for (const thread of this.agentThreads.values()) {\n addAgentThreadMetrics(total, thread.getAgentThreadMetrics());\n }\n return total;\n }\n\n public async *send(messages: AgentThreadSendBatch): AsyncGenerator<AgentThreadAppendContext, void, unknown> {\n const byThread = new Map<string, AgentThreadRuntimeSendBatch>();\n for (const thread of this.agentThreads.values()) {\n byThread.set(thread.threadId, []);\n }\n\n if (isUserToolApprovalOrResponseBatch(messages)) {\n const grouped = new Map<string, UserToolApprovalOrResponseBatch[number][]>();\n for (const msg of messages) {\n const threadId = msg.thread_id;\n if (!byThread.has(threadId)) {\n throw new InvalidAgentSendInputError(`unknown thread_id: ${threadId}`);\n }\n const batch = grouped.get(threadId) ?? [];\n batch.push(msg);\n grouped.set(threadId, batch);\n }\n for (const [threadId, batch] of grouped) {\n byThread.set(threadId, batch);\n }\n } else if (messages.length > 0) {\n if (this.agentThreads.size > 1) {\n throw new InvalidAgentSendInputError(\n 'Cannot process user messages while sub agents are running, please send empty input for previous conversation to complete',\n );\n }\n byThread.set(getMainThreadId(this.agentThreads), messages);\n }\n\n const validationErrors: string[] = [];\n for (const [threadId, batch] of byThread) {\n const thread = this.agentThreads.get(threadId);\n if (!thread) {\n throw new Error(`AgentThreadOrchestrator.send: unknown threadId ${threadId}`);\n }\n try {\n thread.validateSendInput(batch);\n } catch (e) {\n if (e instanceof AgentHarnessError && e.code === 'invalid_send_input') {\n validationErrors.push(`thread ${threadId}: ${e.message}`);\n } else {\n throw e;\n }\n }\n }\n if (validationErrors.length > 0) {\n throw new InvalidAgentSendInputError(validationErrors.join('; '));\n }\n\n for (const [threadId, batch] of byThread) {\n yield* this.sendToThread(threadId, batch);\n }\n }\n\n private async *sendToThread(\n threadId: string,\n messages: AgentThreadRuntimeSendBatch,\n ): AsyncGenerator<AgentThreadAppendContext, void, unknown> {\n const thread = this.agentThreads.get(threadId);\n if (!thread) {\n throw new Error(`AgentThreadOrchestrator.sendToThread: unknown threadId ${threadId}`);\n }\n yield* thread.send(messages);\n }\n\n private async *processAgentStreamChunk(\n chunk: Exclude<AgentThreadEvent, InternalMCPAuthRequiredEvent>,\n signal: AbortSignal,\n ): AsyncGenerator<AgentThreadExecutionEvent, { shouldStopExecution: boolean }, unknown> {\n if (chunk.type === InternalEventType.PASSTHROUGH) {\n yield chunk.event;\n return { shouldStopExecution: false };\n }\n\n if (!('thread_id' in chunk) || chunk.thread_id == null) {\n yield chunk;\n return { shouldStopExecution: false };\n }\n\n const currentThread = this.agentThreads.get(chunk.thread_id);\n if (!currentThread) {\n throw new Error('unreachable');\n }\n\n switch (chunk.type) {\n case EventType.TOOL_APPROVAL_REQUIRED:\n case EventType.TOOL_RESPONSE_REQUIRED:\n yield chunk;\n return { shouldStopExecution: true };\n case InternalEventType.AGENT_DONE: {\n if (chunk.parent) {\n if (!chunk.send_to_parent) {\n throw new Error('unreachable');\n }\n const parentThread = this.agentThreads.get(chunk.parent.thread_id);\n if (!parentThread) {\n throw new Error('unreachable: parent thread missing');\n }\n const subAgentToolIsOpen = parentThread.hasOpenToolCallId(chunk.parent.tool_call_id);\n if (subAgentToolIsOpen) {\n const parentToolResponse: ToolResponseEvent = {\n type: EventType.TOOL_RESPONSE,\n id: newEventId(),\n created_at: new Date().toISOString(),\n thread_id: chunk.parent.thread_id,\n tool_call_id: chunk.send_to_parent.tool_call_id,\n content: '',\n };\n yield parentToolResponse;\n yield* this.sendToThread(chunk.parent.thread_id, [chunk.send_to_parent]);\n }\n yield chunk;\n // Move metrics to the finished bucket and drop the live entry with no `yield` between,\n // so getMetrics() counts this sub-agent once. After `yield chunk` per durable-state.\n addAgentThreadMetrics(this.finishedSubAgentMetrics, currentThread.getAgentThreadMetrics());\n this.agentThreads.delete(chunk.thread_id);\n return { shouldStopExecution: false };\n }\n yield chunk;\n return { shouldStopExecution: true };\n }\n case InternalEventType.AGENT_CREATE_SUBAGENT: {\n const parent = {\n tool_call_id: chunk.tool_call_id,\n thread_id: chunk.thread_id,\n };\n const subAgentThreadId = getThreadId();\n const subAgentThread = await this.createDynamicSubAgentThread({\n parentDefinition: currentThread.definition,\n request: chunk.agent_info,\n threadId: subAgentThreadId,\n parent,\n signal,\n });\n\n yield {\n type: EventType.THREAD_CREATED,\n id: newEventId(),\n agent_info: {\n type: 'dynamic',\n name: chunk.agent_info.name,\n input: chunk.agent_info.input,\n model: chunk.agent_info.model,\n },\n created_at: new Date().toISOString(),\n parent,\n title: chunk.agent_info.name,\n thread_id: subAgentThreadId,\n };\n this.agentThreads.set(subAgentThreadId, subAgentThread);\n return { shouldStopExecution: false };\n }\n default:\n yield chunk;\n return { shouldStopExecution: false };\n }\n }\n\n public async *execute({\n signal,\n }: {\n signal: AbortSignal;\n }): AsyncGenerator<AgentThreadExecutionEvent, AgentThreadExecutionResult, unknown> {\n const { agentThreads } = this;\n\n let shouldStopExecution = false;\n let caughtError: unknown;\n let output: ModelMessageEvent | null = null;\n const requiredActions: ActionRequiredEvent[] = [];\n let rootAgentError: AgentThreadExecutionResult['root_agent_error'];\n const pendingAuthEvents: InternalMCPAuthRequiredEvent[] = [];\n const mainThread = [...agentThreads.values()].find(e => !e.parent);\n if (!mainThread) {\n throw new Error('Unreachable: no root thread found');\n }\n const rootSpan = createRootAgentSpan(mainThread, this.tracing);\n\n onSignalAbort(signal, () => {\n shouldStopExecution = true;\n });\n\n try {\n while (agentThreads.size > 0) {\n if (shouldStopExecution) {\n break;\n }\n\n const activeThreads = getActiveAgentThreads(agentThreads);\n\n for (let i = 0; i < activeThreads.length && !shouldStopExecution; i += MAX_PARALLEL_SUB_AGENTS) {\n const batch = activeThreads.slice(i, i + MAX_PARALLEL_SUB_AGENTS);\n const generators = batch.map(thread => {\n if (!thread.parent) {\n return rootSpan.wrapThreadWithContext(thread, signal);\n }\n return wrapWithSubAgentSpan(rootSpan.trace, thread, signal);\n });\n\n for await (const chunk of mergeAsyncGenerators(generators, this.logger)) {\n if (chunk.type === InternalEventType.MCP_AUTH_REQUIRED) {\n pendingAuthEvents.push(chunk);\n shouldStopExecution = true;\n continue;\n }\n if (chunk.type === InternalEventType.AGENT_DONE && !chunk.parent) {\n // Root-thread only — sub-agent AGENT_DONE would overwrite root trace output /\n // leave a stale error; sub-agent spans finalize in wrapWithSubAgentSpan.\n rootSpan.setOutputFromEvent(chunk);\n }\n\n const result = yield* this.processAgentStreamChunk(chunk, signal);\n if (result.shouldStopExecution) {\n shouldStopExecution = true;\n if (\n !rootAgentError &&\n chunk.type === InternalEventType.AGENT_DONE &&\n isInternalThreadDoneError(chunk) &&\n !chunk.parent\n ) {\n rootAgentError = { error: chunk.error, output: chunk.output };\n }\n if (chunk.type !== InternalEventType.PASSTHROUGH) {\n const { output: outputContribution, requiredAction } = agentThreadEventToTerminalFields(chunk);\n if (outputContribution) {\n output = outputContribution;\n }\n if (requiredAction) {\n requiredActions.push(requiredAction);\n }\n }\n }\n }\n }\n }\n } catch (error) {\n caughtError = error;\n throw error;\n } finally {\n rootSpan.finalize(mainThread, caughtError);\n rootSpan.end();\n }\n\n if (pendingAuthEvents.length > 0) {\n const authEvent = mergeAuthEvents(pendingAuthEvents);\n yield authEvent;\n const authRequiredAction: ActionRequiredEvent = {\n type: EventType.MCP_AUTH_REQUIRED,\n id: authEvent.id,\n created_at: authEvent.created_at,\n thread_id: authEvent.thread_id,\n mcp_servers: authEvent.mcp_servers.map(({ thread_ids, ...s }) => {\n void thread_ids;\n return s;\n }),\n };\n requiredActions.push(authRequiredAction);\n }\n\n return {\n output,\n required_actions: requiredActions,\n root_agent_error: rootAgentError,\n };\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"DeferredTool.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/DeferredTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAML,KAAK,QAAQ,EAGd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAc,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAG5D,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAEzD,eAAO,MAAM,eAAe,eAAe,CAAC;AAC5C,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAClD,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AAkCpE,qBAAa,YAAa,SAAQ,YAAY;IAC5C,QAAQ,CAAC,IAAI,oBAA4B;IACzC,QAAQ,CAAC,WAAW,mBAAmB;IACvC,SAAkB,WAAW,gDAAgD;IAE7E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,YACE,OAAO,EAAE,SAAS,QAAQ,EAAE,EAC5B,OAAO,EAAE;QACP,OAAO,EAAE,YAAY,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;KAChB,EAMF;IAED,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAqBlD;IAED,SAAS,CAAC,QAAQ,IAAI,cAAc,EAAE,CAErC;IAEc,YAAY,CACzB,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,EACjC,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CA8B/B;IAED,OAAO,CAAC,aAAa;YAIP,kBAAkB;IAiBhC,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,cAAc;IA8BtB,OAAO,CAAC,gBAAgB;IA+CxB,OAAO,CAAC,wBAAwB;IA8ChC,OAAO,CAAC,aAAa;CA+CtB"}
1
+ {"version":3,"file":"DeferredTool.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/DeferredTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAML,KAAK,QAAQ,EAGd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAc,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAG5D,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAEzD,eAAO,MAAM,eAAe,eAAe,CAAC;AAC5C,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAClD,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AAkCpE,qBAAa,YAAa,SAAQ,YAAY;IAC5C,QAAQ,CAAC,IAAI,oBAA4B;IACzC,QAAQ,CAAC,WAAW,mBAAmB;IACvC,SAAkB,WAAW,gDAAgD;IAE7E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,YACE,OAAO,EAAE,SAAS,QAAQ,EAAE,EAC5B,OAAO,EAAE;QACP,OAAO,EAAE,YAAY,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;KAChB,EAMF;IAED,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAuBlD;IAED,SAAS,CAAC,QAAQ,IAAI,cAAc,EAAE,CAErC;IAEc,YAAY,CACzB,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,EACjC,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CA8B/B;IAED,OAAO,CAAC,aAAa;YAIP,kBAAkB;IAiBhC,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,gBAAgB;IAiDxB,OAAO,CAAC,wBAAwB;IAgDhC,OAAO,CAAC,aAAa;CAiDtB"}
@@ -85,7 +85,9 @@ var DeferredTool = class extends import_LocalToolMCP.LocalToolMCP {
85
85
  buildInstruction(builder) {
86
86
  const servers = [...this.serverMap.values()];
87
87
  const deferredServers = servers.filter((s) => !s.preload);
88
- if (deferredServers.length === 0) return;
88
+ if (deferredServers.length === 0) {
89
+ return;
90
+ }
89
91
  const deferredList = deferredServers.map((s) => s.description ? `- ${s.name}: "${s.description.slice(0, MAX_DESCRIPTION_LENGTH)}"` : `- ${s.name}`).join("\n");
90
92
  builder.addSection(
91
93
  DEFERRED_TOOLS_INSTRUCTION,
@@ -161,7 +163,9 @@ var DeferredTool = class extends import_LocalToolMCP.LocalToolMCP {
161
163
  handler: async (input) => {
162
164
  try {
163
165
  const resolved = await this.resolveServerTools(input.mcp_server);
164
- if (!isResolvedServerTools(resolved)) return resolved;
166
+ if (!isResolvedServerTools(resolved)) {
167
+ return resolved;
168
+ }
165
169
  const { server, tools, metadata } = resolved;
166
170
  return (0, import_IMCPServer.toolResultResponse)({
167
171
  text: `${server.name}:
@@ -192,7 +196,9 @@ var DeferredTool = class extends import_LocalToolMCP.LocalToolMCP {
192
196
  handler: async (input) => {
193
197
  try {
194
198
  const resolved = await this.resolveServerTools(input.mcp_server);
195
- if (!isResolvedServerTools(resolved)) return resolved;
199
+ if (!isResolvedServerTools(resolved)) {
200
+ return resolved;
201
+ }
196
202
  const { tools, metadata } = resolved;
197
203
  const tool = tools.find((t) => t.name === input.tool_name);
198
204
  if (!tool) {
@@ -238,7 +244,9 @@ var DeferredTool = class extends import_LocalToolMCP.LocalToolMCP {
238
244
  handler: async (input) => {
239
245
  try {
240
246
  const resolved = await this.resolveServerTools(input.mcp_server);
241
- if (!isResolvedServerTools(resolved)) return resolved;
247
+ if (!isResolvedServerTools(resolved)) {
248
+ return resolved;
249
+ }
242
250
  const { tools, metadata } = resolved;
243
251
  const tool = tools.find((t) => t.name === input.tool_name);
244
252
  if (!tool) {
@@ -290,7 +298,9 @@ var DeferredTool = class extends import_LocalToolMCP.LocalToolMCP {
290
298
  if ((0, import_IMCPServer.isAuthRequired)(response)) {
291
299
  return response;
292
300
  }
293
- if ((0, import_IMCPServer.isApprovalRequiredResponse)(response)) return response;
301
+ if ((0, import_IMCPServer.isApprovalRequiredResponse)(response)) {
302
+ return response;
303
+ }
294
304
  if (!(0, import_IMCPServer.isCallToolResponseResult)(response)) {
295
305
  throw new Error("Tool call returned an unexpected sub-agent response");
296
306
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/runtime/DeferredTool.ts"],"sourcesContent":["import type { CallToolRequest } from '@modelcontextprotocol/sdk/types.js';\nimport dedent from 'dedent';\nimport type { Logger } from 'winston';\nimport { z } from 'zod';\nimport type { ApprovalDecision } from '../events/schema';\nimport { InstructionBuilder } from '../InstructionBuilder';\nimport type { InternalToolCallInfo } from '../llm/LLMTypes';\nimport {\n type AgentToolSchema,\n type CallToolResponse,\n isApprovalRequiredResponse,\n isAuthRequired,\n isCallToolResponseResult,\n type IToolSet,\n type ListToolsResolvedResponse,\n toolResultResponse,\n} from '../mcp/IMCPServer';\nimport { defineTool, LocalToolMCP, type ToolDefinition } from '../mcp/LocalToolMCP';\nimport type { AgentTracing } from '../tracing/AgentTracing';\nimport { extractErrorLogFields } from '../util/errorLogFields';\n\nexport const DEFERRED_TOOLS_SERVER_ID = 'deferred-tools';\nconst DEFERRED_TOOLS_INSTRUCTION = 'deferred-tools-instructions';\nexport const LIST_TOOLS_NAME = 'list_tools';\nexport const GET_TOOL_INFO_NAME = 'get_tool_info';\nexport const GET_TOOL_OUTPUT_SCHEMA_NAME = 'get_tool_output_schema';\nconst CALL_TOOL_NAME = 'call_tool';\nconst MAX_DESCRIPTION_LENGTH = 200;\n\nconst listToolsSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server to list tools for.'),\n});\n\nconst getToolInfoSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to inspect.'),\n});\n\nconst getToolOutputSchemaSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to get output schema for.'),\n});\n\nconst callToolSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to call.'),\n input: z.record(z.string(), z.unknown()).default({}).describe('Arguments to pass to the tool.'),\n});\n\ninterface ResolvedServerTools {\n server: IToolSet;\n tools: AgentToolSchema[];\n metadata: Omit<ListToolsResolvedResponse, 'result'>;\n}\n\nfunction isResolvedServerTools(result: CallToolResponse | ResolvedServerTools): result is ResolvedServerTools {\n return 'tools' in result;\n}\n\nexport class DeferredTool extends LocalToolMCP {\n readonly name = DEFERRED_TOOLS_SERVER_ID;\n readonly displayName = 'DeferredTools';\n override readonly description = 'Deferred tool loading for user MCP servers';\n\n private readonly serverMap: Map<string, IToolSet>;\n private readonly tools: ToolDefinition[];\n private readonly logger: Logger;\n\n constructor(\n servers: readonly IToolSet[],\n options: {\n tracing: AgentTracing;\n logger: Logger;\n },\n ) {\n super({ tracing: options.tracing });\n this.logger = options.logger.child({ module: 'DeferredTool' });\n this.serverMap = new Map(servers.map(s => [s.name, s]));\n this.tools = this.buildTools();\n }\n\n buildInstruction(builder: InstructionBuilder): void {\n const servers = [...this.serverMap.values()];\n\n // Membership follows `preload` only (origin/main). Selective `preload_tools` /\n // `hasPreloadedTools` must not hide a server from deferred discovery instructions.\n const deferredServers = servers.filter(s => !s.preload);\n\n if (deferredServers.length === 0) return;\n\n const deferredList = deferredServers\n .map(s => (s.description ? `- ${s.name}: \"${s.description.slice(0, MAX_DESCRIPTION_LENGTH)}\"` : `- ${s.name}`))\n .join('\\n');\n\n builder.addSection(\n DEFERRED_TOOLS_INSTRUCTION,\n dedent`\n The following MCP servers have deferred tool loading. Their tools are NOT pre-loaded.\n ${deferredList}\n\n The Agent MUST use ${LIST_TOOLS_NAME} and ${GET_TOOL_INFO_NAME} to discover tools before calling them.`,\n );\n }\n\n protected getTools(): ToolDefinition[] {\n return this.tools;\n }\n\n override async toolCallInfo(\n params: CallToolRequest['params'],\n resolveUnderlyingTool?: boolean,\n ): Promise<InternalToolCallInfo> {\n if (params.name !== CALL_TOOL_NAME) {\n return super.toolCallInfo(params, resolveUnderlyingTool);\n }\n if (resolveUnderlyingTool === false) {\n const base = await super.toolCallInfo(params, resolveUnderlyingTool);\n return { ...base, is_deferred: true };\n }\n const parsed = callToolSchema.safeParse(params.arguments);\n if (!parsed.success) {\n this.logger.warn(`Failed to parse call_tool arguments`, {\n tool: params.name,\n errors: parsed.error.issues,\n });\n return { ...(await super.toolCallInfo(params)), is_deferred: true };\n }\n const server = this.resolveServer(parsed.data.mcp_server);\n if (!server) {\n this.logger.warn(`Server not found for toolCallInfo`, {\n mcpServer: parsed.data.mcp_server,\n toolName: parsed.data.tool_name,\n availableServers: [...this.serverMap.keys()],\n });\n return { ...(await super.toolCallInfo(params)), is_deferred: true };\n }\n const underlying = await server.toolCallInfo({\n name: parsed.data.tool_name,\n arguments: parsed.data.input,\n });\n return { ...underlying, is_deferred: true };\n }\n\n private resolveServer(name: string): IToolSet | undefined {\n return this.serverMap.get(name);\n }\n\n private async resolveServerTools(mcpServer: string): Promise<CallToolResponse | ResolvedServerTools> {\n const server = this.resolveServer(mcpServer);\n if (!server) {\n return toolResultResponse({\n text: JSON.stringify({ error: `MCP server '${mcpServer}' not found` }),\n isError: true,\n });\n }\n\n const listResponse = await server.listTools();\n if (isAuthRequired(listResponse)) {\n return listResponse;\n }\n const { result, ...metadata } = listResponse;\n return { server, tools: result.tools, metadata };\n }\n\n private buildTools(): ToolDefinition[] {\n return [this.buildListTools(), this.buildGetToolInfo(), this.buildGetToolOutputSchema(), this.buildCallTool()];\n }\n\n private buildListTools(): ToolDefinition {\n return defineTool({\n name: LIST_TOOLS_NAME,\n description: dedent`\n List tool names available on an MCP server.\n Returns tool names only — use ${GET_TOOL_INFO_NAME} to get full details before calling a tool.`,\n schema: listToolsSchema,\n handler: async (input: { mcp_server: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) return resolved;\n const { server, tools, metadata } = resolved;\n return toolResultResponse({\n text: `${server.name}:\\n ${tools.map(t => t.name).join(', ')}`,\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('list_tools failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n });\n return toolResultResponse({\n text: JSON.stringify({ error: `Failed to list tools for '${input.mcp_server}'.` }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildGetToolInfo(): ToolDefinition {\n return defineTool({\n name: GET_TOOL_INFO_NAME,\n description: dedent`\n Get description, inputSchema and outputSchema for a specific tool on an MCP server.\n If outputSchema is null, it will NOT be present in ${GET_TOOL_OUTPUT_SCHEMA_NAME} as well.\n The Agent MUST call ${LIST_TOOLS_NAME} first to know which tools are available.`,\n schema: getToolInfoSchema,\n handler: async (input: { mcp_server: string; tool_name: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) return resolved;\n const { tools, metadata } = resolved;\n const tool = tools.find(t => t.name === input.tool_name);\n if (!tool) {\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool '${input.tool_name}' not found on server '${input.mcp_server}'` }),\n overrides: metadata,\n isError: true,\n });\n }\n\n return toolResultResponse({\n text: JSON.stringify({\n description: tool.description,\n inputSchema: tool.inputSchema,\n outputSchema: tool.outputSchema ?? null,\n }),\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('get_tool_info failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({\n error: `Failed to get tool info: ${error instanceof Error ? error.message : 'unknown'}`,\n }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildGetToolOutputSchema(): ToolDefinition {\n return defineTool({\n name: GET_TOOL_OUTPUT_SCHEMA_NAME,\n description: dedent`\n Get the outputSchema for a specific tool on an MCP server.\n The Agent MUST not call ${GET_TOOL_OUTPUT_SCHEMA_NAME} and ${GET_TOOL_INFO_NAME} for the same tool.\n The Agent MUST either call ${GET_TOOL_OUTPUT_SCHEMA_NAME} or ${GET_TOOL_INFO_NAME} before entering Code Mode.\n The Agent must NOT assume the structure of a tool's response from its name or description alone.`,\n schema: getToolOutputSchemaSchema,\n handler: async (input: { mcp_server: string; tool_name: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) return resolved;\n const { tools, metadata } = resolved;\n const tool = tools.find(t => t.name === input.tool_name);\n if (!tool) {\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool '${input.tool_name}' not found on server '${input.mcp_server}'` }),\n overrides: metadata,\n isError: true,\n });\n }\n\n return toolResultResponse({\n text: JSON.stringify({\n outputSchema: tool.outputSchema ?? null,\n }),\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('get_tool_output_schema failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({\n error: `Failed to get output schema: ${error instanceof Error ? error.message : 'unknown'}`,\n }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildCallTool(): ToolDefinition {\n return defineTool({\n name: CALL_TOOL_NAME,\n description: dedent`\n Call a tool on an MCP server.\n The Agent MUST call ${LIST_TOOLS_NAME} and ${GET_TOOL_INFO_NAME} before calling a tool.`,\n schema: callToolSchema,\n handler: async (\n input: { mcp_server: string; tool_name: string; input: Record<string, unknown> },\n approvalDecision?: ApprovalDecision,\n ) => {\n const server = this.resolveServer(input.mcp_server);\n if (!server) {\n return toolResultResponse({\n text: JSON.stringify({ error: `MCP server '${input.mcp_server}' not found` }),\n isError: true,\n });\n }\n\n try {\n const response = await server.callTool({ name: input.tool_name, arguments: input.input }, approvalDecision);\n\n if (isAuthRequired(response)) {\n return response;\n }\n\n if (isApprovalRequiredResponse(response)) return response;\n\n if (!isCallToolResponseResult(response)) {\n throw new Error('Tool call returned an unexpected sub-agent response');\n }\n\n return response;\n } catch (error) {\n this.logger.error('call_tool failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool call failed: ${error instanceof Error ? error.message : 'unknown'}` }),\n isError: true,\n });\n }\n },\n });\n }\n}\n"],"mappings":"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","names":["dedent"]}
1
+ {"version":3,"sources":["../../../src/core/runtime/DeferredTool.ts"],"sourcesContent":["import type { CallToolRequest } from '@modelcontextprotocol/sdk/types.js';\nimport dedent from 'dedent';\nimport type { Logger } from 'winston';\nimport { z } from 'zod';\nimport type { ApprovalDecision } from '../events/schema';\nimport { InstructionBuilder } from '../InstructionBuilder';\nimport type { InternalToolCallInfo } from '../llm/LLMTypes';\nimport {\n type AgentToolSchema,\n type CallToolResponse,\n isApprovalRequiredResponse,\n isAuthRequired,\n isCallToolResponseResult,\n type IToolSet,\n type ListToolsResolvedResponse,\n toolResultResponse,\n} from '../mcp/IMCPServer';\nimport { defineTool, LocalToolMCP, type ToolDefinition } from '../mcp/LocalToolMCP';\nimport type { AgentTracing } from '../tracing/AgentTracing';\nimport { extractErrorLogFields } from '../util/errorLogFields';\n\nexport const DEFERRED_TOOLS_SERVER_ID = 'deferred-tools';\nconst DEFERRED_TOOLS_INSTRUCTION = 'deferred-tools-instructions';\nexport const LIST_TOOLS_NAME = 'list_tools';\nexport const GET_TOOL_INFO_NAME = 'get_tool_info';\nexport const GET_TOOL_OUTPUT_SCHEMA_NAME = 'get_tool_output_schema';\nconst CALL_TOOL_NAME = 'call_tool';\nconst MAX_DESCRIPTION_LENGTH = 200;\n\nconst listToolsSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server to list tools for.'),\n});\n\nconst getToolInfoSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to inspect.'),\n});\n\nconst getToolOutputSchemaSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to get output schema for.'),\n});\n\nconst callToolSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to call.'),\n input: z.record(z.string(), z.unknown()).default({}).describe('Arguments to pass to the tool.'),\n});\n\ninterface ResolvedServerTools {\n server: IToolSet;\n tools: AgentToolSchema[];\n metadata: Omit<ListToolsResolvedResponse, 'result'>;\n}\n\nfunction isResolvedServerTools(result: CallToolResponse | ResolvedServerTools): result is ResolvedServerTools {\n return 'tools' in result;\n}\n\nexport class DeferredTool extends LocalToolMCP {\n readonly name = DEFERRED_TOOLS_SERVER_ID;\n readonly displayName = 'DeferredTools';\n override readonly description = 'Deferred tool loading for user MCP servers';\n\n private readonly serverMap: Map<string, IToolSet>;\n private readonly tools: ToolDefinition[];\n private readonly logger: Logger;\n\n constructor(\n servers: readonly IToolSet[],\n options: {\n tracing: AgentTracing;\n logger: Logger;\n },\n ) {\n super({ tracing: options.tracing });\n this.logger = options.logger.child({ module: 'DeferredTool' });\n this.serverMap = new Map(servers.map(s => [s.name, s]));\n this.tools = this.buildTools();\n }\n\n buildInstruction(builder: InstructionBuilder): void {\n const servers = [...this.serverMap.values()];\n\n // Membership follows `preload` only (origin/main). Selective `preload_tools` /\n // `hasPreloadedTools` must not hide a server from deferred discovery instructions.\n const deferredServers = servers.filter(s => !s.preload);\n\n if (deferredServers.length === 0) {\n return;\n }\n\n const deferredList = deferredServers\n .map(s => (s.description ? `- ${s.name}: \"${s.description.slice(0, MAX_DESCRIPTION_LENGTH)}\"` : `- ${s.name}`))\n .join('\\n');\n\n builder.addSection(\n DEFERRED_TOOLS_INSTRUCTION,\n dedent`\n The following MCP servers have deferred tool loading. Their tools are NOT pre-loaded.\n ${deferredList}\n\n The Agent MUST use ${LIST_TOOLS_NAME} and ${GET_TOOL_INFO_NAME} to discover tools before calling them.`,\n );\n }\n\n protected getTools(): ToolDefinition[] {\n return this.tools;\n }\n\n override async toolCallInfo(\n params: CallToolRequest['params'],\n resolveUnderlyingTool?: boolean,\n ): Promise<InternalToolCallInfo> {\n if (params.name !== CALL_TOOL_NAME) {\n return super.toolCallInfo(params, resolveUnderlyingTool);\n }\n if (resolveUnderlyingTool === false) {\n const base = await super.toolCallInfo(params, resolveUnderlyingTool);\n return { ...base, is_deferred: true };\n }\n const parsed = callToolSchema.safeParse(params.arguments);\n if (!parsed.success) {\n this.logger.warn(`Failed to parse call_tool arguments`, {\n tool: params.name,\n errors: parsed.error.issues,\n });\n return { ...(await super.toolCallInfo(params)), is_deferred: true };\n }\n const server = this.resolveServer(parsed.data.mcp_server);\n if (!server) {\n this.logger.warn(`Server not found for toolCallInfo`, {\n mcpServer: parsed.data.mcp_server,\n toolName: parsed.data.tool_name,\n availableServers: [...this.serverMap.keys()],\n });\n return { ...(await super.toolCallInfo(params)), is_deferred: true };\n }\n const underlying = await server.toolCallInfo({\n name: parsed.data.tool_name,\n arguments: parsed.data.input,\n });\n return { ...underlying, is_deferred: true };\n }\n\n private resolveServer(name: string): IToolSet | undefined {\n return this.serverMap.get(name);\n }\n\n private async resolveServerTools(mcpServer: string): Promise<CallToolResponse | ResolvedServerTools> {\n const server = this.resolveServer(mcpServer);\n if (!server) {\n return toolResultResponse({\n text: JSON.stringify({ error: `MCP server '${mcpServer}' not found` }),\n isError: true,\n });\n }\n\n const listResponse = await server.listTools();\n if (isAuthRequired(listResponse)) {\n return listResponse;\n }\n const { result, ...metadata } = listResponse;\n return { server, tools: result.tools, metadata };\n }\n\n private buildTools(): ToolDefinition[] {\n return [this.buildListTools(), this.buildGetToolInfo(), this.buildGetToolOutputSchema(), this.buildCallTool()];\n }\n\n private buildListTools(): ToolDefinition {\n return defineTool({\n name: LIST_TOOLS_NAME,\n description: dedent`\n List tool names available on an MCP server.\n Returns tool names only — use ${GET_TOOL_INFO_NAME} to get full details before calling a tool.`,\n schema: listToolsSchema,\n handler: async (input: { mcp_server: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) {\n return resolved;\n }\n const { server, tools, metadata } = resolved;\n return toolResultResponse({\n text: `${server.name}:\\n ${tools.map(t => t.name).join(', ')}`,\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('list_tools failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n });\n return toolResultResponse({\n text: JSON.stringify({ error: `Failed to list tools for '${input.mcp_server}'.` }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildGetToolInfo(): ToolDefinition {\n return defineTool({\n name: GET_TOOL_INFO_NAME,\n description: dedent`\n Get description, inputSchema and outputSchema for a specific tool on an MCP server.\n If outputSchema is null, it will NOT be present in ${GET_TOOL_OUTPUT_SCHEMA_NAME} as well.\n The Agent MUST call ${LIST_TOOLS_NAME} first to know which tools are available.`,\n schema: getToolInfoSchema,\n handler: async (input: { mcp_server: string; tool_name: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) {\n return resolved;\n }\n const { tools, metadata } = resolved;\n const tool = tools.find(t => t.name === input.tool_name);\n if (!tool) {\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool '${input.tool_name}' not found on server '${input.mcp_server}'` }),\n overrides: metadata,\n isError: true,\n });\n }\n\n return toolResultResponse({\n text: JSON.stringify({\n description: tool.description,\n inputSchema: tool.inputSchema,\n outputSchema: tool.outputSchema ?? null,\n }),\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('get_tool_info failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({\n error: `Failed to get tool info: ${error instanceof Error ? error.message : 'unknown'}`,\n }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildGetToolOutputSchema(): ToolDefinition {\n return defineTool({\n name: GET_TOOL_OUTPUT_SCHEMA_NAME,\n description: dedent`\n Get the outputSchema for a specific tool on an MCP server.\n The Agent MUST not call ${GET_TOOL_OUTPUT_SCHEMA_NAME} and ${GET_TOOL_INFO_NAME} for the same tool.\n The Agent MUST either call ${GET_TOOL_OUTPUT_SCHEMA_NAME} or ${GET_TOOL_INFO_NAME} before entering Code Mode.\n The Agent must NOT assume the structure of a tool's response from its name or description alone.`,\n schema: getToolOutputSchemaSchema,\n handler: async (input: { mcp_server: string; tool_name: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) {\n return resolved;\n }\n const { tools, metadata } = resolved;\n const tool = tools.find(t => t.name === input.tool_name);\n if (!tool) {\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool '${input.tool_name}' not found on server '${input.mcp_server}'` }),\n overrides: metadata,\n isError: true,\n });\n }\n\n return toolResultResponse({\n text: JSON.stringify({\n outputSchema: tool.outputSchema ?? null,\n }),\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('get_tool_output_schema failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({\n error: `Failed to get output schema: ${error instanceof Error ? error.message : 'unknown'}`,\n }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildCallTool(): ToolDefinition {\n return defineTool({\n name: CALL_TOOL_NAME,\n description: dedent`\n Call a tool on an MCP server.\n The Agent MUST call ${LIST_TOOLS_NAME} and ${GET_TOOL_INFO_NAME} before calling a tool.`,\n schema: callToolSchema,\n handler: async (\n input: { mcp_server: string; tool_name: string; input: Record<string, unknown> },\n approvalDecision?: ApprovalDecision,\n ) => {\n const server = this.resolveServer(input.mcp_server);\n if (!server) {\n return toolResultResponse({\n text: JSON.stringify({ error: `MCP server '${input.mcp_server}' not found` }),\n isError: true,\n });\n }\n\n try {\n const response = await server.callTool({ name: input.tool_name, arguments: input.input }, approvalDecision);\n\n if (isAuthRequired(response)) {\n return response;\n }\n\n if (isApprovalRequiredResponse(response)) {\n return response;\n }\n\n if (!isCallToolResponseResult(response)) {\n throw new Error('Tool call returned an unexpected sub-agent response');\n }\n\n return response;\n } catch (error) {\n this.logger.error('call_tool failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool call failed: ${error instanceof Error ? error.message : 'unknown'}` }),\n isError: true,\n });\n }\n },\n });\n }\n}\n"],"mappings":"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","names":["dedent"]}
@@ -52,7 +52,9 @@ var DeferredTool = class extends LocalToolMCP {
52
52
  buildInstruction(builder) {
53
53
  const servers = [...this.serverMap.values()];
54
54
  const deferredServers = servers.filter((s) => !s.preload);
55
- if (deferredServers.length === 0) return;
55
+ if (deferredServers.length === 0) {
56
+ return;
57
+ }
56
58
  const deferredList = deferredServers.map((s) => s.description ? `- ${s.name}: "${s.description.slice(0, MAX_DESCRIPTION_LENGTH)}"` : `- ${s.name}`).join("\n");
57
59
  builder.addSection(
58
60
  DEFERRED_TOOLS_INSTRUCTION,
@@ -128,7 +130,9 @@ var DeferredTool = class extends LocalToolMCP {
128
130
  handler: async (input) => {
129
131
  try {
130
132
  const resolved = await this.resolveServerTools(input.mcp_server);
131
- if (!isResolvedServerTools(resolved)) return resolved;
133
+ if (!isResolvedServerTools(resolved)) {
134
+ return resolved;
135
+ }
132
136
  const { server, tools, metadata } = resolved;
133
137
  return toolResultResponse({
134
138
  text: `${server.name}:
@@ -159,7 +163,9 @@ var DeferredTool = class extends LocalToolMCP {
159
163
  handler: async (input) => {
160
164
  try {
161
165
  const resolved = await this.resolveServerTools(input.mcp_server);
162
- if (!isResolvedServerTools(resolved)) return resolved;
166
+ if (!isResolvedServerTools(resolved)) {
167
+ return resolved;
168
+ }
163
169
  const { tools, metadata } = resolved;
164
170
  const tool = tools.find((t) => t.name === input.tool_name);
165
171
  if (!tool) {
@@ -205,7 +211,9 @@ var DeferredTool = class extends LocalToolMCP {
205
211
  handler: async (input) => {
206
212
  try {
207
213
  const resolved = await this.resolveServerTools(input.mcp_server);
208
- if (!isResolvedServerTools(resolved)) return resolved;
214
+ if (!isResolvedServerTools(resolved)) {
215
+ return resolved;
216
+ }
209
217
  const { tools, metadata } = resolved;
210
218
  const tool = tools.find((t) => t.name === input.tool_name);
211
219
  if (!tool) {
@@ -257,7 +265,9 @@ var DeferredTool = class extends LocalToolMCP {
257
265
  if (isAuthRequired(response)) {
258
266
  return response;
259
267
  }
260
- if (isApprovalRequiredResponse(response)) return response;
268
+ if (isApprovalRequiredResponse(response)) {
269
+ return response;
270
+ }
261
271
  if (!isCallToolResponseResult(response)) {
262
272
  throw new Error("Tool call returned an unexpected sub-agent response");
263
273
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/runtime/DeferredTool.ts"],"sourcesContent":["import type { CallToolRequest } from '@modelcontextprotocol/sdk/types.js';\nimport dedent from 'dedent';\nimport type { Logger } from 'winston';\nimport { z } from 'zod';\nimport type { ApprovalDecision } from '../events/schema';\nimport { InstructionBuilder } from '../InstructionBuilder';\nimport type { InternalToolCallInfo } from '../llm/LLMTypes';\nimport {\n type AgentToolSchema,\n type CallToolResponse,\n isApprovalRequiredResponse,\n isAuthRequired,\n isCallToolResponseResult,\n type IToolSet,\n type ListToolsResolvedResponse,\n toolResultResponse,\n} from '../mcp/IMCPServer';\nimport { defineTool, LocalToolMCP, type ToolDefinition } from '../mcp/LocalToolMCP';\nimport type { AgentTracing } from '../tracing/AgentTracing';\nimport { extractErrorLogFields } from '../util/errorLogFields';\n\nexport const DEFERRED_TOOLS_SERVER_ID = 'deferred-tools';\nconst DEFERRED_TOOLS_INSTRUCTION = 'deferred-tools-instructions';\nexport const LIST_TOOLS_NAME = 'list_tools';\nexport const GET_TOOL_INFO_NAME = 'get_tool_info';\nexport const GET_TOOL_OUTPUT_SCHEMA_NAME = 'get_tool_output_schema';\nconst CALL_TOOL_NAME = 'call_tool';\nconst MAX_DESCRIPTION_LENGTH = 200;\n\nconst listToolsSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server to list tools for.'),\n});\n\nconst getToolInfoSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to inspect.'),\n});\n\nconst getToolOutputSchemaSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to get output schema for.'),\n});\n\nconst callToolSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to call.'),\n input: z.record(z.string(), z.unknown()).default({}).describe('Arguments to pass to the tool.'),\n});\n\ninterface ResolvedServerTools {\n server: IToolSet;\n tools: AgentToolSchema[];\n metadata: Omit<ListToolsResolvedResponse, 'result'>;\n}\n\nfunction isResolvedServerTools(result: CallToolResponse | ResolvedServerTools): result is ResolvedServerTools {\n return 'tools' in result;\n}\n\nexport class DeferredTool extends LocalToolMCP {\n readonly name = DEFERRED_TOOLS_SERVER_ID;\n readonly displayName = 'DeferredTools';\n override readonly description = 'Deferred tool loading for user MCP servers';\n\n private readonly serverMap: Map<string, IToolSet>;\n private readonly tools: ToolDefinition[];\n private readonly logger: Logger;\n\n constructor(\n servers: readonly IToolSet[],\n options: {\n tracing: AgentTracing;\n logger: Logger;\n },\n ) {\n super({ tracing: options.tracing });\n this.logger = options.logger.child({ module: 'DeferredTool' });\n this.serverMap = new Map(servers.map(s => [s.name, s]));\n this.tools = this.buildTools();\n }\n\n buildInstruction(builder: InstructionBuilder): void {\n const servers = [...this.serverMap.values()];\n\n // Membership follows `preload` only (origin/main). Selective `preload_tools` /\n // `hasPreloadedTools` must not hide a server from deferred discovery instructions.\n const deferredServers = servers.filter(s => !s.preload);\n\n if (deferredServers.length === 0) return;\n\n const deferredList = deferredServers\n .map(s => (s.description ? `- ${s.name}: \"${s.description.slice(0, MAX_DESCRIPTION_LENGTH)}\"` : `- ${s.name}`))\n .join('\\n');\n\n builder.addSection(\n DEFERRED_TOOLS_INSTRUCTION,\n dedent`\n The following MCP servers have deferred tool loading. Their tools are NOT pre-loaded.\n ${deferredList}\n\n The Agent MUST use ${LIST_TOOLS_NAME} and ${GET_TOOL_INFO_NAME} to discover tools before calling them.`,\n );\n }\n\n protected getTools(): ToolDefinition[] {\n return this.tools;\n }\n\n override async toolCallInfo(\n params: CallToolRequest['params'],\n resolveUnderlyingTool?: boolean,\n ): Promise<InternalToolCallInfo> {\n if (params.name !== CALL_TOOL_NAME) {\n return super.toolCallInfo(params, resolveUnderlyingTool);\n }\n if (resolveUnderlyingTool === false) {\n const base = await super.toolCallInfo(params, resolveUnderlyingTool);\n return { ...base, is_deferred: true };\n }\n const parsed = callToolSchema.safeParse(params.arguments);\n if (!parsed.success) {\n this.logger.warn(`Failed to parse call_tool arguments`, {\n tool: params.name,\n errors: parsed.error.issues,\n });\n return { ...(await super.toolCallInfo(params)), is_deferred: true };\n }\n const server = this.resolveServer(parsed.data.mcp_server);\n if (!server) {\n this.logger.warn(`Server not found for toolCallInfo`, {\n mcpServer: parsed.data.mcp_server,\n toolName: parsed.data.tool_name,\n availableServers: [...this.serverMap.keys()],\n });\n return { ...(await super.toolCallInfo(params)), is_deferred: true };\n }\n const underlying = await server.toolCallInfo({\n name: parsed.data.tool_name,\n arguments: parsed.data.input,\n });\n return { ...underlying, is_deferred: true };\n }\n\n private resolveServer(name: string): IToolSet | undefined {\n return this.serverMap.get(name);\n }\n\n private async resolveServerTools(mcpServer: string): Promise<CallToolResponse | ResolvedServerTools> {\n const server = this.resolveServer(mcpServer);\n if (!server) {\n return toolResultResponse({\n text: JSON.stringify({ error: `MCP server '${mcpServer}' not found` }),\n isError: true,\n });\n }\n\n const listResponse = await server.listTools();\n if (isAuthRequired(listResponse)) {\n return listResponse;\n }\n const { result, ...metadata } = listResponse;\n return { server, tools: result.tools, metadata };\n }\n\n private buildTools(): ToolDefinition[] {\n return [this.buildListTools(), this.buildGetToolInfo(), this.buildGetToolOutputSchema(), this.buildCallTool()];\n }\n\n private buildListTools(): ToolDefinition {\n return defineTool({\n name: LIST_TOOLS_NAME,\n description: dedent`\n List tool names available on an MCP server.\n Returns tool names only — use ${GET_TOOL_INFO_NAME} to get full details before calling a tool.`,\n schema: listToolsSchema,\n handler: async (input: { mcp_server: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) return resolved;\n const { server, tools, metadata } = resolved;\n return toolResultResponse({\n text: `${server.name}:\\n ${tools.map(t => t.name).join(', ')}`,\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('list_tools failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n });\n return toolResultResponse({\n text: JSON.stringify({ error: `Failed to list tools for '${input.mcp_server}'.` }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildGetToolInfo(): ToolDefinition {\n return defineTool({\n name: GET_TOOL_INFO_NAME,\n description: dedent`\n Get description, inputSchema and outputSchema for a specific tool on an MCP server.\n If outputSchema is null, it will NOT be present in ${GET_TOOL_OUTPUT_SCHEMA_NAME} as well.\n The Agent MUST call ${LIST_TOOLS_NAME} first to know which tools are available.`,\n schema: getToolInfoSchema,\n handler: async (input: { mcp_server: string; tool_name: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) return resolved;\n const { tools, metadata } = resolved;\n const tool = tools.find(t => t.name === input.tool_name);\n if (!tool) {\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool '${input.tool_name}' not found on server '${input.mcp_server}'` }),\n overrides: metadata,\n isError: true,\n });\n }\n\n return toolResultResponse({\n text: JSON.stringify({\n description: tool.description,\n inputSchema: tool.inputSchema,\n outputSchema: tool.outputSchema ?? null,\n }),\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('get_tool_info failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({\n error: `Failed to get tool info: ${error instanceof Error ? error.message : 'unknown'}`,\n }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildGetToolOutputSchema(): ToolDefinition {\n return defineTool({\n name: GET_TOOL_OUTPUT_SCHEMA_NAME,\n description: dedent`\n Get the outputSchema for a specific tool on an MCP server.\n The Agent MUST not call ${GET_TOOL_OUTPUT_SCHEMA_NAME} and ${GET_TOOL_INFO_NAME} for the same tool.\n The Agent MUST either call ${GET_TOOL_OUTPUT_SCHEMA_NAME} or ${GET_TOOL_INFO_NAME} before entering Code Mode.\n The Agent must NOT assume the structure of a tool's response from its name or description alone.`,\n schema: getToolOutputSchemaSchema,\n handler: async (input: { mcp_server: string; tool_name: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) return resolved;\n const { tools, metadata } = resolved;\n const tool = tools.find(t => t.name === input.tool_name);\n if (!tool) {\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool '${input.tool_name}' not found on server '${input.mcp_server}'` }),\n overrides: metadata,\n isError: true,\n });\n }\n\n return toolResultResponse({\n text: JSON.stringify({\n outputSchema: tool.outputSchema ?? null,\n }),\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('get_tool_output_schema failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({\n error: `Failed to get output schema: ${error instanceof Error ? error.message : 'unknown'}`,\n }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildCallTool(): ToolDefinition {\n return defineTool({\n name: CALL_TOOL_NAME,\n description: dedent`\n Call a tool on an MCP server.\n The Agent MUST call ${LIST_TOOLS_NAME} and ${GET_TOOL_INFO_NAME} before calling a tool.`,\n schema: callToolSchema,\n handler: async (\n input: { mcp_server: string; tool_name: string; input: Record<string, unknown> },\n approvalDecision?: ApprovalDecision,\n ) => {\n const server = this.resolveServer(input.mcp_server);\n if (!server) {\n return toolResultResponse({\n text: JSON.stringify({ error: `MCP server '${input.mcp_server}' not found` }),\n isError: true,\n });\n }\n\n try {\n const response = await server.callTool({ name: input.tool_name, arguments: input.input }, approvalDecision);\n\n if (isAuthRequired(response)) {\n return response;\n }\n\n if (isApprovalRequiredResponse(response)) return response;\n\n if (!isCallToolResponseResult(response)) {\n throw new Error('Tool call returned an unexpected sub-agent response');\n }\n\n return response;\n } catch (error) {\n this.logger.error('call_tool failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool call failed: ${error instanceof Error ? error.message : 'unknown'}` }),\n isError: true,\n });\n }\n },\n });\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/core/runtime/DeferredTool.ts"],"sourcesContent":["import type { CallToolRequest } from '@modelcontextprotocol/sdk/types.js';\nimport dedent from 'dedent';\nimport type { Logger } from 'winston';\nimport { z } from 'zod';\nimport type { ApprovalDecision } from '../events/schema';\nimport { InstructionBuilder } from '../InstructionBuilder';\nimport type { InternalToolCallInfo } from '../llm/LLMTypes';\nimport {\n type AgentToolSchema,\n type CallToolResponse,\n isApprovalRequiredResponse,\n isAuthRequired,\n isCallToolResponseResult,\n type IToolSet,\n type ListToolsResolvedResponse,\n toolResultResponse,\n} from '../mcp/IMCPServer';\nimport { defineTool, LocalToolMCP, type ToolDefinition } from '../mcp/LocalToolMCP';\nimport type { AgentTracing } from '../tracing/AgentTracing';\nimport { extractErrorLogFields } from '../util/errorLogFields';\n\nexport const DEFERRED_TOOLS_SERVER_ID = 'deferred-tools';\nconst DEFERRED_TOOLS_INSTRUCTION = 'deferred-tools-instructions';\nexport const LIST_TOOLS_NAME = 'list_tools';\nexport const GET_TOOL_INFO_NAME = 'get_tool_info';\nexport const GET_TOOL_OUTPUT_SCHEMA_NAME = 'get_tool_output_schema';\nconst CALL_TOOL_NAME = 'call_tool';\nconst MAX_DESCRIPTION_LENGTH = 200;\n\nconst listToolsSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server to list tools for.'),\n});\n\nconst getToolInfoSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to inspect.'),\n});\n\nconst getToolOutputSchemaSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to get output schema for.'),\n});\n\nconst callToolSchema = z.object({\n mcp_server: z.string().describe('Name of the MCP server.'),\n tool_name: z.string().describe('Name of the tool to call.'),\n input: z.record(z.string(), z.unknown()).default({}).describe('Arguments to pass to the tool.'),\n});\n\ninterface ResolvedServerTools {\n server: IToolSet;\n tools: AgentToolSchema[];\n metadata: Omit<ListToolsResolvedResponse, 'result'>;\n}\n\nfunction isResolvedServerTools(result: CallToolResponse | ResolvedServerTools): result is ResolvedServerTools {\n return 'tools' in result;\n}\n\nexport class DeferredTool extends LocalToolMCP {\n readonly name = DEFERRED_TOOLS_SERVER_ID;\n readonly displayName = 'DeferredTools';\n override readonly description = 'Deferred tool loading for user MCP servers';\n\n private readonly serverMap: Map<string, IToolSet>;\n private readonly tools: ToolDefinition[];\n private readonly logger: Logger;\n\n constructor(\n servers: readonly IToolSet[],\n options: {\n tracing: AgentTracing;\n logger: Logger;\n },\n ) {\n super({ tracing: options.tracing });\n this.logger = options.logger.child({ module: 'DeferredTool' });\n this.serverMap = new Map(servers.map(s => [s.name, s]));\n this.tools = this.buildTools();\n }\n\n buildInstruction(builder: InstructionBuilder): void {\n const servers = [...this.serverMap.values()];\n\n // Membership follows `preload` only (origin/main). Selective `preload_tools` /\n // `hasPreloadedTools` must not hide a server from deferred discovery instructions.\n const deferredServers = servers.filter(s => !s.preload);\n\n if (deferredServers.length === 0) {\n return;\n }\n\n const deferredList = deferredServers\n .map(s => (s.description ? `- ${s.name}: \"${s.description.slice(0, MAX_DESCRIPTION_LENGTH)}\"` : `- ${s.name}`))\n .join('\\n');\n\n builder.addSection(\n DEFERRED_TOOLS_INSTRUCTION,\n dedent`\n The following MCP servers have deferred tool loading. Their tools are NOT pre-loaded.\n ${deferredList}\n\n The Agent MUST use ${LIST_TOOLS_NAME} and ${GET_TOOL_INFO_NAME} to discover tools before calling them.`,\n );\n }\n\n protected getTools(): ToolDefinition[] {\n return this.tools;\n }\n\n override async toolCallInfo(\n params: CallToolRequest['params'],\n resolveUnderlyingTool?: boolean,\n ): Promise<InternalToolCallInfo> {\n if (params.name !== CALL_TOOL_NAME) {\n return super.toolCallInfo(params, resolveUnderlyingTool);\n }\n if (resolveUnderlyingTool === false) {\n const base = await super.toolCallInfo(params, resolveUnderlyingTool);\n return { ...base, is_deferred: true };\n }\n const parsed = callToolSchema.safeParse(params.arguments);\n if (!parsed.success) {\n this.logger.warn(`Failed to parse call_tool arguments`, {\n tool: params.name,\n errors: parsed.error.issues,\n });\n return { ...(await super.toolCallInfo(params)), is_deferred: true };\n }\n const server = this.resolveServer(parsed.data.mcp_server);\n if (!server) {\n this.logger.warn(`Server not found for toolCallInfo`, {\n mcpServer: parsed.data.mcp_server,\n toolName: parsed.data.tool_name,\n availableServers: [...this.serverMap.keys()],\n });\n return { ...(await super.toolCallInfo(params)), is_deferred: true };\n }\n const underlying = await server.toolCallInfo({\n name: parsed.data.tool_name,\n arguments: parsed.data.input,\n });\n return { ...underlying, is_deferred: true };\n }\n\n private resolveServer(name: string): IToolSet | undefined {\n return this.serverMap.get(name);\n }\n\n private async resolveServerTools(mcpServer: string): Promise<CallToolResponse | ResolvedServerTools> {\n const server = this.resolveServer(mcpServer);\n if (!server) {\n return toolResultResponse({\n text: JSON.stringify({ error: `MCP server '${mcpServer}' not found` }),\n isError: true,\n });\n }\n\n const listResponse = await server.listTools();\n if (isAuthRequired(listResponse)) {\n return listResponse;\n }\n const { result, ...metadata } = listResponse;\n return { server, tools: result.tools, metadata };\n }\n\n private buildTools(): ToolDefinition[] {\n return [this.buildListTools(), this.buildGetToolInfo(), this.buildGetToolOutputSchema(), this.buildCallTool()];\n }\n\n private buildListTools(): ToolDefinition {\n return defineTool({\n name: LIST_TOOLS_NAME,\n description: dedent`\n List tool names available on an MCP server.\n Returns tool names only — use ${GET_TOOL_INFO_NAME} to get full details before calling a tool.`,\n schema: listToolsSchema,\n handler: async (input: { mcp_server: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) {\n return resolved;\n }\n const { server, tools, metadata } = resolved;\n return toolResultResponse({\n text: `${server.name}:\\n ${tools.map(t => t.name).join(', ')}`,\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('list_tools failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n });\n return toolResultResponse({\n text: JSON.stringify({ error: `Failed to list tools for '${input.mcp_server}'.` }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildGetToolInfo(): ToolDefinition {\n return defineTool({\n name: GET_TOOL_INFO_NAME,\n description: dedent`\n Get description, inputSchema and outputSchema for a specific tool on an MCP server.\n If outputSchema is null, it will NOT be present in ${GET_TOOL_OUTPUT_SCHEMA_NAME} as well.\n The Agent MUST call ${LIST_TOOLS_NAME} first to know which tools are available.`,\n schema: getToolInfoSchema,\n handler: async (input: { mcp_server: string; tool_name: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) {\n return resolved;\n }\n const { tools, metadata } = resolved;\n const tool = tools.find(t => t.name === input.tool_name);\n if (!tool) {\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool '${input.tool_name}' not found on server '${input.mcp_server}'` }),\n overrides: metadata,\n isError: true,\n });\n }\n\n return toolResultResponse({\n text: JSON.stringify({\n description: tool.description,\n inputSchema: tool.inputSchema,\n outputSchema: tool.outputSchema ?? null,\n }),\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('get_tool_info failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({\n error: `Failed to get tool info: ${error instanceof Error ? error.message : 'unknown'}`,\n }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildGetToolOutputSchema(): ToolDefinition {\n return defineTool({\n name: GET_TOOL_OUTPUT_SCHEMA_NAME,\n description: dedent`\n Get the outputSchema for a specific tool on an MCP server.\n The Agent MUST not call ${GET_TOOL_OUTPUT_SCHEMA_NAME} and ${GET_TOOL_INFO_NAME} for the same tool.\n The Agent MUST either call ${GET_TOOL_OUTPUT_SCHEMA_NAME} or ${GET_TOOL_INFO_NAME} before entering Code Mode.\n The Agent must NOT assume the structure of a tool's response from its name or description alone.`,\n schema: getToolOutputSchemaSchema,\n handler: async (input: { mcp_server: string; tool_name: string }) => {\n try {\n const resolved = await this.resolveServerTools(input.mcp_server);\n if (!isResolvedServerTools(resolved)) {\n return resolved;\n }\n const { tools, metadata } = resolved;\n const tool = tools.find(t => t.name === input.tool_name);\n if (!tool) {\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool '${input.tool_name}' not found on server '${input.mcp_server}'` }),\n overrides: metadata,\n isError: true,\n });\n }\n\n return toolResultResponse({\n text: JSON.stringify({\n outputSchema: tool.outputSchema ?? null,\n }),\n overrides: metadata,\n });\n } catch (error) {\n this.logger.error('get_tool_output_schema failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({\n error: `Failed to get output schema: ${error instanceof Error ? error.message : 'unknown'}`,\n }),\n isError: true,\n });\n }\n },\n });\n }\n\n private buildCallTool(): ToolDefinition {\n return defineTool({\n name: CALL_TOOL_NAME,\n description: dedent`\n Call a tool on an MCP server.\n The Agent MUST call ${LIST_TOOLS_NAME} and ${GET_TOOL_INFO_NAME} before calling a tool.`,\n schema: callToolSchema,\n handler: async (\n input: { mcp_server: string; tool_name: string; input: Record<string, unknown> },\n approvalDecision?: ApprovalDecision,\n ) => {\n const server = this.resolveServer(input.mcp_server);\n if (!server) {\n return toolResultResponse({\n text: JSON.stringify({ error: `MCP server '${input.mcp_server}' not found` }),\n isError: true,\n });\n }\n\n try {\n const response = await server.callTool({ name: input.tool_name, arguments: input.input }, approvalDecision);\n\n if (isAuthRequired(response)) {\n return response;\n }\n\n if (isApprovalRequiredResponse(response)) {\n return response;\n }\n\n if (!isCallToolResponseResult(response)) {\n throw new Error('Tool call returned an unexpected sub-agent response');\n }\n\n return response;\n } catch (error) {\n this.logger.error('call_tool failed', {\n ...extractErrorLogFields(error),\n mcpServer: input.mcp_server,\n toolName: input.tool_name,\n });\n return toolResultResponse({\n text: JSON.stringify({ error: `Tool call failed: ${error instanceof Error ? error.message : 'unknown'}` }),\n isError: true,\n });\n }\n },\n });\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"contextUtils.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/contextUtils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAGL,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,cAAc,EACd,cAAc,EACd,QAAQ,EACT,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EACV,2BAA2B,EAC3B,cAAc,EACd,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,eAAO,MAAM,sBAAsB,QAIlC,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,CAE/D;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,GAAG,IAAI,iBAAiB,CAEjF;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAGlE;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,2BAA2B,GAAG,GAAG,IAAI,uBAAuB,CAE1G;AAOD,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,2BAA2B,GAAG,GAAG,IAAI,uBAAuB,CAEhH;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,2BAA2B,GAAG,GAAG,IAAI,qBAAqB,CAEjG;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,2BAA2B,GAAG,GAAG,IAAI,cAAc,CAGxF;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,uBAAuB,GAC7B,KAAK,IAAI,uBAAuB,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAExD;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAQ9F;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,CAS1E;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,oBAAoB,GAAG,QAAQ,CAavE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,gBAAgB,CAGvF;AAED,wBAAgB,0CAA0C,CACxD,OAAO,EAAE,MAAM,GAAG,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,EAClF,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAWR;AAED,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,mBAAmB,CAgChG"}
1
+ {"version":3,"file":"contextUtils.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/contextUtils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAGL,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,cAAc,EACd,cAAc,EACd,QAAQ,EACT,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EACV,2BAA2B,EAC3B,cAAc,EACd,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,eAAO,MAAM,sBAAsB,QAIlC,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,CAE/D;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,GAAG,IAAI,iBAAiB,CAEjF;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAKlE;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,2BAA2B,GAAG,GAAG,IAAI,uBAAuB,CAE1G;AAOD,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,2BAA2B,GAAG,GAAG,IAAI,uBAAuB,CAEhH;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,2BAA2B,GAAG,GAAG,IAAI,qBAAqB,CAEjG;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,2BAA2B,GAAG,GAAG,IAAI,cAAc,CAGxF;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,uBAAuB,GAC7B,KAAK,IAAI,uBAAuB,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAExD;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAQ9F;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,CAS1E;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,oBAAoB,GAAG,QAAQ,CAavE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,gBAAgB,CAGvF;AAED,wBAAgB,0CAA0C,CACxD,OAAO,EAAE,MAAM,GAAG,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,EAClF,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAWR;AAED,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,mBAAmB,CAgChG"}
@@ -71,7 +71,9 @@ function isLLMContextMessage(msg) {
71
71
  return "role" in msg;
72
72
  }
73
73
  function isInternalSystemMessage(m) {
74
- if (!isLLMContextMessage(m)) return false;
74
+ if (!isLLMContextMessage(m)) {
75
+ return false;
76
+ }
75
77
  return m.role === "user" && typeof m.content === "string" && m.content.startsWith(SYSTEM_TAG_START);
76
78
  }
77
79
  function isApprovalDecisionMessage(msg) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/runtime/contextUtils.ts"],"sourcesContent":["import dedent from 'dedent';\nimport type { ApprovalDecision } from '../events/schema';\nimport {\n EventType,\n type AgentApprovalDecisionMessage,\n type UserToolApprovalMessage,\n type UserToolResponseMessage,\n} from '../events/schema';\nimport type {\n EnrichedToolCall,\n InternalEnrichedToolCall,\n InternalToolCallInfo,\n LLMToolMessage,\n LLMUserMessage,\n ToolInfo,\n} from '../llm/LLMTypes';\nimport { UNKNOWN_TOOL_NAME } from '../llm/LLMTypes';\nimport { estimateTokensForString } from '../llm/usage';\nimport type {\n AgentThreadRuntimeSendInput,\n ContextMessage,\n InternalThreadDoneEvent,\n LLMContextMessage,\n} from './AgentThread.types';\nimport type { CurrentContextUsage } from './contextUsage';\nimport type { AgentInputUserMessage } from './UserInputMessage';\n\nexport const SYSTEM_TAG_START = '<tfy-internal>';\nconst SYSTEM_TAG_END = '</tfy-internal>';\nexport const INTERNAL_SYSTEM_PROMPT = dedent`\nMessages wrapped in tfy-internal tags contain information hidden from the user. The Agent must keep this information in mind when conversing with the user.\nThe Agent must never generate any content with tfy-internal tags.\nThe Agent cannot generate any content with tfy-internal tags.\n`;\n\nexport function internalSystemTag(m: string): string {\n return SYSTEM_TAG_START + m + SYSTEM_TAG_END;\n}\n\nexport function internalSystemMessage(m: string): LLMUserMessage {\n return { role: 'user' as const, content: internalSystemTag(m) };\n}\n\nexport function isLLMContextMessage(msg: ContextMessage): msg is LLMContextMessage {\n return 'role' in msg;\n}\n\nexport function isInternalSystemMessage(m: ContextMessage): boolean {\n if (!isLLMContextMessage(m)) return false;\n return m.role === 'user' && typeof m.content === 'string' && m.content.startsWith(SYSTEM_TAG_START);\n}\n\nexport function isApprovalDecisionMessage(msg: AgentThreadRuntimeSendInput): msg is UserToolApprovalMessage {\n return 'type' in msg && msg.type === EventType.USER_TOOL_APPROVAL;\n}\n\nfunction isUserToolApprovalDecisionMessage(msg: ContextMessage): msg is AgentApprovalDecisionMessage {\n // `'type' in msg` already narrows to AgentApprovalDecisionMessage (literal type).\n return 'type' in msg;\n}\n\nexport function isClientSideToolResponseMessage(msg: AgentThreadRuntimeSendInput): msg is UserToolResponseMessage {\n return 'type' in msg && msg.type === EventType.USER_TOOL_RESPONSE;\n}\n\nexport function isInputUserMessage(msg: AgentThreadRuntimeSendInput): msg is AgentInputUserMessage {\n return 'type' in msg && msg.type === EventType.USER_MESSAGE;\n}\n\nexport function isLLMToolMessage(msg: AgentThreadRuntimeSendInput): msg is LLMToolMessage {\n // `'role' in msg` already narrows to LLMToolMessage among AgentThreadRuntimeSendInput.\n return 'role' in msg;\n}\n\nexport function isInternalThreadDoneError(\n event: InternalThreadDoneEvent,\n): event is InternalThreadDoneEvent & { status: 'error' } {\n return event.status === 'error';\n}\n\nexport function scanApprovalDecisions(context: ContextMessage[]): Map<string, ApprovalDecision> {\n const decisions = new Map<string, ApprovalDecision>();\n for (const msg of context) {\n if (isUserToolApprovalDecisionMessage(msg)) {\n decisions.set(msg.tool_call_id, msg.approval);\n }\n }\n return decisions;\n}\n\nexport function makeUnknownToolInfo(toolName: string): InternalToolCallInfo {\n return {\n type: 'mcp',\n mcp_server_id: UNKNOWN_TOOL_NAME,\n mcp_server_name: UNKNOWN_TOOL_NAME,\n original_tool_name: toolName,\n is_approval_required: false,\n is_client_side: false,\n };\n}\n\nexport function toToolCallInfo(toolInfo: InternalToolCallInfo): ToolInfo {\n if (toolInfo.type === 'mcp') {\n return {\n type: toolInfo.type,\n name: toolInfo.original_tool_name,\n server_id: toolInfo.mcp_server_id,\n server_name: toolInfo.mcp_server_name,\n };\n }\n return {\n type: toolInfo.type,\n name: toolInfo.original_tool_name,\n };\n}\n\nexport function toEnrichedToolCall(toolCall: InternalEnrichedToolCall): EnrichedToolCall {\n const { tool_info, ...rest } = toolCall;\n return { ...rest, tool_info: toToolCallInfo(tool_info) };\n}\n\nexport function assistantMessageContentToStringForSubAgent(\n content: string | ({ type?: string; text?: string } | string)[] | null | undefined,\n errorMessage?: string,\n): string {\n let text = '';\n if (typeof content === 'string') {\n text = content;\n } else if (Array.isArray(content)) {\n text = content.map(item => (typeof item === 'string' ? item : JSON.stringify(item))).join('');\n }\n if (errorMessage) {\n return text ? `${errorMessage}\\n${text}` : errorMessage;\n }\n return text;\n}\n\nexport function getThreadId(): string {\n return crypto.randomUUID();\n}\n\nexport function estimateTokensForContextMessages(messages: ContextMessage[]): CurrentContextUsage {\n let tokenCount = 0;\n\n for (const b of messages) {\n if ('content' in b && b.content) {\n if (typeof b.content === 'string') {\n tokenCount += estimateTokensForString(b.content);\n } else if (Array.isArray(b.content)) {\n for (const part of b.content) {\n if ('text' in part && typeof part.text === 'string') {\n tokenCount += estimateTokensForString(part.text);\n }\n }\n }\n }\n\n if ('tool_calls' in b && b.tool_calls) {\n for (const toolCall of b.tool_calls) {\n tokenCount += estimateTokensForString(toolCall.function.name);\n tokenCount += estimateTokensForString(toolCall.function.arguments);\n }\n }\n\n if ('tool_call_id' in b && b.tool_call_id) {\n tokenCount += estimateTokensForString(b.tool_call_id);\n }\n }\n\n return {\n prompt_tokens: tokenCount,\n completion_tokens: 0,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAmB;AAEnB,oBAKO;AASP,sBAAkC;AAClC,mBAAwC;AAUjC,IAAM,mBAAmB;AAChC,IAAM,iBAAiB;AAChB,IAAM,yBAAyB,cAAAA;AAAA;AAAA;AAAA;AAAA;AAM/B,SAAS,kBAAkB,GAAmB;AACnD,SAAO,mBAAmB,IAAI;AAChC;AAEO,SAAS,sBAAsB,GAA2B;AAC/D,SAAO,EAAE,MAAM,QAAiB,SAAS,kBAAkB,CAAC,EAAE;AAChE;AAEO,SAAS,oBAAoB,KAA+C;AACjF,SAAO,UAAU;AACnB;AAEO,SAAS,wBAAwB,GAA4B;AAClE,MAAI,CAAC,oBAAoB,CAAC,EAAG,QAAO;AACpC,SAAO,EAAE,SAAS,UAAU,OAAO,EAAE,YAAY,YAAY,EAAE,QAAQ,WAAW,gBAAgB;AACpG;AAEO,SAAS,0BAA0B,KAAkE;AAC1G,SAAO,UAAU,OAAO,IAAI,SAAS,wBAAU;AACjD;AAEA,SAAS,kCAAkC,KAA0D;AAEnG,SAAO,UAAU;AACnB;AAEO,SAAS,gCAAgC,KAAkE;AAChH,SAAO,UAAU,OAAO,IAAI,SAAS,wBAAU;AACjD;AAEO,SAAS,mBAAmB,KAAgE;AACjG,SAAO,UAAU,OAAO,IAAI,SAAS,wBAAU;AACjD;AAEO,SAAS,iBAAiB,KAAyD;AAExF,SAAO,UAAU;AACnB;AAEO,SAAS,0BACd,OACwD;AACxD,SAAO,MAAM,WAAW;AAC1B;AAEO,SAAS,sBAAsB,SAA0D;AAC9F,QAAM,YAAY,oBAAI,IAA8B;AACpD,aAAW,OAAO,SAAS;AACzB,QAAI,kCAAkC,GAAG,GAAG;AAC1C,gBAAU,IAAI,IAAI,cAAc,IAAI,QAAQ;AAAA,IAC9C;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,oBAAoB,UAAwC;AAC1E,SAAO;AAAA,IACL,MAAM;AAAA,IACN,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,sBAAsB;AAAA,IACtB,gBAAgB;AAAA,EAClB;AACF;AAEO,SAAS,eAAe,UAA0C;AACvE,MAAI,SAAS,SAAS,OAAO;AAC3B,WAAO;AAAA,MACL,MAAM,SAAS;AAAA,MACf,MAAM,SAAS;AAAA,MACf,WAAW,SAAS;AAAA,MACpB,aAAa,SAAS;AAAA,IACxB;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM,SAAS;AAAA,IACf,MAAM,SAAS;AAAA,EACjB;AACF;AAEO,SAAS,mBAAmB,UAAsD;AACvF,QAAM,EAAE,WAAW,GAAG,KAAK,IAAI;AAC/B,SAAO,EAAE,GAAG,MAAM,WAAW,eAAe,SAAS,EAAE;AACzD;AAEO,SAAS,2CACd,SACA,cACQ;AACR,MAAI,OAAO;AACX,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO;AAAA,EACT,WAAW,MAAM,QAAQ,OAAO,GAAG;AACjC,WAAO,QAAQ,IAAI,UAAS,OAAO,SAAS,WAAW,OAAO,KAAK,UAAU,IAAI,CAAE,EAAE,KAAK,EAAE;AAAA,EAC9F;AACA,MAAI,cAAc;AAChB,WAAO,OAAO,GAAG,YAAY;AAAA,EAAK,IAAI,KAAK;AAAA,EAC7C;AACA,SAAO;AACT;AAEO,SAAS,cAAsB;AACpC,SAAO,OAAO,WAAW;AAC3B;AAEO,SAAS,iCAAiC,UAAiD;AAChG,MAAI,aAAa;AAEjB,aAAW,KAAK,UAAU;AACxB,QAAI,aAAa,KAAK,EAAE,SAAS;AAC/B,UAAI,OAAO,EAAE,YAAY,UAAU;AACjC,0BAAc,sCAAwB,EAAE,OAAO;AAAA,MACjD,WAAW,MAAM,QAAQ,EAAE,OAAO,GAAG;AACnC,mBAAW,QAAQ,EAAE,SAAS;AAC5B,cAAI,UAAU,QAAQ,OAAO,KAAK,SAAS,UAAU;AACnD,8BAAc,sCAAwB,KAAK,IAAI;AAAA,UACjD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,gBAAgB,KAAK,EAAE,YAAY;AACrC,iBAAW,YAAY,EAAE,YAAY;AACnC,0BAAc,sCAAwB,SAAS,SAAS,IAAI;AAC5D,0BAAc,sCAAwB,SAAS,SAAS,SAAS;AAAA,MACnE;AAAA,IACF;AAEA,QAAI,kBAAkB,KAAK,EAAE,cAAc;AACzC,wBAAc,sCAAwB,EAAE,YAAY;AAAA,IACtD;AAAA,EACF;AAEA,SAAO;AAAA,IACL,eAAe;AAAA,IACf,mBAAmB;AAAA,EACrB;AACF;","names":["dedent"]}
1
+ {"version":3,"sources":["../../../src/core/runtime/contextUtils.ts"],"sourcesContent":["import dedent from 'dedent';\nimport type { ApprovalDecision } from '../events/schema';\nimport {\n EventType,\n type AgentApprovalDecisionMessage,\n type UserToolApprovalMessage,\n type UserToolResponseMessage,\n} from '../events/schema';\nimport type {\n EnrichedToolCall,\n InternalEnrichedToolCall,\n InternalToolCallInfo,\n LLMToolMessage,\n LLMUserMessage,\n ToolInfo,\n} from '../llm/LLMTypes';\nimport { UNKNOWN_TOOL_NAME } from '../llm/LLMTypes';\nimport { estimateTokensForString } from '../llm/usage';\nimport type {\n AgentThreadRuntimeSendInput,\n ContextMessage,\n InternalThreadDoneEvent,\n LLMContextMessage,\n} from './AgentThread.types';\nimport type { CurrentContextUsage } from './contextUsage';\nimport type { AgentInputUserMessage } from './UserInputMessage';\n\nexport const SYSTEM_TAG_START = '<tfy-internal>';\nconst SYSTEM_TAG_END = '</tfy-internal>';\nexport const INTERNAL_SYSTEM_PROMPT = dedent`\nMessages wrapped in tfy-internal tags contain information hidden from the user. The Agent must keep this information in mind when conversing with the user.\nThe Agent must never generate any content with tfy-internal tags.\nThe Agent cannot generate any content with tfy-internal tags.\n`;\n\nexport function internalSystemTag(m: string): string {\n return SYSTEM_TAG_START + m + SYSTEM_TAG_END;\n}\n\nexport function internalSystemMessage(m: string): LLMUserMessage {\n return { role: 'user' as const, content: internalSystemTag(m) };\n}\n\nexport function isLLMContextMessage(msg: ContextMessage): msg is LLMContextMessage {\n return 'role' in msg;\n}\n\nexport function isInternalSystemMessage(m: ContextMessage): boolean {\n if (!isLLMContextMessage(m)) {\n return false;\n }\n return m.role === 'user' && typeof m.content === 'string' && m.content.startsWith(SYSTEM_TAG_START);\n}\n\nexport function isApprovalDecisionMessage(msg: AgentThreadRuntimeSendInput): msg is UserToolApprovalMessage {\n return 'type' in msg && msg.type === EventType.USER_TOOL_APPROVAL;\n}\n\nfunction isUserToolApprovalDecisionMessage(msg: ContextMessage): msg is AgentApprovalDecisionMessage {\n // `'type' in msg` already narrows to AgentApprovalDecisionMessage (literal type).\n return 'type' in msg;\n}\n\nexport function isClientSideToolResponseMessage(msg: AgentThreadRuntimeSendInput): msg is UserToolResponseMessage {\n return 'type' in msg && msg.type === EventType.USER_TOOL_RESPONSE;\n}\n\nexport function isInputUserMessage(msg: AgentThreadRuntimeSendInput): msg is AgentInputUserMessage {\n return 'type' in msg && msg.type === EventType.USER_MESSAGE;\n}\n\nexport function isLLMToolMessage(msg: AgentThreadRuntimeSendInput): msg is LLMToolMessage {\n // `'role' in msg` already narrows to LLMToolMessage among AgentThreadRuntimeSendInput.\n return 'role' in msg;\n}\n\nexport function isInternalThreadDoneError(\n event: InternalThreadDoneEvent,\n): event is InternalThreadDoneEvent & { status: 'error' } {\n return event.status === 'error';\n}\n\nexport function scanApprovalDecisions(context: ContextMessage[]): Map<string, ApprovalDecision> {\n const decisions = new Map<string, ApprovalDecision>();\n for (const msg of context) {\n if (isUserToolApprovalDecisionMessage(msg)) {\n decisions.set(msg.tool_call_id, msg.approval);\n }\n }\n return decisions;\n}\n\nexport function makeUnknownToolInfo(toolName: string): InternalToolCallInfo {\n return {\n type: 'mcp',\n mcp_server_id: UNKNOWN_TOOL_NAME,\n mcp_server_name: UNKNOWN_TOOL_NAME,\n original_tool_name: toolName,\n is_approval_required: false,\n is_client_side: false,\n };\n}\n\nexport function toToolCallInfo(toolInfo: InternalToolCallInfo): ToolInfo {\n if (toolInfo.type === 'mcp') {\n return {\n type: toolInfo.type,\n name: toolInfo.original_tool_name,\n server_id: toolInfo.mcp_server_id,\n server_name: toolInfo.mcp_server_name,\n };\n }\n return {\n type: toolInfo.type,\n name: toolInfo.original_tool_name,\n };\n}\n\nexport function toEnrichedToolCall(toolCall: InternalEnrichedToolCall): EnrichedToolCall {\n const { tool_info, ...rest } = toolCall;\n return { ...rest, tool_info: toToolCallInfo(tool_info) };\n}\n\nexport function assistantMessageContentToStringForSubAgent(\n content: string | ({ type?: string; text?: string } | string)[] | null | undefined,\n errorMessage?: string,\n): string {\n let text = '';\n if (typeof content === 'string') {\n text = content;\n } else if (Array.isArray(content)) {\n text = content.map(item => (typeof item === 'string' ? item : JSON.stringify(item))).join('');\n }\n if (errorMessage) {\n return text ? `${errorMessage}\\n${text}` : errorMessage;\n }\n return text;\n}\n\nexport function getThreadId(): string {\n return crypto.randomUUID();\n}\n\nexport function estimateTokensForContextMessages(messages: ContextMessage[]): CurrentContextUsage {\n let tokenCount = 0;\n\n for (const b of messages) {\n if ('content' in b && b.content) {\n if (typeof b.content === 'string') {\n tokenCount += estimateTokensForString(b.content);\n } else if (Array.isArray(b.content)) {\n for (const part of b.content) {\n if ('text' in part && typeof part.text === 'string') {\n tokenCount += estimateTokensForString(part.text);\n }\n }\n }\n }\n\n if ('tool_calls' in b && b.tool_calls) {\n for (const toolCall of b.tool_calls) {\n tokenCount += estimateTokensForString(toolCall.function.name);\n tokenCount += estimateTokensForString(toolCall.function.arguments);\n }\n }\n\n if ('tool_call_id' in b && b.tool_call_id) {\n tokenCount += estimateTokensForString(b.tool_call_id);\n }\n }\n\n return {\n prompt_tokens: tokenCount,\n completion_tokens: 0,\n };\n}\n"],"mappings":"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","names":["dedent"]}
@@ -22,7 +22,9 @@ function isLLMContextMessage(msg) {
22
22
  return "role" in msg;
23
23
  }
24
24
  function isInternalSystemMessage(m) {
25
- if (!isLLMContextMessage(m)) return false;
25
+ if (!isLLMContextMessage(m)) {
26
+ return false;
27
+ }
26
28
  return m.role === "user" && typeof m.content === "string" && m.content.startsWith(SYSTEM_TAG_START);
27
29
  }
28
30
  function isApprovalDecisionMessage(msg) {