@openai/agents-core 0.3.7 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/dist/errors.d.ts +40 -0
  2. package/dist/errors.js +38 -1
  3. package/dist/errors.js.map +1 -1
  4. package/dist/errors.mjs +34 -0
  5. package/dist/errors.mjs.map +1 -1
  6. package/dist/index.d.ts +6 -2
  7. package/dist/index.js +13 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +3 -1
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/metadata.js +2 -2
  12. package/dist/metadata.mjs +2 -2
  13. package/dist/result.d.ts +17 -0
  14. package/dist/result.js +71 -24
  15. package/dist/result.js.map +1 -1
  16. package/dist/result.mjs +69 -22
  17. package/dist/result.mjs.map +1 -1
  18. package/dist/run.d.ts +14 -47
  19. package/dist/run.js +421 -994
  20. package/dist/run.js.map +1 -1
  21. package/dist/run.mjs +405 -978
  22. package/dist/run.mjs.map +1 -1
  23. package/dist/runState.d.ts +1286 -172
  24. package/dist/runState.js +146 -16
  25. package/dist/runState.js.map +1 -1
  26. package/dist/runState.mjs +142 -12
  27. package/dist/runState.mjs.map +1 -1
  28. package/dist/runner/constants.d.ts +1 -0
  29. package/dist/runner/constants.js +6 -0
  30. package/dist/runner/constants.js.map +1 -0
  31. package/dist/runner/constants.mjs +3 -0
  32. package/dist/runner/constants.mjs.map +1 -0
  33. package/dist/runner/conversation.d.ts +85 -0
  34. package/dist/runner/conversation.js +275 -0
  35. package/dist/runner/conversation.js.map +1 -0
  36. package/dist/runner/conversation.mjs +269 -0
  37. package/dist/runner/conversation.mjs.map +1 -0
  38. package/dist/runner/guardrails.d.ts +23 -0
  39. package/dist/runner/guardrails.js +174 -0
  40. package/dist/runner/guardrails.js.map +1 -0
  41. package/dist/runner/guardrails.mjs +166 -0
  42. package/dist/runner/guardrails.mjs.map +1 -0
  43. package/dist/runner/items.d.ts +18 -0
  44. package/dist/runner/items.js +89 -0
  45. package/dist/runner/items.js.map +1 -0
  46. package/dist/runner/items.mjs +79 -0
  47. package/dist/runner/items.mjs.map +1 -0
  48. package/dist/runner/mcpApprovals.d.ts +25 -0
  49. package/dist/runner/mcpApprovals.js +66 -0
  50. package/dist/runner/mcpApprovals.js.map +1 -0
  51. package/dist/runner/mcpApprovals.mjs +63 -0
  52. package/dist/runner/mcpApprovals.mjs.map +1 -0
  53. package/dist/runner/modelOutputs.d.ts +10 -0
  54. package/dist/runner/modelOutputs.js +206 -0
  55. package/dist/runner/modelOutputs.js.map +1 -0
  56. package/dist/runner/modelOutputs.mjs +203 -0
  57. package/dist/runner/modelOutputs.mjs.map +1 -0
  58. package/dist/runner/modelPreparation.d.ts +8 -0
  59. package/dist/runner/modelPreparation.js +41 -0
  60. package/dist/runner/modelPreparation.js.map +1 -0
  61. package/dist/runner/modelPreparation.mjs +38 -0
  62. package/dist/runner/modelPreparation.mjs.map +1 -0
  63. package/dist/runner/modelSettings.d.ts +20 -0
  64. package/dist/runner/modelSettings.js +97 -0
  65. package/dist/runner/modelSettings.js.map +1 -0
  66. package/dist/runner/modelSettings.mjs +92 -0
  67. package/dist/runner/modelSettings.mjs.map +1 -0
  68. package/dist/runner/runLoop.d.ts +32 -0
  69. package/dist/runner/runLoop.js +62 -0
  70. package/dist/runner/runLoop.js.map +1 -0
  71. package/dist/runner/runLoop.mjs +57 -0
  72. package/dist/runner/runLoop.mjs.map +1 -0
  73. package/dist/runner/sessionPersistence.d.ts +26 -0
  74. package/dist/runner/sessionPersistence.js +441 -0
  75. package/dist/runner/sessionPersistence.js.map +1 -0
  76. package/dist/runner/sessionPersistence.mjs +431 -0
  77. package/dist/runner/sessionPersistence.mjs.map +1 -0
  78. package/dist/runner/steps.d.ts +48 -0
  79. package/dist/runner/steps.js +40 -0
  80. package/dist/runner/steps.js.map +1 -0
  81. package/dist/runner/steps.mjs +36 -0
  82. package/dist/runner/steps.mjs.map +1 -0
  83. package/dist/runner/streaming.d.ts +9 -0
  84. package/dist/runner/streaming.js +74 -0
  85. package/dist/runner/streaming.js.map +1 -0
  86. package/dist/runner/streaming.mjs +65 -0
  87. package/dist/runner/streaming.mjs.map +1 -0
  88. package/dist/runner/toolExecution.d.ts +15 -0
  89. package/dist/runner/toolExecution.js +997 -0
  90. package/dist/runner/toolExecution.js.map +1 -0
  91. package/dist/runner/toolExecution.mjs +984 -0
  92. package/dist/runner/toolExecution.mjs.map +1 -0
  93. package/dist/runner/toolUseTracker.d.ts +9 -0
  94. package/dist/runner/toolUseTracker.js +34 -0
  95. package/dist/runner/toolUseTracker.js.map +1 -0
  96. package/dist/runner/toolUseTracker.mjs +30 -0
  97. package/dist/runner/toolUseTracker.mjs.map +1 -0
  98. package/dist/runner/tracing.d.ts +23 -0
  99. package/dist/runner/tracing.js +45 -0
  100. package/dist/runner/tracing.js.map +1 -0
  101. package/dist/runner/tracing.mjs +41 -0
  102. package/dist/runner/tracing.mjs.map +1 -0
  103. package/dist/runner/turnPreparation.d.ts +30 -0
  104. package/dist/runner/turnPreparation.js +80 -0
  105. package/dist/runner/turnPreparation.js.map +1 -0
  106. package/dist/runner/turnPreparation.mjs +74 -0
  107. package/dist/runner/turnPreparation.mjs.map +1 -0
  108. package/dist/runner/turnResolution.d.ts +3 -0
  109. package/dist/runner/turnResolution.js +531 -0
  110. package/dist/runner/turnResolution.js.map +1 -0
  111. package/dist/runner/turnResolution.mjs +526 -0
  112. package/dist/runner/turnResolution.mjs.map +1 -0
  113. package/dist/runner/types.d.ts +66 -0
  114. package/dist/runner/types.js +3 -0
  115. package/dist/runner/types.js.map +1 -0
  116. package/dist/runner/types.mjs +2 -0
  117. package/dist/runner/types.mjs.map +1 -0
  118. package/dist/shims/mcp-server/node.js +51 -6
  119. package/dist/shims/mcp-server/node.js.map +1 -1
  120. package/dist/shims/mcp-server/node.mjs +51 -6
  121. package/dist/shims/mcp-server/node.mjs.map +1 -1
  122. package/dist/tool.d.ts +28 -2
  123. package/dist/tool.js +7 -1
  124. package/dist/tool.js.map +1 -1
  125. package/dist/tool.mjs +8 -2
  126. package/dist/tool.mjs.map +1 -1
  127. package/dist/toolGuardrail.d.ts +101 -0
  128. package/dist/toolGuardrail.js +58 -0
  129. package/dist/toolGuardrail.js.map +1 -0
  130. package/dist/toolGuardrail.mjs +51 -0
  131. package/dist/toolGuardrail.mjs.map +1 -0
  132. package/dist/tracing/config.d.ts +3 -0
  133. package/dist/tracing/config.js +3 -0
  134. package/dist/tracing/config.js.map +1 -0
  135. package/dist/tracing/config.mjs +2 -0
  136. package/dist/tracing/config.mjs.map +1 -0
  137. package/dist/tracing/context.d.ts +2 -0
  138. package/dist/tracing/context.js +95 -24
  139. package/dist/tracing/context.js.map +1 -1
  140. package/dist/tracing/context.mjs +95 -24
  141. package/dist/tracing/context.mjs.map +1 -1
  142. package/dist/tracing/createSpans.d.ts +11 -11
  143. package/dist/tracing/index.d.ts +2 -0
  144. package/dist/tracing/index.js.map +1 -1
  145. package/dist/tracing/index.mjs.map +1 -1
  146. package/dist/tracing/provider.js +54 -4
  147. package/dist/tracing/provider.js.map +1 -1
  148. package/dist/tracing/provider.mjs +54 -4
  149. package/dist/tracing/provider.mjs.map +1 -1
  150. package/dist/tracing/spans.d.ts +2 -0
  151. package/dist/tracing/spans.js +6 -0
  152. package/dist/tracing/spans.js.map +1 -1
  153. package/dist/tracing/spans.mjs +6 -0
  154. package/dist/tracing/spans.mjs.map +1 -1
  155. package/dist/tracing/traces.d.ts +11 -1
  156. package/dist/tracing/traces.js +15 -2
  157. package/dist/tracing/traces.js.map +1 -1
  158. package/dist/tracing/traces.mjs +15 -2
  159. package/dist/tracing/traces.mjs.map +1 -1
  160. package/dist/types/protocol.d.ts +11 -0
  161. package/dist/types/protocol.js +1 -0
  162. package/dist/types/protocol.js.map +1 -1
  163. package/dist/types/protocol.mjs +1 -0
  164. package/dist/types/protocol.mjs.map +1 -1
  165. package/dist/utils/binary.d.ts +6 -0
  166. package/dist/utils/binary.js +53 -0
  167. package/dist/utils/binary.js.map +1 -0
  168. package/dist/utils/binary.mjs +49 -0
  169. package/dist/utils/binary.mjs.map +1 -0
  170. package/dist/utils/toolGuardrails.d.ts +24 -0
  171. package/dist/utils/toolGuardrails.js +58 -0
  172. package/dist/utils/toolGuardrails.js.map +1 -0
  173. package/dist/utils/toolGuardrails.mjs +54 -0
  174. package/dist/utils/toolGuardrails.mjs.map +1 -0
  175. package/package.json +4 -3
  176. package/dist/runImplementation.d.ts +0 -161
  177. package/dist/runImplementation.js +0 -2054
  178. package/dist/runImplementation.js.map +0 -1
  179. package/dist/runImplementation.mjs +0 -2028
  180. package/dist/runImplementation.mjs.map +0 -1
@@ -0,0 +1,984 @@
1
+ import { consumeAgentToolRunResult, } from "../agent.mjs";
2
+ import { ToolCallError, UserError } from "../errors.mjs";
3
+ import { getTransferMessage } from "../handoff.mjs";
4
+ import { RunHandoffOutputItem, RunToolApprovalItem, RunToolCallOutputItem, } from "../items.mjs";
5
+ import logger from "../logger.mjs";
6
+ import { resolveComputer } from "../tool.mjs";
7
+ import { encodeUint8ArrayToBase64 } from "../utils/base64.mjs";
8
+ import { toSmartString } from "../utils/smartString.mjs";
9
+ import { isZodObject } from "../utils/index.mjs";
10
+ import { withFunctionSpan, withHandoffSpan } from "../tracing/createSpans.mjs";
11
+ import { runToolInputGuardrails, runToolOutputGuardrails, } from "../utils/toolGuardrails.mjs";
12
+ import { SingleStepResult } from "./steps.mjs";
13
+ const TOOL_APPROVAL_REJECTION_MESSAGE = 'Tool execution was not approved.';
14
+ /**
15
+ * @internal
16
+ * Normalizes tool outputs once so downstream code works with fully structured protocol items.
17
+ * Doing this here keeps API surface stable even when providers add new shapes.
18
+ */
19
+ export function getToolCallOutputItem(toolCall, output) {
20
+ const maybeStructuredOutputs = normalizeStructuredToolOutputs(output);
21
+ if (maybeStructuredOutputs) {
22
+ const structuredItems = maybeStructuredOutputs.map(convertStructuredToolOutputToInputItem);
23
+ return {
24
+ type: 'function_call_result',
25
+ name: toolCall.name,
26
+ callId: toolCall.callId,
27
+ status: 'completed',
28
+ output: structuredItems,
29
+ };
30
+ }
31
+ return {
32
+ type: 'function_call_result',
33
+ name: toolCall.name,
34
+ callId: toolCall.callId,
35
+ status: 'completed',
36
+ output: {
37
+ type: 'text',
38
+ text: toSmartString(output),
39
+ },
40
+ };
41
+ }
42
+ /**
43
+ * @internal
44
+ * Runs every function tool call requested by the model and returns their outputs alongside
45
+ * the `RunItem` instances that should be appended to history.
46
+ */
47
+ export async function executeFunctionToolCalls(agent, toolRuns, runner, state) {
48
+ const deps = { agent, runner, state };
49
+ try {
50
+ const results = await Promise.all(toolRuns.map(async (toolRun) => {
51
+ const parsedArgs = parseToolArguments(toolRun);
52
+ const approvalOutcome = await handleFunctionApproval(deps, toolRun, parsedArgs);
53
+ if (approvalOutcome !== 'approved') {
54
+ return approvalOutcome;
55
+ }
56
+ return runApprovedFunctionTool(deps, toolRun);
57
+ }));
58
+ return results;
59
+ }
60
+ catch (e) {
61
+ throw new ToolCallError(`Failed to run function tools: ${e}`, e, state);
62
+ }
63
+ }
64
+ function parseToolArguments(toolRun) {
65
+ let parsedArgs = toolRun.toolCall.arguments;
66
+ if (toolRun.tool.parameters) {
67
+ if (isZodObject(toolRun.tool.parameters)) {
68
+ parsedArgs = toolRun.tool.parameters.parse(parsedArgs);
69
+ }
70
+ else {
71
+ parsedArgs = JSON.parse(parsedArgs);
72
+ }
73
+ }
74
+ return parsedArgs;
75
+ }
76
+ function buildApprovalRequestResult(deps, toolRun) {
77
+ return {
78
+ type: 'function_approval',
79
+ tool: toolRun.tool,
80
+ runItem: new RunToolApprovalItem(toolRun.toolCall, deps.agent),
81
+ };
82
+ }
83
+ async function buildApprovalRejectionResult(deps, toolRun) {
84
+ const { agent } = deps;
85
+ return withFunctionSpan(async (span) => {
86
+ const response = 'Tool execution was not approved.';
87
+ span.setError({
88
+ message: response,
89
+ data: {
90
+ tool_name: toolRun.tool.name,
91
+ error: `Tool execution for ${toolRun.toolCall.callId} was manually rejected by user.`,
92
+ },
93
+ });
94
+ span.spanData.output = response;
95
+ return {
96
+ type: 'function_output',
97
+ tool: toolRun.tool,
98
+ output: response,
99
+ runItem: new RunToolCallOutputItem(getToolCallOutputItem(toolRun.toolCall, response), agent, response),
100
+ };
101
+ }, {
102
+ data: {
103
+ name: toolRun.tool.name,
104
+ },
105
+ });
106
+ }
107
+ async function handleFunctionApproval(deps, toolRun, parsedArgs) {
108
+ const { state } = deps;
109
+ const needsApproval = await toolRun.tool.needsApproval(state._context, parsedArgs, toolRun.toolCall.callId);
110
+ if (!needsApproval) {
111
+ return 'approved';
112
+ }
113
+ const approval = state._context.isToolApproved({
114
+ toolName: toolRun.tool.name,
115
+ callId: toolRun.toolCall.callId,
116
+ });
117
+ if (approval === false) {
118
+ return await buildApprovalRejectionResult(deps, toolRun);
119
+ }
120
+ if (approval !== true) {
121
+ return buildApprovalRequestResult(deps, toolRun);
122
+ }
123
+ return 'approved';
124
+ }
125
+ async function runApprovedFunctionTool(deps, toolRun) {
126
+ const { agent, runner, state } = deps;
127
+ return withFunctionSpan(async (span) => {
128
+ if (runner.config.traceIncludeSensitiveData) {
129
+ span.spanData.input = toolRun.toolCall.arguments;
130
+ }
131
+ try {
132
+ const inputGuardrailResult = await runToolInputGuardrails({
133
+ guardrails: toolRun.tool.inputGuardrails,
134
+ context: state._context,
135
+ agent,
136
+ toolCall: toolRun.toolCall,
137
+ onResult: (result) => {
138
+ state._toolInputGuardrailResults.push(result);
139
+ },
140
+ });
141
+ emitToolStart(runner, state._context, agent, toolRun.tool, toolRun.toolCall);
142
+ let toolOutput;
143
+ if (inputGuardrailResult.type === 'reject') {
144
+ toolOutput = inputGuardrailResult.message;
145
+ }
146
+ else {
147
+ toolOutput = await toolRun.tool.invoke(state._context, toolRun.toolCall.arguments, { toolCall: toolRun.toolCall });
148
+ toolOutput = await runToolOutputGuardrails({
149
+ guardrails: toolRun.tool.outputGuardrails,
150
+ context: state._context,
151
+ agent,
152
+ toolCall: toolRun.toolCall,
153
+ toolOutput,
154
+ onResult: (result) => {
155
+ state._toolOutputGuardrailResults.push(result);
156
+ },
157
+ });
158
+ }
159
+ const stringResult = toSmartString(toolOutput);
160
+ emitToolEnd(runner, state._context, agent, toolRun.tool, stringResult, toolRun.toolCall);
161
+ if (runner.config.traceIncludeSensitiveData) {
162
+ span.spanData.output = stringResult;
163
+ }
164
+ const functionResult = {
165
+ type: 'function_output',
166
+ tool: toolRun.tool,
167
+ output: toolOutput,
168
+ runItem: new RunToolCallOutputItem(getToolCallOutputItem(toolRun.toolCall, toolOutput), agent, toolOutput),
169
+ };
170
+ const nestedRunResult = consumeAgentToolRunResult(toolRun.toolCall);
171
+ if (nestedRunResult) {
172
+ functionResult.agentRunResult = nestedRunResult;
173
+ const nestedInterruptions = nestedRunResult.interruptions;
174
+ if (nestedInterruptions.length > 0) {
175
+ functionResult.interruptions = nestedInterruptions;
176
+ }
177
+ }
178
+ return functionResult;
179
+ }
180
+ catch (error) {
181
+ span.setError({
182
+ message: 'Error running tool',
183
+ data: {
184
+ tool_name: toolRun.tool.name,
185
+ error: String(error),
186
+ },
187
+ });
188
+ const errorResult = String(error);
189
+ emitToolEnd(runner, state._context, agent, toolRun.tool, errorResult, toolRun.toolCall);
190
+ throw error;
191
+ }
192
+ }, {
193
+ data: {
194
+ name: toolRun.tool.name,
195
+ },
196
+ });
197
+ }
198
+ /**
199
+ * @internal
200
+ */
201
+ // Internal helper: dispatch a computer action and return a screenshot (sync/async)
202
+ async function _runComputerActionAndScreenshot(computer, toolCall) {
203
+ const action = toolCall.action;
204
+ let screenshot;
205
+ // Dispatch based on action type string (assume action.type exists)
206
+ switch (action.type) {
207
+ case 'click':
208
+ await computer.click(action.x, action.y, action.button);
209
+ break;
210
+ case 'double_click':
211
+ await computer.doubleClick(action.x, action.y);
212
+ break;
213
+ case 'drag':
214
+ await computer.drag(action.path.map((p) => [p.x, p.y]));
215
+ break;
216
+ case 'keypress':
217
+ await computer.keypress(action.keys);
218
+ break;
219
+ case 'move':
220
+ await computer.move(action.x, action.y);
221
+ break;
222
+ case 'screenshot':
223
+ screenshot = await computer.screenshot();
224
+ break;
225
+ case 'scroll':
226
+ await computer.scroll(action.x, action.y, action.scroll_x, action.scroll_y);
227
+ break;
228
+ case 'type':
229
+ await computer.type(action.text);
230
+ break;
231
+ case 'wait':
232
+ await computer.wait();
233
+ break;
234
+ default:
235
+ action; // ensures that we handle every action we know of
236
+ // Unknown action, just take screenshot
237
+ break;
238
+ }
239
+ if (typeof screenshot !== 'undefined') {
240
+ return screenshot;
241
+ }
242
+ // Always return screenshot as base64 string
243
+ if (typeof computer.screenshot === 'function') {
244
+ screenshot = await computer.screenshot();
245
+ if (typeof screenshot !== 'undefined') {
246
+ return screenshot;
247
+ }
248
+ }
249
+ throw new Error('Computer does not implement screenshot()');
250
+ }
251
+ function toErrorMessage(error) {
252
+ if (error instanceof Error) {
253
+ return error.message || error.toString();
254
+ }
255
+ try {
256
+ return JSON.stringify(error);
257
+ }
258
+ catch {
259
+ return String(error);
260
+ }
261
+ }
262
+ async function resolveToolApproval(options) {
263
+ const { runContext, toolName, callId, approvalItem, needsApproval, onApproval, } = options;
264
+ if (!needsApproval) {
265
+ return 'approved';
266
+ }
267
+ if (onApproval) {
268
+ const decision = await onApproval(runContext, approvalItem);
269
+ if (decision.approve === true) {
270
+ runContext.approveTool(approvalItem);
271
+ }
272
+ else if (decision.approve === false) {
273
+ runContext.rejectTool(approvalItem);
274
+ }
275
+ }
276
+ const approval = runContext.isToolApproved({
277
+ toolName,
278
+ callId,
279
+ });
280
+ if (approval === true) {
281
+ return 'approved';
282
+ }
283
+ if (approval === false) {
284
+ return 'rejected';
285
+ }
286
+ return 'pending';
287
+ }
288
+ async function handleToolApprovalDecision(options) {
289
+ const { runContext, toolName, callId, approvalItem, needsApproval, onApproval, buildRejectionItem, } = options;
290
+ const approvalState = await resolveToolApproval({
291
+ runContext,
292
+ toolName,
293
+ callId,
294
+ approvalItem,
295
+ needsApproval,
296
+ onApproval,
297
+ });
298
+ if (approvalState === 'rejected') {
299
+ return { status: 'rejected', item: buildRejectionItem() };
300
+ }
301
+ if (approvalState === 'pending') {
302
+ return { status: 'pending', item: approvalItem };
303
+ }
304
+ return { status: 'approved' };
305
+ }
306
+ function emitToolStart(runner, runContext, agent, tool, toolCall) {
307
+ runner.emit('agent_tool_start', runContext, agent, tool, { toolCall });
308
+ if (typeof agent.emit === 'function') {
309
+ agent.emit('agent_tool_start', runContext, tool, { toolCall });
310
+ }
311
+ }
312
+ function emitToolEnd(runner, runContext, agent, tool, output, toolCall) {
313
+ runner.emit('agent_tool_end', runContext, agent, tool, output, { toolCall });
314
+ if (typeof agent.emit === 'function') {
315
+ agent.emit('agent_tool_end', runContext, tool, output, { toolCall });
316
+ }
317
+ }
318
+ export async function executeShellActions(agent, actions, runner, runContext, customLogger = undefined) {
319
+ const _logger = customLogger ?? logger;
320
+ const results = [];
321
+ for (const action of actions) {
322
+ const shellTool = action.shell;
323
+ const toolCall = action.toolCall;
324
+ const approvalItem = new RunToolApprovalItem(toolCall, agent, shellTool.name);
325
+ const approvalDecision = await handleToolApprovalDecision({
326
+ runContext,
327
+ toolName: shellTool.name,
328
+ callId: toolCall.callId,
329
+ approvalItem,
330
+ needsApproval: await shellTool.needsApproval(runContext, toolCall.action, toolCall.callId),
331
+ onApproval: shellTool.onApproval,
332
+ buildRejectionItem: () => {
333
+ const response = TOOL_APPROVAL_REJECTION_MESSAGE;
334
+ const rejectionOutput = {
335
+ stdout: '',
336
+ stderr: response,
337
+ outcome: { type: 'exit', exitCode: null },
338
+ };
339
+ return new RunToolCallOutputItem({
340
+ type: 'shell_call_output',
341
+ callId: toolCall.callId,
342
+ output: [rejectionOutput],
343
+ }, agent, response);
344
+ },
345
+ });
346
+ if (approvalDecision.status !== 'approved') {
347
+ results.push(approvalDecision.item);
348
+ continue;
349
+ }
350
+ emitToolStart(runner, runContext, agent, shellTool, toolCall);
351
+ let shellOutputs;
352
+ const providerMeta = {};
353
+ let maxOutputLength;
354
+ try {
355
+ const shellResult = await shellTool.shell.run(toolCall.action);
356
+ shellOutputs = shellResult.output ?? [];
357
+ if (shellResult.providerData) {
358
+ Object.assign(providerMeta, shellResult.providerData);
359
+ }
360
+ if (typeof shellResult.maxOutputLength === 'number') {
361
+ maxOutputLength = shellResult.maxOutputLength;
362
+ }
363
+ }
364
+ catch (err) {
365
+ const errorText = toErrorMessage(err);
366
+ shellOutputs = [
367
+ {
368
+ stdout: '',
369
+ stderr: errorText,
370
+ outcome: { type: 'exit', exitCode: null },
371
+ },
372
+ ];
373
+ _logger.error('Failed to execute shell action:', err);
374
+ }
375
+ shellOutputs = shellOutputs ?? [];
376
+ emitToolEnd(runner, runContext, agent, shellTool, JSON.stringify(shellOutputs), toolCall);
377
+ const rawItem = {
378
+ type: 'shell_call_output',
379
+ callId: toolCall.callId,
380
+ output: shellOutputs ?? [],
381
+ };
382
+ if (typeof maxOutputLength === 'number') {
383
+ rawItem.maxOutputLength = maxOutputLength;
384
+ }
385
+ if (Object.keys(providerMeta).length > 0) {
386
+ rawItem.providerData = providerMeta;
387
+ }
388
+ results.push(new RunToolCallOutputItem(rawItem, agent, rawItem.output));
389
+ }
390
+ return results;
391
+ }
392
+ export async function executeApplyPatchOperations(agent, actions, runner, runContext, customLogger = undefined) {
393
+ const _logger = customLogger ?? logger;
394
+ const results = [];
395
+ for (const action of actions) {
396
+ const applyPatchTool = action.applyPatch;
397
+ const toolCall = action.toolCall;
398
+ const approvalItem = new RunToolApprovalItem(toolCall, agent, applyPatchTool.name);
399
+ const approvalDecision = await handleToolApprovalDecision({
400
+ runContext,
401
+ toolName: applyPatchTool.name,
402
+ callId: toolCall.callId,
403
+ approvalItem,
404
+ needsApproval: await applyPatchTool.needsApproval(runContext, toolCall.operation, toolCall.callId),
405
+ onApproval: applyPatchTool.onApproval,
406
+ buildRejectionItem: () => {
407
+ const response = TOOL_APPROVAL_REJECTION_MESSAGE;
408
+ return new RunToolCallOutputItem({
409
+ type: 'apply_patch_call_output',
410
+ callId: toolCall.callId,
411
+ status: 'failed',
412
+ output: response,
413
+ }, agent, response);
414
+ },
415
+ });
416
+ if (approvalDecision.status !== 'approved') {
417
+ results.push(approvalDecision.item);
418
+ continue;
419
+ }
420
+ emitToolStart(runner, runContext, agent, applyPatchTool, toolCall);
421
+ let status = 'completed';
422
+ let output = '';
423
+ try {
424
+ let result;
425
+ switch (toolCall.operation.type) {
426
+ case 'create_file':
427
+ result = await applyPatchTool.editor.createFile(toolCall.operation);
428
+ break;
429
+ case 'update_file':
430
+ result = await applyPatchTool.editor.updateFile(toolCall.operation);
431
+ break;
432
+ case 'delete_file':
433
+ result = await applyPatchTool.editor.deleteFile(toolCall.operation);
434
+ break;
435
+ default:
436
+ throw new Error('Unsupported apply_patch operation');
437
+ }
438
+ if (result && typeof result.status === 'string') {
439
+ status = result.status;
440
+ }
441
+ if (result && typeof result.output === 'string') {
442
+ output = result.output;
443
+ }
444
+ }
445
+ catch (err) {
446
+ status = 'failed';
447
+ output = toErrorMessage(err);
448
+ _logger.error('Failed to execute apply_patch operation:', err);
449
+ }
450
+ emitToolEnd(runner, runContext, agent, applyPatchTool, output, toolCall);
451
+ const rawItem = {
452
+ type: 'apply_patch_call_output',
453
+ callId: toolCall.callId,
454
+ status,
455
+ };
456
+ if (output) {
457
+ rawItem.output = output;
458
+ }
459
+ results.push(new RunToolCallOutputItem(rawItem, agent, output));
460
+ }
461
+ return results;
462
+ }
463
+ /**
464
+ * @internal
465
+ * Executes any computer-use actions emitted by the model and returns the resulting items so
466
+ * the run history reflects the computer session.
467
+ */
468
+ export async function executeComputerActions(agent, actions, runner, runContext, customLogger = undefined) {
469
+ const _logger = customLogger ?? logger;
470
+ const results = [];
471
+ for (const action of actions) {
472
+ const toolCall = action.toolCall;
473
+ // Hooks: on_tool_start (global + agent)
474
+ emitToolStart(runner, runContext, agent, action.computer, toolCall);
475
+ // Run the action and get screenshot
476
+ let output;
477
+ try {
478
+ const computer = await resolveComputer({
479
+ tool: action.computer,
480
+ runContext,
481
+ });
482
+ output = await _runComputerActionAndScreenshot(computer, toolCall);
483
+ }
484
+ catch (err) {
485
+ _logger.error('Failed to execute computer action:', err);
486
+ output = '';
487
+ }
488
+ // Hooks: on_tool_end (global + agent)
489
+ emitToolEnd(runner, runContext, agent, action.computer, output, toolCall);
490
+ // Return the screenshot as a data URL when available; fall back to an empty string on failures.
491
+ const imageUrl = output ? `data:image/png;base64,${output}` : '';
492
+ const rawItem = {
493
+ type: 'computer_call_result',
494
+ callId: toolCall.callId,
495
+ output: { type: 'computer_screenshot', data: imageUrl },
496
+ };
497
+ results.push(new RunToolCallOutputItem(rawItem, agent, imageUrl));
498
+ }
499
+ return results;
500
+ }
501
+ /**
502
+ * @internal
503
+ * Drives handoff calls by invoking the downstream agent and capturing any generated items so
504
+ * the current agent can continue with the new context.
505
+ */
506
+ export async function executeHandoffCalls(agent, originalInput, preStepItems, newStepItems, newResponse, runHandoffs, runner, runContext) {
507
+ newStepItems = [...newStepItems];
508
+ if (runHandoffs.length === 0) {
509
+ logger.warn('Incorrectly called executeHandoffCalls with no handoffs. This should not happen. Moving on.');
510
+ return new SingleStepResult(originalInput, newResponse, preStepItems, newStepItems, { type: 'next_step_run_again' });
511
+ }
512
+ if (runHandoffs.length > 1) {
513
+ // multiple handoffs. Ignoring all but the first one by adding reject responses for those
514
+ const outputMessage = 'Multiple handoffs detected, ignoring this one.';
515
+ for (let i = 1; i < runHandoffs.length; i++) {
516
+ newStepItems.push(new RunToolCallOutputItem(getToolCallOutputItem(runHandoffs[i].toolCall, outputMessage), agent, outputMessage));
517
+ }
518
+ }
519
+ const actualHandoff = runHandoffs[0];
520
+ return withHandoffSpan(async (handoffSpan) => {
521
+ const handoff = actualHandoff.handoff;
522
+ const newAgent = await handoff.onInvokeHandoff(runContext, actualHandoff.toolCall.arguments);
523
+ handoffSpan.spanData.to_agent = newAgent.name;
524
+ if (runHandoffs.length > 1) {
525
+ const requestedAgents = runHandoffs.map((h) => h.handoff.agentName);
526
+ handoffSpan.setError({
527
+ message: 'Multiple handoffs requested',
528
+ data: {
529
+ requested_agents: requestedAgents,
530
+ },
531
+ });
532
+ }
533
+ newStepItems.push(new RunHandoffOutputItem(getToolCallOutputItem(actualHandoff.toolCall, getTransferMessage(newAgent)), agent, newAgent));
534
+ runner.emit('agent_handoff', runContext, agent, newAgent);
535
+ agent.emit('agent_handoff', runContext, newAgent);
536
+ const inputFilter = handoff.inputFilter ?? runner.config.handoffInputFilter;
537
+ if (inputFilter) {
538
+ logger.debug('Filtering inputs for handoff');
539
+ if (typeof inputFilter !== 'function') {
540
+ handoffSpan.setError({
541
+ message: 'Invalid input filter',
542
+ data: {
543
+ details: 'not callable',
544
+ },
545
+ });
546
+ }
547
+ const handoffInputData = {
548
+ inputHistory: Array.isArray(originalInput)
549
+ ? [...originalInput]
550
+ : originalInput,
551
+ preHandoffItems: [...preStepItems],
552
+ newItems: [...newStepItems],
553
+ runContext,
554
+ };
555
+ const filtered = inputFilter(handoffInputData);
556
+ originalInput = filtered.inputHistory;
557
+ preStepItems = filtered.preHandoffItems;
558
+ newStepItems = filtered.newItems;
559
+ }
560
+ return new SingleStepResult(originalInput, newResponse, preStepItems, newStepItems, { type: 'next_step_handoff', newAgent });
561
+ }, {
562
+ data: {
563
+ from_agent: agent.name,
564
+ },
565
+ });
566
+ }
567
+ const NOT_FINAL_OUTPUT = {
568
+ isFinalOutput: false,
569
+ isInterrupted: undefined,
570
+ };
571
+ /**
572
+ * Collects approval interruptions from tool execution results and any additional
573
+ * RunItems (e.g., shell/apply_patch approval placeholders).
574
+ */
575
+ export function collectInterruptions(toolResults, additionalItems = []) {
576
+ const interruptions = [];
577
+ for (const item of additionalItems) {
578
+ if (item instanceof RunToolApprovalItem) {
579
+ interruptions.push(item);
580
+ }
581
+ }
582
+ for (const result of toolResults) {
583
+ if (result.runItem instanceof RunToolApprovalItem) {
584
+ interruptions.push(result.runItem);
585
+ }
586
+ if (result.type === 'function_output') {
587
+ if (Array.isArray(result.interruptions)) {
588
+ interruptions.push(...result.interruptions);
589
+ }
590
+ else if (result.agentRunResult) {
591
+ const nestedInterruptions = result.agentRunResult.interruptions;
592
+ if (nestedInterruptions.length > 0) {
593
+ interruptions.push(...nestedInterruptions);
594
+ }
595
+ }
596
+ }
597
+ }
598
+ return interruptions;
599
+ }
600
+ /**
601
+ * @internal
602
+ * Determines whether tool executions produced a final agent output, triggered an interruption,
603
+ * or whether the agent loop should continue collecting more responses.
604
+ */
605
+ export async function checkForFinalOutputFromTools(agent, toolResults, state, additionalInterruptions = []) {
606
+ if (toolResults.length === 0 && additionalInterruptions.length === 0) {
607
+ return NOT_FINAL_OUTPUT;
608
+ }
609
+ const interruptions = collectInterruptions(toolResults, additionalInterruptions);
610
+ if (interruptions.length > 0) {
611
+ return {
612
+ isFinalOutput: false,
613
+ isInterrupted: true,
614
+ interruptions,
615
+ };
616
+ }
617
+ if (agent.toolUseBehavior === 'run_llm_again') {
618
+ return NOT_FINAL_OUTPUT;
619
+ }
620
+ const firstToolResult = toolResults[0];
621
+ if (agent.toolUseBehavior === 'stop_on_first_tool') {
622
+ if (firstToolResult?.type === 'function_output') {
623
+ const stringOutput = toSmartString(firstToolResult.output);
624
+ return {
625
+ isFinalOutput: true,
626
+ isInterrupted: undefined,
627
+ finalOutput: stringOutput,
628
+ };
629
+ }
630
+ return NOT_FINAL_OUTPUT;
631
+ }
632
+ const toolUseBehavior = agent.toolUseBehavior;
633
+ if (typeof toolUseBehavior === 'object') {
634
+ const stoppingTool = toolResults.find((r) => toolUseBehavior.stopAtToolNames.includes(r.tool.name));
635
+ if (stoppingTool?.type === 'function_output') {
636
+ const stringOutput = toSmartString(stoppingTool.output);
637
+ return {
638
+ isFinalOutput: true,
639
+ isInterrupted: undefined,
640
+ finalOutput: stringOutput,
641
+ };
642
+ }
643
+ return NOT_FINAL_OUTPUT;
644
+ }
645
+ if (typeof toolUseBehavior === 'function') {
646
+ return toolUseBehavior(state._context, toolResults);
647
+ }
648
+ throw new UserError(`Invalid toolUseBehavior: ${toolUseBehavior}`, state);
649
+ }
650
+ /**
651
+ * Accepts whatever the tool returned and attempts to coerce it into the structured protocol
652
+ * shapes we expose to downstream model adapters (input_text/input_image/input_file). Tools are
653
+ * allowed to return either a single structured object or an array of them; anything else falls
654
+ * back to the legacy string pipeline.
655
+ */
656
+ function normalizeStructuredToolOutputs(output) {
657
+ if (Array.isArray(output)) {
658
+ const structured = [];
659
+ for (const item of output) {
660
+ const normalized = normalizeStructuredToolOutput(item);
661
+ if (!normalized) {
662
+ return null;
663
+ }
664
+ structured.push(normalized);
665
+ }
666
+ return structured;
667
+ }
668
+ const normalized = normalizeStructuredToolOutput(output);
669
+ return normalized ? [normalized] : null;
670
+ }
671
+ /**
672
+ * Best-effort normalization of a single tool output item. If the object already matches the
673
+ * protocol shape we simply cast it; otherwise we copy the recognised fields into the canonical
674
+ * structure. Returning null lets the caller know we should revert to plain-string handling.
675
+ */
676
+ function normalizeStructuredToolOutput(value) {
677
+ if (!isRecord(value)) {
678
+ return null;
679
+ }
680
+ const type = value.type;
681
+ if (type === 'text' && typeof value.text === 'string') {
682
+ const output = { type: 'text', text: value.text };
683
+ if (isRecord(value.providerData)) {
684
+ output.providerData = value.providerData;
685
+ }
686
+ return output;
687
+ }
688
+ if (type === 'image') {
689
+ const output = { type: 'image' };
690
+ let imageString;
691
+ let imageFileId;
692
+ const fallbackImageMediaType = isNonEmptyString(value.mediaType)
693
+ ? value.mediaType
694
+ : undefined;
695
+ const imageField = value.image;
696
+ if (typeof imageField === 'string' && imageField.length > 0) {
697
+ imageString = imageField;
698
+ }
699
+ else if (isRecord(imageField)) {
700
+ const imageObj = imageField;
701
+ const inlineMediaType = isNonEmptyString(imageObj.mediaType)
702
+ ? imageObj.mediaType
703
+ : fallbackImageMediaType;
704
+ if (isNonEmptyString(imageObj.url)) {
705
+ imageString = imageObj.url;
706
+ }
707
+ else if (isNonEmptyString(imageObj.data)) {
708
+ imageString = toInlineImageString(imageObj.data, inlineMediaType);
709
+ }
710
+ else if (imageObj.data instanceof Uint8Array &&
711
+ imageObj.data.length > 0) {
712
+ imageString = toInlineImageString(imageObj.data, inlineMediaType);
713
+ }
714
+ if (!imageString) {
715
+ const candidateId = (isNonEmptyString(imageObj.fileId) && imageObj.fileId) ||
716
+ (isNonEmptyString(imageObj.id) && imageObj.id) ||
717
+ undefined;
718
+ if (candidateId) {
719
+ imageFileId = candidateId;
720
+ }
721
+ }
722
+ }
723
+ if (!imageString &&
724
+ typeof value.imageUrl === 'string' &&
725
+ value.imageUrl.length > 0) {
726
+ imageString = value.imageUrl;
727
+ }
728
+ if (!imageFileId &&
729
+ typeof value.fileId === 'string' &&
730
+ value.fileId.length > 0) {
731
+ imageFileId = value.fileId;
732
+ }
733
+ if (!imageString &&
734
+ typeof value.data === 'string' &&
735
+ value.data.length > 0) {
736
+ imageString = fallbackImageMediaType
737
+ ? toInlineImageString(value.data, fallbackImageMediaType)
738
+ : value.data;
739
+ }
740
+ else if (!imageString &&
741
+ value.data instanceof Uint8Array &&
742
+ value.data.length > 0) {
743
+ imageString = toInlineImageString(value.data, fallbackImageMediaType);
744
+ }
745
+ if (typeof value.detail === 'string' && value.detail.length > 0) {
746
+ output.detail = value.detail;
747
+ }
748
+ if (imageString) {
749
+ output.image = imageString;
750
+ }
751
+ else if (imageFileId) {
752
+ output.image = { fileId: imageFileId };
753
+ }
754
+ else {
755
+ return null;
756
+ }
757
+ if (isRecord(value.providerData)) {
758
+ output.providerData = value.providerData;
759
+ }
760
+ return output;
761
+ }
762
+ if (type === 'file') {
763
+ const fileValue = normalizeFileValue(value);
764
+ if (!fileValue) {
765
+ return null;
766
+ }
767
+ const output = { type: 'file', file: fileValue };
768
+ if (isRecord(value.providerData)) {
769
+ output.providerData = value.providerData;
770
+ }
771
+ return output;
772
+ }
773
+ return null;
774
+ }
775
+ /**
776
+ * Translates the normalized tool output into the protocol `input_*` items. This is the last hop
777
+ * before we hand the data to model-specific adapters, so we generate the exact schema expected by
778
+ * the protocol definitions.
779
+ */
780
+ function convertStructuredToolOutputToInputItem(output) {
781
+ if (output.type === 'text') {
782
+ const result = {
783
+ type: 'input_text',
784
+ text: output.text,
785
+ };
786
+ if (output.providerData) {
787
+ result.providerData = output.providerData;
788
+ }
789
+ return result;
790
+ }
791
+ if (output.type === 'image') {
792
+ const result = { type: 'input_image' };
793
+ if (typeof output.detail === 'string' && output.detail.length > 0) {
794
+ result.detail = output.detail;
795
+ }
796
+ if (typeof output.image === 'string' && output.image.length > 0) {
797
+ result.image = output.image;
798
+ }
799
+ else if (isRecord(output.image)) {
800
+ const imageObj = output.image;
801
+ const inlineMediaType = isNonEmptyString(imageObj.mediaType)
802
+ ? imageObj.mediaType
803
+ : undefined;
804
+ if (isNonEmptyString(imageObj.url)) {
805
+ result.image = imageObj.url;
806
+ }
807
+ else if (isNonEmptyString(imageObj.data)) {
808
+ result.image =
809
+ inlineMediaType && !imageObj.data.startsWith('data:')
810
+ ? asDataUrl(imageObj.data, inlineMediaType)
811
+ : imageObj.data;
812
+ }
813
+ else if (imageObj.data instanceof Uint8Array &&
814
+ imageObj.data.length > 0) {
815
+ const base64 = encodeUint8ArrayToBase64(imageObj.data);
816
+ result.image = asDataUrl(base64, inlineMediaType);
817
+ }
818
+ else {
819
+ const referencedId = (isNonEmptyString(imageObj.fileId) && imageObj.fileId) ||
820
+ (isNonEmptyString(imageObj.id) && imageObj.id) ||
821
+ undefined;
822
+ if (referencedId) {
823
+ result.image = { id: referencedId };
824
+ }
825
+ }
826
+ }
827
+ if (output.providerData) {
828
+ result.providerData = output.providerData;
829
+ }
830
+ return result;
831
+ }
832
+ if (output.type === 'file') {
833
+ const result = { type: 'input_file' };
834
+ const fileValue = output.file;
835
+ if (typeof fileValue === 'string') {
836
+ result.file = fileValue;
837
+ }
838
+ else if (fileValue && typeof fileValue === 'object') {
839
+ const record = fileValue;
840
+ if ('data' in record && record.data) {
841
+ const mediaType = record.mediaType ?? 'text/plain';
842
+ if (typeof record.data === 'string') {
843
+ result.file = asDataUrl(record.data, mediaType);
844
+ }
845
+ else {
846
+ const base64 = encodeUint8ArrayToBase64(record.data);
847
+ result.file = asDataUrl(base64, mediaType);
848
+ }
849
+ }
850
+ else if (typeof record.url === 'string' && record.url.length > 0) {
851
+ result.file = { url: record.url };
852
+ }
853
+ else {
854
+ const referencedId = (typeof record.id === 'string' &&
855
+ record.id.length > 0 &&
856
+ record.id) ||
857
+ (typeof record.fileId === 'string' && record.fileId.length > 0
858
+ ? record.fileId
859
+ : undefined);
860
+ if (referencedId) {
861
+ result.file = { id: referencedId };
862
+ }
863
+ }
864
+ if (typeof record.filename === 'string' && record.filename.length > 0) {
865
+ result.filename = record.filename;
866
+ }
867
+ }
868
+ if (output.providerData) {
869
+ result.providerData = output.providerData;
870
+ }
871
+ return result;
872
+ }
873
+ const exhaustiveCheck = output;
874
+ return exhaustiveCheck;
875
+ }
876
+ function normalizeFileValue(value) {
877
+ const directFile = value.file;
878
+ if (typeof directFile === 'string' && directFile.length > 0) {
879
+ return directFile;
880
+ }
881
+ const normalizedObject = normalizeFileObjectCandidate(directFile);
882
+ if (normalizedObject) {
883
+ return normalizedObject;
884
+ }
885
+ const legacyValue = normalizeLegacyFileValue(value);
886
+ if (legacyValue) {
887
+ return legacyValue;
888
+ }
889
+ return null;
890
+ }
891
+ function normalizeFileObjectCandidate(value) {
892
+ if (!isRecord(value)) {
893
+ return null;
894
+ }
895
+ if ('data' in value && value.data !== undefined) {
896
+ const dataValue = value.data;
897
+ const hasStringData = typeof dataValue === 'string' && dataValue.length > 0;
898
+ const hasBinaryData = dataValue instanceof Uint8Array && dataValue.length > 0;
899
+ if (!hasStringData && !hasBinaryData) {
900
+ return null;
901
+ }
902
+ if (!isNonEmptyString(value.mediaType) ||
903
+ !isNonEmptyString(value.filename)) {
904
+ return null;
905
+ }
906
+ return {
907
+ data: typeof dataValue === 'string' ? dataValue : new Uint8Array(dataValue),
908
+ mediaType: value.mediaType,
909
+ filename: value.filename,
910
+ };
911
+ }
912
+ if (isNonEmptyString(value.url)) {
913
+ const result = { url: value.url };
914
+ if (isNonEmptyString(value.filename)) {
915
+ result.filename = value.filename;
916
+ }
917
+ return result;
918
+ }
919
+ const referencedId = (isNonEmptyString(value.id) && value.id) ||
920
+ (isNonEmptyString(value.fileId) && value.fileId);
921
+ if (referencedId) {
922
+ const result = { id: referencedId };
923
+ if (isNonEmptyString(value.filename)) {
924
+ result.filename = value.filename;
925
+ }
926
+ return result;
927
+ }
928
+ return null;
929
+ }
930
+ function normalizeLegacyFileValue(value) {
931
+ const filename = typeof value.filename === 'string' && value.filename.length > 0
932
+ ? value.filename
933
+ : undefined;
934
+ const mediaType = typeof value.mediaType === 'string' && value.mediaType.length > 0
935
+ ? value.mediaType
936
+ : undefined;
937
+ if (typeof value.fileData === 'string' && value.fileData.length > 0) {
938
+ if (!mediaType || !filename) {
939
+ return null;
940
+ }
941
+ return { data: value.fileData, mediaType, filename };
942
+ }
943
+ if (value.fileData instanceof Uint8Array && value.fileData.length > 0) {
944
+ if (!mediaType || !filename) {
945
+ return null;
946
+ }
947
+ return { data: new Uint8Array(value.fileData), mediaType, filename };
948
+ }
949
+ if (typeof value.fileUrl === 'string' && value.fileUrl.length > 0) {
950
+ const result = { url: value.fileUrl };
951
+ if (filename) {
952
+ result.filename = filename;
953
+ }
954
+ return result;
955
+ }
956
+ if (typeof value.fileId === 'string' && value.fileId.length > 0) {
957
+ const result = { id: value.fileId };
958
+ if (filename) {
959
+ result.filename = filename;
960
+ }
961
+ return result;
962
+ }
963
+ return null;
964
+ }
965
+ function isRecord(value) {
966
+ return typeof value === 'object' && value !== null;
967
+ }
968
+ function isNonEmptyString(value) {
969
+ return typeof value === 'string' && value.length > 0;
970
+ }
971
+ function toInlineImageString(data, mediaType) {
972
+ if (typeof data === 'string') {
973
+ if (mediaType && !data.startsWith('data:')) {
974
+ return asDataUrl(data, mediaType);
975
+ }
976
+ return data;
977
+ }
978
+ const base64 = encodeUint8ArrayToBase64(data);
979
+ return asDataUrl(base64, mediaType);
980
+ }
981
+ function asDataUrl(base64, mediaType) {
982
+ return mediaType ? `data:${mediaType};base64,${base64}` : base64;
983
+ }
984
+ //# sourceMappingURL=toolExecution.mjs.map