@openai/agents-core 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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,10 @@ 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.
87
90
  */
88
- exports.CURRENT_SCHEMA_VERSION = '1.9';
91
+ exports.CURRENT_SCHEMA_VERSION = '1.10';
89
92
  const SUPPORTED_SCHEMA_VERSIONS = [
90
93
  '1.0',
91
94
  '1.1',
@@ -96,11 +99,13 @@ const SUPPORTED_SCHEMA_VERSIONS = [
96
99
  '1.6',
97
100
  '1.7',
98
101
  '1.8',
102
+ '1.9',
99
103
  exports.CURRENT_SCHEMA_VERSION,
100
104
  ];
101
105
  const $schemaVersion = zod_1.z.enum(SUPPORTED_SCHEMA_VERSIONS);
102
106
  const serializedAgentSchema = zod_1.z.object({
103
107
  name: zod_1.z.string(),
108
+ identity: zod_1.z.string().optional(),
104
109
  });
105
110
  const serializedSpanBase = zod_1.z.object({
106
111
  object: zod_1.z.literal('trace.span'),
@@ -514,10 +519,10 @@ class RunState {
514
519
  */
515
520
  _trace = null;
516
521
  /**
517
- * Runtime-only tool_search-loaded tools, scoped by agent name and preserved across turns for
522
+ * Runtime-only tool_search-loaded tools, scoped by agent object and preserved across turns for
518
523
  * the lifetime of this in-memory run.
519
524
  */
520
- _toolSearchRuntimeToolsByAgentName = new Map();
525
+ _toolSearchRuntimeToolsByAgent = new Map();
521
526
  /**
522
527
  * Persisted sandbox session metadata for sandbox-agent resume.
523
528
  */
@@ -561,20 +566,20 @@ class RunState {
561
566
  setCurrentAgentSpan(span) {
562
567
  this._currentAgentSpan = span;
563
568
  }
564
- getOrCreateToolSearchRuntimeToolState(agentName) {
565
- let state = this._toolSearchRuntimeToolsByAgentName.get(agentName);
569
+ getOrCreateToolSearchRuntimeToolState(agent) {
570
+ let state = this._toolSearchRuntimeToolsByAgent.get(agent);
566
571
  if (!state) {
567
572
  state = {
568
573
  anonymousEntries: [],
569
574
  keyedEntries: new Map(),
570
575
  nextOrder: 0,
571
576
  };
572
- this._toolSearchRuntimeToolsByAgentName.set(agentName, state);
577
+ this._toolSearchRuntimeToolsByAgent.set(agent, state);
573
578
  }
574
579
  return state;
575
580
  }
576
581
  recordToolSearchRuntimeTools(agent, toolSearchOutput, tools) {
577
- const runtimeState = this.getOrCreateToolSearchRuntimeToolState(agent.name);
582
+ const runtimeState = this.getOrCreateToolSearchRuntimeToolState(agent);
578
583
  const entry = {
579
584
  order: runtimeState.nextOrder++,
580
585
  tools,
@@ -587,7 +592,7 @@ class RunState {
587
592
  runtimeState.anonymousEntries.push(entry);
588
593
  }
589
594
  getToolSearchRuntimeTools(agent) {
590
- const runtimeState = this._toolSearchRuntimeToolsByAgentName.get(agent.name);
595
+ const runtimeState = this._toolSearchRuntimeToolsByAgent.get(agent);
591
596
  if (!runtimeState) {
592
597
  return [];
593
598
  }
@@ -724,15 +729,13 @@ class RunState {
724
729
  * rehydrate in a separate process that lacks the original environment variables).
725
730
  */
726
731
  toJSON(options = {}) {
727
- buildAgentMap(this.#startingAgent);
732
+ const agentIdentity = buildAgentIdentityMap(this.#startingAgent);
728
733
  const includeTracingApiKey = options.includeTracingApiKey === true;
729
734
  const contextJson = this._context.toJSON();
730
735
  const output = {
731
736
  $schemaVersion: exports.CURRENT_SCHEMA_VERSION,
732
737
  currentTurn: this._currentTurn,
733
- currentAgent: {
734
- name: this._currentAgent.name,
735
- },
738
+ currentAgent: serializeAgentReference(this._currentAgent, agentIdentity.byAgent),
736
739
  originalInput: this._originalInput,
737
740
  modelResponses: this._modelResponses.map((response) => {
738
741
  return {
@@ -764,7 +767,9 @@ class RunState {
764
767
  };
765
768
  }),
766
769
  context: contextJson,
767
- toolUseTracker: this._toolUseTracker.toJSON(),
770
+ toolUseTracker: this._toolUseTracker.toJSON({
771
+ agentIdentityKeys: agentIdentity.byAgent,
772
+ }),
768
773
  maxTurns: this._maxTurns,
769
774
  currentAgentSpan: this._currentAgentSpan?.toJSON(),
770
775
  noActiveAgentRun: this._noActiveAgentRun,
@@ -772,16 +777,18 @@ class RunState {
772
777
  inputGuardrailResults: this._inputGuardrailResults,
773
778
  outputGuardrailResults: this._outputGuardrailResults.map((r) => ({
774
779
  ...r,
775
- agent: r.agent.toJSON(),
780
+ agent: serializeAgentReference(r.agent, agentIdentity.byAgent),
776
781
  })),
777
782
  toolInputGuardrailResults: this._toolInputGuardrailResults,
778
783
  toolOutputGuardrailResults: this._toolOutputGuardrailResults,
779
- currentStep: this._currentStep,
784
+ currentStep: serializeCurrentStep(this._currentStep, agentIdentity.byAgent),
780
785
  lastModelResponse: this._lastTurnResponse,
781
- generatedItems: this._generatedItems.map((item) => item.toJSON()),
786
+ generatedItems: this._generatedItems.map((item) => serializeRunItem(item, agentIdentity.byAgent)),
782
787
  pendingAgentToolRuns: Object.fromEntries(this._pendingAgentToolRuns.entries()),
783
788
  currentTurnPersistedItemCount: this._currentTurnPersistedItemCount,
784
- lastProcessedResponse: this._lastProcessedResponse,
789
+ lastProcessedResponse: this._lastProcessedResponse
790
+ ? serializeProcessedResponse(this._lastProcessedResponse, agentIdentity.byAgent)
791
+ : undefined,
785
792
  conversationId: this._conversationId,
786
793
  previousResponseId: this._previousResponseId,
787
794
  reasoningItemIdPolicy: this._reasoningItemIdPolicy,
@@ -842,7 +849,9 @@ async function buildRunStateFromString(initialAgent, str, options = {}) {
842
849
  return buildRunStateFromJson(initialAgent, stateJson, options);
843
850
  }
844
851
  function assertSchemaVersionSupportsToolSearch(schemaVersion, stateJson) {
845
- if (schemaVersion === '1.8' || schemaVersion === '1.9') {
852
+ if (schemaVersion === '1.8' ||
853
+ schemaVersion === '1.9' ||
854
+ schemaVersion === exports.CURRENT_SCHEMA_VERSION) {
846
855
  return;
847
856
  }
848
857
  if (!containsSerializedToolSearchState(stateJson)) {
@@ -850,6 +859,9 @@ function assertSchemaVersionSupportsToolSearch(schemaVersion, stateJson) {
850
859
  }
851
860
  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
861
  }
862
+ function schemaVersionSupportsAgentIdentity(schemaVersion) {
863
+ return schemaVersion === exports.CURRENT_SCHEMA_VERSION;
864
+ }
853
865
  function containsSerializedToolSearchState(stateJson) {
854
866
  return (containsToolSearchProtocolItems(stateJson.originalInput) ||
855
867
  containsToolSearchInModelResponses(stateJson.modelResponses) ||
@@ -953,17 +965,17 @@ function assertRuntimeToolKeysMatch(args) {
953
965
  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
966
  }
955
967
  async function getConfiguredAgentTools(args) {
956
- const { agent, context, configuredToolsByAgentName } = args;
957
- const existing = configuredToolsByAgentName.get(agent.name);
968
+ const { agent, context, configuredToolsByAgent } = args;
969
+ const existing = configuredToolsByAgent.get(agent);
958
970
  if (existing) {
959
971
  return existing;
960
972
  }
961
973
  const configuredTools = (await agent.getAllTools(context));
962
- configuredToolsByAgentName.set(agent.name, configuredTools);
974
+ configuredToolsByAgent.set(agent, configuredTools);
963
975
  return configuredTools;
964
976
  }
965
977
  async function rehydrateToolSearchRuntimeTools(state) {
966
- const configuredToolsByAgentName = new Map();
978
+ const configuredToolsByAgent = new Map();
967
979
  const pendingToolSearchCalls = new Map();
968
980
  for (const item of state._generatedItems) {
969
981
  if (item instanceof items_1.RunToolSearchCallItem) {
@@ -971,10 +983,14 @@ async function rehydrateToolSearchRuntimeTools(state) {
971
983
  continue;
972
984
  }
973
985
  const callId = (0, toolSearch_1.resolveToolSearchCallId)(item.rawItem);
974
- pendingToolSearchCalls.set(`${item.agent.name}:${callId}`, {
986
+ const agent = item.agent;
987
+ const pendingCallsById = pendingToolSearchCalls.get(agent) ??
988
+ new Map();
989
+ pendingCallsById.set(callId, {
975
990
  agent: item.agent,
976
991
  toolSearchCall: item.rawItem,
977
992
  });
993
+ pendingToolSearchCalls.set(agent, pendingCallsById);
978
994
  continue;
979
995
  }
980
996
  if (!(item instanceof items_1.RunToolSearchOutputItem)) {
@@ -986,7 +1002,7 @@ async function rehydrateToolSearchRuntimeTools(state) {
986
1002
  const configuredTools = await getConfiguredAgentTools({
987
1003
  agent: item.agent,
988
1004
  context: state._context,
989
- configuredToolsByAgentName,
1005
+ configuredToolsByAgent,
990
1006
  });
991
1007
  const configuredToolKeys = getRuntimeToolKeys(configuredTools, {
992
1008
  allowUnsupported: true,
@@ -996,7 +1012,9 @@ async function rehydrateToolSearchRuntimeTools(state) {
996
1012
  continue;
997
1013
  }
998
1014
  const callId = (0, toolSearch_1.resolveToolSearchCallId)(item.rawItem);
999
- const pendingCall = pendingToolSearchCalls.get(`${item.agent.name}:${callId}`);
1015
+ const pendingCall = pendingToolSearchCalls
1016
+ .get(item.agent)
1017
+ ?.get(callId);
1000
1018
  if (!pendingCall) {
1001
1019
  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
1020
  }
@@ -1039,7 +1057,9 @@ async function rehydrateToolSearchRuntimeTools(state) {
1039
1057
  }
1040
1058
  }
1041
1059
  async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
1042
- const agentMap = buildAgentMap(initialAgent);
1060
+ const agentMap = schemaVersionSupportsAgentIdentity(stateJson.$schemaVersion)
1061
+ ? buildAgentIdentityMap(initialAgent).byIdentity
1062
+ : buildAgentMap(initialAgent);
1043
1063
  const contextOverride = options.contextOverride;
1044
1064
  const contextStrategy = options.contextStrategy ?? 'merge';
1045
1065
  //
@@ -1064,10 +1084,7 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
1064
1084
  //
1065
1085
  // Find the current agent from the initial agent
1066
1086
  //
1067
- const currentAgent = agentMap.get(stateJson.currentAgent.name);
1068
- if (!currentAgent) {
1069
- throw new errors_1.UserError(`Agent ${stateJson.currentAgent.name} not found`);
1070
- }
1087
+ const currentAgent = resolveSerializedAgent(stateJson.currentAgent, agentMap);
1071
1088
  const state = new RunState(context, '', initialAgent, stateJson.maxTurns);
1072
1089
  state._currentAgent = currentAgent;
1073
1090
  state._currentTurn = stateJson.currentTurn;
@@ -1078,7 +1095,13 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
1078
1095
  // rebuild tool use tracker
1079
1096
  state._toolUseTracker = new toolUseTracker_1.AgentToolUseTracker();
1080
1097
  for (const [agentName, toolNames] of Object.entries(stateJson.toolUseTracker)) {
1081
- state._toolUseTracker.addToolUse(agentMap.get(agentName), toolNames, { allowEmpty: true });
1098
+ const agent = agentMap.get(agentName);
1099
+ if (!agent) {
1100
+ throw new errors_1.UserError(`Agent ${agentName} not found`);
1101
+ }
1102
+ state._toolUseTracker.addToolUse(agent, toolNames, {
1103
+ allowEmpty: true,
1104
+ });
1082
1105
  }
1083
1106
  state._pendingAgentToolRuns = new Map(Object.entries(stateJson.pendingAgentToolRuns ?? {}));
1084
1107
  // rebuild current agent span
@@ -1101,7 +1124,7 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
1101
1124
  stateJson.inputGuardrailResults;
1102
1125
  state._outputGuardrailResults = stateJson.outputGuardrailResults.map((r) => ({
1103
1126
  ...r,
1104
- agent: agentMap.get(r.agent.name),
1127
+ agent: resolveSerializedAgent(r.agent, agentMap),
1105
1128
  }));
1106
1129
  state._toolInputGuardrailResults =
1107
1130
  stateJson.toolInputGuardrailResults;
@@ -1124,7 +1147,7 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
1124
1147
  if (stateJson.currentStep?.type === 'next_step_handoff') {
1125
1148
  state._currentStep = {
1126
1149
  type: 'next_step_handoff',
1127
- newAgent: agentMap.get(stateJson.currentStep.newAgent.name),
1150
+ newAgent: resolveSerializedAgent(stateJson.currentStep.newAgent, agentMap),
1128
1151
  };
1129
1152
  }
1130
1153
  else if (stateJson.currentStep?.type === 'next_step_interruption') {
@@ -1145,7 +1168,9 @@ async function rehydrateProcessedResponseTools(initialAgent, state, executionToo
1145
1168
  if (!state._lastProcessedResponse) {
1146
1169
  return;
1147
1170
  }
1148
- state._lastProcessedResponse = await deserializeProcessedResponse(buildAgentMap(initialAgent), state, state._lastProcessedResponse, {
1171
+ const agentIdentity = buildAgentIdentityMap(initialAgent);
1172
+ const serializedProcessedResponse = serializeProcessedResponse(state._lastProcessedResponse, agentIdentity.byAgent);
1173
+ state._lastProcessedResponse = await deserializeProcessedResponse(agentIdentity.byIdentity, state, serializedProcessedResponse, {
1149
1174
  executionTools,
1150
1175
  allowSerializedExecutionToolPlaceholder: false,
1151
1176
  });
@@ -1185,6 +1210,249 @@ function buildAgentMap(initialAgent) {
1185
1210
  }
1186
1211
  return map;
1187
1212
  }
1213
+ /**
1214
+ * @internal
1215
+ */
1216
+ function buildAgentIdentityMap(initialAgent) {
1217
+ const agents = collectAgentGraph(initialAgent);
1218
+ const groups = new Map();
1219
+ const literalNames = new Set();
1220
+ for (const entry of agents) {
1221
+ literalNames.add(entry.agent.name);
1222
+ const group = groups.get(entry.agent.name) ?? [];
1223
+ group.push(entry);
1224
+ groups.set(entry.agent.name, group);
1225
+ }
1226
+ const byIdentity = new Map();
1227
+ const byAgent = new Map();
1228
+ const usedIdentities = new Set();
1229
+ for (const [agentName, group] of groups) {
1230
+ const sortedGroup = group.length === 1
1231
+ ? group
1232
+ : [...group].sort((left, right) => {
1233
+ if (left.agent === initialAgent) {
1234
+ return -1;
1235
+ }
1236
+ if (right.agent === initialAgent) {
1237
+ return 1;
1238
+ }
1239
+ const leftSignature = getAgentIdentitySignature(left.agent);
1240
+ const rightSignature = getAgentIdentitySignature(right.agent);
1241
+ if (leftSignature !== rightSignature) {
1242
+ return leftSignature < rightSignature ? -1 : 1;
1243
+ }
1244
+ return left.index - right.index;
1245
+ });
1246
+ let nextSuffix = 0;
1247
+ for (const { agent } of sortedGroup) {
1248
+ let identity;
1249
+ do {
1250
+ identity =
1251
+ nextSuffix === 0 ? agentName : `${agentName}#${nextSuffix + 1}`;
1252
+ nextSuffix += 1;
1253
+ } while (usedIdentities.has(identity) ||
1254
+ (identity !== agent.name && literalNames.has(identity)));
1255
+ usedIdentities.add(identity);
1256
+ byIdentity.set(identity, agent);
1257
+ byAgent.set(agent, identity);
1258
+ }
1259
+ }
1260
+ return { byIdentity, byAgent };
1261
+ }
1262
+ function collectAgentGraph(initialAgent) {
1263
+ const agents = [];
1264
+ const visitedAgents = new Set();
1265
+ const queue = [initialAgent];
1266
+ while (queue.length > 0) {
1267
+ const currentAgent = queue.shift();
1268
+ if (visitedAgents.has(currentAgent)) {
1269
+ continue;
1270
+ }
1271
+ visitedAgents.add(currentAgent);
1272
+ agents.push({ agent: currentAgent, index: agents.length });
1273
+ for (const handoff of currentAgent.handoffs) {
1274
+ if (handoff instanceof agent_1.Agent) {
1275
+ queue.push(handoff);
1276
+ }
1277
+ else if (handoff.agent) {
1278
+ queue.push(handoff.agent);
1279
+ }
1280
+ }
1281
+ for (const tool of currentAgent.tools) {
1282
+ const sourceAgent = (0, agentToolSourceRegistry_1.getAgentToolSourceAgent)(tool);
1283
+ if (sourceAgent) {
1284
+ queue.push(sourceAgent);
1285
+ }
1286
+ }
1287
+ }
1288
+ return agents;
1289
+ }
1290
+ function getAgentIdentitySignature(agent) {
1291
+ const sandboxAgent = agent;
1292
+ const signature = {
1293
+ type: agent.constructor?.name,
1294
+ name: agent.name,
1295
+ handoffDescription: agent.handoffDescription,
1296
+ instructions: summarizeIdentityValue(agent.instructions),
1297
+ prompt: summarizeIdentityValue(agent.prompt),
1298
+ model: summarizeIdentityValue(agent.model),
1299
+ modelSettings: summarizeIdentityValue(agent.modelSettings),
1300
+ tools: agent.tools.map(summarizeToolIdentity),
1301
+ handoffs: agent.handoffs.map((entry) => entry instanceof agent_1.Agent
1302
+ ? { type: 'agent', name: entry.name }
1303
+ : {
1304
+ type: 'handoff',
1305
+ toolName: entry.toolName,
1306
+ agentName: entry.agentName,
1307
+ targetName: entry.agent?.name,
1308
+ }),
1309
+ mcpServers: agent.mcpServers.map(summarizeIdentityValue),
1310
+ inputGuardrails: agent.inputGuardrails.map(summarizeIdentityValue),
1311
+ outputGuardrails: agent.outputGuardrails.map(summarizeIdentityValue),
1312
+ outputType: summarizeIdentityValue(agent.outputType),
1313
+ toolUseBehavior: summarizeIdentityValue(agent.toolUseBehavior),
1314
+ resetToolChoice: agent.resetToolChoice,
1315
+ defaultManifest: summarizeIdentityValue(sandboxAgent.defaultManifest),
1316
+ baseInstructions: summarizeIdentityValue(sandboxAgent.baseInstructions),
1317
+ capabilities: sandboxAgent.capabilities?.map(summarizeIdentityValue),
1318
+ runAs: summarizeIdentityValue(sandboxAgent.runAs),
1319
+ };
1320
+ return stableStringify(signature);
1321
+ }
1322
+ function summarizeToolIdentity(tool) {
1323
+ return {
1324
+ type: tool.type,
1325
+ name: tool.name,
1326
+ namespace: tool.namespace,
1327
+ strict: tool.strict,
1328
+ parameters: summarizeIdentityValue(tool.parameters),
1329
+ };
1330
+ }
1331
+ function summarizeIdentityValue(value) {
1332
+ return normalizeForIdentity(value, new WeakSet(), 0);
1333
+ }
1334
+ function normalizeForIdentity(value, seen, depth) {
1335
+ if (value === null || typeof value === 'undefined') {
1336
+ return value;
1337
+ }
1338
+ if (typeof value === 'string' ||
1339
+ typeof value === 'number' ||
1340
+ typeof value === 'boolean') {
1341
+ return value;
1342
+ }
1343
+ if (typeof value === 'function') {
1344
+ return `[function:${value.name || 'anonymous'}]`;
1345
+ }
1346
+ if (typeof value !== 'object') {
1347
+ return String(value);
1348
+ }
1349
+ if (seen.has(value)) {
1350
+ return '[circular]';
1351
+ }
1352
+ if (depth >= 4) {
1353
+ return `[${value.constructor?.name ?? 'Object'}]`;
1354
+ }
1355
+ seen.add(value);
1356
+ if (Array.isArray(value)) {
1357
+ return value.map((item) => normalizeForIdentity(item, seen, depth + 1));
1358
+ }
1359
+ if (value instanceof Map) {
1360
+ return [...value.entries()]
1361
+ .map(([key, entryValue]) => [
1362
+ normalizeForIdentity(key, seen, depth + 1),
1363
+ normalizeForIdentity(entryValue, seen, depth + 1),
1364
+ ])
1365
+ .sort((left, right) => stableStringify(left).localeCompare(stableStringify(right)));
1366
+ }
1367
+ if (value instanceof Set) {
1368
+ return [...value.values()]
1369
+ .map((entry) => normalizeForIdentity(entry, seen, depth + 1))
1370
+ .sort((left, right) => stableStringify(left).localeCompare(stableStringify(right)));
1371
+ }
1372
+ const record = value;
1373
+ const normalized = {
1374
+ constructor: value.constructor?.name,
1375
+ };
1376
+ for (const key of Object.keys(record).sort()) {
1377
+ normalized[key] = normalizeForIdentity(record[key], seen, depth + 1);
1378
+ }
1379
+ return normalized;
1380
+ }
1381
+ function stableStringify(value) {
1382
+ return JSON.stringify(value, (_key, currentValue) => {
1383
+ if (!currentValue ||
1384
+ typeof currentValue !== 'object' ||
1385
+ Array.isArray(currentValue)) {
1386
+ return currentValue;
1387
+ }
1388
+ return Object.fromEntries(Object.entries(currentValue).sort(([left], [right]) => left.localeCompare(right)));
1389
+ });
1390
+ }
1391
+ function serializeAgentReference(agent, agentIdentityKeys) {
1392
+ const identity = agentIdentityKeys.get(agent);
1393
+ if (!identity || identity === agent.name) {
1394
+ return { name: agent.name };
1395
+ }
1396
+ return { name: agent.name, identity };
1397
+ }
1398
+ function resolveSerializedAgent(serializedAgent, agentMap, fallbackAgent) {
1399
+ const identity = serializedAgent.identity ?? serializedAgent.name;
1400
+ const agent = agentMap.get(identity);
1401
+ if (agent) {
1402
+ return agent;
1403
+ }
1404
+ if (!serializedAgent.identity && fallbackAgent) {
1405
+ return fallbackAgent;
1406
+ }
1407
+ if (serializedAgent.identity) {
1408
+ throw new errors_1.UserError(`Agent identity ${serializedAgent.identity} not found`);
1409
+ }
1410
+ throw new errors_1.UserError(`Agent ${serializedAgent.name} not found`);
1411
+ }
1412
+ function serializeRunItem(item, agentIdentityKeys) {
1413
+ const serialized = item.toJSON();
1414
+ switch (item.type) {
1415
+ case 'handoff_output_item':
1416
+ serialized.sourceAgent = serializeAgentReference(item.sourceAgent, agentIdentityKeys);
1417
+ serialized.targetAgent = serializeAgentReference(item.targetAgent, agentIdentityKeys);
1418
+ return serialized;
1419
+ default:
1420
+ serialized.agent = serializeAgentReference(item.agent, agentIdentityKeys);
1421
+ return serialized;
1422
+ }
1423
+ }
1424
+ function serializeCurrentStep(currentStep, agentIdentityKeys) {
1425
+ if (!currentStep) {
1426
+ return undefined;
1427
+ }
1428
+ if (currentStep.type === 'next_step_handoff') {
1429
+ return {
1430
+ ...currentStep,
1431
+ newAgent: serializeAgentReference(currentStep.newAgent, agentIdentityKeys),
1432
+ };
1433
+ }
1434
+ if (currentStep.type === 'next_step_interruption') {
1435
+ const interruptions = Array.isArray(currentStep.data?.interruptions)
1436
+ ? currentStep.data.interruptions.map((item) => item instanceof items_1.RunToolApprovalItem
1437
+ ? serializeRunItem(item, agentIdentityKeys)
1438
+ : item)
1439
+ : currentStep.data?.interruptions;
1440
+ return {
1441
+ ...currentStep,
1442
+ data: {
1443
+ ...currentStep.data,
1444
+ interruptions,
1445
+ },
1446
+ };
1447
+ }
1448
+ return currentStep;
1449
+ }
1450
+ function serializeProcessedResponse(processedResponse, agentIdentityKeys) {
1451
+ return {
1452
+ ...processedResponse,
1453
+ newItems: processedResponse.newItems.map((item) => serializeRunItem(item, agentIdentityKeys)),
1454
+ };
1455
+ }
1188
1456
  /**
1189
1457
  * @internal
1190
1458
  */
@@ -1223,23 +1491,23 @@ function deserializeModelResponse(serializedModelResponse) {
1223
1491
  function deserializeItem(serializedItem, agentMap) {
1224
1492
  switch (serializedItem.type) {
1225
1493
  case 'message_output_item':
1226
- return new items_1.RunMessageOutputItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1494
+ return new items_1.RunMessageOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1227
1495
  case 'tool_search_call_item':
1228
- return new items_1.RunToolSearchCallItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1496
+ return new items_1.RunToolSearchCallItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1229
1497
  case 'tool_search_output_item':
1230
- return new items_1.RunToolSearchOutputItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1498
+ return new items_1.RunToolSearchOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1231
1499
  case 'tool_call_item':
1232
- return new items_1.RunToolCallItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1500
+ return new items_1.RunToolCallItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1233
1501
  case 'tool_call_output_item':
1234
- return new items_1.RunToolCallOutputItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name), serializedItem.output);
1502
+ return new items_1.RunToolCallOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap), serializedItem.output);
1235
1503
  case 'reasoning_item':
1236
- return new items_1.RunReasoningItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1504
+ return new items_1.RunReasoningItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1237
1505
  case 'handoff_call_item':
1238
- return new items_1.RunHandoffCallItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name));
1506
+ return new items_1.RunHandoffCallItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
1239
1507
  case 'handoff_output_item':
1240
- return new items_1.RunHandoffOutputItem(serializedItem.rawItem, agentMap.get(serializedItem.sourceAgent.name), agentMap.get(serializedItem.targetAgent.name));
1508
+ return new items_1.RunHandoffOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.sourceAgent, agentMap), resolveSerializedAgent(serializedItem.targetAgent, agentMap));
1241
1509
  case 'tool_approval_item':
1242
- return new items_1.RunToolApprovalItem(serializedItem.rawItem, agentMap.get(serializedItem.agent.name), serializedItem.toolName);
1510
+ return new items_1.RunToolApprovalItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap), serializedItem.toolName);
1243
1511
  }
1244
1512
  }
1245
1513
  function deserializeInterruptionItem(serializedItem, agentMap, currentAgent) {
@@ -1249,7 +1517,7 @@ function deserializeInterruptionItem(serializedItem, agentMap, currentAgent) {
1249
1517
  const parsed = itemSchema.safeParse(serializedItem);
1250
1518
  if (parsed.success) {
1251
1519
  if (parsed.data.type === 'tool_approval_item') {
1252
- const mappedAgent = agentMap.get(parsed.data.agent.name) ?? currentAgent;
1520
+ const mappedAgent = resolveSerializedAgent(parsed.data.agent, agentMap, currentAgent);
1253
1521
  return new items_1.RunToolApprovalItem(parsed.data.rawItem, mappedAgent, parsed.data.toolName);
1254
1522
  }
1255
1523
  const item = deserializeItem(parsed.data, agentMap);
@@ -1273,7 +1541,15 @@ function deserializeInterruptionItem(serializedItem, agentMap, currentAgent) {
1273
1541
  const agentName = value.agent && typeof value.agent.name === 'string'
1274
1542
  ? value.agent.name
1275
1543
  : undefined;
1276
- const mappedAgent = (agentName ? agentMap.get(agentName) : undefined) ?? currentAgent;
1544
+ const agentIdentity = value.agent && typeof value.agent.identity === 'string'
1545
+ ? value.agent.identity
1546
+ : undefined;
1547
+ const mappedAgent = agentName || agentIdentity
1548
+ ? resolveSerializedAgent({
1549
+ name: agentName ?? currentAgent.name,
1550
+ identity: agentIdentity,
1551
+ }, agentMap, currentAgent)
1552
+ : currentAgent;
1277
1553
  const toolName = typeof value.toolName === 'string'
1278
1554
  ? value.toolName
1279
1555
  : typeof rawItem.name === 'string'