@openai/agents-core 0.5.3 → 0.6.0

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 (112) hide show
  1. package/dist/computer.d.ts +10 -2
  2. package/dist/events.d.ts +1 -1
  3. package/dist/events.js.map +1 -1
  4. package/dist/events.mjs.map +1 -1
  5. package/dist/extensions/handoffFilters.d.ts +4 -3
  6. package/dist/extensions/handoffFilters.js +8 -3
  7. package/dist/extensions/handoffFilters.js.map +1 -1
  8. package/dist/extensions/handoffFilters.mjs +9 -4
  9. package/dist/extensions/handoffFilters.mjs.map +1 -1
  10. package/dist/index.d.ts +4 -4
  11. package/dist/index.js +8 -2
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +2 -2
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/items.d.ts +1158 -32
  16. package/dist/items.js +56 -2
  17. package/dist/items.js.map +1 -1
  18. package/dist/items.mjs +53 -1
  19. package/dist/items.mjs.map +1 -1
  20. package/dist/metadata.js +3 -3
  21. package/dist/metadata.mjs +3 -3
  22. package/dist/model.d.ts +14 -2
  23. package/dist/run.js +2 -2
  24. package/dist/run.js.map +1 -1
  25. package/dist/run.mjs +3 -3
  26. package/dist/run.mjs.map +1 -1
  27. package/dist/runContext.d.ts +12 -1
  28. package/dist/runContext.js +145 -41
  29. package/dist/runContext.js.map +1 -1
  30. package/dist/runContext.mjs +145 -41
  31. package/dist/runContext.mjs.map +1 -1
  32. package/dist/runState.d.ts +506 -18
  33. package/dist/runState.js +321 -15
  34. package/dist/runState.js.map +1 -1
  35. package/dist/runState.mjs +322 -16
  36. package/dist/runState.mjs.map +1 -1
  37. package/dist/runner/approvalRejection.d.ts +13 -0
  38. package/dist/runner/approvalRejection.js +44 -0
  39. package/dist/runner/approvalRejection.js.map +1 -0
  40. package/dist/runner/approvalRejection.mjs +37 -0
  41. package/dist/runner/approvalRejection.mjs.map +1 -0
  42. package/dist/runner/mcpApprovals.js +4 -1
  43. package/dist/runner/mcpApprovals.js.map +1 -1
  44. package/dist/runner/mcpApprovals.mjs +4 -1
  45. package/dist/runner/mcpApprovals.mjs.map +1 -1
  46. package/dist/runner/modelOutputs.d.ts +5 -1
  47. package/dist/runner/modelOutputs.js +552 -12
  48. package/dist/runner/modelOutputs.js.map +1 -1
  49. package/dist/runner/modelOutputs.mjs +552 -13
  50. package/dist/runner/modelOutputs.mjs.map +1 -1
  51. package/dist/runner/modelPreparation.js +5 -2
  52. package/dist/runner/modelPreparation.js.map +1 -1
  53. package/dist/runner/modelPreparation.mjs +5 -2
  54. package/dist/runner/modelPreparation.mjs.map +1 -1
  55. package/dist/runner/sessionPersistence.js +17 -3
  56. package/dist/runner/sessionPersistence.js.map +1 -1
  57. package/dist/runner/sessionPersistence.mjs +17 -3
  58. package/dist/runner/sessionPersistence.mjs.map +1 -1
  59. package/dist/runner/streaming.js +8 -0
  60. package/dist/runner/streaming.js.map +1 -1
  61. package/dist/runner/streaming.mjs +9 -1
  62. package/dist/runner/streaming.mjs.map +1 -1
  63. package/dist/runner/toolExecution.js +105 -95
  64. package/dist/runner/toolExecution.js.map +1 -1
  65. package/dist/runner/toolExecution.mjs +100 -90
  66. package/dist/runner/toolExecution.mjs.map +1 -1
  67. package/dist/runner/toolSearch.d.ts +23 -0
  68. package/dist/runner/toolSearch.js +426 -0
  69. package/dist/runner/toolSearch.js.map +1 -0
  70. package/dist/runner/toolSearch.mjs +416 -0
  71. package/dist/runner/toolSearch.mjs.map +1 -0
  72. package/dist/runner/turnResolution.js +2 -1
  73. package/dist/runner/turnResolution.js.map +1 -1
  74. package/dist/runner/turnResolution.mjs +2 -1
  75. package/dist/runner/turnResolution.mjs.map +1 -1
  76. package/dist/tool.d.ts +50 -0
  77. package/dist/tool.js +79 -0
  78. package/dist/tool.js.map +1 -1
  79. package/dist/tool.mjs +74 -0
  80. package/dist/tool.mjs.map +1 -1
  81. package/dist/toolIdentity.d.ts +23 -0
  82. package/dist/toolIdentity.js +105 -0
  83. package/dist/toolIdentity.js.map +1 -0
  84. package/dist/toolIdentity.mjs +89 -0
  85. package/dist/toolIdentity.mjs.map +1 -0
  86. package/dist/tooling.d.ts +24 -0
  87. package/dist/tooling.js +110 -0
  88. package/dist/tooling.js.map +1 -0
  89. package/dist/tooling.mjs +97 -0
  90. package/dist/tooling.mjs.map +1 -0
  91. package/dist/types/aliases.d.ts +3 -3
  92. package/dist/types/protocol.d.ts +417 -12
  93. package/dist/types/protocol.js +59 -4
  94. package/dist/types/protocol.js.map +1 -1
  95. package/dist/types/protocol.mjs +57 -2
  96. package/dist/types/protocol.mjs.map +1 -1
  97. package/dist/types/providerData.d.ts +2 -0
  98. package/dist/utils/index.d.ts +2 -0
  99. package/dist/utils/index.js +15 -1
  100. package/dist/utils/index.js.map +1 -1
  101. package/dist/utils/index.mjs +2 -0
  102. package/dist/utils/index.mjs.map +1 -1
  103. package/dist/utils/serialize.js +37 -6
  104. package/dist/utils/serialize.js.map +1 -1
  105. package/dist/utils/serialize.mjs +37 -6
  106. package/dist/utils/serialize.mjs.map +1 -1
  107. package/dist/utils/toolSearch.d.ts +1 -0
  108. package/dist/utils/toolSearch.js +13 -0
  109. package/dist/utils/toolSearch.js.map +1 -0
  110. package/dist/utils/toolSearch.mjs +2 -0
  111. package/dist/utils/toolSearch.mjs.map +1 -0
  112. package/package.json +2 -2
@@ -1,9 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.processModelResponse = processModelResponse;
4
+ exports.processModelResponseAsync = processModelResponseAsync;
4
5
  const errors_1 = require("../errors.js");
5
6
  const items_1 = require("../items.js");
7
+ const tool_1 = require("../tool.js");
6
8
  const context_1 = require("../tracing/context.js");
9
+ const toolIdentity_1 = require("../toolIdentity.js");
10
+ const utils_1 = require("../utils/index.js");
11
+ const toolSearch_1 = require("./toolSearch.js");
7
12
  function ensureToolAvailable(tool, message, data) {
8
13
  if (!tool) {
9
14
  (0, context_1.addErrorToCurrentSpan)({
@@ -21,17 +26,36 @@ function handleToolCallAction({ output, tool, agent, errorMessage, errorData, it
21
26
  actions.push(buildAction(resolvedTool));
22
27
  }
23
28
  function resolveFunctionOrHandoff(toolCall, handoffMap, functionMap, agent) {
24
- const handoff = handoffMap.get(toolCall.name);
25
- if (handoff) {
26
- return { type: 'handoff', handoff };
29
+ const resolvedToolName = (0, toolIdentity_1.resolveFunctionToolCallName)(toolCall, functionMap) ?? toolCall.name;
30
+ const namespace = (0, toolIdentity_1.getToolCallNamespace)(toolCall);
31
+ if (!namespace && typeof resolvedToolName === 'string') {
32
+ const functionTool = functionMap.get(resolvedToolName);
33
+ const handoff = handoffMap.get(toolCall.name);
34
+ if (functionTool && handoff && resolvedToolName.includes('.')) {
35
+ const message = `Ambiguous dotted tool call ${resolvedToolName} in agent ${agent.name}: it matches both a namespaced function tool and a handoff. Rename one of them or emit the function call with explicit namespace metadata.`;
36
+ (0, context_1.addErrorToCurrentSpan)({
37
+ message,
38
+ data: {
39
+ tool_name: resolvedToolName,
40
+ agent_name: agent.name,
41
+ },
42
+ });
43
+ throw new errors_1.ModelBehaviorError(message);
44
+ }
45
+ if (functionTool && resolvedToolName.includes('.')) {
46
+ return { type: 'function', tool: functionTool };
47
+ }
48
+ if (handoff) {
49
+ return { type: 'handoff', handoff };
50
+ }
27
51
  }
28
- const functionTool = functionMap.get(toolCall.name);
52
+ const functionTool = functionMap.get(resolvedToolName);
29
53
  if (!functionTool) {
30
- const message = `Tool ${toolCall.name} not found in agent ${agent.name}.`;
54
+ const message = `Tool ${resolvedToolName} not found in agent ${agent.name}.`;
31
55
  (0, context_1.addErrorToCurrentSpan)({
32
56
  message,
33
57
  data: {
34
- tool_name: toolCall.name,
58
+ tool_name: resolvedToolName,
35
59
  agent_name: agent.name,
36
60
  },
37
61
  });
@@ -39,6 +63,271 @@ function resolveFunctionOrHandoff(toolCall, handoffMap, functionMap, agent) {
39
63
  }
40
64
  return { type: 'function', tool: functionTool };
41
65
  }
66
+ function normalizeFunctionToolCallForStorage(toolCall, tool) {
67
+ const namespace = (0, toolIdentity_1.getToolCallNamespace)(toolCall);
68
+ const explicitNamespace = (0, toolIdentity_1.getFunctionToolNamespace)(tool);
69
+ const qualifiedToolName = (0, toolIdentity_1.getFunctionToolQualifiedName)(tool);
70
+ if (namespace ||
71
+ !explicitNamespace ||
72
+ !qualifiedToolName ||
73
+ toolCall.name !== qualifiedToolName) {
74
+ return toolCall;
75
+ }
76
+ return {
77
+ ...toolCall,
78
+ name: tool.name,
79
+ namespace: explicitNamespace,
80
+ };
81
+ }
82
+ function getRawAgentInputItem(item) {
83
+ if (item &&
84
+ typeof item === 'object' &&
85
+ 'rawItem' in item &&
86
+ item.rawItem &&
87
+ typeof item.rawItem === 'object') {
88
+ return item.rawItem;
89
+ }
90
+ return item;
91
+ }
92
+ function refreshLoadedDeferredToolNames(state) {
93
+ state.loadedToolNames.clear();
94
+ for (const toolSearchOutput of state.keyedToolSearchOutputsByKey.values()) {
95
+ (0, toolSearch_1.addLoadedToolNamesFromToolSearchOutput)(toolSearchOutput, state.loadedToolNames);
96
+ }
97
+ for (const toolSearchOutput of state.anonymousToolSearchOutputs) {
98
+ (0, toolSearch_1.addLoadedToolNamesFromToolSearchOutput)(toolSearchOutput, state.loadedToolNames);
99
+ }
100
+ }
101
+ function recordLoadedToolSearchOutput(state, toolSearchOutput) {
102
+ const replacementKey = (0, utils_1.getToolSearchOutputReplacementKey)(toolSearchOutput);
103
+ if (replacementKey) {
104
+ state.keyedToolSearchOutputsByKey.set(replacementKey, toolSearchOutput);
105
+ }
106
+ else {
107
+ state.anonymousToolSearchOutputs.push(toolSearchOutput);
108
+ }
109
+ refreshLoadedDeferredToolNames(state);
110
+ }
111
+ function collectLoadedDeferredToolStateFromHistory(items, agent) {
112
+ const state = {
113
+ anonymousToolSearchOutputs: [],
114
+ keyedToolSearchOutputsByKey: new Map(),
115
+ loadedToolNames: new Set(),
116
+ };
117
+ for (const item of items) {
118
+ if (item instanceof items_1.RunToolSearchOutputItem &&
119
+ item.agent.name !== agent.name) {
120
+ continue;
121
+ }
122
+ const rawItem = getRawAgentInputItem(item);
123
+ if (rawItem?.type !== 'tool_search_output') {
124
+ continue;
125
+ }
126
+ const replacementKey = (0, utils_1.getToolSearchOutputReplacementKey)(rawItem);
127
+ if (replacementKey) {
128
+ state.keyedToolSearchOutputsByKey.set(replacementKey, rawItem);
129
+ }
130
+ else {
131
+ state.anonymousToolSearchOutputs.push(rawItem);
132
+ }
133
+ }
134
+ refreshLoadedDeferredToolNames(state);
135
+ return state;
136
+ }
137
+ function seedHostedMcpToolsFromLoadedDeferredToolState(state, mcpToolMap, preserveExistingServerLabels) {
138
+ for (const toolSearchOutput of state.keyedToolSearchOutputsByKey.values()) {
139
+ (0, toolSearch_1.addHostedMcpToolsFromToolSearchOutput)(toolSearchOutput, mcpToolMap, {
140
+ preserveExistingServerLabels,
141
+ });
142
+ }
143
+ for (const toolSearchOutput of state.anonymousToolSearchOutputs) {
144
+ (0, toolSearch_1.addHostedMcpToolsFromToolSearchOutput)(toolSearchOutput, mcpToolMap, {
145
+ preserveExistingServerLabels,
146
+ });
147
+ }
148
+ }
149
+ function buildFunctionToolMap(tools) {
150
+ return new Map(tools
151
+ .filter((t) => t.type === 'function')
152
+ .map((t) => [(0, toolIdentity_1.getFunctionToolQualifiedName)(t) ?? t.name, t]));
153
+ }
154
+ function registerRuntimeToolSearchTools(args) {
155
+ const { availableTools, functionMap, mcpToolMap, replaceableRuntimeToolKeys, runtimeTools, } = args;
156
+ const availableToolsByKey = new Map();
157
+ for (const tool of availableTools) {
158
+ const key = (0, tool_1.getToolSearchRuntimeToolKey)(tool);
159
+ if (key) {
160
+ availableToolsByKey.set(key, tool);
161
+ }
162
+ }
163
+ const novelTools = [];
164
+ for (const runtimeTool of runtimeTools) {
165
+ const runtimeToolKey = (0, tool_1.getToolSearchRuntimeToolKey)(runtimeTool);
166
+ if (!runtimeToolKey) {
167
+ throw new errors_1.ModelBehaviorError('Client tool_search execute() returned an unsupported tool type.');
168
+ }
169
+ const existingTool = availableToolsByKey.get(runtimeToolKey);
170
+ if (existingTool && existingTool !== runtimeTool) {
171
+ if (!replaceableRuntimeToolKeys?.has(runtimeToolKey)) {
172
+ throw new errors_1.ModelBehaviorError(`Client tool_search execute() returned tool "${runtimeToolKey}" that conflicts with an existing available tool.`);
173
+ }
174
+ }
175
+ else if (existingTool === runtimeTool) {
176
+ continue;
177
+ }
178
+ availableToolsByKey.set(runtimeToolKey, runtimeTool);
179
+ novelTools.push(runtimeTool);
180
+ if (runtimeTool.type === 'function') {
181
+ functionMap.set((0, toolIdentity_1.getFunctionToolQualifiedName)(runtimeTool) ?? runtimeTool.name, runtimeTool);
182
+ continue;
183
+ }
184
+ if (runtimeTool.type === 'hosted_tool' &&
185
+ runtimeTool.providerData?.type === 'mcp') {
186
+ mcpToolMap.set(runtimeTool.providerData.server_label, runtimeTool);
187
+ continue;
188
+ }
189
+ throw new errors_1.ModelBehaviorError('Client tool_search execute() returned an unsupported tool type.');
190
+ }
191
+ return novelTools;
192
+ }
193
+ function buildGeneratedClientToolSearchOutputMap(modelResponse, tools, hasClientToolSearchTool) {
194
+ const clientToolSearchCalls = [];
195
+ const pendingClientToolSearchMatchKeys = [];
196
+ const resolvedToolSearchCallIds = new Set();
197
+ for (const output of modelResponse.output) {
198
+ if (output.type === 'tool_search_call') {
199
+ const toolSearchExecution = (0, utils_1.getToolSearchExecution)(output);
200
+ if (toolSearchExecution === 'client' ||
201
+ (typeof toolSearchExecution === 'undefined' && hasClientToolSearchTool)) {
202
+ clientToolSearchCalls.push(output);
203
+ const matchKey = (0, utils_1.getToolSearchMatchKey)(output);
204
+ if (matchKey) {
205
+ pendingClientToolSearchMatchKeys.push(matchKey);
206
+ }
207
+ }
208
+ continue;
209
+ }
210
+ if (output.type !== 'tool_search_output') {
211
+ continue;
212
+ }
213
+ const explicitCallId = (0, utils_1.getToolSearchProviderCallId)(output);
214
+ const toolSearchExecution = (0, utils_1.getToolSearchExecution)(output);
215
+ if (explicitCallId) {
216
+ resolvedToolSearchCallIds.add(explicitCallId);
217
+ const pendingIndex = pendingClientToolSearchMatchKeys.indexOf(explicitCallId);
218
+ if (pendingIndex >= 0) {
219
+ pendingClientToolSearchMatchKeys.splice(pendingIndex, 1);
220
+ }
221
+ continue;
222
+ }
223
+ if (toolSearchExecution !== 'server') {
224
+ const pendingMatchKey = pendingClientToolSearchMatchKeys.shift();
225
+ if (pendingMatchKey) {
226
+ resolvedToolSearchCallIds.add(pendingMatchKey);
227
+ }
228
+ }
229
+ }
230
+ const generatedOutputs = new Map();
231
+ for (const toolSearchCall of clientToolSearchCalls) {
232
+ const matchKey = (0, utils_1.getToolSearchMatchKey)(toolSearchCall);
233
+ if (matchKey && resolvedToolSearchCallIds.has(matchKey)) {
234
+ continue;
235
+ }
236
+ generatedOutputs.set(toolSearchCall, (0, toolSearch_1.createBuiltInClientToolSearchOutput)(toolSearchCall, tools));
237
+ }
238
+ return generatedOutputs;
239
+ }
240
+ async function buildGeneratedClientToolSearchOutputMapAsync(args) {
241
+ const { agent, modelResponse, runContext, tools } = args;
242
+ const clientToolSearchTool = (0, toolSearch_1.getClientToolSearchHelper)(tools);
243
+ const hasClientToolSearchTool = typeof clientToolSearchTool !== 'undefined';
244
+ const executionTools = [...tools];
245
+ const clientToolSearchCalls = [];
246
+ const pendingClientToolSearchMatchKeys = [];
247
+ const resolvedToolSearchCallIds = new Set();
248
+ for (const output of modelResponse.output) {
249
+ if (output.type === 'tool_search_call') {
250
+ const toolSearchExecution = (0, utils_1.getToolSearchExecution)(output);
251
+ if (toolSearchExecution === 'client' ||
252
+ (typeof toolSearchExecution === 'undefined' && hasClientToolSearchTool)) {
253
+ clientToolSearchCalls.push(output);
254
+ const matchKey = (0, utils_1.getToolSearchMatchKey)(output);
255
+ if (matchKey) {
256
+ pendingClientToolSearchMatchKeys.push(matchKey);
257
+ }
258
+ }
259
+ continue;
260
+ }
261
+ if (output.type !== 'tool_search_output') {
262
+ continue;
263
+ }
264
+ const explicitCallId = (0, utils_1.getToolSearchProviderCallId)(output);
265
+ const toolSearchExecution = (0, utils_1.getToolSearchExecution)(output);
266
+ if (explicitCallId) {
267
+ resolvedToolSearchCallIds.add(explicitCallId);
268
+ const pendingIndex = pendingClientToolSearchMatchKeys.indexOf(explicitCallId);
269
+ if (pendingIndex >= 0) {
270
+ pendingClientToolSearchMatchKeys.splice(pendingIndex, 1);
271
+ }
272
+ continue;
273
+ }
274
+ if (toolSearchExecution !== 'server') {
275
+ const pendingMatchKey = pendingClientToolSearchMatchKeys.shift();
276
+ if (pendingMatchKey) {
277
+ resolvedToolSearchCallIds.add(pendingMatchKey);
278
+ }
279
+ }
280
+ }
281
+ const generatedOutputs = new Map();
282
+ for (const toolSearchCall of clientToolSearchCalls) {
283
+ const matchKey = (0, utils_1.getToolSearchMatchKey)(toolSearchCall);
284
+ if (matchKey && resolvedToolSearchCallIds.has(matchKey)) {
285
+ continue;
286
+ }
287
+ if (clientToolSearchTool &&
288
+ (0, tool_1.getClientToolSearchExecutor)(clientToolSearchTool)) {
289
+ const generatedOutput = await (0, toolSearch_1.executeCustomClientToolSearch)({
290
+ agent,
291
+ runContext,
292
+ toolSearchCall,
293
+ toolSearchTool: clientToolSearchTool,
294
+ tools: executionTools,
295
+ });
296
+ generatedOutputs.set(toolSearchCall, generatedOutput);
297
+ executionTools.push(...generatedOutput.runtimeTools);
298
+ continue;
299
+ }
300
+ generatedOutputs.set(toolSearchCall, {
301
+ output: (0, toolSearch_1.createBuiltInClientToolSearchOutput)(toolSearchCall, executionTools),
302
+ runtimeTools: [],
303
+ });
304
+ }
305
+ return generatedOutputs;
306
+ }
307
+ function ensureDeferredFunctionToolLoaded(toolCall, tool, loadedToolNames, agent) {
308
+ if (tool.deferLoading !== true) {
309
+ return;
310
+ }
311
+ const explicitNamespace = (0, toolIdentity_1.getFunctionToolNamespace)(tool);
312
+ const qualifiedName = (0, toolIdentity_1.getFunctionToolQualifiedName)(tool);
313
+ const isLoaded = (qualifiedName ? loadedToolNames.has(qualifiedName) : false) ||
314
+ ((!explicitNamespace || explicitNamespace === tool.name) &&
315
+ loadedToolNames.has(tool.name));
316
+ if (isLoaded) {
317
+ return;
318
+ }
319
+ const toolName = qualifiedName ?? tool.name;
320
+ const message = `Model produced deferred function call ${toolName} before it was loaded via tool_search.`;
321
+ (0, context_1.addErrorToCurrentSpan)({
322
+ message,
323
+ data: {
324
+ agent_name: agent.name,
325
+ tool_name: toolName,
326
+ tool_call_id: toolCall.callId,
327
+ },
328
+ });
329
+ throw new errors_1.ModelBehaviorError(message);
330
+ }
42
331
  function parseShellCallStatus(status) {
43
332
  if (status === 'in_progress' ||
44
333
  status === 'completed' ||
@@ -64,7 +353,7 @@ function hasPendingShellOutputStatus(output) {
64
353
  * Walks a raw model response and classifies each item so the runner can schedule follow-up work.
65
354
  * Returns both the serializable RunItems (for history/streaming) and the actionable tool metadata.
66
355
  */
67
- function processModelResponse(modelResponse, agent, tools, handoffs) {
356
+ function processModelResponse(modelResponse, agent, tools, handoffs, priorItems = []) {
68
357
  const items = [];
69
358
  const runHandoffs = [];
70
359
  const runFunctions = [];
@@ -78,7 +367,7 @@ function processModelResponse(modelResponse, agent, tools, handoffs) {
78
367
  // Resolve tools upfront so we can look up the concrete handler in O(1) while iterating outputs.
79
368
  const functionMap = new Map(tools
80
369
  .filter((t) => t.type === 'function')
81
- .map((t) => [t.name, t]));
370
+ .map((t) => [(0, toolIdentity_1.getFunctionToolQualifiedName)(t) ?? t.name, t]));
82
371
  const computerTool = tools.find((t) => t.type === 'computer');
83
372
  const shellTool = tools.find((t) => t.type === 'shell');
84
373
  const applyPatchTool = tools.find((t) => t.type === 'apply_patch');
@@ -86,12 +375,40 @@ function processModelResponse(modelResponse, agent, tools, handoffs) {
86
375
  .filter((t) => t.type === 'hosted_tool' && t.providerData?.type === 'mcp')
87
376
  .map((t) => t)
88
377
  .map((t) => [t.providerData.server_label, t]));
378
+ const originalMcpServerLabels = new Set(mcpToolMap.keys());
379
+ const hasClientToolSearchTool = tools.some((tool) => tool.type === 'hosted_tool' &&
380
+ tool.providerData?.type === 'tool_search' &&
381
+ tool.providerData.execution === 'client');
382
+ const loadedDeferredToolState = collectLoadedDeferredToolStateFromHistory(priorItems, agent);
383
+ seedHostedMcpToolsFromLoadedDeferredToolState(loadedDeferredToolState, mcpToolMap, originalMcpServerLabels);
384
+ const generatedClientToolSearchOutputsByCall = buildGeneratedClientToolSearchOutputMap(modelResponse, tools, hasClientToolSearchTool);
385
+ let hasGeneratedClientToolSearchOutputs = false;
89
386
  for (const output of modelResponse.output) {
90
387
  if (output.type === 'message') {
91
388
  if (output.role === 'assistant') {
92
389
  items.push(new items_1.RunMessageOutputItem(output, agent));
93
390
  }
94
391
  }
392
+ else if (output.type === 'tool_search_call') {
393
+ items.push(new items_1.RunToolSearchCallItem(output, agent));
394
+ toolsUsed.push('tool_search');
395
+ const generatedOutput = generatedClientToolSearchOutputsByCall.get(output);
396
+ if (generatedOutput) {
397
+ items.push(new items_1.RunToolSearchOutputItem(generatedOutput, agent));
398
+ recordLoadedToolSearchOutput(loadedDeferredToolState, generatedOutput);
399
+ (0, toolSearch_1.addHostedMcpToolsFromToolSearchOutput)(generatedOutput, mcpToolMap, {
400
+ preserveExistingServerLabels: originalMcpServerLabels,
401
+ });
402
+ hasGeneratedClientToolSearchOutputs = true;
403
+ }
404
+ }
405
+ else if (output.type === 'tool_search_output') {
406
+ items.push(new items_1.RunToolSearchOutputItem(output, agent));
407
+ recordLoadedToolSearchOutput(loadedDeferredToolState, output);
408
+ (0, toolSearch_1.addHostedMcpToolsFromToolSearchOutput)(output, mcpToolMap, {
409
+ preserveExistingServerLabels: originalMcpServerLabels,
410
+ });
411
+ }
95
412
  else if (output.type === 'hosted_tool_call') {
96
413
  items.push(new items_1.RunToolCallItem(output, agent));
97
414
  const toolName = output.name;
@@ -204,9 +521,9 @@ function processModelResponse(modelResponse, agent, tools, handoffs) {
204
521
  if (output.type !== 'function_call') {
205
522
  continue;
206
523
  }
207
- toolsUsed.push(output.name);
208
524
  const resolved = resolveFunctionOrHandoff(output, handoffMap, functionMap, agent);
209
525
  if (resolved.type === 'handoff') {
526
+ toolsUsed.push(output.name);
210
527
  items.push(new items_1.RunHandoffCallItem(output, agent));
211
528
  runHandoffs.push({
212
529
  toolCall: output,
@@ -214,9 +531,12 @@ function processModelResponse(modelResponse, agent, tools, handoffs) {
214
531
  });
215
532
  }
216
533
  else {
217
- items.push(new items_1.RunToolCallItem(output, agent));
534
+ ensureDeferredFunctionToolLoaded(output, resolved.tool, loadedDeferredToolState.loadedToolNames, agent);
535
+ const normalizedToolCall = normalizeFunctionToolCallForStorage(output, resolved.tool);
536
+ toolsUsed.push((0, toolIdentity_1.getFunctionToolQualifiedName)(resolved.tool) ?? resolved.tool.name);
537
+ items.push(new items_1.RunToolCallItem(normalizedToolCall, agent));
218
538
  runFunctions.push({
219
- toolCall: output,
539
+ toolCall: normalizedToolCall,
220
540
  tool: resolved.tool,
221
541
  });
222
542
  }
@@ -237,7 +557,227 @@ function processModelResponse(modelResponse, agent, tools, handoffs) {
237
557
  runComputerActions.length > 0 ||
238
558
  runShellActions.length > 0 ||
239
559
  hasHostedShellCall ||
240
- runApplyPatchActions.length > 0);
560
+ runApplyPatchActions.length > 0 ||
561
+ hasGeneratedClientToolSearchOutputs);
562
+ },
563
+ };
564
+ }
565
+ async function processModelResponseAsync(modelResponse, agent, tools, handoffs, state, priorItems = []) {
566
+ const clientToolSearchTool = (0, toolSearch_1.getClientToolSearchHelper)(tools);
567
+ const hasCustomClientToolSearchExecutor = Boolean(clientToolSearchTool && (0, tool_1.getClientToolSearchExecutor)(clientToolSearchTool));
568
+ const hasRelevantClientToolSearchCall = modelResponse.output.some((output) => output.type === 'tool_search_call' &&
569
+ ((0, utils_1.getToolSearchExecution)(output) === 'client' ||
570
+ (typeof (0, utils_1.getToolSearchExecution)(output) === 'undefined' &&
571
+ typeof clientToolSearchTool !== 'undefined')));
572
+ if (!hasCustomClientToolSearchExecutor || !hasRelevantClientToolSearchCall) {
573
+ return processModelResponse(modelResponse, agent, tools, handoffs, priorItems);
574
+ }
575
+ const items = [];
576
+ const runHandoffs = [];
577
+ const runFunctions = [];
578
+ const runComputerActions = [];
579
+ const runShellActions = [];
580
+ let hasHostedShellCall = false;
581
+ const runApplyPatchActions = [];
582
+ const runMCPApprovalRequests = [];
583
+ const toolsUsed = [];
584
+ const handoffMap = new Map(handoffs.map((h) => [h.toolName, h]));
585
+ const functionMap = buildFunctionToolMap(tools);
586
+ const computerTool = tools.find((t) => t.type === 'computer');
587
+ const shellTool = tools.find((t) => t.type === 'shell');
588
+ const applyPatchTool = tools.find((t) => t.type === 'apply_patch');
589
+ const mcpToolMap = new Map(tools
590
+ .filter((t) => t.type === 'hosted_tool' && t.providerData?.type === 'mcp')
591
+ .map((t) => t)
592
+ .map((t) => [t.providerData.server_label, t]));
593
+ const originalMcpServerLabels = new Set(mcpToolMap.keys());
594
+ const replaceableRuntimeToolKeys = new Set(state
595
+ .getToolSearchRuntimeTools(agent)
596
+ .map((tool) => (0, tool_1.getToolSearchRuntimeToolKey)(tool))
597
+ .filter((key) => typeof key === 'string'));
598
+ const loadedDeferredToolState = collectLoadedDeferredToolStateFromHistory(priorItems, agent);
599
+ seedHostedMcpToolsFromLoadedDeferredToolState(loadedDeferredToolState, mcpToolMap, originalMcpServerLabels);
600
+ const generatedClientToolSearchOutputsByCall = await buildGeneratedClientToolSearchOutputMapAsync({
601
+ agent,
602
+ modelResponse,
603
+ runContext: state._context,
604
+ tools,
605
+ });
606
+ let hasGeneratedClientToolSearchOutputs = false;
607
+ const availableTools = [...tools];
608
+ for (const output of modelResponse.output) {
609
+ if (output.type === 'message') {
610
+ if (output.role === 'assistant') {
611
+ items.push(new items_1.RunMessageOutputItem(output, agent));
612
+ }
613
+ }
614
+ else if (output.type === 'tool_search_call') {
615
+ items.push(new items_1.RunToolSearchCallItem(output, agent));
616
+ toolsUsed.push('tool_search');
617
+ const generatedOutput = generatedClientToolSearchOutputsByCall.get(output);
618
+ if (generatedOutput) {
619
+ items.push(new items_1.RunToolSearchOutputItem(generatedOutput.output, agent));
620
+ recordLoadedToolSearchOutput(loadedDeferredToolState, generatedOutput.output);
621
+ (0, toolSearch_1.addHostedMcpToolsFromToolSearchOutput)(generatedOutput.output, mcpToolMap, {
622
+ preserveExistingServerLabels: originalMcpServerLabels,
623
+ });
624
+ const novelRuntimeTools = registerRuntimeToolSearchTools({
625
+ availableTools,
626
+ functionMap,
627
+ mcpToolMap,
628
+ replaceableRuntimeToolKeys,
629
+ runtimeTools: generatedOutput.runtimeTools,
630
+ });
631
+ state.recordToolSearchRuntimeTools(agent, generatedOutput.output, novelRuntimeTools);
632
+ hasGeneratedClientToolSearchOutputs = true;
633
+ }
634
+ }
635
+ else if (output.type === 'tool_search_output') {
636
+ items.push(new items_1.RunToolSearchOutputItem(output, agent));
637
+ recordLoadedToolSearchOutput(loadedDeferredToolState, output);
638
+ (0, toolSearch_1.addHostedMcpToolsFromToolSearchOutput)(output, mcpToolMap, {
639
+ preserveExistingServerLabels: originalMcpServerLabels,
640
+ });
641
+ }
642
+ else if (output.type === 'hosted_tool_call') {
643
+ items.push(new items_1.RunToolCallItem(output, agent));
644
+ const toolName = output.name;
645
+ toolsUsed.push(toolName);
646
+ if (output.providerData?.type === 'mcp_approval_request' ||
647
+ output.name === 'mcp_approval_request') {
648
+ const providerData = output.providerData;
649
+ const mcpServerLabel = providerData.server_label;
650
+ const mcpServerTool = mcpToolMap.get(mcpServerLabel);
651
+ if (typeof mcpServerTool === 'undefined') {
652
+ const message = `MCP server (${mcpServerLabel}) not found in Agent (${agent.name})`;
653
+ (0, context_1.addErrorToCurrentSpan)({
654
+ message,
655
+ data: { mcp_server_label: mcpServerLabel },
656
+ });
657
+ throw new errors_1.ModelBehaviorError(message);
658
+ }
659
+ const approvalItem = new items_1.RunToolApprovalItem({
660
+ type: 'hosted_tool_call',
661
+ name: providerData.name,
662
+ id: providerData.id,
663
+ status: 'in_progress',
664
+ providerData,
665
+ }, agent);
666
+ runMCPApprovalRequests.push({
667
+ requestItem: approvalItem,
668
+ mcpTool: mcpServerTool,
669
+ });
670
+ if (!mcpServerTool.providerData.on_approval) {
671
+ items.push(approvalItem);
672
+ }
673
+ }
674
+ }
675
+ else if (output.type === 'reasoning') {
676
+ items.push(new items_1.RunReasoningItem(output, agent));
677
+ }
678
+ else if (output.type === 'computer_call') {
679
+ handleToolCallAction({
680
+ output,
681
+ tool: computerTool,
682
+ agent,
683
+ errorMessage: 'Model produced computer action without a computer tool.',
684
+ errorData: { agent_name: agent.name },
685
+ items,
686
+ toolsUsed,
687
+ actions: runComputerActions,
688
+ buildAction: (resolvedTool) => ({
689
+ toolCall: output,
690
+ computer: resolvedTool,
691
+ }),
692
+ });
693
+ }
694
+ else if (output.type === 'shell_call') {
695
+ const resolvedShellTool = ensureToolAvailable(shellTool, 'Model produced shell action without a shell tool.', { agent_name: agent.name });
696
+ items.push(new items_1.RunToolCallItem(output, agent));
697
+ toolsUsed.push(resolvedShellTool.name);
698
+ const shellEnvironmentType = resolvedShellTool.environment?.type ?? 'local';
699
+ if (shellEnvironmentType !== 'local') {
700
+ if (isShellCallPendingStatus(output.status)) {
701
+ hasHostedShellCall = true;
702
+ }
703
+ continue;
704
+ }
705
+ if (!resolvedShellTool.shell) {
706
+ const message = 'Model produced local shell action without a local shell implementation.';
707
+ (0, context_1.addErrorToCurrentSpan)({
708
+ message,
709
+ data: { agent_name: agent.name },
710
+ });
711
+ throw new errors_1.ModelBehaviorError(message);
712
+ }
713
+ runShellActions.push({
714
+ toolCall: output,
715
+ shell: resolvedShellTool,
716
+ });
717
+ }
718
+ else if (output.type === 'shell_call_output') {
719
+ items.push(new items_1.RunToolCallOutputItem(output, agent, output.output));
720
+ if (hasPendingShellOutputStatus(output)) {
721
+ hasHostedShellCall = true;
722
+ }
723
+ }
724
+ else if (output.type === 'apply_patch_call') {
725
+ handleToolCallAction({
726
+ output,
727
+ tool: applyPatchTool,
728
+ agent,
729
+ errorMessage: 'Model produced apply_patch action without an apply_patch tool.',
730
+ errorData: { agent_name: agent.name },
731
+ items,
732
+ toolsUsed,
733
+ actions: runApplyPatchActions,
734
+ buildAction: (resolvedTool) => ({
735
+ toolCall: output,
736
+ applyPatch: resolvedTool,
737
+ }),
738
+ });
739
+ }
740
+ if (output.type !== 'function_call') {
741
+ continue;
742
+ }
743
+ const resolved = resolveFunctionOrHandoff(output, handoffMap, functionMap, agent);
744
+ if (resolved.type === 'handoff') {
745
+ toolsUsed.push(output.name);
746
+ items.push(new items_1.RunHandoffCallItem(output, agent));
747
+ runHandoffs.push({
748
+ toolCall: output,
749
+ handoff: resolved.handoff,
750
+ });
751
+ }
752
+ else {
753
+ ensureDeferredFunctionToolLoaded(output, resolved.tool, loadedDeferredToolState.loadedToolNames, agent);
754
+ const normalizedToolCall = normalizeFunctionToolCallForStorage(output, resolved.tool);
755
+ toolsUsed.push((0, toolIdentity_1.getFunctionToolQualifiedName)(resolved.tool) ?? resolved.tool.name);
756
+ items.push(new items_1.RunToolCallItem(normalizedToolCall, agent));
757
+ runFunctions.push({
758
+ toolCall: normalizedToolCall,
759
+ tool: resolved.tool,
760
+ });
761
+ }
762
+ }
763
+ return {
764
+ newItems: items,
765
+ handoffs: runHandoffs,
766
+ functions: runFunctions,
767
+ computerActions: runComputerActions,
768
+ shellActions: runShellActions,
769
+ applyPatchActions: runApplyPatchActions,
770
+ mcpApprovalRequests: runMCPApprovalRequests,
771
+ toolsUsed,
772
+ hasToolsOrApprovalsToRun() {
773
+ return (runHandoffs.length > 0 ||
774
+ runFunctions.length > 0 ||
775
+ runMCPApprovalRequests.length > 0 ||
776
+ runComputerActions.length > 0 ||
777
+ runShellActions.length > 0 ||
778
+ hasHostedShellCall ||
779
+ runApplyPatchActions.length > 0 ||
780
+ hasGeneratedClientToolSearchOutputs);
241
781
  },
242
782
  };
243
783
  }