@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.
- package/README.md +27 -0
- package/dist/agent-session/TurnResourceResolver.d.ts.map +1 -1
- package/dist/agent-session/TurnResourceResolver.js +6 -2
- package/dist/agent-session/TurnResourceResolver.js.map +1 -1
- package/dist/agent-session/TurnResourceResolver.mjs +6 -2
- package/dist/agent-session/TurnResourceResolver.mjs.map +1 -1
- package/dist/agent-session/schemas/turn.d.ts.map +1 -1
- package/dist/agent-session/schemas/turn.js +3 -1
- package/dist/agent-session/schemas/turn.js.map +1 -1
- package/dist/agent-session/schemas/turn.mjs +3 -1
- package/dist/agent-session/schemas/turn.mjs.map +1 -1
- package/dist/agent-session/store/InMemorySessionStore.d.ts.map +1 -1
- package/dist/agent-session/store/InMemorySessionStore.js +24 -8
- package/dist/agent-session/store/InMemorySessionStore.js.map +1 -1
- package/dist/agent-session/store/InMemorySessionStore.mjs +24 -8
- package/dist/agent-session/store/InMemorySessionStore.mjs.map +1 -1
- package/dist/agent-session/store/OffsetPageToken.d.ts.map +1 -1
- package/dist/agent-session/store/OffsetPageToken.js +3 -1
- package/dist/agent-session/store/OffsetPageToken.js.map +1 -1
- package/dist/agent-session/store/OffsetPageToken.mjs +3 -1
- package/dist/agent-session/store/OffsetPageToken.mjs.map +1 -1
- package/dist/agent-session/store/SessionListPageToken.d.ts.map +1 -1
- package/dist/agent-session/store/SessionListPageToken.js +3 -1
- package/dist/agent-session/store/SessionListPageToken.js.map +1 -1
- package/dist/agent-session/store/SessionListPageToken.mjs +3 -1
- package/dist/agent-session/store/SessionListPageToken.mjs.map +1 -1
- package/dist/core/InstructionBuilder.d.ts.map +1 -1
- package/dist/core/InstructionBuilder.js +12 -4
- package/dist/core/InstructionBuilder.js.map +1 -1
- package/dist/core/InstructionBuilder.mjs +12 -4
- package/dist/core/InstructionBuilder.mjs.map +1 -1
- package/dist/core/capabilities/builtins/AskUserQuestion.d.ts.map +1 -1
- package/dist/core/capabilities/builtins/AskUserQuestion.js +5 -0
- package/dist/core/capabilities/builtins/AskUserQuestion.js.map +1 -1
- package/dist/core/capabilities/builtins/AskUserQuestion.mjs +5 -0
- package/dist/core/capabilities/builtins/AskUserQuestion.mjs.map +1 -1
- package/dist/core/capabilities/builtins/LargeToolResponse.d.ts.map +1 -1
- package/dist/core/capabilities/builtins/LargeToolResponse.js +6 -2
- package/dist/core/capabilities/builtins/LargeToolResponse.js.map +1 -1
- package/dist/core/capabilities/builtins/LargeToolResponse.mjs +6 -2
- package/dist/core/capabilities/builtins/LargeToolResponse.mjs.map +1 -1
- package/dist/core/index.d.ts +9 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +25 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +24 -2
- package/dist/core/index.mjs.map +1 -1
- package/dist/core/llm/VercelAILLM.d.ts +1 -0
- package/dist/core/llm/VercelAILLM.d.ts.map +1 -1
- package/dist/core/llm/VercelAILLM.js +13 -14
- package/dist/core/llm/VercelAILLM.js.map +1 -1
- package/dist/core/llm/VercelAILLM.mjs +13 -15
- package/dist/core/llm/VercelAILLM.mjs.map +1 -1
- package/dist/core/mcp/RemoteMCP.d.ts.map +1 -1
- package/dist/core/mcp/RemoteMCP.js +15 -5
- package/dist/core/mcp/RemoteMCP.js.map +1 -1
- package/dist/core/mcp/RemoteMCP.mjs +15 -5
- package/dist/core/mcp/RemoteMCP.mjs.map +1 -1
- package/dist/core/mcp/ToolSelectorPolicy.d.ts.map +1 -1
- package/dist/core/mcp/ToolSelectorPolicy.js +3 -1
- package/dist/core/mcp/ToolSelectorPolicy.js.map +1 -1
- package/dist/core/mcp/ToolSelectorPolicy.mjs +3 -1
- package/dist/core/mcp/ToolSelectorPolicy.mjs.map +1 -1
- package/dist/core/mcp/ToolSet.d.ts.map +1 -1
- package/dist/core/mcp/ToolSet.js +9 -3
- package/dist/core/mcp/ToolSet.js.map +1 -1
- package/dist/core/mcp/ToolSet.mjs +9 -3
- package/dist/core/mcp/ToolSet.mjs.map +1 -1
- package/dist/core/mcp/convertMCPServers.d.ts.map +1 -1
- package/dist/core/mcp/convertMCPServers.js +6 -2
- package/dist/core/mcp/convertMCPServers.js.map +1 -1
- package/dist/core/mcp/convertMCPServers.mjs +6 -2
- package/dist/core/mcp/convertMCPServers.mjs.map +1 -1
- package/dist/core/mcp/remoteMcpClient.d.ts.map +1 -1
- package/dist/core/mcp/remoteMcpClient.js +21 -7
- package/dist/core/mcp/remoteMcpClient.js.map +1 -1
- package/dist/core/mcp/remoteMcpClient.mjs +21 -7
- package/dist/core/mcp/remoteMcpClient.mjs.map +1 -1
- package/dist/core/mcp/toolSelectors.d.ts.map +1 -1
- package/dist/core/mcp/toolSelectors.js +18 -6
- package/dist/core/mcp/toolSelectors.js.map +1 -1
- package/dist/core/mcp/toolSelectors.mjs +18 -6
- package/dist/core/mcp/toolSelectors.mjs.map +1 -1
- package/dist/core/runtime/AgentThread.d.ts.map +1 -1
- package/dist/core/runtime/AgentThread.js +45 -15
- package/dist/core/runtime/AgentThread.js.map +1 -1
- package/dist/core/runtime/AgentThread.mjs +45 -15
- package/dist/core/runtime/AgentThread.mjs.map +1 -1
- package/dist/core/runtime/AgentThreadOrchestrator.d.ts.map +1 -1
- package/dist/core/runtime/AgentThreadOrchestrator.js +27 -9
- package/dist/core/runtime/AgentThreadOrchestrator.js.map +1 -1
- package/dist/core/runtime/AgentThreadOrchestrator.mjs +27 -9
- package/dist/core/runtime/AgentThreadOrchestrator.mjs.map +1 -1
- package/dist/core/runtime/DeferredTool.d.ts.map +1 -1
- package/dist/core/runtime/DeferredTool.js +15 -5
- package/dist/core/runtime/DeferredTool.js.map +1 -1
- package/dist/core/runtime/DeferredTool.mjs +15 -5
- package/dist/core/runtime/DeferredTool.mjs.map +1 -1
- package/dist/core/runtime/contextUtils.d.ts.map +1 -1
- package/dist/core/runtime/contextUtils.js +3 -1
- package/dist/core/runtime/contextUtils.js.map +1 -1
- package/dist/core/runtime/contextUtils.mjs +3 -1
- package/dist/core/runtime/contextUtils.mjs.map +1 -1
- package/dist/core/sandbox/Sandbox.d.ts +7 -9
- package/dist/core/sandbox/Sandbox.d.ts.map +1 -1
- package/dist/core/sandbox/Sandbox.js +55 -63
- package/dist/core/sandbox/Sandbox.js.map +1 -1
- package/dist/core/sandbox/Sandbox.mjs +56 -64
- package/dist/core/sandbox/Sandbox.mjs.map +1 -1
- package/dist/core/sandbox/codeMode/CodeModeDispatcher.d.ts +29 -0
- package/dist/core/sandbox/codeMode/CodeModeDispatcher.d.ts.map +1 -0
- package/dist/core/sandbox/codeMode/CodeModeDispatcher.js +134 -0
- package/dist/core/sandbox/codeMode/CodeModeDispatcher.js.map +1 -0
- package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs +113 -0
- package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs.map +1 -0
- package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts +21 -0
- package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts.map +1 -0
- package/dist/core/sandbox/codeMode/CodeModeTransport.js +19 -0
- package/dist/core/sandbox/codeMode/CodeModeTransport.js.map +1 -0
- package/dist/core/sandbox/codeMode/CodeModeTransport.mjs +1 -0
- package/dist/core/sandbox/codeMode/CodeModeTransport.mjs.map +1 -0
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts +34 -0
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts.map +1 -0
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js +193 -0
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js.map +1 -0
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs +168 -0
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs.map +1 -0
- package/dist/core/sandbox/codeMode/types.d.ts +34 -0
- package/dist/core/sandbox/codeMode/types.d.ts.map +1 -0
- package/dist/core/sandbox/codeMode/types.js +59 -0
- package/dist/core/sandbox/codeMode/types.js.map +1 -0
- package/dist/core/sandbox/codeMode/types.mjs +32 -0
- package/dist/core/sandbox/codeMode/types.mjs.map +1 -0
- package/dist/core/sandbox/provider/DaytonaProvider.d.ts +19 -1
- package/dist/core/sandbox/provider/DaytonaProvider.d.ts.map +1 -1
- package/dist/core/sandbox/provider/DaytonaProvider.js +96 -23
- package/dist/core/sandbox/provider/DaytonaProvider.js.map +1 -1
- package/dist/core/sandbox/provider/DaytonaProvider.mjs +96 -23
- package/dist/core/sandbox/provider/DaytonaProvider.mjs.map +1 -1
- package/dist/core/sandbox/provider/Provider.d.ts +4 -3
- package/dist/core/sandbox/provider/Provider.d.ts.map +1 -1
- package/dist/core/sandbox/provider/Provider.js.map +1 -1
- package/dist/core/sandbox/provider/Provider.mjs.map +1 -1
- package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts +2 -1
- package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts.map +1 -1
- package/dist/core/sandbox/provider/TFYSandboxProvider.js +20 -6
- package/dist/core/sandbox/provider/TFYSandboxProvider.js.map +1 -1
- package/dist/core/sandbox/provider/TFYSandboxProvider.mjs +20 -6
- package/dist/core/sandbox/provider/TFYSandboxProvider.mjs.map +1 -1
- package/dist/core/sandbox/sandboxImage.d.ts +1 -1
- package/dist/core/sandbox/sandboxImage.d.ts.map +1 -1
- package/dist/core/sandbox/sandboxImage.js +1 -1
- package/dist/core/sandbox/sandboxImage.js.map +1 -1
- package/dist/core/sandbox/sandboxImage.mjs +1 -1
- package/dist/core/sandbox/sandboxImage.mjs.map +1 -1
- package/dist/core/sandbox/sandboxScripts.gen.d.ts +1 -1
- package/dist/core/sandbox/sandboxScripts.gen.d.ts.map +1 -1
- package/dist/core/sandbox/sandboxScripts.gen.js +8 -8
- package/dist/core/sandbox/sandboxScripts.gen.js.map +1 -1
- package/dist/core/sandbox/sandboxScripts.gen.mjs +8 -8
- package/dist/core/sandbox/sandboxScripts.gen.mjs.map +1 -1
- package/dist/core/sandbox/skills/SkillMounter.d.ts.map +1 -1
- package/dist/core/sandbox/skills/SkillMounter.js +3 -1
- package/dist/core/sandbox/skills/SkillMounter.js.map +1 -1
- package/dist/core/sandbox/skills/SkillMounter.mjs +3 -1
- package/dist/core/sandbox/skills/SkillMounter.mjs.map +1 -1
- package/dist/core/util/abort.d.ts.map +1 -1
- package/dist/core/util/abort.js +3 -1
- package/dist/core/util/abort.js.map +1 -1
- package/dist/core/util/abort.mjs +3 -1
- package/dist/core/util/abort.mjs.map +1 -1
- package/dist/core/util/errorLogFields.d.ts +5 -0
- package/dist/core/util/errorLogFields.d.ts.map +1 -1
- package/dist/core/util/errorLogFields.js +38 -2
- package/dist/core/util/errorLogFields.js.map +1 -1
- package/dist/core/util/errorLogFields.mjs +37 -2
- package/dist/core/util/errorLogFields.mjs.map +1 -1
- package/package.json +10 -6
- package/dist/core/sandbox/SandboxNatsBridge.d.ts +0 -33
- package/dist/core/sandbox/SandboxNatsBridge.d.ts.map +0 -1
- package/dist/core/sandbox/SandboxNatsBridge.js +0 -222
- package/dist/core/sandbox/SandboxNatsBridge.js.map +0 -1
- package/dist/core/sandbox/SandboxNatsBridge.mjs +0 -201
- 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)
|
|
26
|
-
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
379
|
-
|
|
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":"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","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,
|
|
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)
|
|
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))
|
|
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))
|
|
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))
|
|
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))
|
|
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)
|
|
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))
|
|
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))
|
|
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))
|
|
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))
|
|
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,
|
|
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))
|
|
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,
|
|
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))
|
|
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) {
|