@openai/agents-core 0.9.0 → 0.10.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 (84) hide show
  1. package/dist/agent.d.ts +25 -2
  2. package/dist/agent.js +45 -2
  3. package/dist/agent.js.map +1 -1
  4. package/dist/agent.mjs +46 -3
  5. package/dist/agent.mjs.map +1 -1
  6. package/dist/agentToolRunConfig.js +3 -0
  7. package/dist/agentToolRunConfig.js.map +1 -1
  8. package/dist/agentToolRunConfig.mjs +3 -0
  9. package/dist/agentToolRunConfig.mjs.map +1 -1
  10. package/dist/defaultModel.js +2 -1
  11. package/dist/defaultModel.js.map +1 -1
  12. package/dist/defaultModel.mjs +2 -1
  13. package/dist/defaultModel.mjs.map +1 -1
  14. package/dist/index.d.ts +2 -2
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/mcp.d.ts +9 -3
  18. package/dist/mcp.js +238 -16
  19. package/dist/mcp.js.map +1 -1
  20. package/dist/mcp.mjs +238 -16
  21. package/dist/mcp.mjs.map +1 -1
  22. package/dist/memory/session.d.ts +7 -0
  23. package/dist/memory/session.js.map +1 -1
  24. package/dist/memory/session.mjs.map +1 -1
  25. package/dist/metadata.js +2 -2
  26. package/dist/metadata.js.map +1 -1
  27. package/dist/metadata.mjs +2 -2
  28. package/dist/metadata.mjs.map +1 -1
  29. package/dist/result.d.ts +1 -1
  30. package/dist/result.js.map +1 -1
  31. package/dist/result.mjs.map +1 -1
  32. package/dist/run.d.ts +17 -1
  33. package/dist/run.js +95 -11
  34. package/dist/run.js.map +1 -1
  35. package/dist/run.mjs +96 -12
  36. package/dist/run.mjs.map +1 -1
  37. package/dist/runState.d.ts +33 -6
  38. package/dist/runState.js +326 -46
  39. package/dist/runState.js.map +1 -1
  40. package/dist/runState.mjs +325 -46
  41. package/dist/runState.mjs.map +1 -1
  42. package/dist/runner/sessionPersistence.js +33 -12
  43. package/dist/runner/sessionPersistence.js.map +1 -1
  44. package/dist/runner/sessionPersistence.mjs +33 -12
  45. package/dist/runner/sessionPersistence.mjs.map +1 -1
  46. package/dist/runner/streamReconciliation.d.ts +14 -0
  47. package/dist/runner/streamReconciliation.js +80 -0
  48. package/dist/runner/streamReconciliation.js.map +1 -0
  49. package/dist/runner/streamReconciliation.mjs +72 -0
  50. package/dist/runner/streamReconciliation.mjs.map +1 -0
  51. package/dist/runner/toolExecution.js +45 -12
  52. package/dist/runner/toolExecution.js.map +1 -1
  53. package/dist/runner/toolExecution.mjs +45 -12
  54. package/dist/runner/toolExecution.mjs.map +1 -1
  55. package/dist/runner/toolUseTracker.d.ts +3 -1
  56. package/dist/runner/toolUseTracker.js +2 -2
  57. package/dist/runner/toolUseTracker.js.map +1 -1
  58. package/dist/runner/toolUseTracker.mjs +2 -2
  59. package/dist/runner/toolUseTracker.mjs.map +1 -1
  60. package/dist/runner/turnPreparation.js +1 -1
  61. package/dist/runner/turnPreparation.js.map +1 -1
  62. package/dist/runner/turnPreparation.mjs +1 -1
  63. package/dist/runner/turnPreparation.mjs.map +1 -1
  64. package/dist/sandbox/agent.d.ts +2 -2
  65. package/dist/sandbox/agent.js +1 -0
  66. package/dist/sandbox/agent.js.map +1 -1
  67. package/dist/sandbox/agent.mjs +1 -0
  68. package/dist/sandbox/agent.mjs.map +1 -1
  69. package/dist/sandbox/client.d.ts +3 -3
  70. package/dist/sandbox/client.js +6 -1
  71. package/dist/sandbox/client.js.map +1 -1
  72. package/dist/sandbox/client.mjs +7 -2
  73. package/dist/sandbox/client.mjs.map +1 -1
  74. package/dist/sandbox/manifest.d.ts +6 -5
  75. package/dist/sandbox/manifest.js +7 -0
  76. package/dist/sandbox/manifest.js.map +1 -1
  77. package/dist/sandbox/manifest.mjs +7 -0
  78. package/dist/sandbox/manifest.mjs.map +1 -1
  79. package/dist/sandbox/users.d.ts +7 -2
  80. package/dist/sandbox/users.js +1 -1
  81. package/dist/sandbox/users.js.map +1 -1
  82. package/dist/sandbox/users.mjs +1 -1
  83. package/dist/sandbox/users.mjs.map +1 -1
  84. package/package.json +1 -1
package/dist/runState.js CHANGED
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.RunState = exports.SerializedRunState = exports.CURRENT_SCHEMA_VERSION = void 0;
40
40
  exports.rehydrateProcessedResponseTools = rehydrateProcessedResponseTools;
41
41
  exports.buildAgentMap = buildAgentMap;
42
+ exports.buildAgentIdentityMap = buildAgentIdentityMap;
42
43
  exports.deserializeSpan = deserializeSpan;
43
44
  exports.deserializeModelResponse = deserializeModelResponse;
44
45
  exports.deserializeItem = deserializeItem;
@@ -84,8 +85,11 @@ const toolRehydration_1 = require("./sandbox/runtime/toolRehydration.js");
84
85
  * aliasing to serialized run state payloads.
85
86
  * - 1.9: Adds optional sandbox session persistence with a versioned session-state
86
87
  * envelope for sandbox-agent resume.
88
+ * - 1.10: Adds optional stable agent identity keys so duplicate-name agent graphs can
89
+ * serialize and resume without ambiguous name resolution.
90
+ * - 1.11: Allows null maxTurns to persist runs without a turn limit.
87
91
  */
88
- exports.CURRENT_SCHEMA_VERSION = '1.9';
92
+ exports.CURRENT_SCHEMA_VERSION = '1.11';
89
93
  const SUPPORTED_SCHEMA_VERSIONS = [
90
94
  '1.0',
91
95
  '1.1',
@@ -96,11 +100,14 @@ const SUPPORTED_SCHEMA_VERSIONS = [
96
100
  '1.6',
97
101
  '1.7',
98
102
  '1.8',
103
+ '1.9',
104
+ '1.10',
99
105
  exports.CURRENT_SCHEMA_VERSION,
100
106
  ];
101
107
  const $schemaVersion = zod_1.z.enum(SUPPORTED_SCHEMA_VERSIONS);
102
108
  const serializedAgentSchema = zod_1.z.object({
103
109
  name: zod_1.z.string(),
110
+ identity: zod_1.z.string().optional(),
104
111
  });
105
112
  const serializedSpanBase = zod_1.z.object({
106
113
  object: zod_1.z.literal('trace.span'),
@@ -351,7 +358,7 @@ exports.SerializedRunState = zod_1.z.object({
351
358
  toolInput: zod_1.z.any().optional(),
352
359
  }),
353
360
  toolUseTracker: zod_1.z.record(zod_1.z.string(), zod_1.z.array(zod_1.z.string())),
354
- maxTurns: zod_1.z.number(),
361
+ maxTurns: zod_1.z.number().nullable(),
355
362
  currentAgentSpan: SerializedSpan.nullable().optional(),
356
363
  noActiveAgentRun: zod_1.z.boolean(),
357
364
  inputGuardrailResults: zod_1.z.array(inputGuardrailResultSchema),
@@ -514,10 +521,10 @@ class RunState {
514
521
  */
515
522
  _trace = null;
516
523
  /**
517
- * Runtime-only tool_search-loaded tools, scoped by agent name and preserved across turns for
524
+ * Runtime-only tool_search-loaded tools, scoped by agent object and preserved across turns for
518
525
  * the lifetime of this in-memory run.
519
526
  */
520
- _toolSearchRuntimeToolsByAgentName = new Map();
527
+ _toolSearchRuntimeToolsByAgent = new Map();
521
528
  /**
522
529
  * Persisted sandbox session metadata for sandbox-agent resume.
523
530
  */
@@ -561,20 +568,20 @@ class RunState {
561
568
  setCurrentAgentSpan(span) {
562
569
  this._currentAgentSpan = span;
563
570
  }
564
- getOrCreateToolSearchRuntimeToolState(agentName) {
565
- let state = this._toolSearchRuntimeToolsByAgentName.get(agentName);
571
+ getOrCreateToolSearchRuntimeToolState(agent) {
572
+ let state = this._toolSearchRuntimeToolsByAgent.get(agent);
566
573
  if (!state) {
567
574
  state = {
568
575
  anonymousEntries: [],
569
576
  keyedEntries: new Map(),
570
577
  nextOrder: 0,
571
578
  };
572
- this._toolSearchRuntimeToolsByAgentName.set(agentName, state);
579
+ this._toolSearchRuntimeToolsByAgent.set(agent, state);
573
580
  }
574
581
  return state;
575
582
  }
576
583
  recordToolSearchRuntimeTools(agent, toolSearchOutput, tools) {
577
- const runtimeState = this.getOrCreateToolSearchRuntimeToolState(agent.name);
584
+ const runtimeState = this.getOrCreateToolSearchRuntimeToolState(agent);
578
585
  const entry = {
579
586
  order: runtimeState.nextOrder++,
580
587
  tools,
@@ -587,7 +594,7 @@ class RunState {
587
594
  runtimeState.anonymousEntries.push(entry);
588
595
  }
589
596
  getToolSearchRuntimeTools(agent) {
590
- const runtimeState = this._toolSearchRuntimeToolsByAgentName.get(agent.name);
597
+ const runtimeState = this._toolSearchRuntimeToolsByAgent.get(agent);
591
598
  if (!runtimeState) {
592
599
  return [];
593
600
  }
@@ -724,15 +731,13 @@ class RunState {
724
731
  * rehydrate in a separate process that lacks the original environment variables).
725
732
  */
726
733
  toJSON(options = {}) {
727
- buildAgentMap(this.#startingAgent);
734
+ const agentIdentity = buildAgentIdentityMap(this.#startingAgent);
728
735
  const includeTracingApiKey = options.includeTracingApiKey === true;
729
736
  const contextJson = this._context.toJSON();
730
737
  const output = {
731
738
  $schemaVersion: exports.CURRENT_SCHEMA_VERSION,
732
739
  currentTurn: this._currentTurn,
733
- currentAgent: {
734
- name: this._currentAgent.name,
735
- },
740
+ currentAgent: serializeAgentReference(this._currentAgent, agentIdentity.byAgent),
736
741
  originalInput: this._originalInput,
737
742
  modelResponses: this._modelResponses.map((response) => {
738
743
  return {
@@ -764,7 +769,9 @@ class RunState {
764
769
  };
765
770
  }),
766
771
  context: contextJson,
767
- toolUseTracker: this._toolUseTracker.toJSON(),
772
+ toolUseTracker: this._toolUseTracker.toJSON({
773
+ agentIdentityKeys: agentIdentity.byAgent,
774
+ }),
768
775
  maxTurns: this._maxTurns,
769
776
  currentAgentSpan: this._currentAgentSpan?.toJSON(),
770
777
  noActiveAgentRun: this._noActiveAgentRun,
@@ -772,16 +779,18 @@ class RunState {
772
779
  inputGuardrailResults: this._inputGuardrailResults,
773
780
  outputGuardrailResults: this._outputGuardrailResults.map((r) => ({
774
781
  ...r,
775
- agent: r.agent.toJSON(),
782
+ agent: serializeAgentReference(r.agent, agentIdentity.byAgent),
776
783
  })),
777
784
  toolInputGuardrailResults: this._toolInputGuardrailResults,
778
785
  toolOutputGuardrailResults: this._toolOutputGuardrailResults,
779
- currentStep: this._currentStep,
786
+ currentStep: serializeCurrentStep(this._currentStep, agentIdentity.byAgent),
780
787
  lastModelResponse: this._lastTurnResponse,
781
- generatedItems: this._generatedItems.map((item) => item.toJSON()),
788
+ generatedItems: this._generatedItems.map((item) => serializeRunItem(item, agentIdentity.byAgent)),
782
789
  pendingAgentToolRuns: Object.fromEntries(this._pendingAgentToolRuns.entries()),
783
790
  currentTurnPersistedItemCount: this._currentTurnPersistedItemCount,
784
- lastProcessedResponse: this._lastProcessedResponse,
791
+ lastProcessedResponse: this._lastProcessedResponse
792
+ ? serializeProcessedResponse(this._lastProcessedResponse, agentIdentity.byAgent)
793
+ : undefined,
785
794
  conversationId: this._conversationId,
786
795
  previousResponseId: this._previousResponseId,
787
796
  reasoningItemIdPolicy: this._reasoningItemIdPolicy,
@@ -842,7 +851,10 @@ async function buildRunStateFromString(initialAgent, str, options = {}) {
842
851
  return buildRunStateFromJson(initialAgent, stateJson, options);
843
852
  }
844
853
  function assertSchemaVersionSupportsToolSearch(schemaVersion, stateJson) {
845
- if (schemaVersion === '1.8' || schemaVersion === '1.9') {
854
+ if (schemaVersion === '1.8' ||
855
+ schemaVersion === '1.9' ||
856
+ schemaVersion === '1.10' ||
857
+ schemaVersion === exports.CURRENT_SCHEMA_VERSION) {
846
858
  return;
847
859
  }
848
860
  if (!containsSerializedToolSearchState(stateJson)) {
@@ -850,6 +862,9 @@ function assertSchemaVersionSupportsToolSearch(schemaVersion, stateJson) {
850
862
  }
851
863
  throw new errors_1.UserError(`Run state schema version ${schemaVersion} does not support tool_search items. Please reserialize the run state with schema ${exports.CURRENT_SCHEMA_VERSION}.`);
852
864
  }
865
+ function schemaVersionSupportsAgentIdentity(schemaVersion) {
866
+ return schemaVersion === '1.10' || schemaVersion === exports.CURRENT_SCHEMA_VERSION;
867
+ }
853
868
  function containsSerializedToolSearchState(stateJson) {
854
869
  return (containsToolSearchProtocolItems(stateJson.originalInput) ||
855
870
  containsToolSearchInModelResponses(stateJson.modelResponses) ||
@@ -953,17 +968,17 @@ function assertRuntimeToolKeysMatch(args) {
953
968
  throw new errors_1.UserError(`RunState cannot resume custom client tool_search call ${callId} for agent ${agent.name} because the registered execute callback returned runtime tools [${formatRuntimeToolKeys(actualRuntimeToolKeys)}] but the serialized state expects [${formatRuntimeToolKeys(expectedRuntimeToolKeys)}].`);
954
969
  }
955
970
  async function getConfiguredAgentTools(args) {
956
- const { agent, context, configuredToolsByAgentName } = args;
957
- const existing = configuredToolsByAgentName.get(agent.name);
971
+ const { agent, context, configuredToolsByAgent } = args;
972
+ const existing = configuredToolsByAgent.get(agent);
958
973
  if (existing) {
959
974
  return existing;
960
975
  }
961
976
  const configuredTools = (await agent.getAllTools(context));
962
- configuredToolsByAgentName.set(agent.name, configuredTools);
977
+ configuredToolsByAgent.set(agent, configuredTools);
963
978
  return configuredTools;
964
979
  }
965
980
  async function rehydrateToolSearchRuntimeTools(state) {
966
- const configuredToolsByAgentName = new Map();
981
+ const configuredToolsByAgent = new Map();
967
982
  const pendingToolSearchCalls = new Map();
968
983
  for (const item of state._generatedItems) {
969
984
  if (item instanceof items_1.RunToolSearchCallItem) {
@@ -971,10 +986,14 @@ async function rehydrateToolSearchRuntimeTools(state) {
971
986
  continue;
972
987
  }
973
988
  const callId = (0, toolSearch_1.resolveToolSearchCallId)(item.rawItem);
974
- pendingToolSearchCalls.set(`${item.agent.name}:${callId}`, {
989
+ const agent = item.agent;
990
+ const pendingCallsById = pendingToolSearchCalls.get(agent) ??
991
+ new Map();
992
+ pendingCallsById.set(callId, {
975
993
  agent: item.agent,
976
994
  toolSearchCall: item.rawItem,
977
995
  });
996
+ pendingToolSearchCalls.set(agent, pendingCallsById);
978
997
  continue;
979
998
  }
980
999
  if (!(item instanceof items_1.RunToolSearchOutputItem)) {
@@ -986,7 +1005,7 @@ async function rehydrateToolSearchRuntimeTools(state) {
986
1005
  const configuredTools = await getConfiguredAgentTools({
987
1006
  agent: item.agent,
988
1007
  context: state._context,
989
- configuredToolsByAgentName,
1008
+ configuredToolsByAgent,
990
1009
  });
991
1010
  const configuredToolKeys = getRuntimeToolKeys(configuredTools, {
992
1011
  allowUnsupported: true,
@@ -996,7 +1015,9 @@ async function rehydrateToolSearchRuntimeTools(state) {
996
1015
  continue;
997
1016
  }
998
1017
  const callId = (0, toolSearch_1.resolveToolSearchCallId)(item.rawItem);
999
- const pendingCall = pendingToolSearchCalls.get(`${item.agent.name}:${callId}`);
1018
+ const pendingCall = pendingToolSearchCalls
1019
+ .get(item.agent)
1020
+ ?.get(callId);
1000
1021
  if (!pendingCall) {
1001
1022
  throw new errors_1.UserError(`RunState cannot resume custom client tool_search output ${callId} for agent ${item.agent.name} because the serialized state is missing the matching tool_search call item.`);
1002
1023
  }
@@ -1039,7 +1060,9 @@ async function rehydrateToolSearchRuntimeTools(state) {
1039
1060
  }
1040
1061
  }
1041
1062
  async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
1042
- const agentMap = buildAgentMap(initialAgent);
1063
+ const agentMap = schemaVersionSupportsAgentIdentity(stateJson.$schemaVersion)
1064
+ ? buildAgentIdentityMap(initialAgent).byIdentity
1065
+ : buildAgentMap(initialAgent);
1043
1066
  const contextOverride = options.contextOverride;
1044
1067
  const contextStrategy = options.contextStrategy ?? 'merge';
1045
1068
  //
@@ -1064,10 +1087,7 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
1064
1087
  //
1065
1088
  // Find the current agent from the initial agent
1066
1089
  //
1067
- const currentAgent = agentMap.get(stateJson.currentAgent.name);
1068
- if (!currentAgent) {
1069
- throw new errors_1.UserError(`Agent ${stateJson.currentAgent.name} not found`);
1070
- }
1090
+ const currentAgent = resolveSerializedAgent(stateJson.currentAgent, agentMap);
1071
1091
  const state = new RunState(context, '', initialAgent, stateJson.maxTurns);
1072
1092
  state._currentAgent = currentAgent;
1073
1093
  state._currentTurn = stateJson.currentTurn;
@@ -1078,7 +1098,13 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
1078
1098
  // rebuild tool use tracker
1079
1099
  state._toolUseTracker = new toolUseTracker_1.AgentToolUseTracker();
1080
1100
  for (const [agentName, toolNames] of Object.entries(stateJson.toolUseTracker)) {
1081
- state._toolUseTracker.addToolUse(agentMap.get(agentName), toolNames, { allowEmpty: true });
1101
+ const agent = agentMap.get(agentName);
1102
+ if (!agent) {
1103
+ throw new errors_1.UserError(`Agent ${agentName} not found`);
1104
+ }
1105
+ state._toolUseTracker.addToolUse(agent, toolNames, {
1106
+ allowEmpty: true,
1107
+ });
1082
1108
  }
1083
1109
  state._pendingAgentToolRuns = new Map(Object.entries(stateJson.pendingAgentToolRuns ?? {}));
1084
1110
  // rebuild current agent span
@@ -1101,7 +1127,7 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
1101
1127
  stateJson.inputGuardrailResults;
1102
1128
  state._outputGuardrailResults = stateJson.outputGuardrailResults.map((r) => ({
1103
1129
  ...r,
1104
- agent: agentMap.get(r.agent.name),
1130
+ agent: resolveSerializedAgent(r.agent, agentMap),
1105
1131
  }));
1106
1132
  state._toolInputGuardrailResults =
1107
1133
  stateJson.toolInputGuardrailResults;
@@ -1124,7 +1150,7 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
1124
1150
  if (stateJson.currentStep?.type === 'next_step_handoff') {
1125
1151
  state._currentStep = {
1126
1152
  type: 'next_step_handoff',
1127
- newAgent: agentMap.get(stateJson.currentStep.newAgent.name),
1153
+ newAgent: resolveSerializedAgent(stateJson.currentStep.newAgent, agentMap),
1128
1154
  };
1129
1155
  }
1130
1156
  else if (stateJson.currentStep?.type === 'next_step_interruption') {
@@ -1145,7 +1171,9 @@ async function rehydrateProcessedResponseTools(initialAgent, state, executionToo
1145
1171
  if (!state._lastProcessedResponse) {
1146
1172
  return;
1147
1173
  }
1148
- state._lastProcessedResponse = await deserializeProcessedResponse(buildAgentMap(initialAgent), state, state._lastProcessedResponse, {
1174
+ const agentIdentity = buildAgentIdentityMap(initialAgent);
1175
+ const serializedProcessedResponse = serializeProcessedResponse(state._lastProcessedResponse, agentIdentity.byAgent);
1176
+ state._lastProcessedResponse = await deserializeProcessedResponse(agentIdentity.byIdentity, state, serializedProcessedResponse, {
1149
1177
  executionTools,
1150
1178
  allowSerializedExecutionToolPlaceholder: false,
1151
1179
  });
@@ -1185,6 +1213,250 @@ function buildAgentMap(initialAgent) {
1185
1213
  }
1186
1214
  return map;
1187
1215
  }
1216
+ /**
1217
+ * @internal
1218
+ */
1219
+ function buildAgentIdentityMap(initialAgent) {
1220
+ const agents = collectAgentGraph(initialAgent);
1221
+ const groups = new Map();
1222
+ const literalNames = new Set();
1223
+ for (const entry of agents) {
1224
+ literalNames.add(entry.agent.name);
1225
+ const group = groups.get(entry.agent.name) ?? [];
1226
+ group.push(entry);
1227
+ groups.set(entry.agent.name, group);
1228
+ }
1229
+ const byIdentity = new Map();
1230
+ const byAgent = new Map();
1231
+ const usedIdentities = new Set();
1232
+ for (const [agentName, group] of groups) {
1233
+ const sortedGroup = group.length === 1
1234
+ ? group
1235
+ : [...group].sort((left, right) => {
1236
+ if (left.agent === initialAgent) {
1237
+ return -1;
1238
+ }
1239
+ if (right.agent === initialAgent) {
1240
+ return 1;
1241
+ }
1242
+ const leftSignature = getAgentIdentitySignature(left.agent);
1243
+ const rightSignature = getAgentIdentitySignature(right.agent);
1244
+ if (leftSignature !== rightSignature) {
1245
+ return leftSignature < rightSignature ? -1 : 1;
1246
+ }
1247
+ return left.index - right.index;
1248
+ });
1249
+ let nextSuffix = 0;
1250
+ for (const { agent } of sortedGroup) {
1251
+ let identity;
1252
+ do {
1253
+ identity =
1254
+ nextSuffix === 0 ? agentName : `${agentName}#${nextSuffix + 1}`;
1255
+ nextSuffix += 1;
1256
+ } while (usedIdentities.has(identity) ||
1257
+ (identity !== agent.name && literalNames.has(identity)));
1258
+ usedIdentities.add(identity);
1259
+ byIdentity.set(identity, agent);
1260
+ byAgent.set(agent, identity);
1261
+ }
1262
+ }
1263
+ return { byIdentity, byAgent };
1264
+ }
1265
+ function collectAgentGraph(initialAgent) {
1266
+ const agents = [];
1267
+ const visitedAgents = new Set();
1268
+ const queue = [initialAgent];
1269
+ while (queue.length > 0) {
1270
+ const currentAgent = queue.shift();
1271
+ if (visitedAgents.has(currentAgent)) {
1272
+ continue;
1273
+ }
1274
+ visitedAgents.add(currentAgent);
1275
+ agents.push({ agent: currentAgent, index: agents.length });
1276
+ for (const handoff of currentAgent.handoffs) {
1277
+ if (handoff instanceof agent_1.Agent) {
1278
+ queue.push(handoff);
1279
+ }
1280
+ else if (handoff.agent) {
1281
+ queue.push(handoff.agent);
1282
+ }
1283
+ }
1284
+ for (const tool of currentAgent.tools) {
1285
+ const sourceAgent = (0, agentToolSourceRegistry_1.getAgentToolSourceAgent)(tool);
1286
+ if (sourceAgent) {
1287
+ queue.push(sourceAgent);
1288
+ }
1289
+ }
1290
+ }
1291
+ return agents;
1292
+ }
1293
+ function getAgentIdentitySignature(agent) {
1294
+ const sandboxAgent = agent;
1295
+ const signature = {
1296
+ type: agent.constructor?.name,
1297
+ name: agent.name,
1298
+ handoffDescription: agent.handoffDescription,
1299
+ instructions: summarizeIdentityValue(agent.instructions),
1300
+ prompt: summarizeIdentityValue(agent.prompt),
1301
+ model: summarizeIdentityValue(agent.model),
1302
+ modelSettings: summarizeIdentityValue(agent.modelSettings),
1303
+ tools: agent.tools.map(summarizeToolIdentity),
1304
+ handoffs: agent.handoffs.map((entry) => entry instanceof agent_1.Agent
1305
+ ? { type: 'agent', name: entry.name }
1306
+ : {
1307
+ type: 'handoff',
1308
+ toolName: entry.toolName,
1309
+ agentName: entry.agentName,
1310
+ targetName: entry.agent?.name,
1311
+ }),
1312
+ mcpServers: agent.mcpServers.map(summarizeIdentityValue),
1313
+ mcpConfig: summarizeIdentityValue(agent.mcpConfig),
1314
+ inputGuardrails: agent.inputGuardrails.map(summarizeIdentityValue),
1315
+ outputGuardrails: agent.outputGuardrails.map(summarizeIdentityValue),
1316
+ outputType: summarizeIdentityValue(agent.outputType),
1317
+ toolUseBehavior: summarizeIdentityValue(agent.toolUseBehavior),
1318
+ resetToolChoice: agent.resetToolChoice,
1319
+ defaultManifest: summarizeIdentityValue(sandboxAgent.defaultManifest),
1320
+ baseInstructions: summarizeIdentityValue(sandboxAgent.baseInstructions),
1321
+ capabilities: sandboxAgent.capabilities?.map(summarizeIdentityValue),
1322
+ runAs: summarizeIdentityValue(sandboxAgent.runAs),
1323
+ };
1324
+ return stableStringify(signature);
1325
+ }
1326
+ function summarizeToolIdentity(tool) {
1327
+ return {
1328
+ type: tool.type,
1329
+ name: tool.name,
1330
+ namespace: tool.namespace,
1331
+ strict: tool.strict,
1332
+ parameters: summarizeIdentityValue(tool.parameters),
1333
+ };
1334
+ }
1335
+ function summarizeIdentityValue(value) {
1336
+ return normalizeForIdentity(value, new WeakSet(), 0);
1337
+ }
1338
+ function normalizeForIdentity(value, seen, depth) {
1339
+ if (value === null || typeof value === 'undefined') {
1340
+ return value;
1341
+ }
1342
+ if (typeof value === 'string' ||
1343
+ typeof value === 'number' ||
1344
+ typeof value === 'boolean') {
1345
+ return value;
1346
+ }
1347
+ if (typeof value === 'function') {
1348
+ return `[function:${value.name || 'anonymous'}]`;
1349
+ }
1350
+ if (typeof value !== 'object') {
1351
+ return String(value);
1352
+ }
1353
+ if (seen.has(value)) {
1354
+ return '[circular]';
1355
+ }
1356
+ if (depth >= 4) {
1357
+ return `[${value.constructor?.name ?? 'Object'}]`;
1358
+ }
1359
+ seen.add(value);
1360
+ if (Array.isArray(value)) {
1361
+ return value.map((item) => normalizeForIdentity(item, seen, depth + 1));
1362
+ }
1363
+ if (value instanceof Map) {
1364
+ return [...value.entries()]
1365
+ .map(([key, entryValue]) => [
1366
+ normalizeForIdentity(key, seen, depth + 1),
1367
+ normalizeForIdentity(entryValue, seen, depth + 1),
1368
+ ])
1369
+ .sort((left, right) => stableStringify(left).localeCompare(stableStringify(right)));
1370
+ }
1371
+ if (value instanceof Set) {
1372
+ return [...value.values()]
1373
+ .map((entry) => normalizeForIdentity(entry, seen, depth + 1))
1374
+ .sort((left, right) => stableStringify(left).localeCompare(stableStringify(right)));
1375
+ }
1376
+ const record = value;
1377
+ const normalized = {
1378
+ constructor: value.constructor?.name,
1379
+ };
1380
+ for (const key of Object.keys(record).sort()) {
1381
+ normalized[key] = normalizeForIdentity(record[key], seen, depth + 1);
1382
+ }
1383
+ return normalized;
1384
+ }
1385
+ function stableStringify(value) {
1386
+ return JSON.stringify(value, (_key, currentValue) => {
1387
+ if (!currentValue ||
1388
+ typeof currentValue !== 'object' ||
1389
+ Array.isArray(currentValue)) {
1390
+ return currentValue;
1391
+ }
1392
+ return Object.fromEntries(Object.entries(currentValue).sort(([left], [right]) => left.localeCompare(right)));
1393
+ });
1394
+ }
1395
+ function serializeAgentReference(agent, agentIdentityKeys) {
1396
+ const identity = agentIdentityKeys.get(agent);
1397
+ if (!identity || identity === agent.name) {
1398
+ return { name: agent.name };
1399
+ }
1400
+ return { name: agent.name, identity };
1401
+ }
1402
+ function resolveSerializedAgent(serializedAgent, agentMap, fallbackAgent) {
1403
+ const identity = serializedAgent.identity ?? serializedAgent.name;
1404
+ const agent = agentMap.get(identity);
1405
+ if (agent) {
1406
+ return agent;
1407
+ }
1408
+ if (!serializedAgent.identity && fallbackAgent) {
1409
+ return fallbackAgent;
1410
+ }
1411
+ if (serializedAgent.identity) {
1412
+ throw new errors_1.UserError(`Agent identity ${serializedAgent.identity} not found`);
1413
+ }
1414
+ throw new errors_1.UserError(`Agent ${serializedAgent.name} not found`);
1415
+ }
1416
+ function serializeRunItem(item, agentIdentityKeys) {
1417
+ const serialized = item.toJSON();
1418
+ switch (item.type) {
1419
+ case 'handoff_output_item':
1420
+ serialized.sourceAgent = serializeAgentReference(item.sourceAgent, agentIdentityKeys);
1421
+ serialized.targetAgent = serializeAgentReference(item.targetAgent, agentIdentityKeys);
1422
+ return serialized;
1423
+ default:
1424
+ serialized.agent = serializeAgentReference(item.agent, agentIdentityKeys);
1425
+ return serialized;
1426
+ }
1427
+ }
1428
+ function serializeCurrentStep(currentStep, agentIdentityKeys) {
1429
+ if (!currentStep) {
1430
+ return undefined;
1431
+ }
1432
+ if (currentStep.type === 'next_step_handoff') {
1433
+ return {
1434
+ ...currentStep,
1435
+ newAgent: serializeAgentReference(currentStep.newAgent, agentIdentityKeys),
1436
+ };
1437
+ }
1438
+ if (currentStep.type === 'next_step_interruption') {
1439
+ const interruptions = Array.isArray(currentStep.data?.interruptions)
1440
+ ? currentStep.data.interruptions.map((item) => item instanceof items_1.RunToolApprovalItem
1441
+ ? serializeRunItem(item, agentIdentityKeys)
1442
+ : item)
1443
+ : currentStep.data?.interruptions;
1444
+ return {
1445
+ ...currentStep,
1446
+ data: {
1447
+ ...currentStep.data,
1448
+ interruptions,
1449
+ },
1450
+ };
1451
+ }
1452
+ return currentStep;
1453
+ }
1454
+ function serializeProcessedResponse(processedResponse, agentIdentityKeys) {
1455
+ return {
1456
+ ...processedResponse,
1457
+ newItems: processedResponse.newItems.map((item) => serializeRunItem(item, agentIdentityKeys)),
1458
+ };
1459
+ }
1188
1460
  /**
1189
1461
  * @internal
1190
1462
  */
@@ -1223,23 +1495,23 @@ function deserializeModelResponse(serializedModelResponse) {
1223
1495
  function deserializeItem(serializedItem, agentMap) {
1224
1496
  switch (serializedItem.type) {
1225
1497
  case 'message_output_item':
1226
- return new items_1.RunMessageOutputItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1498
+ return new items_1.RunMessageOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1227
1499
  case 'tool_search_call_item':
1228
- return new items_1.RunToolSearchCallItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1500
+ return new items_1.RunToolSearchCallItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1229
1501
  case 'tool_search_output_item':
1230
- return new items_1.RunToolSearchOutputItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1502
+ return new items_1.RunToolSearchOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1231
1503
  case 'tool_call_item':
1232
- return new items_1.RunToolCallItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1504
+ return new items_1.RunToolCallItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1233
1505
  case 'tool_call_output_item':
1234
- return new items_1.RunToolCallOutputItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name), serializedItem.output);
1506
+ return new items_1.RunToolCallOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap), serializedItem.output);
1235
1507
  case 'reasoning_item':
1236
- return new items_1.RunReasoningItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1508
+ return new items_1.RunReasoningItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1237
1509
  case 'handoff_call_item':
1238
- return new items_1.RunHandoffCallItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1510
+ return new items_1.RunHandoffCallItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1239
1511
  case 'handoff_output_item':
1240
- return new items_1.RunHandoffOutputItem(serializedItem.rawItem, agentMap.get(serializedItem.sourceAgent.name), agentMap.get(serializedItem.targetAgent.name));
1512
+ return new items_1.RunHandoffOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.sourceAgent, agentMap), resolveSerializedAgent(serializedItem.targetAgent, agentMap));
1241
1513
  case 'tool_approval_item':
1242
- return new items_1.RunToolApprovalItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name), serializedItem.toolName);
1514
+ return new items_1.RunToolApprovalItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap), serializedItem.toolName);
1243
1515
  }
1244
1516
  }
1245
1517
  function deserializeInterruptionItem(serializedItem, agentMap, currentAgent) {
@@ -1249,7 +1521,7 @@ function deserializeInterruptionItem(serializedItem, agentMap, currentAgent) {
1249
1521
  const parsed = itemSchema.safeParse(serializedItem);
1250
1522
  if (parsed.success) {
1251
1523
  if (parsed.data.type === 'tool_approval_item') {
1252
- const mappedAgent = agentMap.get(parsed.data.agent.name) ?? currentAgent;
1524
+ const mappedAgent = resolveSerializedAgent(parsed.data.agent, agentMap, currentAgent);
1253
1525
  return new items_1.RunToolApprovalItem(parsed.data.rawItem, mappedAgent, parsed.data.toolName);
1254
1526
  }
1255
1527
  const item = deserializeItem(parsed.data, agentMap);
@@ -1273,7 +1545,15 @@ function deserializeInterruptionItem(serializedItem, agentMap, currentAgent) {
1273
1545
  const agentName = value.agent && typeof value.agent.name === 'string'
1274
1546
  ? value.agent.name
1275
1547
  : undefined;
1276
- const mappedAgent = (agentName ? agentMap.get(agentName) : undefined) ?? currentAgent;
1548
+ const agentIdentity = value.agent && typeof value.agent.identity === 'string'
1549
+ ? value.agent.identity
1550
+ : undefined;
1551
+ const mappedAgent = agentName || agentIdentity
1552
+ ? resolveSerializedAgent({
1553
+ name: agentName ?? currentAgent.name,
1554
+ identity: agentIdentity,
1555
+ }, agentMap, currentAgent)
1556
+ : currentAgent;
1277
1557
  const toolName = typeof value.toolName === 'string'
1278
1558
  ? value.toolName
1279
1559
  : typeof rawItem.name === 'string'