@better-agent/core 0.1.0-beta.2 → 0.1.0-beta.4

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.
@@ -45,7 +45,7 @@ const runAgentLoop = async (options, strategy) => {
45
45
  conversationId: options.conversationId,
46
46
  context: options.context
47
47
  };
48
- const instructionField = "instruction" in options.agent ? options.agent.instruction : void 0;
48
+ const instructionField = options.agent.instruction;
49
49
  const instructionResolver = instructionField;
50
50
  const instruction = typeof instructionResolver === "function" ? instructionResolver(options.context) : instructionField ?? "";
51
51
  const modelCaps = options.agent.model.caps;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-loop.mjs","names":[],"sources":["../../src/run/agent-loop.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { Events } from \"../events\";\nimport type { GenerativeModelInputMessage, GenerativeModelInputMessageContent } from \"../providers\";\nimport type { ConversationItem } from \"../providers\";\nimport { resolveToolsForRun } from \"../tools\";\nimport { executeToolCalls } from \"./execute-tool-calls\";\nimport { prepareConversationReplayInput } from \"./helpers\";\nimport { applyAfterModelCall, applyBeforeModelCall, applyOnStep, applyOnStepFinish } from \"./hooks\";\nimport { projectConversationItemsToInput } from \"./messages\";\nimport {\n type LoopStopDecision,\n evaluateStopConditions,\n extractToolCallRequests,\n} from \"./stop-conditions\";\nimport type {\n LoopState,\n ModelCallStrategy,\n PreviousStepResult,\n RunResult,\n SharedRunLoopOptions,\n} from \"./types\";\n\nexport const runAgentLoop = async <TContext>(\n options: SharedRunLoopOptions<TContext>,\n strategy: ModelCallStrategy<TContext>,\n): Promise<RunResult & { items: ConversationItem[] }> => {\n const traceBase = strategy.mode === \"stream\" ? \"core.run.runStreamLoop\" : \"core.run.runLoop\";\n\n // Resolve plugin tools.\n const pluginToolsResult =\n options.pluginRuntime?.hasTools === true\n ? await options.pluginRuntime.resolveTools(options.context)\n : {\n tools: [],\n runCleanup: async () => {},\n };\n\n // Resolve agent tools.\n const { tools, runCleanup } = await resolveToolsForRun({\n appTools: options.appTools,\n agentTools: options.agent.tools,\n context: options.context,\n });\n\n const resolvedTools = [...tools, ...pluginToolsResult.tools];\n\n if (strategy.mode === \"run\") {\n const blockingTool = resolvedTools.find(\n (tool) =>\n tool.kind === \"client\" || (tool.kind !== \"hosted\" && tool.approval !== undefined),\n );\n\n if (blockingTool) {\n const reason =\n blockingTool.kind === \"client\"\n ? `client tool '${blockingTool.name}'`\n : `approval-gated tool '${blockingTool.name}'`;\n\n throw BetterAgentError.fromCode(\n \"BAD_REQUEST\",\n `Non-stream runs do not support interactive tools. Use stream() for ${reason}.`,\n {\n context: {\n agentName: options.agent.name,\n toolName: blockingTool.name,\n toolTarget: blockingTool.kind,\n },\n trace: [{ at: `${traceBase}.validateNonInteractiveRun` }],\n },\n );\n }\n }\n\n const state: LoopState<TContext> = {\n runId: options.runId,\n agentName: options.agent.name,\n items: [...options.items],\n replayStartIndex: options.replayStartIndex ?? 0,\n steps: [],\n stepIndex: 0,\n maxSteps: options.maxSteps,\n conversationId: options.conversationId,\n context: options.context,\n };\n\n const instructionField = \"instruction\" in options.agent ? options.agent.instruction : undefined;\n const instructionResolver = instructionField as ((context: TContext) => string) | undefined;\n const instruction =\n typeof instructionResolver === \"function\"\n ? instructionResolver(options.context as TContext)\n : (instructionField ?? \"\");\n\n const modelCaps = options.agent.model.caps;\n\n const assertInstructionSupported = (\n currentInstruction: GenerativeModelInputMessageContent<typeof modelCaps> | undefined,\n traceAt: string,\n ): void => {\n if (currentInstruction === undefined || currentInstruction === \"\") {\n return;\n }\n\n if (modelCaps.inputShape === \"prompt\" || modelCaps.supportsInstruction !== true) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Agent '${options.agent.name}' model does not support instructions.`,\n {\n context: {\n agentName: options.agent.name,\n modelId: options.agent.model.modelId,\n inputShape: modelCaps.inputShape ?? \"chat\",\n replayMode:\n modelCaps.replayMode ??\n (modelCaps.inputShape === \"prompt\"\n ? \"single_turn_persistent\"\n : \"multi_turn\"),\n },\n trace: [{ at: traceAt }],\n },\n );\n }\n };\n\n assertInstructionSupported(instruction, `${traceBase}.validateInstruction`);\n\n const stepErrorMessage =\n strategy.mode === \"stream\" ? \"Run stream step failed\" : \"Run loop step failed\";\n\n try {\n while (true) {\n const previousStep = state.steps.at(-1);\n const replayItems = state.items.slice(state.replayStartIndex);\n const projectedMessages =\n state.conversationId !== undefined && options.conversationReplayActive\n ? await prepareConversationReplayInput({\n items: replayItems,\n caps: modelCaps,\n agentName: state.agentName,\n conversationId: state.conversationId,\n conversationReplay: options.conversationReplay,\n })\n : projectConversationItemsToInput(replayItems, modelCaps);\n const prepared = await applyOnStep({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n messages: projectedMessages,\n modelCaps,\n conversationId: state.conversationId,\n context: options.context,\n previousStep,\n onStep: options.agent.onStep,\n pluginRuntime: options.pluginRuntime,\n });\n\n await options.emit({\n type: Events.STEP_START,\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n timestamp: Date.now(),\n conversationId: state.conversationId,\n });\n\n try {\n const activeToolNames = prepared.activeTools;\n const activeTools =\n activeToolNames === undefined\n ? resolvedTools\n : resolvedTools.filter((tool) =>\n activeToolNames.includes(\n tool.kind === \"hosted\"\n ? typeof tool.name === \"string\" && tool.name.length > 0\n ? tool.name\n : tool.type\n : tool.name,\n ),\n );\n\n const effectiveInstruction = (prepared.systemInstruction ?? instruction) as\n | GenerativeModelInputMessageContent<typeof modelCaps>\n | undefined;\n assertInstructionSupported(\n effectiveInstruction,\n `${traceBase}.prepareModelInput.validateInstruction`,\n );\n const modelInput =\n effectiveInstruction === undefined || effectiveInstruction === \"\"\n ? [...prepared.messages]\n : [\n {\n type: \"message\",\n role: \"system\",\n content: effectiveInstruction,\n } as GenerativeModelInputMessage<typeof modelCaps>,\n ...prepared.messages,\n ];\n\n const modelPrepared = await applyBeforeModelCall({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n modelCaps,\n input: modelInput,\n tools: activeTools,\n conversationId: state.conversationId,\n toolChoice: prepared.toolChoice ?? options.toolChoice,\n pluginRuntime: options.pluginRuntime,\n });\n\n const { response, assistantMessageId } = await strategy.call({\n options,\n modelInput: modelPrepared.input,\n tools: modelPrepared.tools,\n toolChoice: modelPrepared.toolChoice,\n stepIndex: state.stepIndex,\n runId: state.runId,\n agentName: state.agentName,\n conversationId: state.conversationId,\n });\n\n await applyAfterModelCall({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n response,\n conversationId: state.conversationId,\n pluginRuntime: options.pluginRuntime,\n });\n\n const toolCalls = extractToolCallRequests(response);\n const toolBatch =\n toolCalls.length > 0\n ? await executeToolCalls({\n runId: state.runId,\n agentName: state.agentName,\n conversationId: state.conversationId,\n parentMessageId: assistantMessageId,\n toolCalls,\n tools: modelPrepared.tools,\n toolErrorMode: options.agent.toolErrorMode,\n onToolError: options.agent.onToolError,\n signal: options.signal,\n emit: options.emit,\n advanced: options.advanced,\n pendingToolRuntime: options.pendingToolRuntime,\n context: options.context,\n pluginRuntime: options.pluginRuntime,\n })\n : { results: [] };\n\n state.items = [...state.items, ...response.output];\n if (toolBatch.results.length > 0) {\n state.items = [...state.items, ...toolBatch.results];\n }\n\n const stepResult: PreviousStepResult = { response };\n state.steps.push(stepResult);\n\n const stopMessages =\n state.conversationId !== undefined && options.conversationReplayActive\n ? await prepareConversationReplayInput({\n items: state.items.slice(state.replayStartIndex),\n caps: modelCaps,\n agentName: state.agentName,\n conversationId: state.conversationId,\n conversationReplay: options.conversationReplay,\n })\n : projectConversationItemsToInput(\n state.items.slice(state.replayStartIndex),\n modelCaps,\n );\n\n const stopDecision: LoopStopDecision = evaluateStopConditions({\n maxSteps: state.maxSteps,\n stepIndex: state.stepIndex,\n steps: state.steps,\n messages: stopMessages,\n lastStep: stepResult,\n stopWhen: options.agent.stopWhen,\n context: options.context,\n });\n\n await options.emit({\n type: Events.STEP_FINISH,\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n toolCallCount: toolCalls.length,\n terminationReason: stopDecision.stop ? stopDecision.reason : undefined,\n timestamp: Date.now(),\n conversationId: state.conversationId,\n });\n\n await applyOnStepFinish({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n result: stepResult,\n conversationId: state.conversationId,\n context: options.context,\n onStepFinish: options.agent.onStepFinish,\n });\n\n if (stopDecision.stop) {\n return {\n response,\n items: state.items,\n };\n }\n\n state.stepIndex += 1;\n } catch (error) {\n const wrapped =\n error instanceof BetterAgentError\n ? error.at({ at: traceBase })\n : BetterAgentError.wrap({\n err: error,\n message: stepErrorMessage,\n opts: {\n code: \"INTERNAL\",\n trace: [{ at: traceBase }],\n },\n });\n await options.emit({\n type: Events.STEP_ERROR,\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n error: wrapped,\n timestamp: Date.now(),\n conversationId: state.conversationId,\n });\n throw wrapped;\n }\n }\n } finally {\n await runCleanup();\n await pluginToolsResult.runCleanup();\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent-loop.mjs","names":[],"sources":["../../src/run/agent-loop.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { Events } from \"../events\";\nimport type { GenerativeModelInputMessage, GenerativeModelInputMessageContent } from \"../providers\";\nimport type { ConversationItem } from \"../providers\";\nimport { resolveToolsForRun } from \"../tools\";\nimport { executeToolCalls } from \"./execute-tool-calls\";\nimport { prepareConversationReplayInput } from \"./helpers\";\nimport { applyAfterModelCall, applyBeforeModelCall, applyOnStep, applyOnStepFinish } from \"./hooks\";\nimport { projectConversationItemsToInput } from \"./messages\";\nimport {\n type LoopStopDecision,\n evaluateStopConditions,\n extractToolCallRequests,\n} from \"./stop-conditions\";\nimport type {\n LoopState,\n ModelCallStrategy,\n PreviousStepResult,\n RunResult,\n SharedRunLoopOptions,\n} from \"./types\";\n\nexport const runAgentLoop = async <TContext>(\n options: SharedRunLoopOptions<TContext>,\n strategy: ModelCallStrategy<TContext>,\n): Promise<RunResult & { items: ConversationItem[] }> => {\n const traceBase = strategy.mode === \"stream\" ? \"core.run.runStreamLoop\" : \"core.run.runLoop\";\n\n // Resolve plugin tools.\n const pluginToolsResult =\n options.pluginRuntime?.hasTools === true\n ? await options.pluginRuntime.resolveTools(options.context)\n : {\n tools: [],\n runCleanup: async () => {},\n };\n\n // Resolve agent tools.\n const { tools, runCleanup } = await resolveToolsForRun({\n appTools: options.appTools,\n agentTools: options.agent.tools,\n context: options.context,\n });\n\n const resolvedTools = [...tools, ...pluginToolsResult.tools];\n\n if (strategy.mode === \"run\") {\n const blockingTool = resolvedTools.find(\n (tool) =>\n tool.kind === \"client\" || (tool.kind !== \"hosted\" && tool.approval !== undefined),\n );\n\n if (blockingTool) {\n const reason =\n blockingTool.kind === \"client\"\n ? `client tool '${blockingTool.name}'`\n : `approval-gated tool '${blockingTool.name}'`;\n\n throw BetterAgentError.fromCode(\n \"BAD_REQUEST\",\n `Non-stream runs do not support interactive tools. Use stream() for ${reason}.`,\n {\n context: {\n agentName: options.agent.name,\n toolName: blockingTool.name,\n toolTarget: blockingTool.kind,\n },\n trace: [{ at: `${traceBase}.validateNonInteractiveRun` }],\n },\n );\n }\n }\n\n const state: LoopState<TContext> = {\n runId: options.runId,\n agentName: options.agent.name,\n items: [...options.items],\n replayStartIndex: options.replayStartIndex ?? 0,\n steps: [],\n stepIndex: 0,\n maxSteps: options.maxSteps,\n conversationId: options.conversationId,\n context: options.context,\n };\n\n const instructionField = options.agent.instruction;\n const instructionResolver = instructionField as ((context: TContext) => string) | undefined;\n const instruction =\n typeof instructionResolver === \"function\"\n ? instructionResolver(options.context as TContext)\n : (instructionField ?? \"\");\n\n const modelCaps = options.agent.model.caps;\n\n const assertInstructionSupported = (\n currentInstruction: GenerativeModelInputMessageContent<typeof modelCaps> | undefined,\n traceAt: string,\n ): void => {\n if (currentInstruction === undefined || currentInstruction === \"\") {\n return;\n }\n\n if (modelCaps.inputShape === \"prompt\" || modelCaps.supportsInstruction !== true) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Agent '${options.agent.name}' model does not support instructions.`,\n {\n context: {\n agentName: options.agent.name,\n modelId: options.agent.model.modelId,\n inputShape: modelCaps.inputShape ?? \"chat\",\n replayMode:\n modelCaps.replayMode ??\n (modelCaps.inputShape === \"prompt\"\n ? \"single_turn_persistent\"\n : \"multi_turn\"),\n },\n trace: [{ at: traceAt }],\n },\n );\n }\n };\n\n assertInstructionSupported(instruction, `${traceBase}.validateInstruction`);\n\n const stepErrorMessage =\n strategy.mode === \"stream\" ? \"Run stream step failed\" : \"Run loop step failed\";\n\n try {\n while (true) {\n const previousStep = state.steps.at(-1);\n const replayItems = state.items.slice(state.replayStartIndex);\n const projectedMessages =\n state.conversationId !== undefined && options.conversationReplayActive\n ? await prepareConversationReplayInput({\n items: replayItems,\n caps: modelCaps,\n agentName: state.agentName,\n conversationId: state.conversationId,\n conversationReplay: options.conversationReplay,\n })\n : projectConversationItemsToInput(replayItems, modelCaps);\n const prepared = await applyOnStep({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n messages: projectedMessages,\n modelCaps,\n conversationId: state.conversationId,\n context: options.context,\n previousStep,\n onStep: options.agent.onStep,\n pluginRuntime: options.pluginRuntime,\n });\n\n await options.emit({\n type: Events.STEP_START,\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n timestamp: Date.now(),\n conversationId: state.conversationId,\n });\n\n try {\n const activeToolNames = prepared.activeTools;\n const activeTools =\n activeToolNames === undefined\n ? resolvedTools\n : resolvedTools.filter((tool) =>\n activeToolNames.includes(\n tool.kind === \"hosted\"\n ? typeof tool.name === \"string\" && tool.name.length > 0\n ? tool.name\n : tool.type\n : tool.name,\n ),\n );\n\n const effectiveInstruction = prepared.systemInstruction ?? instruction;\n assertInstructionSupported(\n effectiveInstruction,\n `${traceBase}.prepareModelInput.validateInstruction`,\n );\n const modelInput =\n effectiveInstruction === undefined || effectiveInstruction === \"\"\n ? [...prepared.messages]\n : [\n {\n type: \"message\",\n role: \"system\",\n content: effectiveInstruction,\n } as GenerativeModelInputMessage<typeof modelCaps>,\n ...prepared.messages,\n ];\n\n const modelPrepared = await applyBeforeModelCall({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n modelCaps,\n input: modelInput,\n tools: activeTools,\n conversationId: state.conversationId,\n toolChoice: prepared.toolChoice ?? options.toolChoice,\n pluginRuntime: options.pluginRuntime,\n });\n\n const { response, assistantMessageId } = await strategy.call({\n options,\n modelInput: modelPrepared.input,\n tools: modelPrepared.tools,\n toolChoice: modelPrepared.toolChoice,\n stepIndex: state.stepIndex,\n runId: state.runId,\n agentName: state.agentName,\n conversationId: state.conversationId,\n });\n\n await applyAfterModelCall({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n response,\n conversationId: state.conversationId,\n pluginRuntime: options.pluginRuntime,\n });\n\n const toolCalls = extractToolCallRequests(response);\n const toolBatch =\n toolCalls.length > 0\n ? await executeToolCalls({\n runId: state.runId,\n agentName: state.agentName,\n conversationId: state.conversationId,\n parentMessageId: assistantMessageId,\n toolCalls,\n tools: modelPrepared.tools,\n toolErrorMode: options.agent.toolErrorMode,\n onToolError: options.agent.onToolError,\n signal: options.signal,\n emit: options.emit,\n advanced: options.advanced,\n pendingToolRuntime: options.pendingToolRuntime,\n context: options.context,\n pluginRuntime: options.pluginRuntime,\n })\n : { results: [] };\n\n state.items = [...state.items, ...response.output];\n if (toolBatch.results.length > 0) {\n state.items = [...state.items, ...toolBatch.results];\n }\n\n const stepResult: PreviousStepResult = { response };\n state.steps.push(stepResult);\n\n const stopMessages =\n state.conversationId !== undefined && options.conversationReplayActive\n ? await prepareConversationReplayInput({\n items: state.items.slice(state.replayStartIndex),\n caps: modelCaps,\n agentName: state.agentName,\n conversationId: state.conversationId,\n conversationReplay: options.conversationReplay,\n })\n : projectConversationItemsToInput(\n state.items.slice(state.replayStartIndex),\n modelCaps,\n );\n\n const stopDecision: LoopStopDecision = evaluateStopConditions({\n maxSteps: state.maxSteps,\n stepIndex: state.stepIndex,\n steps: state.steps,\n messages: stopMessages,\n lastStep: stepResult,\n stopWhen: options.agent.stopWhen,\n context: options.context,\n });\n\n await options.emit({\n type: Events.STEP_FINISH,\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n toolCallCount: toolCalls.length,\n terminationReason: stopDecision.stop ? stopDecision.reason : undefined,\n timestamp: Date.now(),\n conversationId: state.conversationId,\n });\n\n await applyOnStepFinish({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n result: stepResult,\n conversationId: state.conversationId,\n context: options.context,\n onStepFinish: options.agent.onStepFinish,\n });\n\n if (stopDecision.stop) {\n return {\n response,\n items: state.items,\n };\n }\n\n state.stepIndex += 1;\n } catch (error) {\n const wrapped =\n error instanceof BetterAgentError\n ? error.at({ at: traceBase })\n : BetterAgentError.wrap({\n err: error,\n message: stepErrorMessage,\n opts: {\n code: \"INTERNAL\",\n trace: [{ at: traceBase }],\n },\n });\n await options.emit({\n type: Events.STEP_ERROR,\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n error: wrapped,\n timestamp: Date.now(),\n conversationId: state.conversationId,\n });\n throw wrapped;\n }\n }\n } finally {\n await runCleanup();\n await pluginToolsResult.runCleanup();\n }\n};\n"],"mappings":"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"}
@@ -59,43 +59,6 @@ const executeToolCalls = async (params) => {
59
59
  message: args.message ?? extractToolErrorMessage(args.error, args.errorKind),
60
60
  retryable: args.retryable ?? (args.error instanceof BetterAgentError ? args.error.retryable : void 0)
61
61
  });
62
- const emitToolCallStart = async (prepared) => {
63
- await params.emit({
64
- type: Events.TOOL_CALL_START,
65
- runId: params.runId,
66
- agentName: params.agentName,
67
- parentMessageId: params.parentMessageId,
68
- toolCallId: prepared.toolCall.callId,
69
- toolCallName: prepared.toolCall.name,
70
- toolTarget: prepared.toolTarget,
71
- timestamp: Date.now()
72
- });
73
- };
74
- const emitToolCallArgs = async (prepared) => {
75
- await params.emit({
76
- type: Events.TOOL_CALL_ARGS,
77
- runId: params.runId,
78
- agentName: params.agentName,
79
- parentMessageId: params.parentMessageId,
80
- toolCallId: prepared.toolCall.callId,
81
- toolCallName: prepared.toolCall.name,
82
- delta: prepared.toolCall.arguments,
83
- toolTarget: prepared.toolTarget,
84
- timestamp: Date.now()
85
- });
86
- };
87
- const emitToolCallEnd = async (prepared) => {
88
- await params.emit({
89
- type: Events.TOOL_CALL_END,
90
- runId: params.runId,
91
- agentName: params.agentName,
92
- parentMessageId: params.parentMessageId,
93
- toolCallId: prepared.toolCall.callId,
94
- toolCallName: prepared.toolCall.name,
95
- toolTarget: prepared.toolTarget,
96
- timestamp: Date.now()
97
- });
98
- };
99
62
  const emitToolCallResult = async (prepared, outcome) => {
100
63
  await params.emit({
101
64
  type: Events.TOOL_CALL_RESULT,
@@ -423,8 +386,7 @@ const executeToolCalls = async (params) => {
423
386
  tool,
424
387
  toolTarget
425
388
  }),
426
- skip: false,
427
- shouldEmitToolCallEnd: false
389
+ skip: false
428
390
  }, validatedInput.value, recoveryDepth);
429
391
  };
430
392
  const prepareToolCall = async () => {
@@ -434,7 +396,6 @@ const executeToolCalls = async (params) => {
434
396
  tool,
435
397
  toolTarget,
436
398
  skip: false,
437
- shouldEmitToolCallEnd: false,
438
399
  parseError: BetterAgentError.wrap({
439
400
  err: parsed.error,
440
401
  message: `Failed to parse arguments for tool '${toolCall.name}'`,
@@ -462,8 +423,7 @@ const executeToolCalls = async (params) => {
462
423
  toolTarget,
463
424
  args: beforeHook.args,
464
425
  skip: true,
465
- skipResult: beforeHook.decision.result,
466
- shouldEmitToolCallEnd: true
426
+ skipResult: beforeHook.decision.result
467
427
  };
468
428
  const validatedInput = await validateInput(tool.schema, beforeHook.args);
469
429
  if (validatedInput.isErr()) return {
@@ -472,7 +432,6 @@ const executeToolCalls = async (params) => {
472
432
  toolTarget,
473
433
  args: beforeHook.args,
474
434
  skip: false,
475
- shouldEmitToolCallEnd: false,
476
435
  validationError: validatedInput.error.at({ at: "core.run.executeToolCalls.validateToolInput" })
477
436
  };
478
437
  const prepared = {
@@ -488,8 +447,7 @@ const executeToolCalls = async (params) => {
488
447
  tool,
489
448
  toolTarget
490
449
  }),
491
- skip: false,
492
- shouldEmitToolCallEnd: true
450
+ skip: false
493
451
  };
494
452
  if (prepared.resolvedApproval?.required) await emitApprovalRequested(prepared);
495
453
  return prepared;
@@ -526,16 +484,7 @@ const executeToolCalls = async (params) => {
526
484
  result: afterHook.result
527
485
  };
528
486
  };
529
- await emitToolCallStart({
530
- toolCall,
531
- toolTarget
532
- });
533
- await emitToolCallArgs({
534
- toolCall,
535
- toolTarget
536
- });
537
487
  const prepared = await prepareToolCall();
538
- if (prepared.shouldEmitToolCallEnd) await emitToolCallEnd(prepared);
539
488
  const finalOutcome = await applyAfterToolCall(prepared, await executePreparedTool(prepared));
540
489
  await emitToolCallResult(prepared, finalOutcome);
541
490
  results.push({
@@ -1 +1 @@
1
- {"version":3,"file":"execute-tool-calls.mjs","names":[],"sources":["../../src/run/execute-tool-calls.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { logger } from \"@better-agent/shared/logger\";\nimport { safeJsonParse } from \"@better-agent/shared/utils\";\nimport { type Event, Events } from \"../events\";\nimport type { PluginRuntime } from \"../plugins\";\nimport type { GenerativeModelToolCallRequest, GenerativeModelToolCallResult } from \"../providers\";\nimport { validateInput } from \"../schema\";\nimport type {\n AgentToolDefinition,\n ExecutionToolError,\n OnToolError,\n ParseToolError,\n ToolApprovalConfig,\n ToolErrorContext,\n ToolErrorMode,\n ToolErrorPayload,\n ToolErrorResultFor,\n ValidationToolError,\n} from \"../tools\";\nimport type { PendingToolRuntime } from \"./pending-tools\";\nimport type { RunAdvancedOptions } from \"./types\";\n\nconst MAX_TOOL_ERROR_REPAIR_DEPTH = 2;\nconst MAX_TOOL_ERROR_RETRY_ATTEMPTS = 3;\n\ntype RecoverableToolErrorKind = ToolErrorPayload[\"errorKind\"];\ntype ExecutableToolDefinition = Exclude<AgentToolDefinition, { kind: \"hosted\" }>;\n\ntype ToolExecutionOutcome = {\n result: unknown;\n isError?: boolean;\n errorKind?: RecoverableToolErrorKind;\n};\n\ntype ResolvedApproval = {\n required?: boolean;\n timeoutMs?: number;\n meta?: Record<string, unknown>;\n};\n\ntype PreparedToolCall = {\n toolCall: GenerativeModelToolCallRequest;\n tool: ExecutableToolDefinition;\n toolTarget: \"server\" | \"client\";\n args?: unknown;\n validatedInput?: unknown;\n resolvedApproval?: ResolvedApproval;\n skip: boolean;\n skipResult?: unknown;\n parseError?: BetterAgentError;\n validationError?: BetterAgentError;\n shouldEmitToolCallEnd: boolean;\n};\n\nconst getToolRunName = (tool: AgentToolDefinition): string | undefined =>\n tool.kind === \"hosted\"\n ? typeof tool.name === \"string\" && tool.name.length > 0\n ? tool.name\n : typeof tool.type === \"string\" && tool.type.length > 0\n ? tool.type\n : undefined\n : typeof tool.name === \"string\" && tool.name.length > 0\n ? tool.name\n : undefined;\n\n/** Executes the next batch of tool calls. */\nexport const executeToolCalls = async <TContext>(params: {\n runId: string;\n agentName: string;\n conversationId?: string;\n parentMessageId: string;\n toolCalls: readonly GenerativeModelToolCallRequest[];\n tools: readonly AgentToolDefinition[];\n toolErrorMode?: ToolErrorMode;\n onToolError?: OnToolError;\n signal: AbortSignal;\n emit: (event: Event) => Promise<void>;\n advanced?: RunAdvancedOptions;\n pendingToolRuntime?: PendingToolRuntime;\n context?: TContext;\n pluginRuntime?: PluginRuntime | null;\n}): Promise<{\n results: GenerativeModelToolCallResult[];\n}> => {\n const results: GenerativeModelToolCallResult[] = [];\n\n const throwIfAborted = () => {\n if (params.signal.aborted) {\n throw BetterAgentError.fromCode(\"ABORTED\", \"Tool execution was aborted.\", {\n trace: [{ at: \"core.run.executeToolCalls.aborted\" }],\n });\n }\n };\n\n const isAbortError = (error: unknown): boolean =>\n params.signal.aborted === true ||\n (error instanceof BetterAgentError && error.code === \"ABORTED\");\n\n const waitForRetryBackoff = async (ms: number) => {\n if (ms <= 0) {\n throwIfAborted();\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n params.signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n const onAbort = () => {\n clearTimeout(timer);\n reject(\n BetterAgentError.fromCode(\"ABORTED\", \"Tool execution was aborted.\", {\n trace: [{ at: \"core.run.executeToolCalls.retryBackoff\" }],\n }),\n );\n };\n\n if (params.signal.aborted) {\n onAbort();\n return;\n }\n\n params.signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n };\n\n const extractToolErrorMessage = (\n error: unknown,\n errorKind: RecoverableToolErrorKind,\n ): string => {\n const rawMessage =\n error instanceof BetterAgentError || error instanceof Error\n ? error.message\n : typeof error === \"string\"\n ? error\n : \"Unknown tool error\";\n\n if (errorKind === \"parse\") {\n return `Tool arguments could not be parsed as valid JSON. ${rawMessage}`.trim();\n }\n\n if (errorKind === \"validation\") {\n return `Tool arguments failed schema validation. ${rawMessage}`.trim();\n }\n\n return rawMessage;\n };\n\n const createToolErrorOutcome = (args: {\n toolName: string;\n errorKind: RecoverableToolErrorKind;\n message: string;\n retryable?: boolean;\n }): ToolExecutionOutcome => ({\n result: {\n type: \"tool_error\",\n toolName: args.toolName,\n errorKind: args.errorKind,\n message: args.message,\n retryable: args.retryable,\n } satisfies ToolErrorPayload,\n isError: true,\n errorKind: args.errorKind,\n });\n\n const createToolErrorOutcomeFromError = (args: {\n toolName: string;\n error: unknown;\n errorKind: RecoverableToolErrorKind;\n message?: string;\n retryable?: boolean;\n }): ToolExecutionOutcome =>\n createToolErrorOutcome({\n toolName: args.toolName,\n errorKind: args.errorKind,\n message: args.message ?? extractToolErrorMessage(args.error, args.errorKind),\n retryable:\n args.retryable ??\n (args.error instanceof BetterAgentError ? args.error.retryable : undefined),\n });\n\n const emitToolCallStart = async (prepared: {\n toolCall: GenerativeModelToolCallRequest;\n toolTarget: \"server\" | \"client\";\n }) => {\n await params.emit({\n type: Events.TOOL_CALL_START,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n toolTarget: prepared.toolTarget,\n timestamp: Date.now(),\n });\n };\n\n const emitToolCallArgs = async (prepared: {\n toolCall: GenerativeModelToolCallRequest;\n toolTarget: \"server\" | \"client\";\n }) => {\n await params.emit({\n type: Events.TOOL_CALL_ARGS,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n delta: prepared.toolCall.arguments,\n toolTarget: prepared.toolTarget,\n timestamp: Date.now(),\n });\n };\n\n const emitToolCallEnd = async (prepared: {\n toolCall: GenerativeModelToolCallRequest;\n toolTarget: \"server\" | \"client\";\n }) => {\n await params.emit({\n type: Events.TOOL_CALL_END,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n toolTarget: prepared.toolTarget,\n timestamp: Date.now(),\n });\n };\n\n const emitToolCallResult = async (\n prepared: PreparedToolCall,\n outcome: ToolExecutionOutcome,\n ) => {\n await params.emit({\n type: Events.TOOL_CALL_RESULT,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n result: outcome.result,\n isError: outcome.isError,\n errorKind: outcome.errorKind,\n toolTarget: prepared.toolTarget,\n timestamp: Date.now(),\n });\n };\n\n const resolveExecutableTool = (\n toolCall: GenerativeModelToolCallRequest,\n ): { tool: ExecutableToolDefinition; toolTarget: \"server\" | \"client\" } => {\n const tool = params.tools.find((candidate) => getToolRunName(candidate) === toolCall.name);\n if (!tool) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Tool '${toolCall.name}' was requested by the model but is not available for this run.`,\n {\n context: {\n runId: params.runId,\n agentName: params.agentName,\n toolName: toolCall.name,\n },\n trace: [{ at: \"core.run.executeToolCalls.missingTool\" }],\n },\n );\n }\n\n if (tool.kind === \"hosted\") {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Hosted tool '${getToolRunName(tool) ?? toolCall.name}' reached the in-process tool executor, but hosted tools must be executed by the provider during model invocation.`,\n {\n context: {\n runId: params.runId,\n agentName: params.agentName,\n toolName: getToolRunName(tool) ?? toolCall.name,\n toolTarget: tool.kind,\n provider: tool.provider,\n toolType: tool.type,\n },\n trace: [{ at: \"core.run.executeToolCalls.hostedToolInvariant\" }],\n },\n );\n }\n\n return {\n tool,\n toolTarget: tool.kind === \"client\" ? \"client\" : \"server\",\n };\n };\n\n const resolveApprovalConfig = async <TInput>(args: {\n approval?: ToolApprovalConfig<unknown, TInput>;\n input: TInput;\n toolCall: GenerativeModelToolCallRequest;\n tool: ExecutableToolDefinition;\n toolTarget: \"server\" | \"client\";\n }): Promise<ResolvedApproval | undefined> => {\n const approval = args.approval;\n if (!approval) {\n return undefined;\n }\n\n let resolved: ResolvedApproval = {\n required: approval.required,\n timeoutMs: approval.timeoutMs,\n meta: approval.meta,\n };\n\n if (approval.resolve) {\n const runtimeResolved = await approval.resolve({\n context: params.context,\n input: args.input,\n runId: params.runId,\n toolCallId: args.toolCall.callId,\n toolName: args.tool.name,\n toolTarget: args.toolTarget,\n });\n\n resolved = {\n required: runtimeResolved.required ?? resolved.required,\n timeoutMs: runtimeResolved.timeoutMs ?? resolved.timeoutMs,\n meta: runtimeResolved.meta ?? resolved.meta,\n };\n }\n\n return resolved;\n };\n\n const emitApprovalRequested = async (prepared: PreparedToolCall) => {\n await params.emit({\n type: Events.TOOL_APPROVAL_REQUIRED,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n toolTarget: prepared.toolTarget,\n toolInput: prepared.validatedInput,\n state: \"requested\",\n timestamp: Date.now(),\n meta: prepared.resolvedApproval?.meta,\n });\n\n await params.emit({\n type: Events.TOOL_APPROVAL_UPDATED,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n toolTarget: prepared.toolTarget,\n state: \"requested\",\n toolInput: prepared.validatedInput,\n timestamp: Date.now(),\n meta: prepared.resolvedApproval?.meta,\n });\n };\n\n const awaitApprovalIfNeeded = async (\n prepared: PreparedToolCall,\n ): Promise<{ approved: true } | { approved: false; note?: string }> => {\n if (!prepared.resolvedApproval?.required) {\n return { approved: true };\n }\n\n if (!params.pendingToolRuntime) {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Tool '${prepared.tool.name}' requires approval, but no approval runtime is configured.`,\n {\n context: {\n runId: params.runId,\n toolName: prepared.tool.name,\n toolCallId: prepared.toolCall.callId,\n toolTarget: prepared.toolTarget,\n },\n trace: [{ at: \"core.run.executeTools.awaitApprovalIfNeeded\" }],\n },\n );\n }\n\n try {\n const decision = await params.pendingToolRuntime.awaitToolApproval({\n runId: params.runId,\n toolCallId: prepared.toolCall.callId,\n toolName: prepared.tool.name,\n timeoutMs:\n prepared.resolvedApproval.timeoutMs ?? params.advanced?.toolApprovalTimeoutMs,\n signal: params.signal,\n });\n\n await params.emit({\n type: Events.TOOL_APPROVAL_UPDATED,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n toolTarget: prepared.toolTarget,\n state: decision.decision,\n toolInput: prepared.validatedInput,\n timestamp: Date.now(),\n meta: prepared.resolvedApproval.meta,\n note: decision.note,\n actorId: decision.actorId,\n });\n\n if (decision.decision === \"denied\") {\n return decision.note !== undefined\n ? { approved: false, note: decision.note }\n : { approved: false };\n }\n\n return { approved: true };\n } catch (error) {\n if (error instanceof BetterAgentError && error.code === \"TIMEOUT\") {\n await params.emit({\n type: Events.TOOL_APPROVAL_UPDATED,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n toolTarget: prepared.toolTarget,\n state: \"expired\",\n toolInput: prepared.validatedInput,\n timestamp: Date.now(),\n meta: prepared.resolvedApproval.meta,\n });\n }\n\n throw error;\n }\n };\n\n for (const toolCall of params.toolCalls) {\n throwIfAborted();\n\n const { tool, toolTarget } = resolveExecutableTool(toolCall);\n const resolvedToolErrorMode = tool.toolErrorMode ?? params.toolErrorMode ?? \"tool_error\";\n\n const defaultToolErrorOutcome = (args: {\n error: unknown;\n errorKind: RecoverableToolErrorKind;\n retryable?: boolean;\n }): ToolExecutionOutcome => {\n if (isAbortError(args.error)) {\n throw args.error;\n }\n\n if (resolvedToolErrorMode === \"throw\") {\n throw args.error;\n }\n\n return createToolErrorOutcomeFromError({\n toolName: toolCall.name,\n error: args.error,\n errorKind: args.errorKind,\n retryable: args.retryable,\n });\n };\n\n const runToolHandler = async (input: unknown) => {\n if (tool.kind === \"server\") {\n return await tool.handler(input, {\n runId: params.runId,\n agentName: params.agentName,\n ...(params.conversationId !== undefined\n ? { conversationId: params.conversationId }\n : {}),\n parentMessageId: params.parentMessageId,\n signal: params.signal,\n ...(params.context !== undefined ? { context: params.context } : {}),\n emit: params.emit,\n });\n }\n\n if (!params.pendingToolRuntime) {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Client tool '${tool.name}' requires a live runtime capable of accepting tool results.`,\n {\n context: {\n runId: params.runId,\n agentName: params.agentName,\n toolName: tool.name,\n toolCallId: toolCall.callId,\n },\n trace: [{ at: \"core.run.executeToolCalls.awaitClientToolResult\" }],\n },\n );\n }\n\n return await params.pendingToolRuntime.awaitClientToolResult({\n runId: params.runId,\n toolCallId: toolCall.callId,\n toolName: toolCall.name,\n timeoutMs: params.advanced?.clientToolResultTimeoutMs,\n signal: params.signal,\n });\n };\n\n const resolveHookAction = async <T extends ToolErrorContext>(\n context: T,\n ): Promise<ToolErrorResultFor<T> | undefined> => {\n const toolAction = await tool.onToolError?.(context);\n if (toolAction !== undefined) {\n if (toolAction.action !== \"skip\") {\n return toolAction;\n }\n } else {\n return undefined;\n }\n\n const agentAction = await params.onToolError?.(context);\n if (agentAction !== undefined && agentAction.action !== \"skip\") {\n return agentAction;\n }\n\n return undefined;\n };\n\n const resolveToolError = async (args: {\n error: unknown;\n errorKind: RecoverableToolErrorKind;\n input?: unknown;\n recoveryDepth: number;\n }): Promise<ToolExecutionOutcome> => {\n if (isAbortError(args.error)) {\n throw args.error;\n }\n\n if (args.recoveryDepth >= MAX_TOOL_ERROR_REPAIR_DEPTH) {\n return defaultToolErrorOutcome({\n error: args.error,\n errorKind: args.errorKind,\n });\n }\n\n const context =\n args.errorKind === \"parse\"\n ? ({\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n error: args.error,\n rawArguments: toolCall.arguments,\n errorKind: \"parse\",\n } satisfies ParseToolError)\n : args.errorKind === \"validation\"\n ? ({\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n error: args.error,\n rawArguments: toolCall.arguments,\n input: args.input,\n errorKind: \"validation\",\n } satisfies ValidationToolError)\n : ({\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n error: args.error,\n rawArguments: toolCall.arguments,\n input: args.input,\n errorKind: \"execution\",\n } satisfies ExecutionToolError);\n\n const action = await resolveHookAction(context);\n if (action === undefined) {\n return defaultToolErrorOutcome({\n error: args.error,\n errorKind: args.errorKind,\n });\n }\n\n switch (action.action) {\n case \"send_to_model\":\n return createToolErrorOutcomeFromError({\n toolName: toolCall.name,\n error: args.error,\n errorKind: args.errorKind,\n message:\n action.message ?? extractToolErrorMessage(args.error, args.errorKind),\n retryable: action.retryable,\n });\n\n case \"throw\":\n throw args.error;\n\n case \"skip\":\n return defaultToolErrorOutcome({\n error: args.error,\n errorKind: args.errorKind,\n });\n\n case \"repair\":\n return await validateAndExecuteInput(action.input, args.recoveryDepth + 1);\n\n case \"retry\": {\n if (args.errorKind !== \"execution\" || args.input === undefined) {\n logger.warn(\n `[better-agent] Ignoring invalid onToolError action '${action.action}' for tool '${toolCall.name}' (${args.errorKind} error).`,\n );\n return createToolErrorOutcomeFromError({\n toolName: toolCall.name,\n error: args.error,\n errorKind: args.errorKind,\n });\n }\n\n const attempts = Math.max(\n 1,\n Math.min(action.maxAttempts ?? 1, MAX_TOOL_ERROR_RETRY_ATTEMPTS),\n );\n\n let lastError = args.error;\n for (let attempt = 0; attempt < attempts; attempt += 1) {\n throwIfAborted();\n try {\n return { result: await runToolHandler(args.input) };\n } catch (retryError) {\n if (isAbortError(retryError)) {\n throw retryError;\n }\n\n lastError = retryError;\n if (attempt < attempts - 1) {\n await waitForRetryBackoff((attempt + 1) * 500);\n }\n }\n }\n\n return await resolveToolError({\n error: lastError,\n errorKind: \"execution\",\n input: args.input,\n recoveryDepth: args.recoveryDepth + 1,\n });\n }\n\n case \"result\":\n if (args.errorKind !== \"execution\") {\n logger.warn(\n `[better-agent] Ignoring invalid onToolError action '${action.action}' for tool '${toolCall.name}' (${args.errorKind} error).`,\n );\n return createToolErrorOutcomeFromError({\n toolName: toolCall.name,\n error: args.error,\n errorKind: args.errorKind,\n });\n }\n\n return { result: action.value };\n\n default:\n return defaultToolErrorOutcome({\n error: args.error,\n errorKind: args.errorKind,\n });\n }\n };\n\n const executeApprovedInput = async (\n prepared: PreparedToolCall,\n input: unknown,\n recoveryDepth: number,\n ): Promise<ToolExecutionOutcome> => {\n const approval = await awaitApprovalIfNeeded(prepared);\n if (!approval.approved) {\n const denialReason = approval.note ? ` Reason: ${approval.note}` : \"\";\n return {\n result: `Tool '${toolCall.name}' was denied by the operator.${denialReason}`,\n };\n }\n\n try {\n return { result: await runToolHandler(input) };\n } catch (error) {\n if (isAbortError(error)) {\n throw error;\n }\n\n return await resolveToolError({\n error,\n errorKind: \"execution\",\n input,\n recoveryDepth,\n });\n }\n };\n\n const validateAndExecuteInput = async (\n input: unknown,\n recoveryDepth: number,\n ): Promise<ToolExecutionOutcome> => {\n const validatedInput = await validateInput(tool.schema, input);\n if (validatedInput.isErr()) {\n return await resolveToolError({\n error: validatedInput.error.at({\n at: \"core.run.executeToolCalls.validateToolInput\",\n }),\n errorKind: \"validation\",\n input,\n recoveryDepth,\n });\n }\n\n const prepared: PreparedToolCall = {\n toolCall,\n tool,\n toolTarget,\n args: input,\n validatedInput: validatedInput.value,\n resolvedApproval: await resolveApprovalConfig({\n approval: tool.approval,\n input: validatedInput.value,\n toolCall,\n tool,\n toolTarget,\n }),\n skip: false,\n shouldEmitToolCallEnd: false,\n };\n\n return await executeApprovedInput(prepared, validatedInput.value, recoveryDepth);\n };\n\n const prepareToolCall = async (): Promise<PreparedToolCall> => {\n const parsed = safeJsonParse(toolCall.arguments);\n if (parsed.isErr()) {\n return {\n toolCall,\n tool,\n toolTarget,\n skip: false,\n shouldEmitToolCallEnd: false,\n parseError: BetterAgentError.wrap({\n err: parsed.error,\n message: `Failed to parse arguments for tool '${toolCall.name}'`,\n opts: {\n code: \"VALIDATION_FAILED\",\n context: {\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n },\n trace: [{ at: \"core.run.executeToolCalls.parseToolArguments\" }],\n },\n }),\n };\n }\n\n const beforeHook =\n params.pluginRuntime?.hasToolHooks === true\n ? await params.pluginRuntime.applyBeforeToolCall({\n runId: params.runId,\n agentName: params.agentName,\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n args: parsed.value,\n conversationId: params.conversationId,\n })\n : { args: parsed.value };\n\n if (beforeHook?.decision?.skip === true) {\n return {\n toolCall,\n tool,\n toolTarget,\n args: beforeHook.args,\n skip: true,\n skipResult: beforeHook.decision.result,\n shouldEmitToolCallEnd: true,\n };\n }\n\n const validatedInput = await validateInput(tool.schema, beforeHook.args);\n if (validatedInput.isErr()) {\n return {\n toolCall,\n tool,\n toolTarget,\n args: beforeHook.args,\n skip: false,\n shouldEmitToolCallEnd: false,\n validationError: validatedInput.error.at({\n at: \"core.run.executeToolCalls.validateToolInput\",\n }),\n };\n }\n\n const prepared: PreparedToolCall = {\n toolCall,\n tool,\n toolTarget,\n args: beforeHook.args,\n validatedInput: validatedInput.value,\n resolvedApproval: await resolveApprovalConfig({\n approval: tool.approval,\n input: validatedInput.value,\n toolCall,\n tool,\n toolTarget,\n }),\n skip: false,\n shouldEmitToolCallEnd: true,\n };\n\n if (prepared.resolvedApproval?.required) {\n await emitApprovalRequested(prepared);\n }\n\n return prepared;\n };\n\n const executePreparedTool = async (\n prepared: PreparedToolCall,\n ): Promise<ToolExecutionOutcome> => {\n if (prepared.parseError) {\n return await resolveToolError({\n error: prepared.parseError,\n errorKind: \"parse\",\n recoveryDepth: 0,\n });\n }\n\n if (prepared.skip) {\n return { result: prepared.skipResult };\n }\n\n if (prepared.validationError) {\n return await resolveToolError({\n error: prepared.validationError,\n errorKind: \"validation\",\n input: prepared.args,\n recoveryDepth: 0,\n });\n }\n\n return await executeApprovedInput(prepared, prepared.validatedInput, 0);\n };\n\n const applyAfterToolCall = async (\n prepared: PreparedToolCall,\n outcome: ToolExecutionOutcome,\n ): Promise<ToolExecutionOutcome> => {\n if (params.pluginRuntime?.hasToolHooks !== true) {\n return outcome;\n }\n\n const afterHook = await params.pluginRuntime.applyAfterToolCall({\n runId: params.runId,\n agentName: params.agentName,\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n args: prepared.args,\n result: outcome.result,\n conversationId: params.conversationId,\n error:\n outcome.isError === true &&\n typeof outcome.result === \"object\" &&\n outcome.result !== null &&\n \"message\" in outcome.result &&\n typeof outcome.result.message === \"string\"\n ? outcome.result.message\n : undefined,\n });\n\n return {\n ...outcome,\n result: afterHook.result,\n };\n };\n\n await emitToolCallStart({ toolCall, toolTarget });\n await emitToolCallArgs({ toolCall, toolTarget });\n\n const prepared = await prepareToolCall();\n if (prepared.shouldEmitToolCallEnd) {\n await emitToolCallEnd(prepared);\n }\n\n const outcome = await executePreparedTool(prepared);\n const finalOutcome = await applyAfterToolCall(prepared, outcome);\n\n await emitToolCallResult(prepared, finalOutcome);\n\n results.push({\n type: \"tool-call\",\n callId: toolCall.callId,\n name: toolCall.name,\n arguments: toolCall.arguments,\n result: finalOutcome.result,\n isError: finalOutcome.isError,\n });\n }\n\n return { results };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"execute-tool-calls.mjs","names":[],"sources":["../../src/run/execute-tool-calls.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { logger } from \"@better-agent/shared/logger\";\nimport { safeJsonParse } from \"@better-agent/shared/utils\";\nimport { type Event, Events } from \"../events\";\nimport type { PluginRuntime } from \"../plugins\";\nimport type { GenerativeModelToolCallRequest, GenerativeModelToolCallResult } from \"../providers\";\nimport { validateInput } from \"../schema\";\nimport type {\n AgentToolDefinition,\n ExecutionToolError,\n OnToolError,\n ParseToolError,\n ToolApprovalConfig,\n ToolErrorContext,\n ToolErrorMode,\n ToolErrorPayload,\n ToolErrorResultFor,\n ValidationToolError,\n} from \"../tools\";\nimport type { PendingToolRuntime } from \"./pending-tools\";\nimport type { RunAdvancedOptions } from \"./types\";\n\nconst MAX_TOOL_ERROR_REPAIR_DEPTH = 2;\nconst MAX_TOOL_ERROR_RETRY_ATTEMPTS = 3;\n\ntype RecoverableToolErrorKind = ToolErrorPayload[\"errorKind\"];\ntype ExecutableToolDefinition = Exclude<AgentToolDefinition, { kind: \"hosted\" }>;\n\ntype ToolExecutionOutcome = {\n result: unknown;\n isError?: boolean;\n errorKind?: RecoverableToolErrorKind;\n};\n\ntype ResolvedApproval = {\n required?: boolean;\n timeoutMs?: number;\n meta?: Record<string, unknown>;\n};\n\ntype PreparedToolCall = {\n toolCall: GenerativeModelToolCallRequest;\n tool: ExecutableToolDefinition;\n toolTarget: \"server\" | \"client\";\n args?: unknown;\n validatedInput?: unknown;\n resolvedApproval?: ResolvedApproval;\n skip: boolean;\n skipResult?: unknown;\n parseError?: BetterAgentError;\n validationError?: BetterAgentError;\n};\n\nconst getToolRunName = (tool: AgentToolDefinition): string | undefined =>\n tool.kind === \"hosted\"\n ? typeof tool.name === \"string\" && tool.name.length > 0\n ? tool.name\n : typeof tool.type === \"string\" && tool.type.length > 0\n ? tool.type\n : undefined\n : typeof tool.name === \"string\" && tool.name.length > 0\n ? tool.name\n : undefined;\n\n/** Executes the next batch of tool calls. */\nexport const executeToolCalls = async <TContext>(params: {\n runId: string;\n agentName: string;\n conversationId?: string;\n parentMessageId: string;\n toolCalls: readonly GenerativeModelToolCallRequest[];\n tools: readonly AgentToolDefinition[];\n toolErrorMode?: ToolErrorMode;\n onToolError?: OnToolError;\n signal: AbortSignal;\n emit: (event: Event) => Promise<void>;\n advanced?: RunAdvancedOptions;\n pendingToolRuntime?: PendingToolRuntime;\n context?: TContext;\n pluginRuntime?: PluginRuntime | null;\n}): Promise<{\n results: GenerativeModelToolCallResult[];\n}> => {\n const results: GenerativeModelToolCallResult[] = [];\n\n const throwIfAborted = () => {\n if (params.signal.aborted) {\n throw BetterAgentError.fromCode(\"ABORTED\", \"Tool execution was aborted.\", {\n trace: [{ at: \"core.run.executeToolCalls.aborted\" }],\n });\n }\n };\n\n const isAbortError = (error: unknown): boolean =>\n params.signal.aborted === true ||\n (error instanceof BetterAgentError && error.code === \"ABORTED\");\n\n const waitForRetryBackoff = async (ms: number) => {\n if (ms <= 0) {\n throwIfAborted();\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n params.signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n const onAbort = () => {\n clearTimeout(timer);\n reject(\n BetterAgentError.fromCode(\"ABORTED\", \"Tool execution was aborted.\", {\n trace: [{ at: \"core.run.executeToolCalls.retryBackoff\" }],\n }),\n );\n };\n\n if (params.signal.aborted) {\n onAbort();\n return;\n }\n\n params.signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n };\n\n const extractToolErrorMessage = (\n error: unknown,\n errorKind: RecoverableToolErrorKind,\n ): string => {\n const rawMessage =\n error instanceof BetterAgentError || error instanceof Error\n ? error.message\n : typeof error === \"string\"\n ? error\n : \"Unknown tool error\";\n\n if (errorKind === \"parse\") {\n return `Tool arguments could not be parsed as valid JSON. ${rawMessage}`.trim();\n }\n\n if (errorKind === \"validation\") {\n return `Tool arguments failed schema validation. ${rawMessage}`.trim();\n }\n\n return rawMessage;\n };\n\n const createToolErrorOutcome = (args: {\n toolName: string;\n errorKind: RecoverableToolErrorKind;\n message: string;\n retryable?: boolean;\n }): ToolExecutionOutcome => ({\n result: {\n type: \"tool_error\",\n toolName: args.toolName,\n errorKind: args.errorKind,\n message: args.message,\n retryable: args.retryable,\n } satisfies ToolErrorPayload,\n isError: true,\n errorKind: args.errorKind,\n });\n\n const createToolErrorOutcomeFromError = (args: {\n toolName: string;\n error: unknown;\n errorKind: RecoverableToolErrorKind;\n message?: string;\n retryable?: boolean;\n }): ToolExecutionOutcome =>\n createToolErrorOutcome({\n toolName: args.toolName,\n errorKind: args.errorKind,\n message: args.message ?? extractToolErrorMessage(args.error, args.errorKind),\n retryable:\n args.retryable ??\n (args.error instanceof BetterAgentError ? args.error.retryable : undefined),\n });\n\n const emitToolCallResult = async (\n prepared: PreparedToolCall,\n outcome: ToolExecutionOutcome,\n ) => {\n await params.emit({\n type: Events.TOOL_CALL_RESULT,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n result: outcome.result,\n isError: outcome.isError,\n errorKind: outcome.errorKind,\n toolTarget: prepared.toolTarget,\n timestamp: Date.now(),\n });\n };\n\n const resolveExecutableTool = (\n toolCall: GenerativeModelToolCallRequest,\n ): { tool: ExecutableToolDefinition; toolTarget: \"server\" | \"client\" } => {\n const tool = params.tools.find((candidate) => getToolRunName(candidate) === toolCall.name);\n if (!tool) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Tool '${toolCall.name}' was requested by the model but is not available for this run.`,\n {\n context: {\n runId: params.runId,\n agentName: params.agentName,\n toolName: toolCall.name,\n },\n trace: [{ at: \"core.run.executeToolCalls.missingTool\" }],\n },\n );\n }\n\n if (tool.kind === \"hosted\") {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Hosted tool '${getToolRunName(tool) ?? toolCall.name}' reached the in-process tool executor, but hosted tools must be executed by the provider during model invocation.`,\n {\n context: {\n runId: params.runId,\n agentName: params.agentName,\n toolName: getToolRunName(tool) ?? toolCall.name,\n toolTarget: tool.kind,\n provider: tool.provider,\n toolType: tool.type,\n },\n trace: [{ at: \"core.run.executeToolCalls.hostedToolInvariant\" }],\n },\n );\n }\n\n return {\n tool,\n toolTarget: tool.kind === \"client\" ? \"client\" : \"server\",\n };\n };\n\n const resolveApprovalConfig = async <TInput>(args: {\n approval?: ToolApprovalConfig<unknown, TInput>;\n input: TInput;\n toolCall: GenerativeModelToolCallRequest;\n tool: ExecutableToolDefinition;\n toolTarget: \"server\" | \"client\";\n }): Promise<ResolvedApproval | undefined> => {\n const approval = args.approval;\n if (!approval) {\n return undefined;\n }\n\n let resolved: ResolvedApproval = {\n required: approval.required,\n timeoutMs: approval.timeoutMs,\n meta: approval.meta,\n };\n\n if (approval.resolve) {\n const runtimeResolved = await approval.resolve({\n context: params.context,\n input: args.input,\n runId: params.runId,\n toolCallId: args.toolCall.callId,\n toolName: args.tool.name,\n toolTarget: args.toolTarget,\n });\n\n resolved = {\n required: runtimeResolved.required ?? resolved.required,\n timeoutMs: runtimeResolved.timeoutMs ?? resolved.timeoutMs,\n meta: runtimeResolved.meta ?? resolved.meta,\n };\n }\n\n return resolved;\n };\n\n const emitApprovalRequested = async (prepared: PreparedToolCall) => {\n await params.emit({\n type: Events.TOOL_APPROVAL_REQUIRED,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n toolTarget: prepared.toolTarget,\n toolInput: prepared.validatedInput,\n state: \"requested\",\n timestamp: Date.now(),\n meta: prepared.resolvedApproval?.meta,\n });\n\n await params.emit({\n type: Events.TOOL_APPROVAL_UPDATED,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n toolTarget: prepared.toolTarget,\n state: \"requested\",\n toolInput: prepared.validatedInput,\n timestamp: Date.now(),\n meta: prepared.resolvedApproval?.meta,\n });\n };\n\n const awaitApprovalIfNeeded = async (\n prepared: PreparedToolCall,\n ): Promise<{ approved: true } | { approved: false; note?: string }> => {\n if (!prepared.resolvedApproval?.required) {\n return { approved: true };\n }\n\n if (!params.pendingToolRuntime) {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Tool '${prepared.tool.name}' requires approval, but no approval runtime is configured.`,\n {\n context: {\n runId: params.runId,\n toolName: prepared.tool.name,\n toolCallId: prepared.toolCall.callId,\n toolTarget: prepared.toolTarget,\n },\n trace: [{ at: \"core.run.executeTools.awaitApprovalIfNeeded\" }],\n },\n );\n }\n\n try {\n const decision = await params.pendingToolRuntime.awaitToolApproval({\n runId: params.runId,\n toolCallId: prepared.toolCall.callId,\n toolName: prepared.tool.name,\n timeoutMs:\n prepared.resolvedApproval.timeoutMs ?? params.advanced?.toolApprovalTimeoutMs,\n signal: params.signal,\n });\n\n await params.emit({\n type: Events.TOOL_APPROVAL_UPDATED,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n toolTarget: prepared.toolTarget,\n state: decision.decision,\n toolInput: prepared.validatedInput,\n timestamp: Date.now(),\n meta: prepared.resolvedApproval.meta,\n note: decision.note,\n actorId: decision.actorId,\n });\n\n if (decision.decision === \"denied\") {\n return decision.note !== undefined\n ? { approved: false, note: decision.note }\n : { approved: false };\n }\n\n return { approved: true };\n } catch (error) {\n if (error instanceof BetterAgentError && error.code === \"TIMEOUT\") {\n await params.emit({\n type: Events.TOOL_APPROVAL_UPDATED,\n runId: params.runId,\n agentName: params.agentName,\n parentMessageId: params.parentMessageId,\n toolCallId: prepared.toolCall.callId,\n toolCallName: prepared.toolCall.name,\n toolTarget: prepared.toolTarget,\n state: \"expired\",\n toolInput: prepared.validatedInput,\n timestamp: Date.now(),\n meta: prepared.resolvedApproval.meta,\n });\n }\n\n throw error;\n }\n };\n\n for (const toolCall of params.toolCalls) {\n throwIfAborted();\n\n const { tool, toolTarget } = resolveExecutableTool(toolCall);\n const resolvedToolErrorMode = tool.toolErrorMode ?? params.toolErrorMode ?? \"tool_error\";\n\n const defaultToolErrorOutcome = (args: {\n error: unknown;\n errorKind: RecoverableToolErrorKind;\n retryable?: boolean;\n }): ToolExecutionOutcome => {\n if (isAbortError(args.error)) {\n throw args.error;\n }\n\n if (resolvedToolErrorMode === \"throw\") {\n throw args.error;\n }\n\n return createToolErrorOutcomeFromError({\n toolName: toolCall.name,\n error: args.error,\n errorKind: args.errorKind,\n retryable: args.retryable,\n });\n };\n\n const runToolHandler = async (input: unknown) => {\n if (tool.kind === \"server\") {\n return await tool.handler(input, {\n runId: params.runId,\n agentName: params.agentName,\n ...(params.conversationId !== undefined\n ? { conversationId: params.conversationId }\n : {}),\n parentMessageId: params.parentMessageId,\n signal: params.signal,\n ...(params.context !== undefined ? { context: params.context } : {}),\n emit: params.emit,\n });\n }\n\n if (!params.pendingToolRuntime) {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Client tool '${tool.name}' requires a live runtime capable of accepting tool results.`,\n {\n context: {\n runId: params.runId,\n agentName: params.agentName,\n toolName: tool.name,\n toolCallId: toolCall.callId,\n },\n trace: [{ at: \"core.run.executeToolCalls.awaitClientToolResult\" }],\n },\n );\n }\n\n return await params.pendingToolRuntime.awaitClientToolResult({\n runId: params.runId,\n toolCallId: toolCall.callId,\n toolName: toolCall.name,\n timeoutMs: params.advanced?.clientToolResultTimeoutMs,\n signal: params.signal,\n });\n };\n\n const resolveHookAction = async <T extends ToolErrorContext>(\n context: T,\n ): Promise<ToolErrorResultFor<T> | undefined> => {\n const toolAction = await tool.onToolError?.(context);\n if (toolAction !== undefined) {\n if (toolAction.action !== \"skip\") {\n return toolAction;\n }\n } else {\n return undefined;\n }\n\n const agentAction = await params.onToolError?.(context);\n if (agentAction !== undefined && agentAction.action !== \"skip\") {\n return agentAction;\n }\n\n return undefined;\n };\n\n const resolveToolError = async (args: {\n error: unknown;\n errorKind: RecoverableToolErrorKind;\n input?: unknown;\n recoveryDepth: number;\n }): Promise<ToolExecutionOutcome> => {\n if (isAbortError(args.error)) {\n throw args.error;\n }\n\n if (args.recoveryDepth >= MAX_TOOL_ERROR_REPAIR_DEPTH) {\n return defaultToolErrorOutcome({\n error: args.error,\n errorKind: args.errorKind,\n });\n }\n\n const context =\n args.errorKind === \"parse\"\n ? ({\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n error: args.error,\n rawArguments: toolCall.arguments,\n errorKind: \"parse\",\n } satisfies ParseToolError)\n : args.errorKind === \"validation\"\n ? ({\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n error: args.error,\n rawArguments: toolCall.arguments,\n input: args.input,\n errorKind: \"validation\",\n } satisfies ValidationToolError)\n : ({\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n error: args.error,\n rawArguments: toolCall.arguments,\n input: args.input,\n errorKind: \"execution\",\n } satisfies ExecutionToolError);\n\n const action = await resolveHookAction(context);\n if (action === undefined) {\n return defaultToolErrorOutcome({\n error: args.error,\n errorKind: args.errorKind,\n });\n }\n\n switch (action.action) {\n case \"send_to_model\":\n return createToolErrorOutcomeFromError({\n toolName: toolCall.name,\n error: args.error,\n errorKind: args.errorKind,\n message:\n action.message ?? extractToolErrorMessage(args.error, args.errorKind),\n retryable: action.retryable,\n });\n\n case \"throw\":\n throw args.error;\n\n case \"skip\":\n return defaultToolErrorOutcome({\n error: args.error,\n errorKind: args.errorKind,\n });\n\n case \"repair\":\n return await validateAndExecuteInput(action.input, args.recoveryDepth + 1);\n\n case \"retry\": {\n if (args.errorKind !== \"execution\" || args.input === undefined) {\n logger.warn(\n `[better-agent] Ignoring invalid onToolError action '${action.action}' for tool '${toolCall.name}' (${args.errorKind} error).`,\n );\n return createToolErrorOutcomeFromError({\n toolName: toolCall.name,\n error: args.error,\n errorKind: args.errorKind,\n });\n }\n\n const attempts = Math.max(\n 1,\n Math.min(action.maxAttempts ?? 1, MAX_TOOL_ERROR_RETRY_ATTEMPTS),\n );\n\n let lastError = args.error;\n for (let attempt = 0; attempt < attempts; attempt += 1) {\n throwIfAborted();\n try {\n return { result: await runToolHandler(args.input) };\n } catch (retryError) {\n if (isAbortError(retryError)) {\n throw retryError;\n }\n\n lastError = retryError;\n if (attempt < attempts - 1) {\n await waitForRetryBackoff((attempt + 1) * 500);\n }\n }\n }\n\n return await resolveToolError({\n error: lastError,\n errorKind: \"execution\",\n input: args.input,\n recoveryDepth: args.recoveryDepth + 1,\n });\n }\n\n case \"result\":\n if (args.errorKind !== \"execution\") {\n logger.warn(\n `[better-agent] Ignoring invalid onToolError action '${action.action}' for tool '${toolCall.name}' (${args.errorKind} error).`,\n );\n return createToolErrorOutcomeFromError({\n toolName: toolCall.name,\n error: args.error,\n errorKind: args.errorKind,\n });\n }\n\n return { result: action.value };\n\n default:\n return defaultToolErrorOutcome({\n error: args.error,\n errorKind: args.errorKind,\n });\n }\n };\n\n const executeApprovedInput = async (\n prepared: PreparedToolCall,\n input: unknown,\n recoveryDepth: number,\n ): Promise<ToolExecutionOutcome> => {\n const approval = await awaitApprovalIfNeeded(prepared);\n if (!approval.approved) {\n const denialReason = approval.note ? ` Reason: ${approval.note}` : \"\";\n return {\n result: `Tool '${toolCall.name}' was denied by the operator.${denialReason}`,\n };\n }\n\n try {\n return { result: await runToolHandler(input) };\n } catch (error) {\n if (isAbortError(error)) {\n throw error;\n }\n\n return await resolveToolError({\n error,\n errorKind: \"execution\",\n input,\n recoveryDepth,\n });\n }\n };\n\n const validateAndExecuteInput = async (\n input: unknown,\n recoveryDepth: number,\n ): Promise<ToolExecutionOutcome> => {\n const validatedInput = await validateInput(tool.schema, input);\n if (validatedInput.isErr()) {\n return await resolveToolError({\n error: validatedInput.error.at({\n at: \"core.run.executeToolCalls.validateToolInput\",\n }),\n errorKind: \"validation\",\n input,\n recoveryDepth,\n });\n }\n\n const prepared: PreparedToolCall = {\n toolCall,\n tool,\n toolTarget,\n args: input,\n validatedInput: validatedInput.value,\n resolvedApproval: await resolveApprovalConfig({\n approval: tool.approval,\n input: validatedInput.value,\n toolCall,\n tool,\n toolTarget,\n }),\n skip: false,\n };\n\n return await executeApprovedInput(prepared, validatedInput.value, recoveryDepth);\n };\n\n const prepareToolCall = async (): Promise<PreparedToolCall> => {\n const parsed = safeJsonParse(toolCall.arguments);\n if (parsed.isErr()) {\n return {\n toolCall,\n tool,\n toolTarget,\n skip: false,\n parseError: BetterAgentError.wrap({\n err: parsed.error,\n message: `Failed to parse arguments for tool '${toolCall.name}'`,\n opts: {\n code: \"VALIDATION_FAILED\",\n context: {\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n },\n trace: [{ at: \"core.run.executeToolCalls.parseToolArguments\" }],\n },\n }),\n };\n }\n\n const beforeHook =\n params.pluginRuntime?.hasToolHooks === true\n ? await params.pluginRuntime.applyBeforeToolCall({\n runId: params.runId,\n agentName: params.agentName,\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n args: parsed.value,\n conversationId: params.conversationId,\n })\n : { args: parsed.value };\n\n if (beforeHook?.decision?.skip === true) {\n return {\n toolCall,\n tool,\n toolTarget,\n args: beforeHook.args,\n skip: true,\n skipResult: beforeHook.decision.result,\n };\n }\n\n const validatedInput = await validateInput(tool.schema, beforeHook.args);\n if (validatedInput.isErr()) {\n return {\n toolCall,\n tool,\n toolTarget,\n args: beforeHook.args,\n skip: false,\n validationError: validatedInput.error.at({\n at: \"core.run.executeToolCalls.validateToolInput\",\n }),\n };\n }\n\n const prepared: PreparedToolCall = {\n toolCall,\n tool,\n toolTarget,\n args: beforeHook.args,\n validatedInput: validatedInput.value,\n resolvedApproval: await resolveApprovalConfig({\n approval: tool.approval,\n input: validatedInput.value,\n toolCall,\n tool,\n toolTarget,\n }),\n skip: false,\n };\n\n if (prepared.resolvedApproval?.required) {\n await emitApprovalRequested(prepared);\n }\n\n return prepared;\n };\n\n const executePreparedTool = async (\n prepared: PreparedToolCall,\n ): Promise<ToolExecutionOutcome> => {\n if (prepared.parseError) {\n return await resolveToolError({\n error: prepared.parseError,\n errorKind: \"parse\",\n recoveryDepth: 0,\n });\n }\n\n if (prepared.skip) {\n return { result: prepared.skipResult };\n }\n\n if (prepared.validationError) {\n return await resolveToolError({\n error: prepared.validationError,\n errorKind: \"validation\",\n input: prepared.args,\n recoveryDepth: 0,\n });\n }\n\n return await executeApprovedInput(prepared, prepared.validatedInput, 0);\n };\n\n const applyAfterToolCall = async (\n prepared: PreparedToolCall,\n outcome: ToolExecutionOutcome,\n ): Promise<ToolExecutionOutcome> => {\n if (params.pluginRuntime?.hasToolHooks !== true) {\n return outcome;\n }\n\n const afterHook = await params.pluginRuntime.applyAfterToolCall({\n runId: params.runId,\n agentName: params.agentName,\n toolName: toolCall.name,\n toolCallId: toolCall.callId,\n args: prepared.args,\n result: outcome.result,\n conversationId: params.conversationId,\n error:\n outcome.isError === true &&\n typeof outcome.result === \"object\" &&\n outcome.result !== null &&\n \"message\" in outcome.result &&\n typeof outcome.result.message === \"string\"\n ? outcome.result.message\n : undefined,\n });\n\n return {\n ...outcome,\n result: afterHook.result,\n };\n };\n\n const prepared = await prepareToolCall();\n\n const outcome = await executePreparedTool(prepared);\n const finalOutcome = await applyAfterToolCall(prepared, outcome);\n\n await emitToolCallResult(prepared, finalOutcome);\n\n results.push({\n type: \"tool-call\",\n callId: toolCall.callId,\n name: toolCall.name,\n arguments: toolCall.arguments,\n result: finalOutcome.result,\n isError: finalOutcome.isError,\n });\n }\n\n return { results };\n};\n"],"mappings":"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"}
@@ -7,9 +7,9 @@ import { isPlainRecord, safeJsonParse } from "@better-agent/shared/utils";
7
7
 
8
8
  //#region src/run/helpers.ts
9
9
  const MAX_OUTPUT_REPAIR_DEPTH = 2;
10
- const isJsonSchemaRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
11
10
  const normalizeStructuredOutputJsonSchema = (schema) => {
12
11
  const normalized = {};
12
+ const isJsonSchemaRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
13
13
  for (const [key, value] of Object.entries(schema)) {
14
14
  if (Array.isArray(value)) {
15
15
  normalized[key] = value.map((item) => isJsonSchemaRecord(item) ? normalizeStructuredOutputJsonSchema(item) : item);
@@ -31,12 +31,7 @@ function createStreamPersistenceEmitter(params) {
31
31
  seq: nextSeq++,
32
32
  timestamp: event.timestamp ?? Date.now()
33
33
  };
34
- try {
35
- await stream.append(params.streamId, streamEvent);
36
- } catch (error) {
37
- if (error instanceof Error && error.message.includes("not found")) return;
38
- throw error;
39
- }
34
+ await stream.append(params.streamId, streamEvent);
40
35
  };
41
36
  }
42
37
  /** Converts `onEvent` into an internal emitter. */
@@ -406,7 +401,15 @@ async function loadConversationMessages(params) {
406
401
  loaded
407
402
  };
408
403
  const caps = params.caps ?? { inputShape: "chat" };
409
- if ((caps.replayMode ?? (caps.inputShape === "prompt" ? "single_turn_persistent" : "multi_turn")) !== "multi_turn") return {
404
+ const replayMode = caps.replayMode ?? (caps.inputShape === "prompt" ? "single_turn_persistent" : "multi_turn");
405
+ if (replayMode === "single_turn_only") return {
406
+ input: params.input,
407
+ items: durableInputItems,
408
+ replayStartIndex: 0,
409
+ conversationReplayActive: false,
410
+ loaded
411
+ };
412
+ if (replayMode === "single_turn_persistent") return {
410
413
  input: params.input,
411
414
  items: [...loaded.items, ...durableInputItems],
412
415
  replayStartIndex: loaded.items.length,
@@ -445,12 +448,14 @@ async function saveConversationMessages(params) {
445
448
  ...params.loaded?.cursor !== void 0 ? { expectedCursor: params.loaded.cursor } : {}
446
449
  });
447
450
  } catch (error) {
451
+ const code = typeof error?.code === "string" ? error.code : void 0;
452
+ const status = typeof error?.status === "number" ? error.status : void 0;
448
453
  throw BetterAgentError.wrap({
449
454
  err: error,
450
455
  message: "Failed to save conversation messages.",
451
456
  opts: {
452
- code: error instanceof BetterAgentError && error.code !== void 0 ? error.code : typeof error?.code === "string" ? error.code : "INTERNAL",
453
- ...typeof error?.status === "number" ? { status: error.status } : {},
457
+ ...code !== void 0 ? { code } : {},
458
+ ...status !== void 0 ? { status } : {},
454
459
  context: {
455
460
  conversationId: params.conversationId,
456
461
  agentName: params.agentName
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.mjs","names":[],"sources":["../../src/run/helpers.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { isPlainRecord, safeJsonParse } from \"@better-agent/shared/utils\";\nimport type { AnyAgentDefinition } from \"../agent\";\nimport { getPreflightedOutputSchema } from \"../agent/validation\";\nimport type { Event } from \"../events\";\nimport { createIdGenerator } from \"../internal/id\";\nimport type { Awaitable } from \"../internal/types\";\nimport type {\n ConversationStore,\n LoadedConversation,\n StreamEvent,\n StreamStore,\n} from \"../persistence\";\nimport type {\n Capabilities,\n ConversationItem,\n GenerativeModelInput,\n GenerativeModelInputItem,\n GenerativeModelInputMessageContent,\n GenerativeModelOutputMessage,\n Modality,\n OutputSchemaDefinition,\n StructuredOutput,\n} from \"../providers\";\nimport { resolveToJsonSchema, validateInput } from \"../schema\";\nimport {\n normalizeInputToConversationItems,\n normalizeInputToMessages,\n projectConversationItemsToInput,\n pruneInputByCapabilities,\n} from \"./messages\";\nimport type { OnOutputError, OutputErrorContext, OutputErrorMode } from \"./output-errors\";\nimport type { ContextBoundAgent, ConversationReplayOptions, RunOptions, RunResult } from \"./types\";\n\nconst MAX_OUTPUT_REPAIR_DEPTH = 2;\ntype NonTextInputModality = Exclude<Modality, \"text\">;\n\nconst isJsonSchemaRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst normalizeStructuredOutputJsonSchema = (\n schema: Record<string, unknown>,\n): Record<string, unknown> => {\n const normalized: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(schema)) {\n if (Array.isArray(value)) {\n normalized[key] = value.map((item) =>\n isJsonSchemaRecord(item) ? normalizeStructuredOutputJsonSchema(item) : item,\n );\n continue;\n }\n\n normalized[key] = isJsonSchemaRecord(value)\n ? normalizeStructuredOutputJsonSchema(value)\n : value;\n }\n\n const objectLike =\n normalized.type === \"object\" ||\n isJsonSchemaRecord(normalized.properties) ||\n Array.isArray(normalized.required);\n\n if (objectLike && normalized.additionalProperties === undefined) {\n normalized.additionalProperties = false;\n }\n\n return normalized;\n};\n\n/** Creates an emitter that persists stream events. */\nexport function createStreamPersistenceEmitter(params: {\n stream?: StreamStore;\n streamId: string;\n}): ((event: Event) => Promise<void>) | undefined {\n const stream = params.stream;\n if (!stream) {\n return undefined;\n }\n\n let nextSeq = 0;\n\n return async (event: Event) => {\n const streamEvent: StreamEvent = {\n ...event,\n seq: nextSeq++,\n timestamp: event.timestamp ?? Date.now(),\n };\n try {\n await stream.append(params.streamId, streamEvent);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not found\")) {\n return;\n }\n throw error;\n }\n };\n}\n\n/** Converts `onEvent` into an internal emitter. */\nexport function toEventEmitter(onEvent?: RunOptions[\"onEvent\"]): (event: Event) => Promise<void> {\n if (!onEvent) {\n return async () => {};\n }\n\n return async (event) => {\n await onEvent(event);\n };\n}\n\n/** Validates run context against the agent schema. */\nexport async function validateAgentContext<TContext>(\n agent: ContextBoundAgent<TContext>,\n context: TContext | undefined,\n): Promise<TContext | undefined> {\n if (!agent.contextSchema) {\n return context;\n }\n\n const validated = await validateInput<TContext>(agent.contextSchema, context, {\n invalidMessage: \"The provided data is invalid according to context schema.\",\n });\n if (validated.isErr()) {\n throw validated.error.at({ at: \"core.run.validateAgentContext\" });\n }\n\n return validated.value;\n}\n\n/** Minimal model info for runtime validation. */\ntype AgentModelInfo = {\n name: string;\n model: {\n modelId: string;\n caps: Capabilities;\n };\n};\n\nconst throwInvalidStoredConversationItem = (conversationId: string, index: number): never => {\n throw BetterAgentError.fromCode(\"VALIDATION_FAILED\", \"Loaded conversation items are invalid.\", {\n context: { conversationId, index },\n trace: [{ at: \"core.run.validateStoredConversationItems\" }],\n });\n};\n\nconst isConversationPart = (part: unknown): boolean => {\n if (!isPlainRecord(part) || typeof part.type !== \"string\") {\n return false;\n }\n\n switch (part.type) {\n case \"text\":\n return typeof part.text === \"string\";\n case \"reasoning\":\n return (\n typeof part.text === \"string\" &&\n (part.visibility === \"summary\" || part.visibility === \"full\") &&\n (part.provider === undefined || typeof part.provider === \"string\")\n );\n case \"transcript\":\n return (\n typeof part.text === \"string\" &&\n (part.segments === undefined ||\n (Array.isArray(part.segments) &&\n part.segments.every(\n (segment) =>\n isPlainRecord(segment) &&\n typeof segment.id === \"string\" &&\n typeof segment.start === \"number\" &&\n typeof segment.end === \"number\" &&\n typeof segment.text === \"string\" &&\n (segment.speaker === undefined ||\n typeof segment.speaker === \"string\"),\n )))\n );\n case \"image\":\n case \"audio\":\n case \"video\":\n case \"file\":\n return isPlainRecord(part.source);\n case \"embedding\":\n return Array.isArray(part.embedding);\n default:\n return false;\n }\n};\n\nexport const validateStoredConversationItems = (\n items: ConversationItem[],\n conversationId: string,\n): void => {\n for (const [index, item] of items.entries()) {\n if (!isPlainRecord(item) || typeof item.type !== \"string\") {\n throwInvalidStoredConversationItem(conversationId, index);\n }\n\n if (item.type === \"message\") {\n if (\n typeof item.role !== \"string\" ||\n !(\n typeof item.content === \"string\" ||\n (Array.isArray(item.content) &&\n item.content.every((part) => isConversationPart(part)))\n )\n ) {\n throwInvalidStoredConversationItem(conversationId, index);\n }\n continue;\n }\n\n if (item.type === \"tool-call\") {\n if (\n typeof item.name !== \"string\" ||\n typeof item.callId !== \"string\" ||\n (!(\"result\" in item) && typeof item.arguments !== \"string\")\n ) {\n throwInvalidStoredConversationItem(conversationId, index);\n }\n continue;\n }\n\n if (\n item.type === \"provider-tool-result\" &&\n typeof item.name === \"string\" &&\n typeof item.callId === \"string\"\n ) {\n continue;\n }\n\n throwInvalidStoredConversationItem(conversationId, index);\n }\n};\n\nconst throwUnsupportedInputModality = (params: {\n agent: AgentModelInfo;\n modality: \"text\" | \"image\" | \"audio\" | \"video\" | \"file\" | \"embedding\";\n location: string;\n traceAt: string;\n}): never => {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Agent '${params.agent.name}' model does not accept ${params.modality} input at ${params.location}.`,\n {\n context: {\n agentName: params.agent.name,\n modelId: params.agent.model.modelId,\n modality: params.modality,\n location: params.location,\n },\n trace: [{ at: params.traceAt }],\n },\n );\n};\n\nconst validateMessageContentCapabilities = (params: {\n agent: AgentModelInfo;\n content: GenerativeModelInputMessageContent;\n itemIndex: number;\n traceAt: string;\n}): void => {\n const caps = params.agent.model.caps;\n\n if (typeof params.content === \"string\") {\n if (caps.inputModalities?.text === false) {\n throwUnsupportedInputModality({\n agent: params.agent,\n modality: \"text\",\n location: `input[${params.itemIndex}].content`,\n traceAt: params.traceAt,\n });\n }\n return;\n }\n\n if (!Array.isArray(params.content)) {\n return;\n }\n\n for (const [partIndex, part] of params.content.entries()) {\n if (typeof part !== \"object\" || part === null || !(\"type\" in part)) {\n continue;\n }\n\n const partType = (part as { type: string }).type;\n\n if (partType === \"text\" || partType === \"transcript\" || partType === \"reasoning\") {\n if (caps.inputModalities?.text === false) {\n throwUnsupportedInputModality({\n agent: params.agent,\n modality: \"text\",\n location: `input[${params.itemIndex}].content[${partIndex}]`,\n traceAt: params.traceAt,\n });\n }\n continue;\n }\n\n if (\n partType === \"image\" ||\n partType === \"audio\" ||\n partType === \"video\" ||\n partType === \"file\" ||\n partType === \"embedding\"\n ) {\n const modality = partType as NonTextInputModality;\n if (caps.inputModalities?.[modality] !== true) {\n throwUnsupportedInputModality({\n agent: params.agent,\n modality,\n location: `input[${params.itemIndex}].content[${partIndex}]`,\n traceAt: params.traceAt,\n });\n }\n }\n }\n};\n\nconst isReplayInputPart = (part: unknown): boolean => {\n if (!isPlainRecord(part) || typeof part.type !== \"string\") {\n return false;\n }\n\n switch (part.type) {\n case \"text\":\n return typeof part.text === \"string\";\n case \"reasoning\":\n return (\n typeof part.text === \"string\" &&\n (part.visibility === \"summary\" || part.visibility === \"full\") &&\n (part.provider === undefined || typeof part.provider === \"string\")\n );\n case \"transcript\":\n return (\n typeof part.text === \"string\" &&\n (part.segments === undefined ||\n (Array.isArray(part.segments) &&\n part.segments.every(\n (segment) =>\n isPlainRecord(segment) &&\n typeof segment.id === \"string\" &&\n typeof segment.start === \"number\" &&\n typeof segment.end === \"number\" &&\n typeof segment.text === \"string\" &&\n (segment.speaker === undefined ||\n typeof segment.speaker === \"string\"),\n )))\n );\n case \"image\":\n case \"audio\":\n case \"video\":\n case \"file\":\n return isPlainRecord(part.source);\n case \"embedding\":\n return (\n Array.isArray(part.embedding) &&\n part.embedding.every((value) => typeof value === \"number\")\n );\n default:\n return false;\n }\n};\n\nconst isReplayInputItem = (item: unknown): item is GenerativeModelInputItem => {\n if (!isPlainRecord(item) || typeof item.type !== \"string\") {\n return false;\n }\n\n if (item.type === \"message\") {\n if (item.role !== undefined && typeof item.role !== \"string\") {\n return false;\n }\n\n if (typeof item.content === \"string\") {\n return true;\n }\n\n return Array.isArray(item.content) && item.content.every(isReplayInputPart);\n }\n\n if (item.type === \"tool-call\") {\n return typeof item.name === \"string\" && typeof item.callId === \"string\" && \"result\" in item;\n }\n\n return (\n item.type === \"provider-tool-result\" &&\n typeof item.name === \"string\" &&\n typeof item.callId === \"string\" &&\n \"result\" in item\n );\n};\n\nconst validatePreparedReplayInput = (params: {\n input: unknown;\n caps: Capabilities;\n agentName: string;\n conversationId: string;\n}): GenerativeModelInputItem[] => {\n if (!Array.isArray(params.input) || !params.input.every(isReplayInputItem)) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationReplay.prepareInput must return a valid array of model input items.\",\n {\n context: {\n agentName: params.agentName,\n conversationId: params.conversationId,\n },\n trace: [{ at: \"core.run.prepareConversationReplayInput.validatePreparedInput\" }],\n },\n );\n }\n\n for (const item of params.input) {\n if (item.type !== \"message\") {\n continue;\n }\n\n if (params.caps.inputShape === \"prompt\") {\n if (\"role\" in item && item.role !== undefined) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationReplay.prepareInput returned a role-bearing message for a prompt-shaped model.\",\n {\n context: {\n agentName: params.agentName,\n conversationId: params.conversationId,\n },\n trace: [\n {\n at: \"core.run.prepareConversationReplayInput.validatePreparedInput.promptRole\",\n },\n ],\n },\n );\n }\n continue;\n }\n\n if (!(\"role\" in item) || typeof item.role !== \"string\") {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationReplay.prepareInput returned a role-less message for a chat-shaped model.\",\n {\n context: {\n agentName: params.agentName,\n conversationId: params.conversationId,\n },\n trace: [\n {\n at: \"core.run.prepareConversationReplayInput.validatePreparedInput.chatRole\",\n },\n ],\n },\n );\n }\n }\n\n return params.input;\n};\n\n/**\n * Validates that run input only uses modalities supported by the target model.\n */\nexport function validateRunInputCapabilities(params: {\n agent: AgentModelInfo;\n input: GenerativeModelInput;\n traceAt: string;\n}): void {\n const caps = params.agent.model.caps;\n\n if (typeof params.input === \"string\") {\n if (caps.inputModalities?.text === false) {\n throwUnsupportedInputModality({\n agent: params.agent,\n modality: \"text\",\n location: \"input\",\n traceAt: params.traceAt,\n });\n }\n return;\n }\n\n for (const [itemIndex, item] of params.input.entries()) {\n if (item.type !== \"message\") {\n continue;\n }\n\n validateMessageContentCapabilities({\n agent: params.agent,\n content: item.content,\n itemIndex,\n traceAt: params.traceAt,\n });\n }\n}\n\n/**\n * Validates requested output modalities against the target model's capabilities.\n */\nexport function validateRunModalities(params: {\n agent: AgentModelInfo;\n modalities: readonly Modality[] | undefined;\n output: OutputSchemaDefinition | undefined;\n traceAt: string;\n}): void {\n if (!params.modalities || params.modalities.length === 0) {\n return;\n }\n\n const caps = params.agent.model.caps;\n\n for (const modality of params.modalities) {\n if (caps.outputModalities?.[modality] !== undefined) {\n continue;\n }\n\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Agent '${params.agent.name}' model does not support ${modality} output.`,\n {\n context: {\n agentName: params.agent.name,\n modelId: params.agent.model.modelId,\n modality,\n },\n trace: [{ at: params.traceAt }],\n },\n );\n }\n\n if (params.output !== undefined && !params.modalities.includes(\"text\")) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Structured output requires text output for agent '${params.agent.name}'.`,\n {\n context: {\n agentName: params.agent.name,\n modelId: params.agent.model.modelId,\n modalities: [...params.modalities],\n },\n trace: [{ at: params.traceAt }],\n },\n );\n }\n}\n\n/**\n * Prepares replayable model input from durable conversation items for a run.\n *\n * Stored history is projected losslessly first. The run can then override that\n * projection with `prepareInput`, or fall back to capability-based pruning.\n */\nexport function prepareConversationReplayInput(params: {\n items: ConversationItem[];\n caps: Capabilities;\n agentName: string;\n conversationId: string;\n conversationReplay?: ConversationReplayOptions;\n}): Awaitable<GenerativeModelInputItem[]> {\n const projected = projectConversationItemsToInput(params.items, params.caps);\n const replay = params.conversationReplay;\n\n if (typeof replay?.prepareInput === \"function\") {\n return Promise.resolve(\n replay.prepareInput({\n items: params.items,\n caps: params.caps,\n agentName: params.agentName,\n conversationId: params.conversationId,\n }),\n ).then((input) =>\n validatePreparedReplayInput({\n input,\n caps: params.caps,\n agentName: params.agentName,\n conversationId: params.conversationId,\n }),\n );\n }\n\n if (replay?.omitUnsupportedParts === false) {\n return projected;\n }\n\n return pruneInputByCapabilities(projected, params.caps);\n}\n\n/**\n * Converts a public output schema definition into a provider request.\n */\nexport function toStructuredOutputRequest(\n agent: Pick<AnyAgentDefinition, \"model\" | \"name\" | \"outputSchema\">,\n output: OutputSchemaDefinition | undefined,\n): StructuredOutput | undefined {\n if (output === undefined) {\n return undefined;\n }\n\n const modelCaps = agent.model.caps;\n if (!modelCaps.structured_output) {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Model '${agent.model.modelId}' does not support structured output.`,\n {\n context: {\n agentName: agent.name,\n modelId: agent.model.modelId,\n },\n trace: [{ at: \"core.run.toStructuredOutputRequest.capability\" }],\n },\n );\n }\n\n const preflightedSchema =\n output === agent.outputSchema ? getPreflightedOutputSchema(agent) : undefined;\n if (preflightedSchema !== undefined) {\n return {\n name: output.name ?? `${agent.name}_output`,\n schema: normalizeStructuredOutputJsonSchema(preflightedSchema),\n strict: output.strict,\n };\n }\n\n const runtimeResolvedSchema = resolveToJsonSchema(output.schema as never);\n if (runtimeResolvedSchema.isErr()) {\n throw runtimeResolvedSchema.error.at({\n at: \"core.run.toStructuredOutputRequest.resolveSchema\",\n });\n }\n\n return {\n name: output.name ?? `${agent.name}_output`,\n schema: normalizeStructuredOutputJsonSchema(runtimeResolvedSchema.value),\n strict: output.strict,\n };\n}\n\n/**\n * Parses and validates structured output from a provider response.\n *\n * Structured output currently requires text output.\n */\nexport async function finalizeRunResult(\n result: RunResult & { items: ConversationItem[] },\n output: OutputSchemaDefinition | undefined,\n options?: {\n outputErrorMode?: OutputErrorMode;\n onOutputError?: OnOutputError;\n },\n): Promise<RunResult & { items: ConversationItem[] }> {\n if (output === undefined) {\n return result;\n }\n\n const outputMessages = result.response.output.filter(\n (item): item is GenerativeModelOutputMessage => item.type === \"message\",\n );\n const resolvedOutputErrorMode = options?.outputErrorMode ?? \"throw\";\n\n const getLastStructuredText = () =>\n outputMessages\n .map((message) =>\n typeof message.content === \"string\"\n ? message.content\n : message.content\n .filter(\n (\n part,\n ): part is Extract<\n (typeof message.content)[number],\n { type: \"text\" }\n > => part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\"\"),\n )\n .filter((text) => text.trim().length > 0)\n .at(-1);\n\n const defaultOutputErrorBehavior = (error: unknown): never => {\n throw error;\n };\n\n const validateStructuredValue = async (\n value: unknown,\n text: string,\n repairDepth: number,\n ): Promise<unknown> => {\n const validated = await validateInput(output.schema, value);\n if (validated.isErr()) {\n return await resolveOutputError(\n {\n errorKind: \"validation\",\n error: validated.error.at({ at: \"core.run.finalizeRunResult.validateSchema\" }),\n text,\n value,\n },\n repairDepth,\n );\n }\n\n return validated.value;\n };\n\n const parseStructuredText = async (text: string, repairDepth: number): Promise<unknown> => {\n const parsed = safeJsonParse(text);\n if (parsed.isErr()) {\n return await resolveOutputError(\n {\n errorKind: \"parse\",\n error: BetterAgentError.wrap({\n err: parsed.error,\n message:\n \"Structured output was requested, but the model returned invalid JSON.\",\n opts: {\n code: \"VALIDATION_FAILED\",\n context: {\n preview: text.slice(0, 200),\n },\n trace: [{ at: \"core.run.finalizeRunResult.parseJson\" }],\n },\n }),\n text,\n },\n repairDepth,\n );\n }\n\n return await validateStructuredValue(parsed.value, text, repairDepth);\n };\n\n const resolveOutputError = async (\n context: OutputErrorContext,\n repairDepth: number,\n ): Promise<unknown> => {\n if (resolvedOutputErrorMode === \"throw\" || repairDepth >= MAX_OUTPUT_REPAIR_DEPTH) {\n return defaultOutputErrorBehavior(context.error);\n }\n\n const action = await options?.onOutputError?.(context);\n\n switch (action?.action) {\n case \"repair_text\":\n return await parseStructuredText(action.text, repairDepth + 1);\n case \"repair_value\":\n return await validateStructuredValue(\n action.value,\n \"text\" in context ? context.text : \"\",\n repairDepth + 1,\n );\n case \"throw\":\n throw context.error;\n default:\n return defaultOutputErrorBehavior(context.error);\n }\n };\n\n const lastText = getLastStructuredText();\n if (!lastText) {\n const missingTextError = BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"Structured output was requested, but the model did not return JSON text.\",\n {\n trace: [{ at: \"core.run.finalizeRunResult.noStructuredText\" }],\n },\n );\n\n const structured = await resolveOutputError(\n {\n errorKind: \"missing_text\",\n error: missingTextError,\n },\n 0,\n );\n\n return {\n ...result,\n structured,\n };\n }\n\n const structured = await parseStructuredText(lastText, 0);\n\n return {\n ...result,\n structured,\n };\n}\n\n/**\n * Shared id generator for runs and messages.\n */\nexport const generateId = createIdGenerator({\n prefixes: {\n run: \"run\",\n message: \"msg\",\n },\n});\n\n/**\n * Loads persisted conversation history and returns:\n * - `input`: the model-facing input for this run\n * - `items`: the durable conversation state to mutate and save\n * - `loaded`: the original persisted record for save concurrency\n * - `replayStartIndex`: where the current run's replay window starts in `items`\n *\n * `replayStartIndex` is `loaded.items.length` when older history should be kept in\n * durable state but excluded from per-step replay, otherwise it is `0`.\n */\nexport async function loadConversationMessages(params: {\n conversations?: ConversationStore;\n conversationId?: string;\n agentName?: string;\n input: GenerativeModelInput;\n caps?: Capabilities;\n replaceHistory?: boolean;\n conversationReplay?: ConversationReplayOptions;\n}): Promise<{\n input: GenerativeModelInput;\n items: ConversationItem[];\n replayStartIndex: number;\n conversationReplayActive: boolean;\n loaded?: LoadedConversation;\n}> {\n const inputItems = normalizeInputToMessages(\n params.input,\n params.caps ?? { inputShape: \"chat\" },\n );\n const durableInputItems = normalizeInputToConversationItems(\n params.input,\n params.caps ?? { inputShape: \"chat\" },\n );\n\n if (!params.conversations || params.conversationId === undefined) {\n return {\n input: params.input,\n items: durableInputItems,\n replayStartIndex: 0,\n conversationReplayActive: false,\n };\n }\n\n if (!params.agentName) {\n throw BetterAgentError.fromCode(\n \"INTERNAL\",\n \"agentName is required when loading conversation messages.\",\n {\n context: { conversationId: params.conversationId },\n trace: [{ at: \"core.run.loadConversationMessages.missingAgentName\" }],\n },\n );\n }\n\n const loaded = await params.conversations.load({\n conversationId: params.conversationId,\n agentName: params.agentName,\n });\n if (!loaded) {\n return {\n input: params.input,\n items: durableInputItems,\n replayStartIndex: 0,\n conversationReplayActive: false,\n };\n }\n\n validateStoredConversationItems(loaded.items, params.conversationId);\n\n if (params.replaceHistory) {\n return {\n input: params.input,\n items: durableInputItems,\n replayStartIndex: 0,\n conversationReplayActive: false,\n loaded,\n };\n }\n\n const caps = params.caps ?? { inputShape: \"chat\" };\n const replayMode =\n caps.replayMode ?? (caps.inputShape === \"prompt\" ? \"single_turn_persistent\" : \"multi_turn\");\n\n if (replayMode !== \"multi_turn\") {\n return {\n input: params.input,\n items: [...loaded.items, ...durableInputItems],\n replayStartIndex: loaded.items.length,\n conversationReplayActive: false,\n loaded,\n };\n }\n\n const loadedMessages = await prepareConversationReplayInput({\n items: loaded.items,\n caps,\n agentName: params.agentName,\n conversationId: params.conversationId,\n conversationReplay: params.conversationReplay,\n });\n\n return {\n input: [...loadedMessages, ...inputItems],\n items: [...loaded.items, ...durableInputItems],\n replayStartIndex: 0,\n conversationReplayActive: true,\n loaded,\n };\n}\n\n/**\n * Saves durable conversation items after a run completes.\n */\nexport async function saveConversationMessages(params: {\n conversations?: ConversationStore;\n conversationId?: string;\n agentName?: string;\n result: RunResult & { items: ConversationItem[] };\n loaded?: LoadedConversation;\n}): Promise<void> {\n if (!params.conversations || params.conversationId === undefined) {\n return;\n }\n\n if (!params.agentName) {\n throw BetterAgentError.fromCode(\n \"INTERNAL\",\n \"agentName is required when saving conversation messages.\",\n {\n context: { conversationId: params.conversationId },\n trace: [{ at: \"core.run.saveConversationMessages.missingAgentName\" }],\n },\n );\n }\n\n try {\n validateStoredConversationItems(params.result.items, params.conversationId);\n await params.conversations.save({\n conversationId: params.conversationId,\n agentName: params.agentName,\n items: params.result.items,\n ...(params.loaded?.cursor !== undefined\n ? { expectedCursor: params.loaded.cursor }\n : {}),\n });\n } catch (error) {\n throw BetterAgentError.wrap({\n err: error,\n message: \"Failed to save conversation messages.\",\n opts: {\n code:\n error instanceof BetterAgentError && error.code !== undefined\n ? error.code\n : typeof (error as { code?: unknown })?.code === \"string\"\n ? ((error as { code: string }).code as BetterAgentError[\"code\"])\n : \"INTERNAL\",\n ...(typeof (error as { status?: unknown })?.status === \"number\"\n ? { status: (error as { status: number }).status }\n : {}),\n context: {\n conversationId: params.conversationId,\n agentName: params.agentName,\n },\n trace: [{ at: \"core.run.saveConversationMessages\" }],\n },\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"helpers.mjs","names":[],"sources":["../../src/run/helpers.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { isPlainRecord, safeJsonParse } from \"@better-agent/shared/utils\";\nimport type { AnyAgentDefinition } from \"../agent\";\nimport { getPreflightedOutputSchema } from \"../agent/validation\";\nimport type { Event } from \"../events\";\nimport { createIdGenerator } from \"../internal/id\";\nimport type { Awaitable } from \"../internal/types\";\nimport type {\n ConversationStore,\n LoadedConversation,\n StreamEvent,\n StreamStore,\n} from \"../persistence\";\nimport type {\n Capabilities,\n ConversationItem,\n GenerativeModelInput,\n GenerativeModelInputItem,\n GenerativeModelInputMessageContent,\n GenerativeModelOutputMessage,\n Modality,\n OutputSchemaDefinition,\n StructuredOutput,\n} from \"../providers\";\nimport { resolveToJsonSchema, validateInput } from \"../schema\";\nimport {\n normalizeInputToConversationItems,\n normalizeInputToMessages,\n projectConversationItemsToInput,\n pruneInputByCapabilities,\n} from \"./messages\";\nimport type { OnOutputError, OutputErrorContext, OutputErrorMode } from \"./output-errors\";\nimport type { ContextBoundAgent, ConversationReplayOptions, RunOptions, RunResult } from \"./types\";\n\nconst MAX_OUTPUT_REPAIR_DEPTH = 2;\n\nconst normalizeStructuredOutputJsonSchema = (\n schema: Record<string, unknown>,\n): Record<string, unknown> => {\n const normalized: Record<string, unknown> = {};\n\n const isJsonSchemaRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n for (const [key, value] of Object.entries(schema)) {\n if (Array.isArray(value)) {\n normalized[key] = value.map((item) =>\n isJsonSchemaRecord(item) ? normalizeStructuredOutputJsonSchema(item) : item,\n );\n continue;\n }\n\n normalized[key] = isJsonSchemaRecord(value)\n ? normalizeStructuredOutputJsonSchema(value)\n : value;\n }\n\n const objectLike =\n normalized.type === \"object\" ||\n isJsonSchemaRecord(normalized.properties) ||\n Array.isArray(normalized.required);\n\n if (objectLike && normalized.additionalProperties === undefined) {\n normalized.additionalProperties = false;\n }\n\n return normalized;\n};\n\n/** Creates an emitter that persists stream events. */\nexport function createStreamPersistenceEmitter(params: {\n stream?: StreamStore;\n streamId: string;\n}): ((event: Event) => Promise<void>) | undefined {\n const stream = params.stream;\n if (!stream) {\n return undefined;\n }\n\n let nextSeq = 0;\n\n return async (event: Event) => {\n const streamEvent: StreamEvent = {\n ...event,\n seq: nextSeq++,\n timestamp: event.timestamp ?? Date.now(),\n };\n\n await stream.append(params.streamId, streamEvent);\n };\n}\n\n/** Converts `onEvent` into an internal emitter. */\nexport function toEventEmitter(onEvent?: RunOptions[\"onEvent\"]): (event: Event) => Promise<void> {\n if (!onEvent) {\n return async () => {};\n }\n\n return async (event) => {\n await onEvent(event);\n };\n}\n\n/** Validates run context against the agent schema. */\nexport async function validateAgentContext<TContext>(\n agent: ContextBoundAgent<TContext>,\n context: TContext | undefined,\n): Promise<TContext | undefined> {\n if (!agent.contextSchema) {\n return context;\n }\n\n const validated = await validateInput<TContext>(agent.contextSchema, context, {\n invalidMessage: \"The provided data is invalid according to context schema.\",\n });\n if (validated.isErr()) {\n throw validated.error.at({ at: \"core.run.validateAgentContext\" });\n }\n\n return validated.value;\n}\n\n/** Minimal model info for runtime validation. */\ntype AgentModelInfo = {\n name: string;\n model: {\n modelId: string;\n caps: Capabilities;\n };\n};\n\nconst throwInvalidStoredConversationItem = (conversationId: string, index: number): never => {\n throw BetterAgentError.fromCode(\"VALIDATION_FAILED\", \"Loaded conversation items are invalid.\", {\n context: { conversationId, index },\n trace: [{ at: \"core.run.validateStoredConversationItems\" }],\n });\n};\n\nconst isConversationPart = (part: unknown): boolean => {\n if (!isPlainRecord(part) || typeof part.type !== \"string\") {\n return false;\n }\n\n switch (part.type) {\n case \"text\":\n return typeof part.text === \"string\";\n case \"reasoning\":\n return (\n typeof part.text === \"string\" &&\n (part.visibility === \"summary\" || part.visibility === \"full\") &&\n (part.provider === undefined || typeof part.provider === \"string\")\n );\n case \"transcript\":\n return (\n typeof part.text === \"string\" &&\n (part.segments === undefined ||\n (Array.isArray(part.segments) &&\n part.segments.every(\n (segment) =>\n isPlainRecord(segment) &&\n typeof segment.id === \"string\" &&\n typeof segment.start === \"number\" &&\n typeof segment.end === \"number\" &&\n typeof segment.text === \"string\" &&\n (segment.speaker === undefined ||\n typeof segment.speaker === \"string\"),\n )))\n );\n case \"image\":\n case \"audio\":\n case \"video\":\n case \"file\":\n return isPlainRecord(part.source);\n case \"embedding\":\n return Array.isArray(part.embedding);\n default:\n return false;\n }\n};\n\nexport const validateStoredConversationItems = (\n items: ConversationItem[],\n conversationId: string,\n): void => {\n for (const [index, item] of items.entries()) {\n if (!isPlainRecord(item) || typeof item.type !== \"string\") {\n throwInvalidStoredConversationItem(conversationId, index);\n }\n\n if (item.type === \"message\") {\n if (\n typeof item.role !== \"string\" ||\n !(\n typeof item.content === \"string\" ||\n (Array.isArray(item.content) &&\n item.content.every((part) => isConversationPart(part)))\n )\n ) {\n throwInvalidStoredConversationItem(conversationId, index);\n }\n continue;\n }\n\n if (item.type === \"tool-call\") {\n if (\n typeof item.name !== \"string\" ||\n typeof item.callId !== \"string\" ||\n (!(\"result\" in item) && typeof item.arguments !== \"string\")\n ) {\n throwInvalidStoredConversationItem(conversationId, index);\n }\n continue;\n }\n\n if (\n item.type === \"provider-tool-result\" &&\n typeof item.name === \"string\" &&\n typeof item.callId === \"string\"\n ) {\n continue;\n }\n\n throwInvalidStoredConversationItem(conversationId, index);\n }\n};\n\nconst throwUnsupportedInputModality = (params: {\n agent: AgentModelInfo;\n modality: \"text\" | \"image\" | \"audio\" | \"video\" | \"file\" | \"embedding\";\n location: string;\n traceAt: string;\n}): never => {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Agent '${params.agent.name}' model does not accept ${params.modality} input at ${params.location}.`,\n {\n context: {\n agentName: params.agent.name,\n modelId: params.agent.model.modelId,\n modality: params.modality,\n location: params.location,\n },\n trace: [{ at: params.traceAt }],\n },\n );\n};\n\nconst validateMessageContentCapabilities = (params: {\n agent: AgentModelInfo;\n content: GenerativeModelInputMessageContent;\n itemIndex: number;\n traceAt: string;\n}): void => {\n const caps = params.agent.model.caps;\n\n if (typeof params.content === \"string\") {\n if (caps.inputModalities?.text === false) {\n throwUnsupportedInputModality({\n agent: params.agent,\n modality: \"text\",\n location: `input[${params.itemIndex}].content`,\n traceAt: params.traceAt,\n });\n }\n return;\n }\n\n if (!Array.isArray(params.content)) {\n return;\n }\n\n for (const [partIndex, part] of params.content.entries()) {\n if (typeof part !== \"object\" || part === null || !(\"type\" in part)) {\n continue;\n }\n\n const partType = (part as { type: string }).type;\n\n if (partType === \"text\" || partType === \"transcript\" || partType === \"reasoning\") {\n if (caps.inputModalities?.text === false) {\n throwUnsupportedInputModality({\n agent: params.agent,\n modality: \"text\",\n location: `input[${params.itemIndex}].content[${partIndex}]`,\n traceAt: params.traceAt,\n });\n }\n continue;\n }\n\n if (\n partType === \"image\" ||\n partType === \"audio\" ||\n partType === \"video\" ||\n partType === \"file\" ||\n partType === \"embedding\"\n ) {\n const modality = partType as Exclude<Modality, \"text\">;\n if (caps.inputModalities?.[modality] !== true) {\n throwUnsupportedInputModality({\n agent: params.agent,\n modality,\n location: `input[${params.itemIndex}].content[${partIndex}]`,\n traceAt: params.traceAt,\n });\n }\n }\n }\n};\n\nconst isReplayInputPart = (part: unknown): boolean => {\n if (!isPlainRecord(part) || typeof part.type !== \"string\") {\n return false;\n }\n\n switch (part.type) {\n case \"text\":\n return typeof part.text === \"string\";\n case \"reasoning\":\n return (\n typeof part.text === \"string\" &&\n (part.visibility === \"summary\" || part.visibility === \"full\") &&\n (part.provider === undefined || typeof part.provider === \"string\")\n );\n case \"transcript\":\n return (\n typeof part.text === \"string\" &&\n (part.segments === undefined ||\n (Array.isArray(part.segments) &&\n part.segments.every(\n (segment) =>\n isPlainRecord(segment) &&\n typeof segment.id === \"string\" &&\n typeof segment.start === \"number\" &&\n typeof segment.end === \"number\" &&\n typeof segment.text === \"string\" &&\n (segment.speaker === undefined ||\n typeof segment.speaker === \"string\"),\n )))\n );\n case \"image\":\n case \"audio\":\n case \"video\":\n case \"file\":\n return isPlainRecord(part.source);\n case \"embedding\":\n return (\n Array.isArray(part.embedding) &&\n part.embedding.every((value) => typeof value === \"number\")\n );\n default:\n return false;\n }\n};\n\nconst isReplayInputItem = (item: unknown): item is GenerativeModelInputItem => {\n if (!isPlainRecord(item) || typeof item.type !== \"string\") {\n return false;\n }\n\n if (item.type === \"message\") {\n if (item.role !== undefined && typeof item.role !== \"string\") {\n return false;\n }\n\n if (typeof item.content === \"string\") {\n return true;\n }\n\n return Array.isArray(item.content) && item.content.every(isReplayInputPart);\n }\n\n if (item.type === \"tool-call\") {\n return typeof item.name === \"string\" && typeof item.callId === \"string\" && \"result\" in item;\n }\n\n return (\n item.type === \"provider-tool-result\" &&\n typeof item.name === \"string\" &&\n typeof item.callId === \"string\" &&\n \"result\" in item\n );\n};\n\nconst validatePreparedReplayInput = (params: {\n input: unknown;\n caps: Capabilities;\n agentName: string;\n conversationId: string;\n}): GenerativeModelInputItem[] => {\n if (!Array.isArray(params.input) || !params.input.every(isReplayInputItem)) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationReplay.prepareInput must return a valid array of model input items.\",\n {\n context: {\n agentName: params.agentName,\n conversationId: params.conversationId,\n },\n trace: [{ at: \"core.run.prepareConversationReplayInput.validatePreparedInput\" }],\n },\n );\n }\n\n for (const item of params.input) {\n if (item.type !== \"message\") {\n continue;\n }\n\n if (params.caps.inputShape === \"prompt\") {\n if (\"role\" in item && item.role !== undefined) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationReplay.prepareInput returned a role-bearing message for a prompt-shaped model.\",\n {\n context: {\n agentName: params.agentName,\n conversationId: params.conversationId,\n },\n trace: [\n {\n at: \"core.run.prepareConversationReplayInput.validatePreparedInput.promptRole\",\n },\n ],\n },\n );\n }\n continue;\n }\n\n if (!(\"role\" in item) || typeof item.role !== \"string\") {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationReplay.prepareInput returned a role-less message for a chat-shaped model.\",\n {\n context: {\n agentName: params.agentName,\n conversationId: params.conversationId,\n },\n trace: [\n {\n at: \"core.run.prepareConversationReplayInput.validatePreparedInput.chatRole\",\n },\n ],\n },\n );\n }\n }\n\n return params.input;\n};\n\n/**\n * Validates that run input only uses modalities supported by the target model.\n */\nexport function validateRunInputCapabilities(params: {\n agent: AgentModelInfo;\n input: GenerativeModelInput;\n traceAt: string;\n}): void {\n const caps = params.agent.model.caps;\n\n if (typeof params.input === \"string\") {\n if (caps.inputModalities?.text === false) {\n throwUnsupportedInputModality({\n agent: params.agent,\n modality: \"text\",\n location: \"input\",\n traceAt: params.traceAt,\n });\n }\n return;\n }\n\n for (const [itemIndex, item] of params.input.entries()) {\n if (item.type !== \"message\") {\n continue;\n }\n\n validateMessageContentCapabilities({\n agent: params.agent,\n content: item.content,\n itemIndex,\n traceAt: params.traceAt,\n });\n }\n}\n\n/**\n * Validates requested output modalities against the target model's capabilities.\n */\nexport function validateRunModalities(params: {\n agent: AgentModelInfo;\n modalities: readonly Modality[] | undefined;\n output: OutputSchemaDefinition | undefined;\n traceAt: string;\n}): void {\n if (!params.modalities || params.modalities.length === 0) {\n return;\n }\n\n const caps = params.agent.model.caps;\n\n for (const modality of params.modalities) {\n if (caps.outputModalities?.[modality] !== undefined) {\n continue;\n }\n\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Agent '${params.agent.name}' model does not support ${modality} output.`,\n {\n context: {\n agentName: params.agent.name,\n modelId: params.agent.model.modelId,\n modality,\n },\n trace: [{ at: params.traceAt }],\n },\n );\n }\n\n if (params.output !== undefined && !params.modalities.includes(\"text\")) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Structured output requires text output for agent '${params.agent.name}'.`,\n {\n context: {\n agentName: params.agent.name,\n modelId: params.agent.model.modelId,\n modalities: [...params.modalities],\n },\n trace: [{ at: params.traceAt }],\n },\n );\n }\n}\n\n/**\n * Prepares replayable model input from durable conversation items for a run.\n *\n * Stored history is projected losslessly first. The run can then override that\n * projection with `prepareInput`, or fall back to capability-based pruning.\n */\nexport function prepareConversationReplayInput(params: {\n items: ConversationItem[];\n caps: Capabilities;\n agentName: string;\n conversationId: string;\n conversationReplay?: ConversationReplayOptions;\n}): Awaitable<GenerativeModelInputItem[]> {\n const projected = projectConversationItemsToInput(params.items, params.caps);\n const replay = params.conversationReplay;\n\n if (typeof replay?.prepareInput === \"function\") {\n return Promise.resolve(\n replay.prepareInput({\n items: params.items,\n caps: params.caps,\n agentName: params.agentName,\n conversationId: params.conversationId,\n }),\n ).then((input) =>\n validatePreparedReplayInput({\n input,\n caps: params.caps,\n agentName: params.agentName,\n conversationId: params.conversationId,\n }),\n );\n }\n\n if (replay?.omitUnsupportedParts === false) {\n return projected;\n }\n\n return pruneInputByCapabilities(projected, params.caps);\n}\n\n/**\n * Converts a public output schema definition into a provider request.\n */\nexport function toStructuredOutputRequest(\n agent: Pick<AnyAgentDefinition, \"model\" | \"name\" | \"outputSchema\">,\n output: OutputSchemaDefinition | undefined,\n): StructuredOutput | undefined {\n if (output === undefined) {\n return undefined;\n }\n\n const modelCaps = agent.model.caps;\n if (!modelCaps.structured_output) {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Model '${agent.model.modelId}' does not support structured output.`,\n {\n context: {\n agentName: agent.name,\n modelId: agent.model.modelId,\n },\n trace: [{ at: \"core.run.toStructuredOutputRequest.capability\" }],\n },\n );\n }\n\n const preflightedSchema =\n output === agent.outputSchema ? getPreflightedOutputSchema(agent) : undefined;\n if (preflightedSchema !== undefined) {\n return {\n name: output.name ?? `${agent.name}_output`,\n schema: normalizeStructuredOutputJsonSchema(preflightedSchema),\n strict: output.strict,\n };\n }\n\n const runtimeResolvedSchema = resolveToJsonSchema(output.schema as never);\n if (runtimeResolvedSchema.isErr()) {\n throw runtimeResolvedSchema.error.at({\n at: \"core.run.toStructuredOutputRequest.resolveSchema\",\n });\n }\n\n return {\n name: output.name ?? `${agent.name}_output`,\n schema: normalizeStructuredOutputJsonSchema(runtimeResolvedSchema.value),\n strict: output.strict,\n };\n}\n\n/**\n * Parses and validates structured output from a provider response.\n *\n * Structured output currently requires text output.\n */\nexport async function finalizeRunResult(\n result: RunResult & { items: ConversationItem[] },\n output: OutputSchemaDefinition | undefined,\n options?: {\n outputErrorMode?: OutputErrorMode;\n onOutputError?: OnOutputError;\n },\n): Promise<RunResult & { items: ConversationItem[] }> {\n if (output === undefined) {\n return result;\n }\n\n const outputMessages = result.response.output.filter(\n (item): item is GenerativeModelOutputMessage => item.type === \"message\",\n );\n const resolvedOutputErrorMode = options?.outputErrorMode ?? \"throw\";\n\n const getLastStructuredText = () =>\n outputMessages\n .map((message) =>\n typeof message.content === \"string\"\n ? message.content\n : message.content\n .filter(\n (\n part,\n ): part is Extract<\n (typeof message.content)[number],\n { type: \"text\" }\n > => part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\"\"),\n )\n .filter((text) => text.trim().length > 0)\n .at(-1);\n\n const defaultOutputErrorBehavior = (error: unknown): never => {\n throw error;\n };\n\n const validateStructuredValue = async (\n value: unknown,\n text: string,\n repairDepth: number,\n ): Promise<unknown> => {\n const validated = await validateInput(output.schema, value);\n if (validated.isErr()) {\n return await resolveOutputError(\n {\n errorKind: \"validation\",\n error: validated.error.at({ at: \"core.run.finalizeRunResult.validateSchema\" }),\n text,\n value,\n },\n repairDepth,\n );\n }\n\n return validated.value;\n };\n\n const parseStructuredText = async (text: string, repairDepth: number): Promise<unknown> => {\n const parsed = safeJsonParse(text);\n if (parsed.isErr()) {\n return await resolveOutputError(\n {\n errorKind: \"parse\",\n error: BetterAgentError.wrap({\n err: parsed.error,\n message:\n \"Structured output was requested, but the model returned invalid JSON.\",\n opts: {\n code: \"VALIDATION_FAILED\",\n context: {\n preview: text.slice(0, 200),\n },\n trace: [{ at: \"core.run.finalizeRunResult.parseJson\" }],\n },\n }),\n text,\n },\n repairDepth,\n );\n }\n\n return await validateStructuredValue(parsed.value, text, repairDepth);\n };\n\n const resolveOutputError = async (\n context: OutputErrorContext,\n repairDepth: number,\n ): Promise<unknown> => {\n if (resolvedOutputErrorMode === \"throw\" || repairDepth >= MAX_OUTPUT_REPAIR_DEPTH) {\n return defaultOutputErrorBehavior(context.error);\n }\n\n const action = await options?.onOutputError?.(context);\n\n switch (action?.action) {\n case \"repair_text\":\n return await parseStructuredText(action.text, repairDepth + 1);\n case \"repair_value\":\n return await validateStructuredValue(\n action.value,\n \"text\" in context ? context.text : \"\",\n repairDepth + 1,\n );\n case \"throw\":\n throw context.error;\n default:\n return defaultOutputErrorBehavior(context.error);\n }\n };\n\n const lastText = getLastStructuredText();\n if (!lastText) {\n const missingTextError = BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"Structured output was requested, but the model did not return JSON text.\",\n {\n trace: [{ at: \"core.run.finalizeRunResult.noStructuredText\" }],\n },\n );\n\n const structured = await resolveOutputError(\n {\n errorKind: \"missing_text\",\n error: missingTextError,\n },\n 0,\n );\n\n return {\n ...result,\n structured,\n };\n }\n\n const structured = await parseStructuredText(lastText, 0);\n\n return {\n ...result,\n structured,\n };\n}\n\n/**\n * Shared id generator for runs and messages.\n */\nexport const generateId = createIdGenerator({\n prefixes: {\n run: \"run\",\n message: \"msg\",\n },\n});\n\n/**\n * Loads persisted conversation history and returns:\n * - `input`: the model-facing input for this run\n * - `items`: the durable conversation state to mutate and save\n * - `loaded`: the original persisted record for save concurrency\n * - `replayStartIndex`: where the current run's replay window starts in `items`\n *\n * `replayStartIndex` is `loaded.items.length` when older history should be kept in\n * durable state but excluded from per-step replay, otherwise it is `0`.\n */\nexport async function loadConversationMessages(params: {\n conversations?: ConversationStore;\n conversationId?: string;\n agentName?: string;\n input: GenerativeModelInput;\n caps?: Capabilities;\n replaceHistory?: boolean;\n conversationReplay?: ConversationReplayOptions;\n}): Promise<{\n input: GenerativeModelInput;\n items: ConversationItem[];\n replayStartIndex: number;\n conversationReplayActive: boolean;\n loaded?: LoadedConversation;\n}> {\n const inputItems = normalizeInputToMessages(\n params.input,\n params.caps ?? { inputShape: \"chat\" },\n );\n const durableInputItems = normalizeInputToConversationItems(\n params.input,\n params.caps ?? { inputShape: \"chat\" },\n );\n\n if (!params.conversations || params.conversationId === undefined) {\n return {\n input: params.input,\n items: durableInputItems,\n replayStartIndex: 0,\n conversationReplayActive: false,\n };\n }\n\n if (!params.agentName) {\n throw BetterAgentError.fromCode(\n \"INTERNAL\",\n \"agentName is required when loading conversation messages.\",\n {\n context: { conversationId: params.conversationId },\n trace: [{ at: \"core.run.loadConversationMessages.missingAgentName\" }],\n },\n );\n }\n\n const loaded = await params.conversations.load({\n conversationId: params.conversationId,\n agentName: params.agentName,\n });\n if (!loaded) {\n return {\n input: params.input,\n items: durableInputItems,\n replayStartIndex: 0,\n conversationReplayActive: false,\n };\n }\n\n validateStoredConversationItems(loaded.items, params.conversationId);\n\n if (params.replaceHistory) {\n return {\n input: params.input,\n items: durableInputItems,\n replayStartIndex: 0,\n conversationReplayActive: false,\n loaded,\n };\n }\n\n const caps = params.caps ?? { inputShape: \"chat\" };\n const replayMode =\n caps.replayMode ?? (caps.inputShape === \"prompt\" ? \"single_turn_persistent\" : \"multi_turn\");\n\n if (replayMode === \"single_turn_only\") {\n return {\n input: params.input,\n items: durableInputItems,\n replayStartIndex: 0,\n conversationReplayActive: false,\n loaded,\n };\n }\n\n if (replayMode === \"single_turn_persistent\") {\n return {\n input: params.input,\n items: [...loaded.items, ...durableInputItems],\n replayStartIndex: loaded.items.length,\n conversationReplayActive: false,\n loaded,\n };\n }\n\n const loadedMessages = await prepareConversationReplayInput({\n items: loaded.items,\n caps,\n agentName: params.agentName,\n conversationId: params.conversationId,\n conversationReplay: params.conversationReplay,\n });\n\n return {\n input: [...loadedMessages, ...inputItems],\n items: [...loaded.items, ...durableInputItems],\n replayStartIndex: 0,\n conversationReplayActive: true,\n loaded,\n };\n}\n\n/**\n * Saves durable conversation items after a run completes.\n */\nexport async function saveConversationMessages(params: {\n conversations?: ConversationStore;\n conversationId?: string;\n agentName?: string;\n result: { items: ConversationItem[] };\n loaded?: LoadedConversation;\n}): Promise<void> {\n if (!params.conversations || params.conversationId === undefined) {\n return;\n }\n\n if (!params.agentName) {\n throw BetterAgentError.fromCode(\n \"INTERNAL\",\n \"agentName is required when saving conversation messages.\",\n {\n context: { conversationId: params.conversationId },\n trace: [{ at: \"core.run.saveConversationMessages.missingAgentName\" }],\n },\n );\n }\n\n try {\n validateStoredConversationItems(params.result.items, params.conversationId);\n await params.conversations.save({\n conversationId: params.conversationId,\n agentName: params.agentName,\n items: params.result.items,\n ...(params.loaded?.cursor !== undefined\n ? { expectedCursor: params.loaded.cursor }\n : {}),\n });\n } catch (error) {\n const code =\n typeof (error as { code?: unknown })?.code === \"string\"\n ? ((error as { code: string }).code as BetterAgentError[\"code\"])\n : undefined;\n const status =\n typeof (error as { status?: unknown })?.status === \"number\"\n ? (error as { status: number }).status\n : undefined;\n\n throw BetterAgentError.wrap({\n err: error,\n message: \"Failed to save conversation messages.\",\n opts: {\n ...(code !== undefined ? { code } : {}),\n ...(status !== undefined ? { status } : {}),\n context: {\n conversationId: params.conversationId,\n agentName: params.agentName,\n },\n trace: [{ at: \"core.run.saveConversationMessages\" }],\n },\n });\n }\n}\n"],"mappings":"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"}
@@ -5,6 +5,31 @@ const getAssistantMessageIdFromEvent = (event) => {
5
5
  if ("parentMessageId" in event && typeof event.parentMessageId === "string" && event.parentMessageId.length > 0) return event.parentMessageId;
6
6
  if ("messageId" in event && typeof event.messageId === "string" && event.messageId.length > 0 && "role" in event && event.role === "assistant") return event.messageId;
7
7
  };
8
+ const resolveToolTarget = (tools, toolCallName) => {
9
+ const tool = tools.find((candidate) => {
10
+ if (candidate.kind === "hosted") return candidate.name === toolCallName || candidate.type === toolCallName;
11
+ return candidate.name === toolCallName;
12
+ });
13
+ if (!tool) return;
14
+ return tool.kind;
15
+ };
16
+ const enrichToolEvent = (event, params) => {
17
+ switch (event.type) {
18
+ case "TOOL_CALL_START":
19
+ case "TOOL_CALL_ARGS":
20
+ case "TOOL_CALL_END":
21
+ case "TOOL_CALL_RESULT": {
22
+ const toolTarget = resolveToolTarget(params.tools, event.toolCallName);
23
+ return {
24
+ ...event,
25
+ runId: params.runId,
26
+ agentName: params.agentName,
27
+ ...toolTarget !== void 0 ? { toolTarget } : {}
28
+ };
29
+ }
30
+ default: return event;
31
+ }
32
+ };
8
33
  const createRunModelCallStrategy = () => ({
9
34
  mode: "run",
10
35
  async call(params) {
@@ -43,8 +68,13 @@ const createRunModelCallStrategy = () => ({
43
68
  if (responseResult.isErr()) throw responseResult.error;
44
69
  const { response, events } = responseResult.value;
45
70
  for (const event of events ?? []) {
46
- assistantMessageId = getAssistantMessageIdFromEvent(event) ?? assistantMessageId;
47
- await options.emit({ ...event });
71
+ const enrichedEvent = enrichToolEvent(event, {
72
+ runId: params.runId,
73
+ agentName: params.agentName,
74
+ tools: params.tools
75
+ });
76
+ assistantMessageId = getAssistantMessageIdFromEvent(enrichedEvent) ?? assistantMessageId;
77
+ await options.emit({ ...enrichedEvent });
48
78
  }
49
79
  return {
50
80
  response,
@@ -90,8 +120,13 @@ const createStreamModelCallStrategy = () => ({
90
120
  if (streamResult.isErr()) throw streamResult.error;
91
121
  for await (const eventResult of streamResult.value.events) {
92
122
  if (eventResult.isErr()) throw eventResult.error;
93
- assistantMessageId = getAssistantMessageIdFromEvent(eventResult.value) ?? assistantMessageId;
94
- await options.emit({ ...eventResult.value });
123
+ const enrichedEvent = enrichToolEvent(eventResult.value, {
124
+ runId: params.runId,
125
+ agentName: params.agentName,
126
+ tools: params.tools
127
+ });
128
+ assistantMessageId = getAssistantMessageIdFromEvent(enrichedEvent) ?? assistantMessageId;
129
+ await options.emit({ ...enrichedEvent });
95
130
  }
96
131
  return {
97
132
  response: await streamResult.value.final,
@@ -1 +1 @@
1
- {"version":3,"file":"model-strategy.mjs","names":[],"sources":["../../src/run/model-strategy.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport type { Event } from \"../events\";\nimport type { ModelCallStrategy } from \"./types\";\n\nconst getAssistantMessageIdFromEvent = (event: Event): string | undefined => {\n if (\n \"parentMessageId\" in event &&\n typeof event.parentMessageId === \"string\" &&\n event.parentMessageId.length > 0\n ) {\n return event.parentMessageId;\n }\n\n if (\n \"messageId\" in event &&\n typeof event.messageId === \"string\" &&\n event.messageId.length > 0 &&\n \"role\" in event &&\n event.role === \"assistant\"\n ) {\n return event.messageId;\n }\n\n return undefined;\n};\n\nexport const createRunModelCallStrategy = <TContext>(): ModelCallStrategy<TContext> => ({\n mode: \"run\",\n async call(params) {\n const { options } = params;\n let firstGeneratedMessageId: string | undefined;\n let assistantMessageId: string | undefined;\n const generateMessageId = () => {\n const id = options.generateMessageId();\n firstGeneratedMessageId ??= id;\n return id;\n };\n\n const modelContext = {\n runId: params.runId,\n agentName: params.agentName,\n providerId: options.agent.model.providerId,\n modelId: options.agent.model.modelId,\n signal: options.signal,\n generateMessageId,\n conversationId: params.conversationId,\n };\n\n if (!options.agent.model.doGenerate) {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Model '${options.agent.model.modelId}' does not implement doGenerate().`,\n {\n context: {\n agentName: params.agentName,\n modelId: options.agent.model.modelId,\n },\n trace: [{ at: \"core.run.runLoop.model.doGenerate\" }],\n },\n );\n }\n\n const responseResult = await options.agent.model.doGenerate(\n {\n ...(options.modelOptions ?? {}),\n input: params.modelInput,\n modalities: options.modalities,\n tools: params.tools.length > 0 ? params.tools : undefined,\n toolChoice: params.toolChoice,\n structured_output: options.structuredOutput,\n },\n modelContext,\n );\n if (responseResult.isErr()) {\n throw responseResult.error;\n }\n\n const { response, events } = responseResult.value;\n for (const event of events ?? []) {\n assistantMessageId = getAssistantMessageIdFromEvent(event) ?? assistantMessageId;\n await options.emit({\n ...event,\n });\n }\n\n return {\n response,\n // Prefer the provider ID, then reuse or generate one.\n assistantMessageId:\n assistantMessageId ?? firstGeneratedMessageId ?? generateMessageId(),\n };\n },\n});\n\nexport const createStreamModelCallStrategy = <TContext>(): ModelCallStrategy<TContext> => ({\n mode: \"stream\",\n async call(params) {\n const { options } = params;\n let firstGeneratedMessageId: string | undefined;\n let assistantMessageId: string | undefined;\n const generateMessageId = () => {\n const id = options.generateMessageId();\n firstGeneratedMessageId ??= id;\n return id;\n };\n\n const modelContext = {\n runId: params.runId,\n agentName: params.agentName,\n providerId: options.agent.model.providerId,\n modelId: options.agent.model.modelId,\n signal: options.signal,\n generateMessageId,\n conversationId: params.conversationId,\n };\n\n if (!options.agent.model.doGenerateStream) {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Model '${options.agent.model.modelId}' does not implement doGenerateStream().`,\n {\n context: {\n agentName: params.agentName,\n modelId: options.agent.model.modelId,\n },\n trace: [{ at: \"core.run.runStreamLoop.model.doGenerateStream\" }],\n },\n );\n }\n\n const streamResult = await options.agent.model.doGenerateStream(\n {\n ...(options.modelOptions ?? {}),\n input: params.modelInput,\n modalities: options.modalities,\n tools: params.tools.length > 0 ? params.tools : undefined,\n toolChoice: params.toolChoice,\n structured_output: options.structuredOutput,\n },\n modelContext,\n );\n\n if (streamResult.isErr()) {\n throw streamResult.error;\n }\n\n for await (const eventResult of streamResult.value.events) {\n if (eventResult.isErr()) {\n throw eventResult.error;\n }\n\n assistantMessageId =\n getAssistantMessageIdFromEvent(eventResult.value) ?? assistantMessageId;\n await options.emit({\n ...eventResult.value,\n });\n }\n\n return {\n response: await streamResult.value.final,\n // Prefer the provider ID, then reuse or generate one.\n assistantMessageId:\n assistantMessageId ?? firstGeneratedMessageId ?? generateMessageId(),\n };\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"model-strategy.mjs","names":[],"sources":["../../src/run/model-strategy.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport type { Event } from \"../events\";\nimport type { AgentToolDefinition, ToolTarget } from \"../tools\";\nimport type { ModelCallStrategy } from \"./types\";\n\nconst getAssistantMessageIdFromEvent = (event: Event): string | undefined => {\n if (\n \"parentMessageId\" in event &&\n typeof event.parentMessageId === \"string\" &&\n event.parentMessageId.length > 0\n ) {\n return event.parentMessageId;\n }\n\n if (\n \"messageId\" in event &&\n typeof event.messageId === \"string\" &&\n event.messageId.length > 0 &&\n \"role\" in event &&\n event.role === \"assistant\"\n ) {\n return event.messageId;\n }\n\n return undefined;\n};\n\nconst resolveToolTarget = (\n tools: AgentToolDefinition[],\n toolCallName: string,\n): ToolTarget | undefined => {\n const tool = tools.find((candidate) => {\n if (candidate.kind === \"hosted\") {\n return candidate.name === toolCallName || candidate.type === toolCallName;\n }\n\n return candidate.name === toolCallName;\n });\n\n if (!tool) {\n return undefined;\n }\n\n return tool.kind;\n};\n\nconst enrichToolEvent = (\n event: Event,\n params: {\n runId: string;\n agentName: string;\n tools: AgentToolDefinition[];\n },\n): Event => {\n switch (event.type) {\n case \"TOOL_CALL_START\":\n case \"TOOL_CALL_ARGS\":\n case \"TOOL_CALL_END\":\n case \"TOOL_CALL_RESULT\": {\n const toolTarget = resolveToolTarget(params.tools, event.toolCallName);\n return {\n ...event,\n runId: params.runId,\n agentName: params.agentName,\n ...(toolTarget !== undefined ? { toolTarget } : {}),\n };\n }\n default:\n return event;\n }\n};\n\nexport const createRunModelCallStrategy = <TContext>(): ModelCallStrategy<TContext> => ({\n mode: \"run\",\n async call(params) {\n const { options } = params;\n let firstGeneratedMessageId: string | undefined;\n let assistantMessageId: string | undefined;\n const generateMessageId = () => {\n const id = options.generateMessageId();\n firstGeneratedMessageId ??= id;\n return id;\n };\n\n const modelContext = {\n runId: params.runId,\n agentName: params.agentName,\n providerId: options.agent.model.providerId,\n modelId: options.agent.model.modelId,\n signal: options.signal,\n generateMessageId,\n conversationId: params.conversationId,\n };\n\n if (!options.agent.model.doGenerate) {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Model '${options.agent.model.modelId}' does not implement doGenerate().`,\n {\n context: {\n agentName: params.agentName,\n modelId: options.agent.model.modelId,\n },\n trace: [{ at: \"core.run.runLoop.model.doGenerate\" }],\n },\n );\n }\n\n const responseResult = await options.agent.model.doGenerate(\n {\n ...(options.modelOptions ?? {}),\n input: params.modelInput,\n modalities: options.modalities,\n tools: params.tools.length > 0 ? params.tools : undefined,\n toolChoice: params.toolChoice,\n structured_output: options.structuredOutput,\n },\n modelContext,\n );\n if (responseResult.isErr()) {\n throw responseResult.error;\n }\n\n const { response, events } = responseResult.value;\n for (const event of events ?? []) {\n const enrichedEvent = enrichToolEvent(event, {\n runId: params.runId,\n agentName: params.agentName,\n tools: params.tools,\n });\n assistantMessageId =\n getAssistantMessageIdFromEvent(enrichedEvent) ?? assistantMessageId;\n await options.emit({\n ...enrichedEvent,\n });\n }\n\n return {\n response,\n // Prefer the provider ID, then reuse or generate one.\n assistantMessageId:\n assistantMessageId ?? firstGeneratedMessageId ?? generateMessageId(),\n };\n },\n});\n\nexport const createStreamModelCallStrategy = <TContext>(): ModelCallStrategy<TContext> => ({\n mode: \"stream\",\n async call(params) {\n const { options } = params;\n let firstGeneratedMessageId: string | undefined;\n let assistantMessageId: string | undefined;\n const generateMessageId = () => {\n const id = options.generateMessageId();\n firstGeneratedMessageId ??= id;\n return id;\n };\n\n const modelContext = {\n runId: params.runId,\n agentName: params.agentName,\n providerId: options.agent.model.providerId,\n modelId: options.agent.model.modelId,\n signal: options.signal,\n generateMessageId,\n conversationId: params.conversationId,\n };\n\n if (!options.agent.model.doGenerateStream) {\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n `Model '${options.agent.model.modelId}' does not implement doGenerateStream().`,\n {\n context: {\n agentName: params.agentName,\n modelId: options.agent.model.modelId,\n },\n trace: [{ at: \"core.run.runStreamLoop.model.doGenerateStream\" }],\n },\n );\n }\n\n const streamResult = await options.agent.model.doGenerateStream(\n {\n ...(options.modelOptions ?? {}),\n input: params.modelInput,\n modalities: options.modalities,\n tools: params.tools.length > 0 ? params.tools : undefined,\n toolChoice: params.toolChoice,\n structured_output: options.structuredOutput,\n },\n modelContext,\n );\n\n if (streamResult.isErr()) {\n throw streamResult.error;\n }\n\n for await (const eventResult of streamResult.value.events) {\n if (eventResult.isErr()) {\n throw eventResult.error;\n }\n\n const enrichedEvent = enrichToolEvent(eventResult.value, {\n runId: params.runId,\n agentName: params.agentName,\n tools: params.tools,\n });\n assistantMessageId =\n getAssistantMessageIdFromEvent(enrichedEvent) ?? assistantMessageId;\n await options.emit({\n ...enrichedEvent,\n });\n }\n\n return {\n response: await streamResult.value.final,\n // Prefer the provider ID, then reuse or generate one.\n assistantMessageId:\n assistantMessageId ?? firstGeneratedMessageId ?? generateMessageId(),\n };\n },\n});\n"],"mappings":"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"}
@@ -7,10 +7,9 @@ function createAgentRegistry(agents) {
7
7
  for (const agent of agents) registry.set(agent.name, agent);
8
8
  return registry;
9
9
  }
10
- function resolveAgentFromRegistry(agents, agent, traceAt) {
11
- const resolved = typeof agent === "string" ? agents.get(agent) : agents.get(agent.name) ?? agent;
10
+ function resolveAgentFromRegistry(agents, agentName, traceAt) {
11
+ const resolved = agents.get(agentName);
12
12
  if (resolved) return resolved;
13
- const agentName = typeof agent === "string" ? agent : agent.name;
14
13
  throw BetterAgentError.fromCode("NOT_FOUND", `Agent '${agentName}' does not exist.`, {
15
14
  context: { agentName },
16
15
  trace: [{ at: traceAt }]
@@ -1 +1 @@
1
- {"version":3,"file":"registry.mjs","names":[],"sources":["../../src/run/registry.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport type { AnyAgentDefinition } from \"../agent\";\n\n/** Builds a read-only agent registry. */\nexport function createAgentRegistry(\n agents: readonly AnyAgentDefinition[],\n): ReadonlyMap<string, AnyAgentDefinition> {\n const registry = new Map<string, AnyAgentDefinition>();\n\n for (const agent of agents) {\n registry.set(agent.name, agent);\n }\n\n return registry;\n}\n\nexport function resolveAgentFromRegistry(\n agents: ReadonlyMap<string, AnyAgentDefinition>,\n agent: string | AnyAgentDefinition,\n traceAt: string,\n): AnyAgentDefinition {\n const resolved =\n typeof agent === \"string\" ? agents.get(agent) : (agents.get(agent.name) ?? agent);\n if (resolved) {\n return resolved;\n }\n\n const agentName = typeof agent === \"string\" ? agent : agent.name;\n throw BetterAgentError.fromCode(\"NOT_FOUND\", `Agent '${agentName}' does not exist.`, {\n context: { agentName },\n trace: [{ at: traceAt }],\n });\n}\n"],"mappings":";;;;AAIA,SAAgB,oBACZ,QACuC;CACvC,MAAM,2BAAW,IAAI,KAAiC;AAEtD,MAAK,MAAM,SAAS,OAChB,UAAS,IAAI,MAAM,MAAM,MAAM;AAGnC,QAAO;;AAGX,SAAgB,yBACZ,QACA,OACA,SACkB;CAClB,MAAM,WACF,OAAO,UAAU,WAAW,OAAO,IAAI,MAAM,GAAI,OAAO,IAAI,MAAM,KAAK,IAAI;AAC/E,KAAI,SACA,QAAO;CAGX,MAAM,YAAY,OAAO,UAAU,WAAW,QAAQ,MAAM;AAC5D,OAAM,iBAAiB,SAAS,aAAa,UAAU,UAAU,oBAAoB;EACjF,SAAS,EAAE,WAAW;EACtB,OAAO,CAAC,EAAE,IAAI,SAAS,CAAC;EAC3B,CAAC"}
1
+ {"version":3,"file":"registry.mjs","names":[],"sources":["../../src/run/registry.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport type { AnyAgentDefinition } from \"../agent\";\n\n/** Builds a read-only agent registry. */\nexport function createAgentRegistry(\n agents: readonly AnyAgentDefinition[],\n): ReadonlyMap<string, AnyAgentDefinition> {\n const registry = new Map<string, AnyAgentDefinition>();\n\n for (const agent of agents) {\n registry.set(agent.name, agent);\n }\n\n return registry;\n}\n\nexport function resolveAgentFromRegistry(\n agents: ReadonlyMap<string, AnyAgentDefinition>,\n agentName: string,\n traceAt: string,\n): AnyAgentDefinition {\n const resolved = agents.get(agentName);\n if (resolved) {\n return resolved;\n }\n\n throw BetterAgentError.fromCode(\"NOT_FOUND\", `Agent '${agentName}' does not exist.`, {\n context: { agentName },\n trace: [{ at: traceAt }],\n });\n}\n"],"mappings":";;;;AAIA,SAAgB,oBACZ,QACuC;CACvC,MAAM,2BAAW,IAAI,KAAiC;AAEtD,MAAK,MAAM,SAAS,OAChB,UAAS,IAAI,MAAM,MAAM,MAAM;AAGnC,QAAO;;AAGX,SAAgB,yBACZ,QACA,WACA,SACkB;CAClB,MAAM,WAAW,OAAO,IAAI,UAAU;AACtC,KAAI,SACA,QAAO;AAGX,OAAM,iBAAiB,SAAS,aAAa,UAAU,UAAU,oBAAoB;EACjF,SAAS,EAAE,WAAW;EACtB,OAAO,CAAC,EAAE,IAAI,SAAS,CAAC;EAC3B,CAAC"}
@@ -142,10 +142,7 @@ function createRuntime(options) {
142
142
  }) : params.result.items;
143
143
  if (params.saveConversationParams) await saveConversationMessages({
144
144
  ...params.saveConversationParams,
145
- result: {
146
- ...params.result,
147
- items: itemsToSave
148
- }
145
+ result: { items: itemsToSave }
149
146
  });
150
147
  const publicResult = {
151
148
  response: params.result.response,
@@ -228,7 +225,7 @@ function createRuntime(options) {
228
225
  conversationReplay: effectiveConversationReplay
229
226
  });
230
227
  const validatedContext = await validateAgentContext(resolvedAgent, runOptions.context);
231
- const resolvedConversations = runOptions.persistence?.conversations ?? options.conversations;
228
+ const resolvedConversations = resolvedPersistence?.conversations;
232
229
  const conversationInput = await loadConversationMessages({
233
230
  input: runOptions.input,
234
231
  caps: resolvedAgent.model.caps,
@@ -315,7 +312,12 @@ function createRuntime(options) {
315
312
  });
316
313
  const queue = createAsyncEventQueue();
317
314
  const runPersistence = runOptions.persistence;
318
- const streamStore = runPersistence?.stream ?? options.stream;
315
+ const resolvedPersistence = buildPersistence(runPersistence, {
316
+ stream: options.stream,
317
+ conversations: options.conversations,
318
+ runtimeState: options.runtimeState
319
+ });
320
+ const streamStore = resolvedPersistence?.stream;
319
321
  const execution = createRuntimeExecutionContext({
320
322
  resolvedAgent,
321
323
  conversationId: runOptions.conversationId,
@@ -326,11 +328,6 @@ function createRuntime(options) {
326
328
  streamStore,
327
329
  queue
328
330
  });
329
- const resolvedPersistence = buildPersistence(runPersistence, {
330
- stream: streamStore,
331
- conversations: options.conversations,
332
- runtimeState: options.runtimeState
333
- });
334
331
  const result = (async () => {
335
332
  try {
336
333
  const effectiveConversationReplay = resolveConversationReplay(resolvedAgent, runOptions.conversationReplay);
@@ -339,7 +336,7 @@ function createRuntime(options) {
339
336
  conversationReplay: effectiveConversationReplay
340
337
  });
341
338
  const validatedContext = await validateAgentContext(resolvedAgent, runOptions.context);
342
- const resolvedConversations = runPersistence?.conversations ?? options.conversations;
339
+ const resolvedConversations = resolvedPersistence?.conversations;
343
340
  const conversationInput = await loadConversationMessages({
344
341
  input: runOptions.input,
345
342
  caps: resolvedAgent.model.caps,
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.mjs","names":[],"sources":["../../src/run/runtime.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { logger } from \"@better-agent/shared/logger\";\nimport type { AnyAgentDefinition } from \"../agent\";\nimport { type Event, Events } from \"../events\";\nimport type { ConversationRuntimeStateStore, ConversationStore, StreamStore } from \"../persistence\";\nimport type { PluginRuntime } from \"../plugins\";\nimport type { ConversationItem, OutputSchemaDefinition } from \"../providers\";\nimport { type AsyncEventQueue, createAsyncEventQueue } from \"./event-queue\";\nimport { executeRun } from \"./execution\";\nimport {\n createStreamPersistenceEmitter,\n generateId,\n loadConversationMessages,\n saveConversationMessages,\n toEventEmitter,\n validateAgentContext,\n validateStoredConversationItems,\n} from \"./helpers\";\nimport { createPendingToolRuntime } from \"./pending-tools\";\nimport { createAgentRegistry, resolveAgentFromRegistry } from \"./registry\";\nimport type {\n BetterAgentRuntime,\n ContextBoundAgent,\n ResumeConversationOptions,\n RunAdvancedOptions,\n RunOptions,\n RunResult,\n StreamResult,\n SubmitToolApprovalParams,\n SubmitToolResultParams,\n} from \"./types\";\n\n/** Creates a runtime for registered agents. */\nexport function createRuntime<const TAgents extends readonly AnyAgentDefinition[]>(options: {\n agents: TAgents;\n pluginRuntime?: PluginRuntime | null;\n stream?: StreamStore;\n conversations?: ConversationStore;\n runtimeState?: ConversationRuntimeStateStore;\n streamLifecycle?: \"request_bound\" | \"detached\";\n advanced?: RunAdvancedOptions;\n}): BetterAgentRuntime<TAgents> {\n const agents = createAgentRegistry(options.agents);\n const pluginRuntime = options.pluginRuntime ?? null;\n const pendingToolRuntime = createPendingToolRuntime();\n const streamLifecycle = options.streamLifecycle ?? \"request_bound\";\n const activeRuns = new Map<string, AbortController>();\n\n const resolveConversationReplay = (\n agent: AnyAgentDefinition,\n runReplay: RunOptions<unknown>[\"conversationReplay\"],\n ): RunOptions<unknown>[\"conversationReplay\"] => {\n const agentReplay = agent.conversationReplay;\n if (!agentReplay && !runReplay) {\n return undefined;\n }\n\n const merged = {\n ...(agentReplay ?? {}),\n ...(runReplay ?? {}),\n };\n\n if (\n runReplay &&\n Object.prototype.hasOwnProperty.call(runReplay, \"prepareInput\") &&\n runReplay.prepareInput === null\n ) {\n merged.prepareInput = undefined;\n }\n\n return merged;\n };\n\n const warnIgnoredConversationReplay = (params: {\n agent: AnyAgentDefinition;\n conversationReplay: RunOptions<unknown>[\"conversationReplay\"];\n }) => {\n if (!params.conversationReplay) {\n return;\n }\n\n const replayMode =\n params.agent.model.caps.replayMode ??\n (params.agent.model.caps.inputShape === \"prompt\"\n ? \"single_turn_persistent\"\n : \"multi_turn\");\n\n if (replayMode === \"multi_turn\") {\n return;\n }\n\n logger.warn(\n `conversationReplay was provided for agent '${params.agent.name}', but model replayMode is '${replayMode}', so stored history replay customization was skipped.`,\n );\n };\n\n const buildPersistence = <TContext>(\n persistence?: RunOptions<TContext>[\"persistence\"],\n defaults?: {\n stream?: StreamStore;\n conversations?: ConversationStore;\n runtimeState?: ConversationRuntimeStateStore;\n },\n ) => {\n const resolved = {\n stream: persistence?.stream ?? defaults?.stream,\n conversations: persistence?.conversations ?? defaults?.conversations,\n runtimeState: persistence?.runtimeState ?? defaults?.runtimeState,\n };\n\n return resolved.stream || resolved.conversations || resolved.runtimeState\n ? resolved\n : undefined;\n };\n\n const createPluginEventContext = (params: {\n runId: string;\n agentName: string;\n conversationId?: string;\n abortController: AbortController;\n }) => ({\n runId: params.runId,\n agentName: params.agentName,\n conversationId: params.conversationId,\n control: {\n abortRun: async () => {\n params.abortController.abort();\n },\n },\n });\n\n const createLiveEmitter = (params: {\n runId: string;\n agentName: string;\n conversationId?: string;\n abortController: AbortController;\n persistenceEmit?: (event: Event) => Promise<void>;\n queuePush?: (event: Event) => Promise<void>;\n onEvent?: RunOptions<unknown>[\"onEvent\"];\n }) => {\n const userEmit = toEventEmitter(params.onEvent);\n\n return async (event: Event) => {\n const pluginEventContext = createPluginEventContext({\n runId: params.runId,\n agentName: params.agentName,\n abortController: params.abortController,\n conversationId: params.conversationId,\n });\n\n const transformed =\n pluginRuntime?.hasEventMiddleware === true\n ? await pluginRuntime.dispatchEvent(event, pluginEventContext)\n : event;\n\n if (!transformed) {\n return;\n }\n\n if (params.persistenceEmit) {\n await params.persistenceEmit(transformed);\n }\n\n if (pluginRuntime?.hasOnEvent) {\n await pluginRuntime.dispatchOnEvent(transformed, pluginEventContext);\n }\n\n if (params.queuePush) {\n await params.queuePush(transformed);\n }\n\n await userEmit(transformed);\n };\n };\n\n const wrapRuntimeError = (params: {\n error: unknown;\n message: string;\n traceAt: string;\n isAbort?: boolean;\n }) =>\n BetterAgentError.wrap({\n err: params.error,\n message: params.message,\n opts: {\n code: params.isAbort\n ? \"ABORTED\"\n : params.error instanceof BetterAgentError\n ? params.error.code\n : \"INTERNAL\",\n trace: [{ at: params.traceAt }],\n },\n });\n\n const emitSafely = async (emit: (event: Event) => Promise<void>, event: Event) => {\n try {\n await emit(event);\n } catch (error) {\n logger.error(\"Failed to emit runtime event.\", error);\n }\n };\n\n const closeStreamSafely = async (streamStore: StreamStore | undefined, runId: string) => {\n if (!streamStore) {\n return;\n }\n\n try {\n await streamStore.close(runId);\n } catch (error) {\n logger.error(`Failed to close stream '${runId}'.`, error);\n }\n };\n\n const createRuntimeExecutionContext = (params: {\n resolvedAgent: AnyAgentDefinition;\n conversationId?: string;\n onEvent?: RunOptions<unknown>[\"onEvent\"];\n externalSignal?: AbortSignal;\n streamStore?: StreamStore;\n queue?: AsyncEventQueue<Event>;\n queueSignal?: AbortSignal;\n detachFromExternalAbort?: boolean;\n }) => {\n const runId = generateId(\"run\");\n const abortController = new AbortController();\n activeRuns.set(runId, abortController);\n const signalController = new AbortController();\n const abortFromSignal = (signal: AbortSignal) => {\n if (!signalController.signal.aborted) {\n signalController.abort(signal.reason);\n }\n };\n const onInternalAbort = () => abortFromSignal(abortController.signal);\n const onExternalAbort = () => {\n if (params.externalSignal) {\n abortFromSignal(params.externalSignal);\n }\n };\n const signal = signalController.signal;\n const persistenceEmit = params.streamStore\n ? createStreamPersistenceEmitter({\n stream: params.streamStore,\n streamId: runId,\n })\n : undefined;\n const emit = createLiveEmitter({\n runId,\n agentName: params.resolvedAgent.name,\n abortController,\n conversationId: params.conversationId,\n persistenceEmit,\n queuePush: params.queue\n ? async (event) => {\n if (!params.queueSignal?.aborted) {\n params.queue?.push(event);\n }\n }\n : undefined,\n onEvent: params.onEvent,\n });\n\n abortController.signal.addEventListener(\"abort\", onInternalAbort, { once: true });\n if (params.externalSignal && !params.detachFromExternalAbort) {\n if (params.externalSignal.aborted) {\n abortFromSignal(params.externalSignal);\n } else {\n params.externalSignal.addEventListener(\"abort\", onExternalAbort, { once: true });\n }\n }\n\n if (params.queue && params.queueSignal) {\n const closeQueueOnAbort = () => params.queue?.close();\n if (params.queueSignal.aborted) {\n closeQueueOnAbort();\n } else {\n params.queueSignal.addEventListener(\"abort\", closeQueueOnAbort, { once: true });\n }\n }\n\n return {\n runId,\n signal,\n emit,\n cleanupSignal() {\n abortController.signal.removeEventListener(\"abort\", onInternalAbort);\n params.externalSignal?.removeEventListener(\"abort\", onExternalAbort);\n },\n };\n };\n\n const completeRunSuccess = async <TResult>(params: {\n runId: string;\n resolvedAgent: AnyAgentDefinition;\n conversationId?: string;\n emit: (event: Event) => Promise<void>;\n result: RunResult & { items: ConversationItem[] };\n saveConversationParams?: Omit<Parameters<typeof saveConversationMessages>[0], \"result\">;\n streamStore?: StreamStore;\n runtimeState?: ConversationRuntimeStateStore;\n queue?: AsyncEventQueue<Event>;\n success: (result: RunResult) => TResult;\n }) => {\n const itemsToSave =\n pluginRuntime?.hasOnBeforeSave === true\n ? await pluginRuntime.applyBeforeSave({\n runId: params.runId,\n agentName: params.resolvedAgent.name,\n items: params.result.items,\n conversationId: params.conversationId,\n })\n : params.result.items;\n\n if (params.saveConversationParams) {\n await saveConversationMessages({\n ...params.saveConversationParams,\n result: { ...params.result, items: itemsToSave },\n });\n }\n\n const publicResult = {\n response: params.result.response,\n structured: params.result.structured,\n };\n await params.emit({\n type: Events.RUN_FINISHED,\n runId: params.runId,\n agentName: params.resolvedAgent.name,\n result: publicResult,\n timestamp: Date.now(),\n conversationId: params.conversationId,\n });\n\n activeRuns.delete(params.runId);\n if (params.runtimeState && params.conversationId !== undefined) {\n await params.runtimeState.clear({\n conversationId: params.conversationId,\n agentName: params.resolvedAgent.name,\n });\n }\n await closeStreamSafely(params.streamStore, params.runId);\n params.queue?.close();\n pendingToolRuntime.clearRun(params.runId, \"Run finished\");\n return params.success(publicResult);\n };\n\n const handleRunFailure = async (params: {\n error: unknown;\n signal: AbortSignal;\n traceAt: string;\n emit: (event: Event) => Promise<void>;\n runId: string;\n resolvedAgent: AnyAgentDefinition;\n conversationId?: string;\n streamStore?: StreamStore;\n runtimeState?: ConversationRuntimeStateStore;\n queue?: AsyncEventQueue<Event>;\n }): Promise<never> => {\n const isAbort =\n params.signal.aborted ||\n (params.error instanceof BetterAgentError && params.error.code === \"ABORTED\");\n\n const wrapped = wrapRuntimeError({\n error: params.error,\n message: \"Run failed\",\n traceAt: params.traceAt,\n isAbort,\n });\n\n if (isAbort) {\n await emitSafely(params.emit, {\n type: Events.RUN_ABORTED,\n runId: params.runId,\n agentName: params.resolvedAgent.name,\n timestamp: Date.now(),\n conversationId: params.conversationId,\n });\n } else {\n await emitSafely(params.emit, {\n type: Events.RUN_ERROR,\n runId: params.runId,\n agentName: params.resolvedAgent.name,\n error: wrapped,\n timestamp: Date.now(),\n conversationId: params.conversationId,\n });\n }\n\n activeRuns.delete(params.runId);\n if (params.runtimeState && params.conversationId !== undefined) {\n await params.runtimeState.clear({\n conversationId: params.conversationId,\n agentName: params.resolvedAgent.name,\n });\n }\n await closeStreamSafely(params.streamStore, params.runId);\n params.queue?.fail(wrapped);\n pendingToolRuntime.clearRun(params.runId, wrapped.message);\n throw wrapped;\n };\n\n return {\n streamLifecycle,\n run: (async <TContext, TOutput extends OutputSchemaDefinition | undefined = undefined>(\n agent: TAgents[number][\"name\"],\n runOptions: RunOptions<TContext, TOutput>,\n ): Promise<RunResult> => {\n const resolvedAgent = resolveAgentFromRegistry(\n agents,\n agent,\n \"core.run.createRuntime.run\",\n ) as ContextBoundAgent<TContext>;\n if (\n runOptions.conversationId !== undefined &&\n runOptions.conversationId.trim().length === 0\n ) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationId must be a non-empty string.\",\n {\n context: { conversationId: runOptions.conversationId },\n trace: [{ at: \"core.run.createRuntime.run.validateConversationId\" }],\n },\n );\n }\n\n const execution = createRuntimeExecutionContext({\n resolvedAgent,\n conversationId: runOptions.conversationId,\n onEvent: runOptions.onEvent,\n externalSignal: runOptions.signal,\n });\n\n const resolvedPersistence = buildPersistence(runOptions.persistence, {\n stream: options.stream,\n conversations: options.conversations,\n runtimeState: options.runtimeState,\n });\n\n try {\n const effectiveConversationReplay = resolveConversationReplay(\n resolvedAgent,\n runOptions.conversationReplay,\n );\n warnIgnoredConversationReplay({\n agent: resolvedAgent,\n conversationReplay: effectiveConversationReplay,\n });\n const validatedContext = await validateAgentContext(\n resolvedAgent,\n runOptions.context,\n );\n const runPersistence = runOptions.persistence;\n const resolvedConversations =\n runPersistence?.conversations ?? options.conversations;\n const conversationInput = await loadConversationMessages({\n input: runOptions.input,\n caps: resolvedAgent.model.caps,\n agentName: resolvedAgent.name,\n replaceHistory: runOptions.replaceHistory,\n conversationReplay: effectiveConversationReplay,\n conversations: resolvedConversations,\n conversationId: runOptions.conversationId,\n });\n\n await execution.emit({\n type: Events.RUN_STARTED,\n runId: execution.runId,\n agentName: resolvedAgent.name,\n runInput: {\n input: runOptions.input,\n context: validatedContext,\n },\n timestamp: Date.now(),\n conversationId: runOptions.conversationId,\n });\n\n if (execution.signal.aborted) {\n throw BetterAgentError.fromCode(\"ABORTED\", \"Run aborted before it started\", {\n context: { runId: execution.runId, agentName: resolvedAgent.name },\n trace: [{ at: \"core.run.createRuntime.run.abortedBeforeStart\" }],\n });\n }\n\n const result = await executeRun({\n agent: resolvedAgent,\n options: {\n ...runOptions,\n input: conversationInput.input,\n initialItems: conversationInput.items,\n replayStartIndex: conversationInput.replayStartIndex,\n conversationReplayActive: conversationInput.conversationReplayActive,\n conversationReplay: effectiveConversationReplay,\n context: validatedContext,\n runId: execution.runId,\n signal: execution.signal,\n emit: execution.emit,\n generateMessageId: () => generateId(\"message\"),\n mode: \"run\",\n advancedDefaults: options.advanced,\n persistence: resolvedPersistence,\n pendingToolRuntime,\n pluginRuntime,\n },\n });\n\n return await completeRunSuccess({\n runId: execution.runId,\n resolvedAgent,\n emit: execution.emit,\n result,\n saveConversationParams: {\n agentName: resolvedAgent.name,\n loaded: conversationInput.loaded,\n conversations: resolvedConversations,\n conversationId: runOptions.conversationId,\n },\n runtimeState: resolvedPersistence?.runtimeState,\n conversationId: runOptions.conversationId,\n success: (publicResult) => publicResult,\n });\n } catch (error) {\n return await handleRunFailure({\n error,\n signal: execution.signal,\n traceAt: \"core.run.createRuntime.run\",\n emit: execution.emit,\n runId: execution.runId,\n resolvedAgent,\n conversationId: runOptions.conversationId,\n runtimeState: resolvedPersistence?.runtimeState,\n });\n } finally {\n execution.cleanupSignal();\n }\n }) as unknown as BetterAgentRuntime<TAgents>[\"run\"],\n\n stream: (<TContext, TOutput extends OutputSchemaDefinition | undefined = undefined>(\n agent: TAgents[number][\"name\"],\n runOptions: RunOptions<TContext, TOutput>,\n ): StreamResult => {\n const resolvedAgent = resolveAgentFromRegistry(\n agents,\n agent,\n \"core.run.createRuntime.stream\",\n ) as ContextBoundAgent<TContext>;\n if (\n runOptions.conversationId !== undefined &&\n runOptions.conversationId.trim().length === 0\n ) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationId must be a non-empty string.\",\n {\n context: { conversationId: runOptions.conversationId },\n trace: [{ at: \"core.run.createRuntime.stream.validateConversationId\" }],\n },\n );\n }\n\n const queue = createAsyncEventQueue<Event>();\n const runPersistence = runOptions.persistence;\n const streamStore = runPersistence?.stream ?? options.stream;\n const execution = createRuntimeExecutionContext({\n resolvedAgent,\n conversationId: runOptions.conversationId,\n onEvent: runOptions.onEvent,\n externalSignal: runOptions.signal,\n detachFromExternalAbort: streamLifecycle === \"detached\",\n queueSignal: streamLifecycle === \"detached\" ? runOptions.signal : undefined,\n streamStore,\n queue,\n });\n\n const resolvedPersistence = buildPersistence(runPersistence, {\n stream: streamStore,\n conversations: options.conversations,\n runtimeState: options.runtimeState,\n });\n\n const result = (async (): Promise<RunResult> => {\n try {\n const effectiveConversationReplay = resolveConversationReplay(\n resolvedAgent,\n runOptions.conversationReplay,\n );\n warnIgnoredConversationReplay({\n agent: resolvedAgent,\n conversationReplay: effectiveConversationReplay,\n });\n const validatedContext = await validateAgentContext(\n resolvedAgent,\n runOptions.context,\n );\n const resolvedConversations =\n runPersistence?.conversations ?? options.conversations;\n const conversationInput = await loadConversationMessages({\n input: runOptions.input,\n caps: resolvedAgent.model.caps,\n agentName: resolvedAgent.name,\n replaceHistory: runOptions.replaceHistory,\n conversationReplay: effectiveConversationReplay,\n conversations: resolvedConversations,\n conversationId: runOptions.conversationId,\n });\n\n if (streamStore) {\n await streamStore.open(execution.runId, { runId: execution.runId });\n }\n\n if (\n resolvedPersistence?.runtimeState &&\n runOptions.conversationId !== undefined\n ) {\n await resolvedPersistence.runtimeState.set({\n conversationId: runOptions.conversationId,\n agentName: resolvedAgent.name,\n status: \"running\",\n updatedAt: Date.now(),\n activeRunId: execution.runId,\n activeStreamId: streamStore ? execution.runId : undefined,\n });\n }\n\n await execution.emit({\n type: Events.RUN_STARTED,\n runId: execution.runId,\n agentName: resolvedAgent.name,\n runInput: {\n input: runOptions.input,\n context: validatedContext,\n },\n timestamp: Date.now(),\n conversationId: runOptions.conversationId,\n });\n\n if (execution.signal.aborted) {\n throw BetterAgentError.fromCode(\n \"ABORTED\",\n \"Run aborted before it started\",\n {\n context: { runId: execution.runId, agentName: resolvedAgent.name },\n trace: [{ at: \"core.run.createRuntime.stream.abortedBeforeStart\" }],\n },\n );\n }\n\n const runResult = await executeRun({\n agent: resolvedAgent,\n options: {\n ...runOptions,\n input: conversationInput.input,\n initialItems: conversationInput.items,\n replayStartIndex: conversationInput.replayStartIndex,\n conversationReplayActive: conversationInput.conversationReplayActive,\n conversationReplay: effectiveConversationReplay,\n context: validatedContext,\n runId: execution.runId,\n signal: execution.signal,\n emit: execution.emit,\n generateMessageId: () => generateId(\"message\"),\n mode: \"stream\",\n advancedDefaults: options.advanced,\n persistence: resolvedPersistence,\n pendingToolRuntime,\n pluginRuntime,\n },\n });\n\n return await completeRunSuccess({\n runId: execution.runId,\n resolvedAgent,\n emit: execution.emit,\n result: runResult,\n streamStore,\n queue,\n saveConversationParams: {\n agentName: resolvedAgent.name,\n loaded: conversationInput.loaded,\n conversations: resolvedConversations,\n conversationId: runOptions.conversationId,\n },\n runtimeState: resolvedPersistence?.runtimeState,\n conversationId: runOptions.conversationId,\n success: (publicResult) => publicResult,\n });\n } catch (error) {\n return await handleRunFailure({\n error,\n signal: execution.signal,\n traceAt: \"core.run.createRuntime.stream\",\n emit: execution.emit,\n runId: execution.runId,\n resolvedAgent,\n conversationId: runOptions.conversationId,\n streamStore,\n runtimeState: resolvedPersistence?.runtimeState,\n queue,\n });\n } finally {\n execution.cleanupSignal();\n }\n })();\n\n void result.catch(() => {});\n\n return {\n runId: execution.runId,\n events: queue.iterate(),\n result,\n };\n }) as unknown as BetterAgentRuntime<TAgents>[\"stream\"],\n\n loadConversation: async <TName extends TAgents[number][\"name\"]>(\n agent: TName,\n conversationId: string,\n ) => {\n if (conversationId.trim().length === 0) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationId must be a non-empty string.\",\n {\n context: { conversationId },\n trace: [\n {\n at: \"core.run.createRuntime.loadConversation.validateConversationId\",\n },\n ],\n },\n );\n }\n const resolvedAgent = resolveAgentFromRegistry(\n agents,\n agent,\n \"core.run.createRuntime.loadConversation\",\n );\n const conversations = options.conversations;\n if (!conversations) {\n return null;\n }\n\n const loaded = await conversations.load({\n conversationId,\n agentName: resolvedAgent.name,\n });\n if (!loaded) {\n return null;\n }\n\n validateStoredConversationItems(loaded.items, conversationId);\n return { items: loaded.items };\n },\n resumeStream: async (params) => {\n if (params.streamId.trim().length === 0) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"streamId must be a non-empty string.\",\n {\n context: { streamId: params.streamId },\n trace: [{ at: \"core.run.createRuntime.resumeStream.validateStreamId\" }],\n },\n );\n }\n if (!options.stream) {\n return null;\n }\n\n return options.stream.resume(params.streamId, params.afterSeq);\n },\n\n resumeConversation: async <TName extends TAgents[number][\"name\"]>(\n agent: TName,\n params: ResumeConversationOptions,\n ) => {\n if (params.conversationId.trim().length === 0) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationId must be a non-empty string.\",\n {\n context: { conversationId: params.conversationId },\n trace: [\n {\n at: \"core.run.createRuntime.resumeConversation.validateConversationId\",\n },\n ],\n },\n );\n }\n\n const resolvedAgent = resolveAgentFromRegistry(\n agents,\n agent,\n \"core.run.createRuntime.resumeConversation\",\n );\n const state = !options.runtimeState\n ? null\n : await options.runtimeState.get({\n conversationId: params.conversationId,\n agentName: resolvedAgent.name,\n });\n\n if (!state || state.status !== \"running\" || !state.activeStreamId || !options.stream) {\n return null;\n }\n\n // biome-ignore lint/style/noNonNullAssertion: activeStreamId is checked above via runtime state existence\n return options.stream.resume(state.activeStreamId!, params.afterSeq);\n },\n\n abortRun: async (runId: string): Promise<boolean> => {\n const controller = activeRuns.get(runId);\n if (!controller) {\n return false;\n }\n\n controller.abort();\n return true;\n },\n\n submitToolResult: async (params: SubmitToolResultParams): Promise<boolean> =>\n pendingToolRuntime.submitToolResult(params),\n\n submitToolApproval: async (params: SubmitToolApprovalParams): Promise<boolean> =>\n pendingToolRuntime.submitToolApproval(params),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"runtime.mjs","names":[],"sources":["../../src/run/runtime.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { logger } from \"@better-agent/shared/logger\";\nimport type { AnyAgentDefinition } from \"../agent\";\nimport { type Event, Events } from \"../events\";\nimport type { ConversationRuntimeStateStore, ConversationStore, StreamStore } from \"../persistence\";\nimport type { PluginRuntime } from \"../plugins\";\nimport type { ConversationItem, OutputSchemaDefinition } from \"../providers\";\nimport { type AsyncEventQueue, createAsyncEventQueue } from \"./event-queue\";\nimport { executeRun } from \"./execution\";\nimport {\n createStreamPersistenceEmitter,\n generateId,\n loadConversationMessages,\n saveConversationMessages,\n toEventEmitter,\n validateAgentContext,\n validateStoredConversationItems,\n} from \"./helpers\";\nimport { createPendingToolRuntime } from \"./pending-tools\";\nimport { createAgentRegistry, resolveAgentFromRegistry } from \"./registry\";\nimport type {\n BetterAgentRuntime,\n ContextBoundAgent,\n ResumeConversationOptions,\n RunAdvancedOptions,\n RunOptions,\n RunResult,\n StreamResult,\n SubmitToolApprovalParams,\n SubmitToolResultParams,\n} from \"./types\";\n\n/** Creates a runtime for registered agents. */\nexport function createRuntime<const TAgents extends readonly AnyAgentDefinition[]>(options: {\n agents: TAgents;\n pluginRuntime?: PluginRuntime | null;\n stream?: StreamStore;\n conversations?: ConversationStore;\n runtimeState?: ConversationRuntimeStateStore;\n streamLifecycle?: \"request_bound\" | \"detached\";\n advanced?: RunAdvancedOptions;\n}): BetterAgentRuntime<TAgents> {\n const agents = createAgentRegistry(options.agents);\n const pluginRuntime = options.pluginRuntime ?? null;\n const pendingToolRuntime = createPendingToolRuntime();\n const streamLifecycle = options.streamLifecycle ?? \"request_bound\";\n const activeRuns = new Map<string, AbortController>();\n\n const resolveConversationReplay = (\n agent: AnyAgentDefinition,\n runReplay: RunOptions<unknown>[\"conversationReplay\"],\n ): RunOptions<unknown>[\"conversationReplay\"] => {\n const agentReplay = agent.conversationReplay;\n if (!agentReplay && !runReplay) {\n return undefined;\n }\n\n const merged = {\n ...(agentReplay ?? {}),\n ...(runReplay ?? {}),\n };\n\n if (\n runReplay &&\n Object.prototype.hasOwnProperty.call(runReplay, \"prepareInput\") &&\n runReplay.prepareInput === null\n ) {\n merged.prepareInput = undefined;\n }\n\n return merged;\n };\n\n const warnIgnoredConversationReplay = (params: {\n agent: AnyAgentDefinition;\n conversationReplay: RunOptions<unknown>[\"conversationReplay\"];\n }) => {\n if (!params.conversationReplay) {\n return;\n }\n\n const replayMode =\n params.agent.model.caps.replayMode ??\n (params.agent.model.caps.inputShape === \"prompt\"\n ? \"single_turn_persistent\"\n : \"multi_turn\");\n\n if (replayMode === \"multi_turn\") {\n return;\n }\n\n logger.warn(\n `conversationReplay was provided for agent '${params.agent.name}', but model replayMode is '${replayMode}', so stored history replay customization was skipped.`,\n );\n };\n\n const buildPersistence = <TContext>(\n persistence?: RunOptions<TContext>[\"persistence\"],\n defaults?: {\n stream?: StreamStore;\n conversations?: ConversationStore;\n runtimeState?: ConversationRuntimeStateStore;\n },\n ) => {\n const resolved = {\n stream: persistence?.stream ?? defaults?.stream,\n conversations: persistence?.conversations ?? defaults?.conversations,\n runtimeState: persistence?.runtimeState ?? defaults?.runtimeState,\n };\n\n return resolved.stream || resolved.conversations || resolved.runtimeState\n ? resolved\n : undefined;\n };\n\n const createPluginEventContext = (params: {\n runId: string;\n agentName: string;\n conversationId?: string;\n abortController: AbortController;\n }) => ({\n runId: params.runId,\n agentName: params.agentName,\n conversationId: params.conversationId,\n control: {\n abortRun: async () => {\n params.abortController.abort();\n },\n },\n });\n\n const createLiveEmitter = (params: {\n runId: string;\n agentName: string;\n conversationId?: string;\n abortController: AbortController;\n persistenceEmit?: (event: Event) => Promise<void>;\n queuePush?: (event: Event) => Promise<void>;\n onEvent?: RunOptions<unknown>[\"onEvent\"];\n }) => {\n const userEmit = toEventEmitter(params.onEvent);\n\n return async (event: Event) => {\n const pluginEventContext = createPluginEventContext({\n runId: params.runId,\n agentName: params.agentName,\n abortController: params.abortController,\n conversationId: params.conversationId,\n });\n\n const transformed =\n pluginRuntime?.hasEventMiddleware === true\n ? await pluginRuntime.dispatchEvent(event, pluginEventContext)\n : event;\n\n if (!transformed) {\n return;\n }\n\n if (params.persistenceEmit) {\n await params.persistenceEmit(transformed);\n }\n\n if (pluginRuntime?.hasOnEvent) {\n await pluginRuntime.dispatchOnEvent(transformed, pluginEventContext);\n }\n\n if (params.queuePush) {\n await params.queuePush(transformed);\n }\n\n await userEmit(transformed);\n };\n };\n\n const wrapRuntimeError = (params: {\n error: unknown;\n message: string;\n traceAt: string;\n isAbort?: boolean;\n }) =>\n BetterAgentError.wrap({\n err: params.error,\n message: params.message,\n opts: {\n code: params.isAbort\n ? \"ABORTED\"\n : params.error instanceof BetterAgentError\n ? params.error.code\n : \"INTERNAL\",\n trace: [{ at: params.traceAt }],\n },\n });\n\n const emitSafely = async (emit: (event: Event) => Promise<void>, event: Event) => {\n try {\n await emit(event);\n } catch (error) {\n logger.error(\"Failed to emit runtime event.\", error);\n }\n };\n\n const closeStreamSafely = async (streamStore: StreamStore | undefined, runId: string) => {\n if (!streamStore) {\n return;\n }\n\n try {\n await streamStore.close(runId);\n } catch (error) {\n logger.error(`Failed to close stream '${runId}'.`, error);\n }\n };\n\n const createRuntimeExecutionContext = (params: {\n resolvedAgent: AnyAgentDefinition;\n conversationId?: string;\n onEvent?: RunOptions<unknown>[\"onEvent\"];\n externalSignal?: AbortSignal;\n streamStore?: StreamStore;\n queue?: AsyncEventQueue<Event>;\n queueSignal?: AbortSignal;\n detachFromExternalAbort?: boolean;\n }) => {\n const runId = generateId(\"run\");\n const abortController = new AbortController();\n activeRuns.set(runId, abortController);\n const signalController = new AbortController();\n const abortFromSignal = (signal: AbortSignal) => {\n if (!signalController.signal.aborted) {\n signalController.abort(signal.reason);\n }\n };\n const onInternalAbort = () => abortFromSignal(abortController.signal);\n const onExternalAbort = () => {\n if (params.externalSignal) {\n abortFromSignal(params.externalSignal);\n }\n };\n const signal = signalController.signal;\n const persistenceEmit = params.streamStore\n ? createStreamPersistenceEmitter({\n stream: params.streamStore,\n streamId: runId,\n })\n : undefined;\n const emit = createLiveEmitter({\n runId,\n agentName: params.resolvedAgent.name,\n abortController,\n conversationId: params.conversationId,\n persistenceEmit,\n queuePush: params.queue\n ? async (event) => {\n if (!params.queueSignal?.aborted) {\n params.queue?.push(event);\n }\n }\n : undefined,\n onEvent: params.onEvent,\n });\n\n abortController.signal.addEventListener(\"abort\", onInternalAbort, { once: true });\n if (params.externalSignal && !params.detachFromExternalAbort) {\n if (params.externalSignal.aborted) {\n abortFromSignal(params.externalSignal);\n } else {\n params.externalSignal.addEventListener(\"abort\", onExternalAbort, { once: true });\n }\n }\n\n if (params.queue && params.queueSignal) {\n const closeQueueOnAbort = () => params.queue?.close();\n if (params.queueSignal.aborted) {\n closeQueueOnAbort();\n } else {\n params.queueSignal.addEventListener(\"abort\", closeQueueOnAbort, { once: true });\n }\n }\n\n return {\n runId,\n signal,\n emit,\n cleanupSignal() {\n abortController.signal.removeEventListener(\"abort\", onInternalAbort);\n params.externalSignal?.removeEventListener(\"abort\", onExternalAbort);\n },\n };\n };\n\n const completeRunSuccess = async <TResult>(params: {\n runId: string;\n resolvedAgent: AnyAgentDefinition;\n conversationId?: string;\n emit: (event: Event) => Promise<void>;\n result: RunResult & { items: ConversationItem[] };\n saveConversationParams?: Omit<Parameters<typeof saveConversationMessages>[0], \"result\">;\n streamStore?: StreamStore;\n runtimeState?: ConversationRuntimeStateStore;\n queue?: AsyncEventQueue<Event>;\n success: (result: RunResult) => TResult;\n }) => {\n const itemsToSave =\n pluginRuntime?.hasOnBeforeSave === true\n ? await pluginRuntime.applyBeforeSave({\n runId: params.runId,\n agentName: params.resolvedAgent.name,\n items: params.result.items,\n conversationId: params.conversationId,\n })\n : params.result.items;\n\n if (params.saveConversationParams) {\n await saveConversationMessages({\n ...params.saveConversationParams,\n result: { items: itemsToSave },\n });\n }\n\n const publicResult = {\n response: params.result.response,\n structured: params.result.structured,\n };\n await params.emit({\n type: Events.RUN_FINISHED,\n runId: params.runId,\n agentName: params.resolvedAgent.name,\n result: publicResult,\n timestamp: Date.now(),\n conversationId: params.conversationId,\n });\n\n activeRuns.delete(params.runId);\n if (params.runtimeState && params.conversationId !== undefined) {\n await params.runtimeState.clear({\n conversationId: params.conversationId,\n agentName: params.resolvedAgent.name,\n });\n }\n await closeStreamSafely(params.streamStore, params.runId);\n params.queue?.close();\n pendingToolRuntime.clearRun(params.runId, \"Run finished\");\n return params.success(publicResult);\n };\n\n const handleRunFailure = async (params: {\n error: unknown;\n signal: AbortSignal;\n traceAt: string;\n emit: (event: Event) => Promise<void>;\n runId: string;\n resolvedAgent: AnyAgentDefinition;\n conversationId?: string;\n streamStore?: StreamStore;\n runtimeState?: ConversationRuntimeStateStore;\n queue?: AsyncEventQueue<Event>;\n }): Promise<never> => {\n const isAbort =\n params.signal.aborted ||\n (params.error instanceof BetterAgentError && params.error.code === \"ABORTED\");\n\n const wrapped = wrapRuntimeError({\n error: params.error,\n message: \"Run failed\",\n traceAt: params.traceAt,\n isAbort,\n });\n\n if (isAbort) {\n await emitSafely(params.emit, {\n type: Events.RUN_ABORTED,\n runId: params.runId,\n agentName: params.resolvedAgent.name,\n timestamp: Date.now(),\n conversationId: params.conversationId,\n });\n } else {\n await emitSafely(params.emit, {\n type: Events.RUN_ERROR,\n runId: params.runId,\n agentName: params.resolvedAgent.name,\n error: wrapped,\n timestamp: Date.now(),\n conversationId: params.conversationId,\n });\n }\n\n activeRuns.delete(params.runId);\n if (params.runtimeState && params.conversationId !== undefined) {\n await params.runtimeState.clear({\n conversationId: params.conversationId,\n agentName: params.resolvedAgent.name,\n });\n }\n await closeStreamSafely(params.streamStore, params.runId);\n params.queue?.fail(wrapped);\n pendingToolRuntime.clearRun(params.runId, wrapped.message);\n throw wrapped;\n };\n\n return {\n streamLifecycle,\n run: (async <TContext, TOutput extends OutputSchemaDefinition | undefined = undefined>(\n agent: TAgents[number][\"name\"],\n runOptions: RunOptions<TContext, TOutput>,\n ): Promise<RunResult> => {\n const resolvedAgent = resolveAgentFromRegistry(\n agents,\n agent,\n \"core.run.createRuntime.run\",\n ) as ContextBoundAgent<TContext>;\n\n if (\n runOptions.conversationId !== undefined &&\n runOptions.conversationId.trim().length === 0\n ) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationId must be a non-empty string.\",\n {\n context: { conversationId: runOptions.conversationId },\n trace: [{ at: \"core.run.createRuntime.run.validateConversationId\" }],\n },\n );\n }\n\n const execution = createRuntimeExecutionContext({\n resolvedAgent,\n conversationId: runOptions.conversationId,\n onEvent: runOptions.onEvent,\n externalSignal: runOptions.signal,\n });\n\n const resolvedPersistence = buildPersistence(runOptions.persistence, {\n stream: options.stream,\n conversations: options.conversations,\n runtimeState: options.runtimeState,\n });\n\n try {\n const effectiveConversationReplay = resolveConversationReplay(\n resolvedAgent,\n runOptions.conversationReplay,\n );\n warnIgnoredConversationReplay({\n agent: resolvedAgent,\n conversationReplay: effectiveConversationReplay,\n });\n const validatedContext = await validateAgentContext(\n resolvedAgent,\n runOptions.context,\n );\n const resolvedConversations = resolvedPersistence?.conversations;\n const conversationInput = await loadConversationMessages({\n input: runOptions.input,\n caps: resolvedAgent.model.caps,\n agentName: resolvedAgent.name,\n replaceHistory: runOptions.replaceHistory,\n conversationReplay: effectiveConversationReplay,\n conversations: resolvedConversations,\n conversationId: runOptions.conversationId,\n });\n\n await execution.emit({\n type: Events.RUN_STARTED,\n runId: execution.runId,\n agentName: resolvedAgent.name,\n runInput: {\n input: runOptions.input,\n context: validatedContext,\n },\n timestamp: Date.now(),\n conversationId: runOptions.conversationId,\n });\n\n if (execution.signal.aborted) {\n throw BetterAgentError.fromCode(\"ABORTED\", \"Run aborted before it started\", {\n context: { runId: execution.runId, agentName: resolvedAgent.name },\n trace: [{ at: \"core.run.createRuntime.run.abortedBeforeStart\" }],\n });\n }\n\n const result = await executeRun({\n agent: resolvedAgent,\n options: {\n ...runOptions,\n input: conversationInput.input,\n initialItems: conversationInput.items,\n replayStartIndex: conversationInput.replayStartIndex,\n conversationReplayActive: conversationInput.conversationReplayActive,\n conversationReplay: effectiveConversationReplay,\n context: validatedContext,\n runId: execution.runId,\n signal: execution.signal,\n emit: execution.emit,\n generateMessageId: () => generateId(\"message\"),\n mode: \"run\",\n advancedDefaults: options.advanced,\n persistence: resolvedPersistence,\n pendingToolRuntime,\n pluginRuntime,\n },\n });\n\n return await completeRunSuccess({\n runId: execution.runId,\n resolvedAgent,\n emit: execution.emit,\n result,\n saveConversationParams: {\n agentName: resolvedAgent.name,\n loaded: conversationInput.loaded,\n conversations: resolvedConversations,\n conversationId: runOptions.conversationId,\n },\n runtimeState: resolvedPersistence?.runtimeState,\n conversationId: runOptions.conversationId,\n success: (publicResult) => publicResult,\n });\n } catch (error) {\n return await handleRunFailure({\n error,\n signal: execution.signal,\n traceAt: \"core.run.createRuntime.run\",\n emit: execution.emit,\n runId: execution.runId,\n resolvedAgent,\n conversationId: runOptions.conversationId,\n runtimeState: resolvedPersistence?.runtimeState,\n });\n } finally {\n execution.cleanupSignal();\n }\n }) as BetterAgentRuntime<TAgents>[\"run\"],\n\n stream: (<TContext, TOutput extends OutputSchemaDefinition | undefined = undefined>(\n agent: TAgents[number][\"name\"],\n runOptions: RunOptions<TContext, TOutput>,\n ): StreamResult => {\n const resolvedAgent = resolveAgentFromRegistry(\n agents,\n agent,\n \"core.run.createRuntime.stream\",\n ) as ContextBoundAgent<TContext>;\n\n if (\n runOptions.conversationId !== undefined &&\n runOptions.conversationId.trim().length === 0\n ) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationId must be a non-empty string.\",\n {\n context: { conversationId: runOptions.conversationId },\n trace: [{ at: \"core.run.createRuntime.stream.validateConversationId\" }],\n },\n );\n }\n\n const queue = createAsyncEventQueue<Event>();\n const runPersistence = runOptions.persistence;\n const resolvedPersistence = buildPersistence(runPersistence, {\n stream: options.stream,\n conversations: options.conversations,\n runtimeState: options.runtimeState,\n });\n const streamStore = resolvedPersistence?.stream;\n const execution = createRuntimeExecutionContext({\n resolvedAgent,\n conversationId: runOptions.conversationId,\n onEvent: runOptions.onEvent,\n externalSignal: runOptions.signal,\n detachFromExternalAbort: streamLifecycle === \"detached\",\n queueSignal: streamLifecycle === \"detached\" ? runOptions.signal : undefined,\n streamStore,\n queue,\n });\n\n const result = (async (): Promise<RunResult> => {\n try {\n const effectiveConversationReplay = resolveConversationReplay(\n resolvedAgent,\n runOptions.conversationReplay,\n );\n warnIgnoredConversationReplay({\n agent: resolvedAgent,\n conversationReplay: effectiveConversationReplay,\n });\n const validatedContext = await validateAgentContext(\n resolvedAgent,\n runOptions.context,\n );\n const resolvedConversations = resolvedPersistence?.conversations;\n const conversationInput = await loadConversationMessages({\n input: runOptions.input,\n caps: resolvedAgent.model.caps,\n agentName: resolvedAgent.name,\n replaceHistory: runOptions.replaceHistory,\n conversationReplay: effectiveConversationReplay,\n conversations: resolvedConversations,\n conversationId: runOptions.conversationId,\n });\n\n if (streamStore) {\n await streamStore.open(execution.runId, { runId: execution.runId });\n }\n\n if (\n resolvedPersistence?.runtimeState &&\n runOptions.conversationId !== undefined\n ) {\n await resolvedPersistence.runtimeState.set({\n conversationId: runOptions.conversationId,\n agentName: resolvedAgent.name,\n status: \"running\",\n updatedAt: Date.now(),\n activeRunId: execution.runId,\n activeStreamId: streamStore ? execution.runId : undefined,\n });\n }\n\n await execution.emit({\n type: Events.RUN_STARTED,\n runId: execution.runId,\n agentName: resolvedAgent.name,\n runInput: {\n input: runOptions.input,\n context: validatedContext,\n },\n timestamp: Date.now(),\n conversationId: runOptions.conversationId,\n });\n\n if (execution.signal.aborted) {\n throw BetterAgentError.fromCode(\n \"ABORTED\",\n \"Run aborted before it started\",\n {\n context: { runId: execution.runId, agentName: resolvedAgent.name },\n trace: [{ at: \"core.run.createRuntime.stream.abortedBeforeStart\" }],\n },\n );\n }\n\n const runResult = await executeRun({\n agent: resolvedAgent,\n options: {\n ...runOptions,\n input: conversationInput.input,\n initialItems: conversationInput.items,\n replayStartIndex: conversationInput.replayStartIndex,\n conversationReplayActive: conversationInput.conversationReplayActive,\n conversationReplay: effectiveConversationReplay,\n context: validatedContext,\n runId: execution.runId,\n signal: execution.signal,\n emit: execution.emit,\n generateMessageId: () => generateId(\"message\"),\n mode: \"stream\",\n advancedDefaults: options.advanced,\n persistence: resolvedPersistence,\n pendingToolRuntime,\n pluginRuntime,\n },\n });\n\n return await completeRunSuccess({\n runId: execution.runId,\n resolvedAgent,\n emit: execution.emit,\n result: runResult,\n streamStore,\n queue,\n saveConversationParams: {\n agentName: resolvedAgent.name,\n loaded: conversationInput.loaded,\n conversations: resolvedConversations,\n conversationId: runOptions.conversationId,\n },\n runtimeState: resolvedPersistence?.runtimeState,\n conversationId: runOptions.conversationId,\n success: (publicResult) => publicResult,\n });\n } catch (error) {\n return await handleRunFailure({\n error,\n signal: execution.signal,\n traceAt: \"core.run.createRuntime.stream\",\n emit: execution.emit,\n runId: execution.runId,\n resolvedAgent,\n conversationId: runOptions.conversationId,\n streamStore,\n runtimeState: resolvedPersistence?.runtimeState,\n queue,\n });\n } finally {\n execution.cleanupSignal();\n }\n })();\n\n void result.catch(() => {});\n\n return {\n runId: execution.runId,\n events: queue.iterate(),\n result,\n };\n }) as BetterAgentRuntime<TAgents>[\"stream\"],\n\n loadConversation: async <TName extends TAgents[number][\"name\"]>(\n agent: TName,\n conversationId: string,\n ) => {\n if (conversationId.trim().length === 0) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationId must be a non-empty string.\",\n {\n context: { conversationId },\n trace: [\n {\n at: \"core.run.createRuntime.loadConversation.validateConversationId\",\n },\n ],\n },\n );\n }\n const resolvedAgent = resolveAgentFromRegistry(\n agents,\n agent,\n \"core.run.createRuntime.loadConversation\",\n );\n const conversations = options.conversations;\n if (!conversations) {\n return null;\n }\n\n const loaded = await conversations.load({\n conversationId,\n agentName: resolvedAgent.name,\n });\n if (!loaded) {\n return null;\n }\n\n validateStoredConversationItems(loaded.items, conversationId);\n return { items: loaded.items };\n },\n resumeStream: async (params) => {\n if (params.streamId.trim().length === 0) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"streamId must be a non-empty string.\",\n {\n context: { streamId: params.streamId },\n trace: [{ at: \"core.run.createRuntime.resumeStream.validateStreamId\" }],\n },\n );\n }\n if (!options.stream) {\n return null;\n }\n\n return options.stream.resume(params.streamId, params.afterSeq);\n },\n\n resumeConversation: async <TName extends TAgents[number][\"name\"]>(\n agent: TName,\n params: ResumeConversationOptions,\n ) => {\n if (params.conversationId.trim().length === 0) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n \"conversationId must be a non-empty string.\",\n {\n context: { conversationId: params.conversationId },\n trace: [\n {\n at: \"core.run.createRuntime.resumeConversation.validateConversationId\",\n },\n ],\n },\n );\n }\n\n const resolvedAgent = resolveAgentFromRegistry(\n agents,\n agent,\n \"core.run.createRuntime.resumeConversation\",\n );\n const state = !options.runtimeState\n ? null\n : await options.runtimeState.get({\n conversationId: params.conversationId,\n agentName: resolvedAgent.name,\n });\n\n if (!state || state.status !== \"running\" || !state.activeStreamId || !options.stream) {\n return null;\n }\n\n // biome-ignore lint/style/noNonNullAssertion: activeStreamId is checked above via runtime state existence\n return options.stream.resume(state.activeStreamId!, params.afterSeq);\n },\n\n abortRun: async (runId: string): Promise<boolean> => {\n const controller = activeRuns.get(runId);\n if (!controller) {\n return false;\n }\n\n controller.abort();\n return true;\n },\n\n submitToolResult: async (params: SubmitToolResultParams): Promise<boolean> =>\n pendingToolRuntime.submitToolResult(params),\n\n submitToolApproval: async (params: SubmitToolApprovalParams): Promise<boolean> =>\n pendingToolRuntime.submitToolApproval(params),\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-agent/core",
3
- "version": "0.1.0-beta.2",
3
+ "version": "0.1.0-beta.4",
4
4
  "description": "Better Agent core TypeScript library",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -60,7 +60,7 @@
60
60
  "access": "public"
61
61
  },
62
62
  "dependencies": {
63
- "@better-agent/shared": "0.1.0-beta.2",
63
+ "@better-agent/shared": "0.1.0-beta.4",
64
64
  "ajv": "^8.17.1",
65
65
  "@standard-schema/spec": "1.1.0",
66
66
  "json-schema-to-ts": "^3.1.1"