@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/memory/session.d.ts +7 -0
- package/dist/memory/session.js.map +1 -1
- package/dist/memory/session.mjs.map +1 -1
- package/dist/metadata.js +2 -2
- package/dist/metadata.mjs +2 -2
- package/dist/run.js +36 -0
- package/dist/run.js.map +1 -1
- package/dist/run.mjs +36 -0
- package/dist/run.mjs.map +1 -1
- package/dist/runState.d.ts +28 -3
- package/dist/runState.js +321 -45
- package/dist/runState.js.map +1 -1
- package/dist/runState.mjs +320 -45
- package/dist/runState.mjs.map +1 -1
- package/dist/runner/sessionPersistence.js +33 -12
- package/dist/runner/sessionPersistence.js.map +1 -1
- package/dist/runner/sessionPersistence.mjs +33 -12
- package/dist/runner/sessionPersistence.mjs.map +1 -1
- package/dist/runner/streamReconciliation.d.ts +14 -0
- package/dist/runner/streamReconciliation.js +80 -0
- package/dist/runner/streamReconciliation.js.map +1 -0
- package/dist/runner/streamReconciliation.mjs +72 -0
- package/dist/runner/streamReconciliation.mjs.map +1 -0
- package/dist/runner/toolUseTracker.d.ts +3 -1
- package/dist/runner/toolUseTracker.js +2 -2
- package/dist/runner/toolUseTracker.js.map +1 -1
- package/dist/runner/toolUseTracker.mjs +2 -2
- package/dist/runner/toolUseTracker.mjs.map +1 -1
- package/package.json +1 -1
package/dist/runState.mjs
CHANGED
|
@@ -40,8 +40,10 @@ import { getSerializedApplyPatchToolPlaceholder, getSerializedComputerToolPlaceh
|
|
|
40
40
|
* aliasing to serialized run state payloads.
|
|
41
41
|
* - 1.9: Adds optional sandbox session persistence with a versioned session-state
|
|
42
42
|
* envelope for sandbox-agent resume.
|
|
43
|
+
* - 1.10: Adds optional stable agent identity keys so duplicate-name agent graphs can
|
|
44
|
+
* serialize and resume without ambiguous name resolution.
|
|
43
45
|
*/
|
|
44
|
-
export const CURRENT_SCHEMA_VERSION = '1.
|
|
46
|
+
export const CURRENT_SCHEMA_VERSION = '1.10';
|
|
45
47
|
const SUPPORTED_SCHEMA_VERSIONS = [
|
|
46
48
|
'1.0',
|
|
47
49
|
'1.1',
|
|
@@ -52,11 +54,13 @@ const SUPPORTED_SCHEMA_VERSIONS = [
|
|
|
52
54
|
'1.6',
|
|
53
55
|
'1.7',
|
|
54
56
|
'1.8',
|
|
57
|
+
'1.9',
|
|
55
58
|
CURRENT_SCHEMA_VERSION,
|
|
56
59
|
];
|
|
57
60
|
const $schemaVersion = z.enum(SUPPORTED_SCHEMA_VERSIONS);
|
|
58
61
|
const serializedAgentSchema = z.object({
|
|
59
62
|
name: z.string(),
|
|
63
|
+
identity: z.string().optional(),
|
|
60
64
|
});
|
|
61
65
|
const serializedSpanBase = z.object({
|
|
62
66
|
object: z.literal('trace.span'),
|
|
@@ -470,10 +474,10 @@ export class RunState {
|
|
|
470
474
|
*/
|
|
471
475
|
_trace = null;
|
|
472
476
|
/**
|
|
473
|
-
* Runtime-only tool_search-loaded tools, scoped by agent
|
|
477
|
+
* Runtime-only tool_search-loaded tools, scoped by agent object and preserved across turns for
|
|
474
478
|
* the lifetime of this in-memory run.
|
|
475
479
|
*/
|
|
476
|
-
|
|
480
|
+
_toolSearchRuntimeToolsByAgent = new Map();
|
|
477
481
|
/**
|
|
478
482
|
* Persisted sandbox session metadata for sandbox-agent resume.
|
|
479
483
|
*/
|
|
@@ -517,20 +521,20 @@ export class RunState {
|
|
|
517
521
|
setCurrentAgentSpan(span) {
|
|
518
522
|
this._currentAgentSpan = span;
|
|
519
523
|
}
|
|
520
|
-
getOrCreateToolSearchRuntimeToolState(
|
|
521
|
-
let state = this.
|
|
524
|
+
getOrCreateToolSearchRuntimeToolState(agent) {
|
|
525
|
+
let state = this._toolSearchRuntimeToolsByAgent.get(agent);
|
|
522
526
|
if (!state) {
|
|
523
527
|
state = {
|
|
524
528
|
anonymousEntries: [],
|
|
525
529
|
keyedEntries: new Map(),
|
|
526
530
|
nextOrder: 0,
|
|
527
531
|
};
|
|
528
|
-
this.
|
|
532
|
+
this._toolSearchRuntimeToolsByAgent.set(agent, state);
|
|
529
533
|
}
|
|
530
534
|
return state;
|
|
531
535
|
}
|
|
532
536
|
recordToolSearchRuntimeTools(agent, toolSearchOutput, tools) {
|
|
533
|
-
const runtimeState = this.getOrCreateToolSearchRuntimeToolState(agent
|
|
537
|
+
const runtimeState = this.getOrCreateToolSearchRuntimeToolState(agent);
|
|
534
538
|
const entry = {
|
|
535
539
|
order: runtimeState.nextOrder++,
|
|
536
540
|
tools,
|
|
@@ -543,7 +547,7 @@ export class RunState {
|
|
|
543
547
|
runtimeState.anonymousEntries.push(entry);
|
|
544
548
|
}
|
|
545
549
|
getToolSearchRuntimeTools(agent) {
|
|
546
|
-
const runtimeState = this.
|
|
550
|
+
const runtimeState = this._toolSearchRuntimeToolsByAgent.get(agent);
|
|
547
551
|
if (!runtimeState) {
|
|
548
552
|
return [];
|
|
549
553
|
}
|
|
@@ -680,15 +684,13 @@ export class RunState {
|
|
|
680
684
|
* rehydrate in a separate process that lacks the original environment variables).
|
|
681
685
|
*/
|
|
682
686
|
toJSON(options = {}) {
|
|
683
|
-
|
|
687
|
+
const agentIdentity = buildAgentIdentityMap(this.#startingAgent);
|
|
684
688
|
const includeTracingApiKey = options.includeTracingApiKey === true;
|
|
685
689
|
const contextJson = this._context.toJSON();
|
|
686
690
|
const output = {
|
|
687
691
|
$schemaVersion: CURRENT_SCHEMA_VERSION,
|
|
688
692
|
currentTurn: this._currentTurn,
|
|
689
|
-
currentAgent:
|
|
690
|
-
name: this._currentAgent.name,
|
|
691
|
-
},
|
|
693
|
+
currentAgent: serializeAgentReference(this._currentAgent, agentIdentity.byAgent),
|
|
692
694
|
originalInput: this._originalInput,
|
|
693
695
|
modelResponses: this._modelResponses.map((response) => {
|
|
694
696
|
return {
|
|
@@ -720,7 +722,9 @@ export class RunState {
|
|
|
720
722
|
};
|
|
721
723
|
}),
|
|
722
724
|
context: contextJson,
|
|
723
|
-
toolUseTracker: this._toolUseTracker.toJSON(
|
|
725
|
+
toolUseTracker: this._toolUseTracker.toJSON({
|
|
726
|
+
agentIdentityKeys: agentIdentity.byAgent,
|
|
727
|
+
}),
|
|
724
728
|
maxTurns: this._maxTurns,
|
|
725
729
|
currentAgentSpan: this._currentAgentSpan?.toJSON(),
|
|
726
730
|
noActiveAgentRun: this._noActiveAgentRun,
|
|
@@ -728,16 +732,18 @@ export class RunState {
|
|
|
728
732
|
inputGuardrailResults: this._inputGuardrailResults,
|
|
729
733
|
outputGuardrailResults: this._outputGuardrailResults.map((r) => ({
|
|
730
734
|
...r,
|
|
731
|
-
agent: r.agent.
|
|
735
|
+
agent: serializeAgentReference(r.agent, agentIdentity.byAgent),
|
|
732
736
|
})),
|
|
733
737
|
toolInputGuardrailResults: this._toolInputGuardrailResults,
|
|
734
738
|
toolOutputGuardrailResults: this._toolOutputGuardrailResults,
|
|
735
|
-
currentStep: this._currentStep,
|
|
739
|
+
currentStep: serializeCurrentStep(this._currentStep, agentIdentity.byAgent),
|
|
736
740
|
lastModelResponse: this._lastTurnResponse,
|
|
737
|
-
generatedItems: this._generatedItems.map((item) => item.
|
|
741
|
+
generatedItems: this._generatedItems.map((item) => serializeRunItem(item, agentIdentity.byAgent)),
|
|
738
742
|
pendingAgentToolRuns: Object.fromEntries(this._pendingAgentToolRuns.entries()),
|
|
739
743
|
currentTurnPersistedItemCount: this._currentTurnPersistedItemCount,
|
|
740
|
-
lastProcessedResponse: this._lastProcessedResponse
|
|
744
|
+
lastProcessedResponse: this._lastProcessedResponse
|
|
745
|
+
? serializeProcessedResponse(this._lastProcessedResponse, agentIdentity.byAgent)
|
|
746
|
+
: undefined,
|
|
741
747
|
conversationId: this._conversationId,
|
|
742
748
|
previousResponseId: this._previousResponseId,
|
|
743
749
|
reasoningItemIdPolicy: this._reasoningItemIdPolicy,
|
|
@@ -797,7 +803,9 @@ async function buildRunStateFromString(initialAgent, str, options = {}) {
|
|
|
797
803
|
return buildRunStateFromJson(initialAgent, stateJson, options);
|
|
798
804
|
}
|
|
799
805
|
function assertSchemaVersionSupportsToolSearch(schemaVersion, stateJson) {
|
|
800
|
-
if (schemaVersion === '1.8' ||
|
|
806
|
+
if (schemaVersion === '1.8' ||
|
|
807
|
+
schemaVersion === '1.9' ||
|
|
808
|
+
schemaVersion === CURRENT_SCHEMA_VERSION) {
|
|
801
809
|
return;
|
|
802
810
|
}
|
|
803
811
|
if (!containsSerializedToolSearchState(stateJson)) {
|
|
@@ -805,6 +813,9 @@ function assertSchemaVersionSupportsToolSearch(schemaVersion, stateJson) {
|
|
|
805
813
|
}
|
|
806
814
|
throw new UserError(`Run state schema version ${schemaVersion} does not support tool_search items. Please reserialize the run state with schema ${CURRENT_SCHEMA_VERSION}.`);
|
|
807
815
|
}
|
|
816
|
+
function schemaVersionSupportsAgentIdentity(schemaVersion) {
|
|
817
|
+
return schemaVersion === CURRENT_SCHEMA_VERSION;
|
|
818
|
+
}
|
|
808
819
|
function containsSerializedToolSearchState(stateJson) {
|
|
809
820
|
return (containsToolSearchProtocolItems(stateJson.originalInput) ||
|
|
810
821
|
containsToolSearchInModelResponses(stateJson.modelResponses) ||
|
|
@@ -908,17 +919,17 @@ function assertRuntimeToolKeysMatch(args) {
|
|
|
908
919
|
throw new 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)}].`);
|
|
909
920
|
}
|
|
910
921
|
async function getConfiguredAgentTools(args) {
|
|
911
|
-
const { agent, context,
|
|
912
|
-
const existing =
|
|
922
|
+
const { agent, context, configuredToolsByAgent } = args;
|
|
923
|
+
const existing = configuredToolsByAgent.get(agent);
|
|
913
924
|
if (existing) {
|
|
914
925
|
return existing;
|
|
915
926
|
}
|
|
916
927
|
const configuredTools = (await agent.getAllTools(context));
|
|
917
|
-
|
|
928
|
+
configuredToolsByAgent.set(agent, configuredTools);
|
|
918
929
|
return configuredTools;
|
|
919
930
|
}
|
|
920
931
|
async function rehydrateToolSearchRuntimeTools(state) {
|
|
921
|
-
const
|
|
932
|
+
const configuredToolsByAgent = new Map();
|
|
922
933
|
const pendingToolSearchCalls = new Map();
|
|
923
934
|
for (const item of state._generatedItems) {
|
|
924
935
|
if (item instanceof RunToolSearchCallItem) {
|
|
@@ -926,10 +937,14 @@ async function rehydrateToolSearchRuntimeTools(state) {
|
|
|
926
937
|
continue;
|
|
927
938
|
}
|
|
928
939
|
const callId = resolveToolSearchCallId(item.rawItem);
|
|
929
|
-
|
|
940
|
+
const agent = item.agent;
|
|
941
|
+
const pendingCallsById = pendingToolSearchCalls.get(agent) ??
|
|
942
|
+
new Map();
|
|
943
|
+
pendingCallsById.set(callId, {
|
|
930
944
|
agent: item.agent,
|
|
931
945
|
toolSearchCall: item.rawItem,
|
|
932
946
|
});
|
|
947
|
+
pendingToolSearchCalls.set(agent, pendingCallsById);
|
|
933
948
|
continue;
|
|
934
949
|
}
|
|
935
950
|
if (!(item instanceof RunToolSearchOutputItem)) {
|
|
@@ -941,7 +956,7 @@ async function rehydrateToolSearchRuntimeTools(state) {
|
|
|
941
956
|
const configuredTools = await getConfiguredAgentTools({
|
|
942
957
|
agent: item.agent,
|
|
943
958
|
context: state._context,
|
|
944
|
-
|
|
959
|
+
configuredToolsByAgent,
|
|
945
960
|
});
|
|
946
961
|
const configuredToolKeys = getRuntimeToolKeys(configuredTools, {
|
|
947
962
|
allowUnsupported: true,
|
|
@@ -951,7 +966,9 @@ async function rehydrateToolSearchRuntimeTools(state) {
|
|
|
951
966
|
continue;
|
|
952
967
|
}
|
|
953
968
|
const callId = resolveToolSearchCallId(item.rawItem);
|
|
954
|
-
const pendingCall = pendingToolSearchCalls
|
|
969
|
+
const pendingCall = pendingToolSearchCalls
|
|
970
|
+
.get(item.agent)
|
|
971
|
+
?.get(callId);
|
|
955
972
|
if (!pendingCall) {
|
|
956
973
|
throw new 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.`);
|
|
957
974
|
}
|
|
@@ -994,7 +1011,9 @@ async function rehydrateToolSearchRuntimeTools(state) {
|
|
|
994
1011
|
}
|
|
995
1012
|
}
|
|
996
1013
|
async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
|
|
997
|
-
const agentMap =
|
|
1014
|
+
const agentMap = schemaVersionSupportsAgentIdentity(stateJson.$schemaVersion)
|
|
1015
|
+
? buildAgentIdentityMap(initialAgent).byIdentity
|
|
1016
|
+
: buildAgentMap(initialAgent);
|
|
998
1017
|
const contextOverride = options.contextOverride;
|
|
999
1018
|
const contextStrategy = options.contextStrategy ?? 'merge';
|
|
1000
1019
|
//
|
|
@@ -1019,10 +1038,7 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
|
|
|
1019
1038
|
//
|
|
1020
1039
|
// Find the current agent from the initial agent
|
|
1021
1040
|
//
|
|
1022
|
-
const currentAgent =
|
|
1023
|
-
if (!currentAgent) {
|
|
1024
|
-
throw new UserError(`Agent ${stateJson.currentAgent.name} not found`);
|
|
1025
|
-
}
|
|
1041
|
+
const currentAgent = resolveSerializedAgent(stateJson.currentAgent, agentMap);
|
|
1026
1042
|
const state = new RunState(context, '', initialAgent, stateJson.maxTurns);
|
|
1027
1043
|
state._currentAgent = currentAgent;
|
|
1028
1044
|
state._currentTurn = stateJson.currentTurn;
|
|
@@ -1033,7 +1049,13 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
|
|
|
1033
1049
|
// rebuild tool use tracker
|
|
1034
1050
|
state._toolUseTracker = new AgentToolUseTracker();
|
|
1035
1051
|
for (const [agentName, toolNames] of Object.entries(stateJson.toolUseTracker)) {
|
|
1036
|
-
|
|
1052
|
+
const agent = agentMap.get(agentName);
|
|
1053
|
+
if (!agent) {
|
|
1054
|
+
throw new UserError(`Agent ${agentName} not found`);
|
|
1055
|
+
}
|
|
1056
|
+
state._toolUseTracker.addToolUse(agent, toolNames, {
|
|
1057
|
+
allowEmpty: true,
|
|
1058
|
+
});
|
|
1037
1059
|
}
|
|
1038
1060
|
state._pendingAgentToolRuns = new Map(Object.entries(stateJson.pendingAgentToolRuns ?? {}));
|
|
1039
1061
|
// rebuild current agent span
|
|
@@ -1056,7 +1078,7 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
|
|
|
1056
1078
|
stateJson.inputGuardrailResults;
|
|
1057
1079
|
state._outputGuardrailResults = stateJson.outputGuardrailResults.map((r) => ({
|
|
1058
1080
|
...r,
|
|
1059
|
-
agent:
|
|
1081
|
+
agent: resolveSerializedAgent(r.agent, agentMap),
|
|
1060
1082
|
}));
|
|
1061
1083
|
state._toolInputGuardrailResults =
|
|
1062
1084
|
stateJson.toolInputGuardrailResults;
|
|
@@ -1079,7 +1101,7 @@ async function buildRunStateFromJson(initialAgent, stateJson, options = {}) {
|
|
|
1079
1101
|
if (stateJson.currentStep?.type === 'next_step_handoff') {
|
|
1080
1102
|
state._currentStep = {
|
|
1081
1103
|
type: 'next_step_handoff',
|
|
1082
|
-
newAgent:
|
|
1104
|
+
newAgent: resolveSerializedAgent(stateJson.currentStep.newAgent, agentMap),
|
|
1083
1105
|
};
|
|
1084
1106
|
}
|
|
1085
1107
|
else if (stateJson.currentStep?.type === 'next_step_interruption') {
|
|
@@ -1100,7 +1122,9 @@ export async function rehydrateProcessedResponseTools(initialAgent, state, execu
|
|
|
1100
1122
|
if (!state._lastProcessedResponse) {
|
|
1101
1123
|
return;
|
|
1102
1124
|
}
|
|
1103
|
-
|
|
1125
|
+
const agentIdentity = buildAgentIdentityMap(initialAgent);
|
|
1126
|
+
const serializedProcessedResponse = serializeProcessedResponse(state._lastProcessedResponse, agentIdentity.byAgent);
|
|
1127
|
+
state._lastProcessedResponse = await deserializeProcessedResponse(agentIdentity.byIdentity, state, serializedProcessedResponse, {
|
|
1104
1128
|
executionTools,
|
|
1105
1129
|
allowSerializedExecutionToolPlaceholder: false,
|
|
1106
1130
|
});
|
|
@@ -1140,6 +1164,249 @@ export function buildAgentMap(initialAgent) {
|
|
|
1140
1164
|
}
|
|
1141
1165
|
return map;
|
|
1142
1166
|
}
|
|
1167
|
+
/**
|
|
1168
|
+
* @internal
|
|
1169
|
+
*/
|
|
1170
|
+
export function buildAgentIdentityMap(initialAgent) {
|
|
1171
|
+
const agents = collectAgentGraph(initialAgent);
|
|
1172
|
+
const groups = new Map();
|
|
1173
|
+
const literalNames = new Set();
|
|
1174
|
+
for (const entry of agents) {
|
|
1175
|
+
literalNames.add(entry.agent.name);
|
|
1176
|
+
const group = groups.get(entry.agent.name) ?? [];
|
|
1177
|
+
group.push(entry);
|
|
1178
|
+
groups.set(entry.agent.name, group);
|
|
1179
|
+
}
|
|
1180
|
+
const byIdentity = new Map();
|
|
1181
|
+
const byAgent = new Map();
|
|
1182
|
+
const usedIdentities = new Set();
|
|
1183
|
+
for (const [agentName, group] of groups) {
|
|
1184
|
+
const sortedGroup = group.length === 1
|
|
1185
|
+
? group
|
|
1186
|
+
: [...group].sort((left, right) => {
|
|
1187
|
+
if (left.agent === initialAgent) {
|
|
1188
|
+
return -1;
|
|
1189
|
+
}
|
|
1190
|
+
if (right.agent === initialAgent) {
|
|
1191
|
+
return 1;
|
|
1192
|
+
}
|
|
1193
|
+
const leftSignature = getAgentIdentitySignature(left.agent);
|
|
1194
|
+
const rightSignature = getAgentIdentitySignature(right.agent);
|
|
1195
|
+
if (leftSignature !== rightSignature) {
|
|
1196
|
+
return leftSignature < rightSignature ? -1 : 1;
|
|
1197
|
+
}
|
|
1198
|
+
return left.index - right.index;
|
|
1199
|
+
});
|
|
1200
|
+
let nextSuffix = 0;
|
|
1201
|
+
for (const { agent } of sortedGroup) {
|
|
1202
|
+
let identity;
|
|
1203
|
+
do {
|
|
1204
|
+
identity =
|
|
1205
|
+
nextSuffix === 0 ? agentName : `${agentName}#${nextSuffix + 1}`;
|
|
1206
|
+
nextSuffix += 1;
|
|
1207
|
+
} while (usedIdentities.has(identity) ||
|
|
1208
|
+
(identity !== agent.name && literalNames.has(identity)));
|
|
1209
|
+
usedIdentities.add(identity);
|
|
1210
|
+
byIdentity.set(identity, agent);
|
|
1211
|
+
byAgent.set(agent, identity);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
return { byIdentity, byAgent };
|
|
1215
|
+
}
|
|
1216
|
+
function collectAgentGraph(initialAgent) {
|
|
1217
|
+
const agents = [];
|
|
1218
|
+
const visitedAgents = new Set();
|
|
1219
|
+
const queue = [initialAgent];
|
|
1220
|
+
while (queue.length > 0) {
|
|
1221
|
+
const currentAgent = queue.shift();
|
|
1222
|
+
if (visitedAgents.has(currentAgent)) {
|
|
1223
|
+
continue;
|
|
1224
|
+
}
|
|
1225
|
+
visitedAgents.add(currentAgent);
|
|
1226
|
+
agents.push({ agent: currentAgent, index: agents.length });
|
|
1227
|
+
for (const handoff of currentAgent.handoffs) {
|
|
1228
|
+
if (handoff instanceof Agent) {
|
|
1229
|
+
queue.push(handoff);
|
|
1230
|
+
}
|
|
1231
|
+
else if (handoff.agent) {
|
|
1232
|
+
queue.push(handoff.agent);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
for (const tool of currentAgent.tools) {
|
|
1236
|
+
const sourceAgent = getAgentToolSourceAgent(tool);
|
|
1237
|
+
if (sourceAgent) {
|
|
1238
|
+
queue.push(sourceAgent);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
return agents;
|
|
1243
|
+
}
|
|
1244
|
+
function getAgentIdentitySignature(agent) {
|
|
1245
|
+
const sandboxAgent = agent;
|
|
1246
|
+
const signature = {
|
|
1247
|
+
type: agent.constructor?.name,
|
|
1248
|
+
name: agent.name,
|
|
1249
|
+
handoffDescription: agent.handoffDescription,
|
|
1250
|
+
instructions: summarizeIdentityValue(agent.instructions),
|
|
1251
|
+
prompt: summarizeIdentityValue(agent.prompt),
|
|
1252
|
+
model: summarizeIdentityValue(agent.model),
|
|
1253
|
+
modelSettings: summarizeIdentityValue(agent.modelSettings),
|
|
1254
|
+
tools: agent.tools.map(summarizeToolIdentity),
|
|
1255
|
+
handoffs: agent.handoffs.map((entry) => entry instanceof Agent
|
|
1256
|
+
? { type: 'agent', name: entry.name }
|
|
1257
|
+
: {
|
|
1258
|
+
type: 'handoff',
|
|
1259
|
+
toolName: entry.toolName,
|
|
1260
|
+
agentName: entry.agentName,
|
|
1261
|
+
targetName: entry.agent?.name,
|
|
1262
|
+
}),
|
|
1263
|
+
mcpServers: agent.mcpServers.map(summarizeIdentityValue),
|
|
1264
|
+
inputGuardrails: agent.inputGuardrails.map(summarizeIdentityValue),
|
|
1265
|
+
outputGuardrails: agent.outputGuardrails.map(summarizeIdentityValue),
|
|
1266
|
+
outputType: summarizeIdentityValue(agent.outputType),
|
|
1267
|
+
toolUseBehavior: summarizeIdentityValue(agent.toolUseBehavior),
|
|
1268
|
+
resetToolChoice: agent.resetToolChoice,
|
|
1269
|
+
defaultManifest: summarizeIdentityValue(sandboxAgent.defaultManifest),
|
|
1270
|
+
baseInstructions: summarizeIdentityValue(sandboxAgent.baseInstructions),
|
|
1271
|
+
capabilities: sandboxAgent.capabilities?.map(summarizeIdentityValue),
|
|
1272
|
+
runAs: summarizeIdentityValue(sandboxAgent.runAs),
|
|
1273
|
+
};
|
|
1274
|
+
return stableStringify(signature);
|
|
1275
|
+
}
|
|
1276
|
+
function summarizeToolIdentity(tool) {
|
|
1277
|
+
return {
|
|
1278
|
+
type: tool.type,
|
|
1279
|
+
name: tool.name,
|
|
1280
|
+
namespace: tool.namespace,
|
|
1281
|
+
strict: tool.strict,
|
|
1282
|
+
parameters: summarizeIdentityValue(tool.parameters),
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
function summarizeIdentityValue(value) {
|
|
1286
|
+
return normalizeForIdentity(value, new WeakSet(), 0);
|
|
1287
|
+
}
|
|
1288
|
+
function normalizeForIdentity(value, seen, depth) {
|
|
1289
|
+
if (value === null || typeof value === 'undefined') {
|
|
1290
|
+
return value;
|
|
1291
|
+
}
|
|
1292
|
+
if (typeof value === 'string' ||
|
|
1293
|
+
typeof value === 'number' ||
|
|
1294
|
+
typeof value === 'boolean') {
|
|
1295
|
+
return value;
|
|
1296
|
+
}
|
|
1297
|
+
if (typeof value === 'function') {
|
|
1298
|
+
return `[function:${value.name || 'anonymous'}]`;
|
|
1299
|
+
}
|
|
1300
|
+
if (typeof value !== 'object') {
|
|
1301
|
+
return String(value);
|
|
1302
|
+
}
|
|
1303
|
+
if (seen.has(value)) {
|
|
1304
|
+
return '[circular]';
|
|
1305
|
+
}
|
|
1306
|
+
if (depth >= 4) {
|
|
1307
|
+
return `[${value.constructor?.name ?? 'Object'}]`;
|
|
1308
|
+
}
|
|
1309
|
+
seen.add(value);
|
|
1310
|
+
if (Array.isArray(value)) {
|
|
1311
|
+
return value.map((item) => normalizeForIdentity(item, seen, depth + 1));
|
|
1312
|
+
}
|
|
1313
|
+
if (value instanceof Map) {
|
|
1314
|
+
return [...value.entries()]
|
|
1315
|
+
.map(([key, entryValue]) => [
|
|
1316
|
+
normalizeForIdentity(key, seen, depth + 1),
|
|
1317
|
+
normalizeForIdentity(entryValue, seen, depth + 1),
|
|
1318
|
+
])
|
|
1319
|
+
.sort((left, right) => stableStringify(left).localeCompare(stableStringify(right)));
|
|
1320
|
+
}
|
|
1321
|
+
if (value instanceof Set) {
|
|
1322
|
+
return [...value.values()]
|
|
1323
|
+
.map((entry) => normalizeForIdentity(entry, seen, depth + 1))
|
|
1324
|
+
.sort((left, right) => stableStringify(left).localeCompare(stableStringify(right)));
|
|
1325
|
+
}
|
|
1326
|
+
const record = value;
|
|
1327
|
+
const normalized = {
|
|
1328
|
+
constructor: value.constructor?.name,
|
|
1329
|
+
};
|
|
1330
|
+
for (const key of Object.keys(record).sort()) {
|
|
1331
|
+
normalized[key] = normalizeForIdentity(record[key], seen, depth + 1);
|
|
1332
|
+
}
|
|
1333
|
+
return normalized;
|
|
1334
|
+
}
|
|
1335
|
+
function stableStringify(value) {
|
|
1336
|
+
return JSON.stringify(value, (_key, currentValue) => {
|
|
1337
|
+
if (!currentValue ||
|
|
1338
|
+
typeof currentValue !== 'object' ||
|
|
1339
|
+
Array.isArray(currentValue)) {
|
|
1340
|
+
return currentValue;
|
|
1341
|
+
}
|
|
1342
|
+
return Object.fromEntries(Object.entries(currentValue).sort(([left], [right]) => left.localeCompare(right)));
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
function serializeAgentReference(agent, agentIdentityKeys) {
|
|
1346
|
+
const identity = agentIdentityKeys.get(agent);
|
|
1347
|
+
if (!identity || identity === agent.name) {
|
|
1348
|
+
return { name: agent.name };
|
|
1349
|
+
}
|
|
1350
|
+
return { name: agent.name, identity };
|
|
1351
|
+
}
|
|
1352
|
+
function resolveSerializedAgent(serializedAgent, agentMap, fallbackAgent) {
|
|
1353
|
+
const identity = serializedAgent.identity ?? serializedAgent.name;
|
|
1354
|
+
const agent = agentMap.get(identity);
|
|
1355
|
+
if (agent) {
|
|
1356
|
+
return agent;
|
|
1357
|
+
}
|
|
1358
|
+
if (!serializedAgent.identity && fallbackAgent) {
|
|
1359
|
+
return fallbackAgent;
|
|
1360
|
+
}
|
|
1361
|
+
if (serializedAgent.identity) {
|
|
1362
|
+
throw new UserError(`Agent identity ${serializedAgent.identity} not found`);
|
|
1363
|
+
}
|
|
1364
|
+
throw new UserError(`Agent ${serializedAgent.name} not found`);
|
|
1365
|
+
}
|
|
1366
|
+
function serializeRunItem(item, agentIdentityKeys) {
|
|
1367
|
+
const serialized = item.toJSON();
|
|
1368
|
+
switch (item.type) {
|
|
1369
|
+
case 'handoff_output_item':
|
|
1370
|
+
serialized.sourceAgent = serializeAgentReference(item.sourceAgent, agentIdentityKeys);
|
|
1371
|
+
serialized.targetAgent = serializeAgentReference(item.targetAgent, agentIdentityKeys);
|
|
1372
|
+
return serialized;
|
|
1373
|
+
default:
|
|
1374
|
+
serialized.agent = serializeAgentReference(item.agent, agentIdentityKeys);
|
|
1375
|
+
return serialized;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
function serializeCurrentStep(currentStep, agentIdentityKeys) {
|
|
1379
|
+
if (!currentStep) {
|
|
1380
|
+
return undefined;
|
|
1381
|
+
}
|
|
1382
|
+
if (currentStep.type === 'next_step_handoff') {
|
|
1383
|
+
return {
|
|
1384
|
+
...currentStep,
|
|
1385
|
+
newAgent: serializeAgentReference(currentStep.newAgent, agentIdentityKeys),
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
if (currentStep.type === 'next_step_interruption') {
|
|
1389
|
+
const interruptions = Array.isArray(currentStep.data?.interruptions)
|
|
1390
|
+
? currentStep.data.interruptions.map((item) => item instanceof RunToolApprovalItem
|
|
1391
|
+
? serializeRunItem(item, agentIdentityKeys)
|
|
1392
|
+
: item)
|
|
1393
|
+
: currentStep.data?.interruptions;
|
|
1394
|
+
return {
|
|
1395
|
+
...currentStep,
|
|
1396
|
+
data: {
|
|
1397
|
+
...currentStep.data,
|
|
1398
|
+
interruptions,
|
|
1399
|
+
},
|
|
1400
|
+
};
|
|
1401
|
+
}
|
|
1402
|
+
return currentStep;
|
|
1403
|
+
}
|
|
1404
|
+
function serializeProcessedResponse(processedResponse, agentIdentityKeys) {
|
|
1405
|
+
return {
|
|
1406
|
+
...processedResponse,
|
|
1407
|
+
newItems: processedResponse.newItems.map((item) => serializeRunItem(item, agentIdentityKeys)),
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1143
1410
|
/**
|
|
1144
1411
|
* @internal
|
|
1145
1412
|
*/
|
|
@@ -1178,23 +1445,23 @@ export function deserializeModelResponse(serializedModelResponse) {
|
|
|
1178
1445
|
export function deserializeItem(serializedItem, agentMap) {
|
|
1179
1446
|
switch (serializedItem.type) {
|
|
1180
1447
|
case 'message_output_item':
|
|
1181
|
-
return new RunMessageOutputItem(serializedItem.rawItem,
|
|
1448
|
+
return new RunMessageOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
|
|
1182
1449
|
case 'tool_search_call_item':
|
|
1183
|
-
return new RunToolSearchCallItem(serializedItem.rawItem,
|
|
1450
|
+
return new RunToolSearchCallItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
|
|
1184
1451
|
case 'tool_search_output_item':
|
|
1185
|
-
return new RunToolSearchOutputItem(serializedItem.rawItem,
|
|
1452
|
+
return new RunToolSearchOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
|
|
1186
1453
|
case 'tool_call_item':
|
|
1187
|
-
return new RunToolCallItem(serializedItem.rawItem,
|
|
1454
|
+
return new RunToolCallItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
|
|
1188
1455
|
case 'tool_call_output_item':
|
|
1189
|
-
return new RunToolCallOutputItem(serializedItem.rawItem,
|
|
1456
|
+
return new RunToolCallOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap), serializedItem.output);
|
|
1190
1457
|
case 'reasoning_item':
|
|
1191
|
-
return new RunReasoningItem(serializedItem.rawItem,
|
|
1458
|
+
return new RunReasoningItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
|
|
1192
1459
|
case 'handoff_call_item':
|
|
1193
|
-
return new RunHandoffCallItem(serializedItem.rawItem,
|
|
1460
|
+
return new RunHandoffCallItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap));
|
|
1194
1461
|
case 'handoff_output_item':
|
|
1195
|
-
return new RunHandoffOutputItem(serializedItem.rawItem,
|
|
1462
|
+
return new RunHandoffOutputItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.sourceAgent, agentMap), resolveSerializedAgent(serializedItem.targetAgent, agentMap));
|
|
1196
1463
|
case 'tool_approval_item':
|
|
1197
|
-
return new RunToolApprovalItem(serializedItem.rawItem,
|
|
1464
|
+
return new RunToolApprovalItem(serializedItem.rawItem, resolveSerializedAgent(serializedItem.agent, agentMap), serializedItem.toolName);
|
|
1198
1465
|
}
|
|
1199
1466
|
}
|
|
1200
1467
|
function deserializeInterruptionItem(serializedItem, agentMap, currentAgent) {
|
|
@@ -1204,7 +1471,7 @@ function deserializeInterruptionItem(serializedItem, agentMap, currentAgent) {
|
|
|
1204
1471
|
const parsed = itemSchema.safeParse(serializedItem);
|
|
1205
1472
|
if (parsed.success) {
|
|
1206
1473
|
if (parsed.data.type === 'tool_approval_item') {
|
|
1207
|
-
const mappedAgent =
|
|
1474
|
+
const mappedAgent = resolveSerializedAgent(parsed.data.agent, agentMap, currentAgent);
|
|
1208
1475
|
return new RunToolApprovalItem(parsed.data.rawItem, mappedAgent, parsed.data.toolName);
|
|
1209
1476
|
}
|
|
1210
1477
|
const item = deserializeItem(parsed.data, agentMap);
|
|
@@ -1228,7 +1495,15 @@ function deserializeInterruptionItem(serializedItem, agentMap, currentAgent) {
|
|
|
1228
1495
|
const agentName = value.agent && typeof value.agent.name === 'string'
|
|
1229
1496
|
? value.agent.name
|
|
1230
1497
|
: undefined;
|
|
1231
|
-
const
|
|
1498
|
+
const agentIdentity = value.agent && typeof value.agent.identity === 'string'
|
|
1499
|
+
? value.agent.identity
|
|
1500
|
+
: undefined;
|
|
1501
|
+
const mappedAgent = agentName || agentIdentity
|
|
1502
|
+
? resolveSerializedAgent({
|
|
1503
|
+
name: agentName ?? currentAgent.name,
|
|
1504
|
+
identity: agentIdentity,
|
|
1505
|
+
}, agentMap, currentAgent)
|
|
1506
|
+
: currentAgent;
|
|
1232
1507
|
const toolName = typeof value.toolName === 'string'
|
|
1233
1508
|
? value.toolName
|
|
1234
1509
|
: typeof rawItem.name === 'string'
|