@linnlabs/linnkit 0.8.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 (83) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/bin/linnkit.cjs +7 -0
  5. package/dist/{agentSpec-EkmviZjy.d.cts → agentSpec-Du4Iye0q.d.cts} +16 -1
  6. package/dist/{agentSpec-EkmviZjy.d.ts → agentSpec-Du4Iye0q.d.ts} +16 -1
  7. package/dist/cli.cjs +234 -91
  8. package/dist/cli.cjs.map +1 -1
  9. package/dist/cli.js +234 -91
  10. package/dist/cli.js.map +1 -1
  11. package/dist/context-manager.cjs +230 -32
  12. package/dist/context-manager.cjs.map +1 -1
  13. package/dist/context-manager.d.cts +52 -15
  14. package/dist/context-manager.d.ts +52 -15
  15. package/dist/context-manager.js +230 -33
  16. package/dist/context-manager.js.map +1 -1
  17. package/dist/{context-trace-HE2qY5Q-.d.cts → context-trace-BHKDS-eq.d.cts} +2 -2
  18. package/dist/{context-trace-DRi5M4lX.d.ts → context-trace-CHbqHmyE.d.ts} +2 -2
  19. package/dist/contracts.cjs +3 -1
  20. package/dist/contracts.cjs.map +1 -1
  21. package/dist/contracts.d.cts +3 -3
  22. package/dist/contracts.d.ts +3 -3
  23. package/dist/contracts.js +3 -1
  24. package/dist/contracts.js.map +1 -1
  25. package/dist/{defaultGraphExecutor-BBswR8wn.d.ts → defaultGraphExecutor-B29_qTHy.d.ts} +16 -15
  26. package/dist/{defaultGraphExecutor-BIjJj7WF.d.cts → defaultGraphExecutor-C2E59v_R.d.cts} +16 -15
  27. package/dist/{index-Cm-JbzTH.d.cts → index-BAaUP9yU.d.cts} +38 -15
  28. package/dist/{index-DRBWi1fy.d.ts → index-BaVpVNi2.d.ts} +38 -15
  29. package/dist/{index-DO4dQgf2.d.cts → index-BnYCS8Zg.d.cts} +2 -2
  30. package/dist/{index-CJeWHopy.d.ts → index-C0DAjsdX.d.ts} +2 -2
  31. package/dist/{index-Dl5PLgAv.d.cts → index-CKQzzZ5Y.d.cts} +2 -2
  32. package/dist/{index-CHqwkvGp.d.ts → index-D0mKxTR5.d.ts} +2 -2
  33. package/dist/index.cjs +327 -110
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +10 -10
  36. package/dist/index.d.ts +10 -10
  37. package/dist/index.js +327 -110
  38. package/dist/index.js.map +1 -1
  39. package/dist/{ports-DnLuKfpE.d.ts → ports-DpPTFhSd.d.ts} +2 -2
  40. package/dist/{ports-DaatKJXp.d.cts → ports-s-tSp3sB.d.cts} +2 -2
  41. package/dist/quickstart.cjs +232 -88
  42. package/dist/quickstart.cjs.map +1 -1
  43. package/dist/quickstart.d.cts +7 -7
  44. package/dist/quickstart.d.ts +7 -7
  45. package/dist/quickstart.js +232 -88
  46. package/dist/quickstart.js.map +1 -1
  47. package/dist/{runAgent-CPj_9e58.d.ts → runAgent-C6F-399C.d.ts} +5 -5
  48. package/dist/{runAgent-HYKlXbVr.d.cts → runAgent-ilEj66Ik.d.cts} +5 -5
  49. package/dist/{runHandle-D3gPsD7B.d.cts → runHandle-BNOqS-Bl.d.cts} +3 -3
  50. package/dist/{runHandle-CyXvzgzk.d.ts → runHandle-BdLXOFqF.d.ts} +3 -3
  51. package/dist/runtime-kernel/events.cjs +1 -0
  52. package/dist/runtime-kernel/events.cjs.map +1 -1
  53. package/dist/runtime-kernel/events.d.cts +4 -4
  54. package/dist/runtime-kernel/events.d.ts +4 -4
  55. package/dist/runtime-kernel/events.js +1 -0
  56. package/dist/runtime-kernel/events.js.map +1 -1
  57. package/dist/runtime-kernel.cjs +318 -103
  58. package/dist/runtime-kernel.cjs.map +1 -1
  59. package/dist/runtime-kernel.d.cts +8 -8
  60. package/dist/runtime-kernel.d.ts +8 -8
  61. package/dist/runtime-kernel.js +315 -104
  62. package/dist/runtime-kernel.js.map +1 -1
  63. package/dist/testkit.cjs +331 -116
  64. package/dist/testkit.cjs.map +1 -1
  65. package/dist/testkit.d.cts +8 -8
  66. package/dist/testkit.d.ts +8 -8
  67. package/dist/testkit.js +331 -116
  68. package/dist/testkit.js.map +1 -1
  69. package/dist/{todo-B1PmDlp3.d.cts → todo-Ca8llpRQ.d.cts} +1 -1
  70. package/dist/{todo-B1PmDlp3.d.ts → todo-Ca8llpRQ.d.ts} +1 -1
  71. package/dist/{toolContracts-CLkQmhTG.d.cts → toolContracts-Bm3EZ1UM.d.cts} +13 -2
  72. package/dist/{toolContracts-Blll0241.d.ts → toolContracts-f8lzZBNa.d.ts} +13 -2
  73. package/docs/integration/README.md +1 -1
  74. package/docs/integration/agent-registration-guide.md +1 -1
  75. package/docs/integration/child-runs.md +4 -1
  76. package/docs/integration/context-engineering.md +30 -15
  77. package/docs/integration/context-fences.md +32 -3
  78. package/docs/integration/llm-provider.md +1 -1
  79. package/docs/integration/persistence.md +1 -0
  80. package/docs/integration/run-supervisor.md +3 -0
  81. package/docs/integration/tool-development-guide.md +7 -5
  82. package/docs/integration/tool-history.md +43 -17
  83. package/package.json +5 -4
@@ -265,6 +265,7 @@ var AgentSpecBudgetPolicy = zod.z.object({
265
265
  });
266
266
  var AgentSpecToolHistoryPolicy = zod.z.object({
267
267
  strategy: zod.z.enum(["per-pair", "per-run", "none"]).optional(),
268
+ retentionMode: zod.z.enum(["drop", "compress"]).optional(),
268
269
  keepLatestToolPairs: zod.z.number().int().nonnegative().optional(),
269
270
  keepLatestRuns: zod.z.number().int().nonnegative().optional(),
270
271
  maxInteractionGroups: zod.z.number().int().nonnegative().optional(),
@@ -1021,6 +1022,17 @@ var logger = new Logger("GraphExecutor");
1021
1022
  function asLocalRecord(local) {
1022
1023
  return local && typeof local === "object" ? { ...local } : {};
1023
1024
  }
1025
+ function readNonEmptyString(value) {
1026
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1027
+ }
1028
+ function readRuntimeConversationId(state) {
1029
+ const local = state?.local && typeof state.local === "object" ? state.local : void 0;
1030
+ return readNonEmptyString(local?.conversationId);
1031
+ }
1032
+ function readRuntimeTurnId(state) {
1033
+ const local = state?.local && typeof state.local === "object" ? state.local : void 0;
1034
+ return readNonEmptyString(local?.turnId);
1035
+ }
1024
1036
  var GraphExecutor = class {
1025
1037
  constructor(checkpointer, config = {}) {
1026
1038
  this.checkpointer = checkpointer;
@@ -1038,8 +1050,8 @@ var GraphExecutor = class {
1038
1050
  registerNode(node) {
1039
1051
  this.nodes.set(node.id, node);
1040
1052
  }
1041
- async peekCheckpoint(conversationId) {
1042
- return await this.checkpointer.load(conversationId);
1053
+ async peekCheckpoint(checkpointKey) {
1054
+ return await this.checkpointer.load(checkpointKey);
1043
1055
  }
1044
1056
  sanitize(state) {
1045
1057
  const local = asLocalRecord(state.local);
@@ -1051,8 +1063,8 @@ var GraphExecutor = class {
1051
1063
  local
1052
1064
  };
1053
1065
  }
1054
- async prime(conversationId, local, nodeId = "user") {
1055
- this.ephemeralLocals.set(conversationId, { ...local || {} });
1066
+ async prime(checkpointKey, local, nodeId = "user") {
1067
+ this.ephemeralLocals.set(checkpointKey, { ...local || {} });
1056
1068
  const localSansMemory = { ...local || {} };
1057
1069
  if ("memory" in localSansMemory) delete localSansMemory.memory;
1058
1070
  const state = {
@@ -1060,10 +1072,10 @@ var GraphExecutor = class {
1060
1072
  schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
1061
1073
  local: localSansMemory
1062
1074
  };
1063
- await this.checkpointer.save(conversationId, state);
1075
+ await this.checkpointer.save(checkpointKey, state);
1064
1076
  }
1065
- async setNode(conversationId, nodeId, localPatch) {
1066
- const current = await this.checkpointer.load(conversationId) || {
1077
+ async setNode(checkpointKey, nodeId, localPatch) {
1078
+ const current = await this.checkpointer.load(checkpointKey) || {
1067
1079
  schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
1068
1080
  local: {}
1069
1081
  };
@@ -1074,19 +1086,46 @@ var GraphExecutor = class {
1074
1086
  schemaVersion: current.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
1075
1087
  local: mergedLocal
1076
1088
  };
1077
- await this.checkpointer.save(conversationId, next);
1089
+ await this.checkpointer.save(checkpointKey, next);
1078
1090
  }
1079
- async runUntilYield(conversationId) {
1091
+ async runUntilYield(checkpointKey) {
1080
1092
  const runId = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
1081
1093
  let lifecyclePhase = "completed";
1094
+ let initialState = null;
1095
+ try {
1096
+ initialState = await this.loadInitialState(checkpointKey);
1097
+ } catch (err) {
1098
+ lifecyclePhase = "failed";
1099
+ this.telemetryPort.emit({
1100
+ kind: "run_lifecycle",
1101
+ runId,
1102
+ phase: "spawned",
1103
+ scope: {}
1104
+ });
1105
+ this.telemetryPort.emit({
1106
+ kind: "run_lifecycle",
1107
+ runId,
1108
+ phase: lifecyclePhase,
1109
+ scope: {}
1110
+ });
1111
+ throw err;
1112
+ }
1113
+ let lifecycleConversationId = readRuntimeConversationId(initialState);
1114
+ let lifecycleTurnId = readRuntimeTurnId(initialState);
1082
1115
  this.telemetryPort.emit({
1083
1116
  kind: "run_lifecycle",
1084
1117
  runId,
1085
1118
  phase: "spawned",
1086
- scope: { conversationId: conversationId || void 0 }
1119
+ scope: {
1120
+ conversationId: lifecycleConversationId,
1121
+ turnId: lifecycleTurnId
1122
+ }
1087
1123
  });
1088
1124
  try {
1089
- return await this.runUntilYieldInternal(conversationId);
1125
+ const result = await this.runUntilYieldInternal(checkpointKey, initialState);
1126
+ lifecycleConversationId = readRuntimeConversationId(result.checkpoint);
1127
+ lifecycleTurnId = readRuntimeTurnId(result.checkpoint);
1128
+ return result;
1090
1129
  } catch (err) {
1091
1130
  lifecyclePhase = err?.name === "AbortError" ? "cancelled" : "failed";
1092
1131
  throw err;
@@ -1095,17 +1134,23 @@ var GraphExecutor = class {
1095
1134
  kind: "run_lifecycle",
1096
1135
  runId,
1097
1136
  phase: lifecyclePhase,
1098
- scope: { conversationId: conversationId || void 0 }
1137
+ scope: {
1138
+ conversationId: lifecycleConversationId,
1139
+ turnId: lifecycleTurnId
1140
+ }
1099
1141
  });
1100
1142
  }
1101
1143
  }
1102
- async runUntilYieldInternal(conversationId) {
1103
- let state = await this.checkpointer.load(conversationId) || {
1144
+ async loadInitialState(checkpointKey) {
1145
+ return await this.checkpointer.load(checkpointKey) || {
1104
1146
  nodeId: "user",
1105
1147
  schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
1106
1148
  local: {}
1107
1149
  };
1108
- const ephemeral = this.ephemeralLocals.get(conversationId) || {};
1150
+ }
1151
+ async runUntilYieldInternal(checkpointKey, initialState) {
1152
+ let state = initialState;
1153
+ const ephemeral = this.ephemeralLocals.get(checkpointKey) || {};
1109
1154
  state = {
1110
1155
  ...state,
1111
1156
  schemaVersion: state.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
@@ -1134,7 +1179,7 @@ var GraphExecutor = class {
1134
1179
  const signalRaw = state.local?.signal;
1135
1180
  if (isAbortSignal2(signalRaw) && signalRaw.aborted) {
1136
1181
  logger.warn("[GraphExecutor] \u6536\u5230 AbortSignal\uFF0C\u7ACB\u5373\u505C\u6B62\u63A8\u7406\u5FAA\u73AF");
1137
- this.ephemeralLocals.delete(conversationId);
1182
+ this.ephemeralLocals.delete(checkpointKey);
1138
1183
  throwAbortError();
1139
1184
  }
1140
1185
  const isLastStep = cycleStepCount >= this.config.maxSteps;
@@ -1182,8 +1227,8 @@ var GraphExecutor = class {
1182
1227
  checkpointCount
1183
1228
  });
1184
1229
  const cp2 = this.sanitize(state);
1185
- await this.checkpointer.save(conversationId, cp2);
1186
- this.ephemeralLocals.delete(conversationId);
1230
+ await this.checkpointer.save(checkpointKey, cp2);
1231
+ this.ephemeralLocals.delete(checkpointKey);
1187
1232
  return { events: allEvents, checkpoint: cp2, stepCount };
1188
1233
  }
1189
1234
  logger.info("[GraphExecutor] \u8282\u70B9\u5207\u6362", {
@@ -1194,18 +1239,18 @@ var GraphExecutor = class {
1194
1239
  });
1195
1240
  const nodeRunStartedAt = Date.now();
1196
1241
  const nodeIdForTelemetry = state.nodeId;
1242
+ const conversationIdForTelemetry = readRuntimeConversationId(state);
1197
1243
  let result;
1198
1244
  try {
1199
1245
  result = await node.run(state);
1200
1246
  } finally {
1201
- const turnIdForTelemetry = typeof state.local?.turnId === "string" ? state.local.turnId : void 0;
1202
1247
  this.telemetryPort.emit({
1203
1248
  kind: "graph_node",
1204
1249
  nodeId: nodeIdForTelemetry,
1205
1250
  durationMs: Date.now() - nodeRunStartedAt,
1206
1251
  scope: {
1207
- conversationId: conversationId || void 0,
1208
- turnId: turnIdForTelemetry
1252
+ conversationId: conversationIdForTelemetry,
1253
+ turnId: readRuntimeTurnId(state)
1209
1254
  }
1210
1255
  });
1211
1256
  }
@@ -1244,7 +1289,7 @@ var GraphExecutor = class {
1244
1289
  });
1245
1290
  state = { ...state, nodeId: nextNodeId };
1246
1291
  const cp2 = this.sanitize(state);
1247
- await this.checkpointer.save(conversationId, cp2);
1292
+ await this.checkpointer.save(checkpointKey, cp2);
1248
1293
  continue;
1249
1294
  }
1250
1295
  if (result.kind === "yield") {
@@ -1255,7 +1300,7 @@ var GraphExecutor = class {
1255
1300
  checkpointCount
1256
1301
  });
1257
1302
  const cp2 = this.sanitize(state);
1258
- await this.checkpointer.save(conversationId, cp2);
1303
+ await this.checkpointer.save(checkpointKey, cp2);
1259
1304
  return { events: allEvents, checkpoint: cp2, stepCount };
1260
1305
  }
1261
1306
  if (result.kind === "pause") {
@@ -1266,7 +1311,7 @@ var GraphExecutor = class {
1266
1311
  checkpointCount
1267
1312
  });
1268
1313
  const cp2 = this.sanitize(state);
1269
- await this.checkpointer.save(conversationId, cp2);
1314
+ await this.checkpointer.save(checkpointKey, cp2);
1270
1315
  return { events: allEvents, checkpoint: cp2, stepCount };
1271
1316
  }
1272
1317
  }
@@ -1277,8 +1322,8 @@ var GraphExecutor = class {
1277
1322
  checkpointCount
1278
1323
  });
1279
1324
  const cp = this.sanitize(state);
1280
- await this.checkpointer.save(conversationId, cp);
1281
- this.ephemeralLocals.delete(conversationId);
1325
+ await this.checkpointer.save(checkpointKey, cp);
1326
+ this.ephemeralLocals.delete(checkpointKey);
1282
1327
  return { events: allEvents, checkpoint: cp, stepCount };
1283
1328
  }
1284
1329
  };
@@ -1475,15 +1520,15 @@ function splitConcatenatedJsonObjects(input) {
1475
1520
  }
1476
1521
 
1477
1522
  // src/runtime-kernel/graph-engine/tick-pipeline/helpers.ts
1478
- function readNonEmptyString(value) {
1523
+ function readNonEmptyString2(value) {
1479
1524
  if (typeof value !== "string") return void 0;
1480
1525
  const trimmed = value.trim();
1481
1526
  return trimmed.length > 0 ? trimmed : void 0;
1482
1527
  }
1483
1528
  function resolveConversationIdForRuntimeEvents(toolContext) {
1484
- const fromCamel = readNonEmptyString(toolContext?.conversationId);
1529
+ const fromCamel = readNonEmptyString2(toolContext?.conversationId);
1485
1530
  if (fromCamel) return fromCamel;
1486
- const fromSnake = toolContext ? readNonEmptyString(toolContext["conversation_id"]) : void 0;
1531
+ const fromSnake = toolContext ? readNonEmptyString2(toolContext["conversation_id"]) : void 0;
1487
1532
  if (fromSnake) return fromSnake;
1488
1533
  return generateMessageId();
1489
1534
  }
@@ -1842,7 +1887,7 @@ var runModelLockMiddleware = async (ctx, stage, next) => {
1842
1887
  if (stage.id !== "execute_llm") {
1843
1888
  return;
1844
1889
  }
1845
- const normalized = readNonEmptyString(ctx.cloudQuotaFallbackAppliedModelId);
1890
+ const normalized = readNonEmptyString2(ctx.cloudQuotaFallbackAppliedModelId);
1846
1891
  if (!normalized) {
1847
1892
  return;
1848
1893
  }
@@ -2443,7 +2488,7 @@ function createExecuteLlmStage(dependencies) {
2443
2488
  streamEventHandler,
2444
2489
  ctx.signal,
2445
2490
  (fallbackModelId) => {
2446
- ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString(fallbackModelId);
2491
+ ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString2(fallbackModelId);
2447
2492
  },
2448
2493
  (info) => {
2449
2494
  ctx.modelFallbackAudit = info;
@@ -2487,7 +2532,7 @@ function createPrepareCallStage(dependencies) {
2487
2532
  return {
2488
2533
  id: "prepare_call",
2489
2534
  async run(ctx) {
2490
- const lockedRunModelId = readNonEmptyString(ctx.executorLocal?.runLockedModelId);
2535
+ const lockedRunModelId = readNonEmptyString2(ctx.executorLocal?.runLockedModelId);
2491
2536
  const requestedModelId = lockedRunModelId ?? ctx.request.model_id;
2492
2537
  ctx.modelId = dependencies.modelResolver.resolveModelId(requestedModelId);
2493
2538
  await emitAuditEnvelope(ctx.audit, {
@@ -2559,7 +2604,7 @@ var GraphAgentExecutor = class {
2559
2604
  this.llmCaller = dependencies.llmCaller;
2560
2605
  this.toolRuntime = dependencies.toolRuntime;
2561
2606
  this.contextBuilder = dependencies.contextBuilder;
2562
- this.cloudQuotaFallbackModelId = readNonEmptyString(dependencies.cloudQuotaFallbackModelId);
2607
+ this.cloudQuotaFallbackModelId = readNonEmptyString2(dependencies.cloudQuotaFallbackModelId);
2563
2608
  this.modelCatalog = dependencies.modelCatalog ?? createEmptyModelCatalog();
2564
2609
  this.modelResolver = dependencies.modelResolver ?? new ModelResolver({
2565
2610
  modelCatalog: this.modelCatalog
@@ -2607,7 +2652,7 @@ var GraphAgentExecutor = class {
2607
2652
  llmMessages: [],
2608
2653
  mode: input.request.mode === "chat" ? "chat" : "agent",
2609
2654
  conversationId: resolveConversationIdForRuntimeEvents(input.toolContext),
2610
- turnId: readNonEmptyString(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
2655
+ turnId: readNonEmptyString2(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
2611
2656
  telemetry: this.telemetryPort,
2612
2657
  audit: this.auditPort
2613
2658
  };
@@ -2657,18 +2702,18 @@ function isSummarizationCallbacks(value) {
2657
2702
  function isGraphSseSink(value) {
2658
2703
  return typeof value === "function";
2659
2704
  }
2660
- function readNonEmptyString2(value) {
2705
+ function readNonEmptyString3(value) {
2661
2706
  if (typeof value !== "string") return void 0;
2662
2707
  const trimmed = value.trim();
2663
2708
  return trimmed.length > 0 ? trimmed : void 0;
2664
2709
  }
2665
2710
  function readGraphAgentLocal(local) {
2666
2711
  const source = local ?? {};
2667
- const answerId = readNonEmptyString2(source.answerId);
2712
+ const answerId = readNonEmptyString3(source.answerId);
2668
2713
  const chunkSeq = Number.isInteger(source.chunkSeq) ? Number(source.chunkSeq) : 0;
2669
2714
  return {
2670
- conversationId: readNonEmptyString2(source.conversationId) ?? "",
2671
- turnId: readNonEmptyString2(source.turnId),
2715
+ conversationId: readNonEmptyString3(source.conversationId) ?? "",
2716
+ turnId: readNonEmptyString3(source.turnId),
2672
2717
  request: isAgentInvocationRequest(source.request) ? source.request : void 0,
2673
2718
  toolContext: isToolExecutionContext(source.toolContext) ? source.toolContext : void 0,
2674
2719
  history: isRuntimeEventArray(source.history) ? source.history : [],
@@ -3433,7 +3478,7 @@ var LlmNode = class {
3433
3478
  function isRecord8(value) {
3434
3479
  return typeof value === "object" && value !== null && !Array.isArray(value);
3435
3480
  }
3436
- function readNonEmptyString3(value) {
3481
+ function readNonEmptyString4(value) {
3437
3482
  if (typeof value !== "string") {
3438
3483
  return void 0;
3439
3484
  }
@@ -3455,7 +3500,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
3455
3500
  return void 0;
3456
3501
  }
3457
3502
  if (toolName === "write_report") {
3458
- const report = readNonEmptyString3(data.report);
3503
+ const report = readNonEmptyString4(data.report);
3459
3504
  if (!report) {
3460
3505
  throw new Error("[write_report] \u5DE5\u5177\u8F93\u51FA\u7F3A\u5C11 data.report\uFF08\u5FC5\u987B\u63D0\u4F9B\u5B8C\u6574\u62A5\u544A\u6B63\u6587\uFF09");
3461
3506
  }
@@ -3465,7 +3510,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
3465
3510
  if (data.success !== true) {
3466
3511
  return void 0;
3467
3512
  }
3468
- const finalAnswer = readNonEmptyString3(data.final_answer);
3513
+ const finalAnswer = readNonEmptyString4(data.final_answer);
3469
3514
  if (!finalAnswer) {
3470
3515
  throw new Error("[research_run_writer] \u5DE5\u5177\u8F93\u51FA\u7F3A\u5C11 data.final_answer\uFF08success=true \u65F6\u5FC5\u987B\u63D0\u4F9B\u6700\u7EC8\u62A5\u544A\u6B63\u6587\uFF09");
3471
3516
  }
@@ -4010,6 +4055,31 @@ function ensureToolContextRuntimeCapability(params) {
4010
4055
  function getToolContextRuntimeBinding(context) {
4011
4056
  return readBinding(context);
4012
4057
  }
4058
+ function copyToolContextRuntimeCapability(source, target) {
4059
+ const sourceBinding = readBinding(source);
4060
+ if (!sourceBinding) {
4061
+ return void 0;
4062
+ }
4063
+ const existingTargetBinding = readBinding(target);
4064
+ if (existingTargetBinding) {
4065
+ exposeCompatibilitySurface(target, existingTargetBinding);
4066
+ return existingTargetBinding;
4067
+ }
4068
+ const targetBinding = createRuntimeBinding({
4069
+ context: target,
4070
+ persistedHistory: () => sourceBinding.getPersistedHistoryEvents(),
4071
+ workingHistory: () => sourceBinding.getWorkingHistoryEvents(),
4072
+ executionMeta: sourceBinding.readExecutionMeta()
4073
+ });
4074
+ Object.defineProperty(target, TOOL_CONTEXT_RUNTIME_BINDING_KEY, {
4075
+ value: targetBinding,
4076
+ enumerable: false,
4077
+ configurable: true,
4078
+ writable: false
4079
+ });
4080
+ exposeCompatibilitySurface(target, targetBinding);
4081
+ return targetBinding;
4082
+ }
4013
4083
  function readToolContextWorkingHistory(context) {
4014
4084
  if (context.conversationView) {
4015
4085
  return context.conversationView.getWorkingHistoryEvents();
@@ -4423,6 +4493,22 @@ var ToolNode = class {
4423
4493
  });
4424
4494
  }
4425
4495
  async run(state) {
4496
+ const events = [];
4497
+ while (true) {
4498
+ const result = await this.runNextPendingToolCall(state);
4499
+ if (Array.isArray(result.events) && result.events.length > 0) {
4500
+ events.push(...result.events);
4501
+ }
4502
+ if (result.kind === "route" && result.nextNodeId === "tool") {
4503
+ continue;
4504
+ }
4505
+ return {
4506
+ ...result,
4507
+ events
4508
+ };
4509
+ }
4510
+ }
4511
+ async runNextPendingToolCall(state) {
4426
4512
  const calls = state.local?.pendingToolCalls ?? [];
4427
4513
  const signalRaw = state.local?.signal;
4428
4514
  if (isAbortSignal(signalRaw) && signalRaw.aborted) {
@@ -4630,18 +4716,25 @@ var ToolNode = class {
4630
4716
  rawArguments: context.call.function?.arguments,
4631
4717
  parsedArguments: context.toolArgs
4632
4718
  });
4719
+ const remainingCalls = context.calls.slice(1);
4633
4720
  context.state.local = buildErrorLocalState({
4634
4721
  local: context.local,
4635
- remainingCalls: context.calls.slice(1),
4722
+ remainingCalls,
4636
4723
  conversationId: context.conversationId,
4637
4724
  turnId: context.turnId,
4638
4725
  runtimeEvents: context.bridge.getRuntimeEvents(),
4639
4726
  nextProtocolErrorCount: fuse.nextCount
4640
4727
  });
4641
- if (fuse.shouldFuse) {
4728
+ if (fuse.shouldFuse && remainingCalls.length === 0) {
4642
4729
  throw createToolProtocolFuseError(fuse.nextCount, context.exec.error);
4643
4730
  }
4644
- return { kind: "route", nextNodeId: "llm", events: context.bridge.getRuntimeEvents() };
4731
+ return {
4732
+ kind: "route",
4733
+ // 同一个 assistant.tool_calls batch 必须为每个 call 产出 tool_output。
4734
+ // 出错时也继续消费剩余 call,ToolNode.run 会在本节点内 drain 完 batch 再回 LLM。
4735
+ nextNodeId: remainingCalls.length > 0 ? "tool" : "llm",
4736
+ events: context.bridge.getRuntimeEvents()
4737
+ };
4645
4738
  }
4646
4739
  };
4647
4740
 
@@ -4838,12 +4931,12 @@ function asRecord(value) {
4838
4931
  }
4839
4932
  return value;
4840
4933
  }
4841
- function summarizeCheckpoint(conversationId, state, savedAt) {
4934
+ function summarizeCheckpoint(checkpointKey, state, savedAt) {
4842
4935
  const local = asRecord(state.local);
4843
4936
  const executorLocal = asRecord(local?.executorLocal);
4844
4937
  const pendingToolCalls = local?.pendingToolCalls;
4845
4938
  return {
4846
- conversationId,
4939
+ checkpointKey,
4847
4940
  schemaVersion: state.schemaVersion ?? 1,
4848
4941
  savedAt,
4849
4942
  currentNode: state.nodeId,
@@ -4862,25 +4955,25 @@ var MemoryCheckpointer = class {
4862
4955
  local: state.local && typeof state.local === "object" && !Array.isArray(state.local) ? { ...state.local } : state.local
4863
4956
  };
4864
4957
  }
4865
- async load(conversationId) {
4866
- const entry = this.store.get(conversationId);
4958
+ async load(checkpointKey) {
4959
+ const entry = this.store.get(checkpointKey);
4867
4960
  return entry ? this.cloneState(entry.state) : null;
4868
4961
  }
4869
- async save(conversationId, state) {
4870
- this.store.set(conversationId, {
4962
+ async save(checkpointKey, state) {
4963
+ this.store.set(checkpointKey, {
4871
4964
  state: this.cloneState(state),
4872
4965
  savedAt: Date.now()
4873
4966
  });
4874
4967
  }
4875
- async clear(conversationId) {
4876
- this.store.delete(conversationId);
4968
+ async clear(checkpointKey) {
4969
+ this.store.delete(checkpointKey);
4877
4970
  }
4878
- async peekMeta(conversationId) {
4879
- const entry = this.store.get(conversationId);
4880
- return entry ? summarizeCheckpoint(conversationId, entry.state, entry.savedAt) : null;
4971
+ async peekMeta(checkpointKey) {
4972
+ const entry = this.store.get(checkpointKey);
4973
+ return entry ? summarizeCheckpoint(checkpointKey, entry.state, entry.savedAt) : null;
4881
4974
  }
4882
4975
  async list(filter = {}) {
4883
- const summaries = Array.from(this.store.entries()).map(([conversationId, entry]) => summarizeCheckpoint(conversationId, entry.state, entry.savedAt)).filter((summary) => filter.savedAfter === void 0 ? true : summary.savedAt > filter.savedAfter).sort((left, right) => right.savedAt - left.savedAt);
4976
+ const summaries = Array.from(this.store.entries()).map(([checkpointKey, entry]) => summarizeCheckpoint(checkpointKey, entry.state, entry.savedAt)).filter((summary) => filter.savedAfter === void 0 ? true : summary.savedAt > filter.savedAfter).sort((left, right) => right.savedAt - left.savedAt);
4884
4977
  if (filter.limit === void 0) {
4885
4978
  return summaries;
4886
4979
  }
@@ -4952,6 +5045,7 @@ __export(tools_exports, {
4952
5045
  CommonParameterTypes: () => CommonParameterTypes,
4953
5046
  ContextCheckpointTool: () => ContextCheckpointTool,
4954
5047
  computeToolIdempotencyKey: () => computeToolIdempotencyKey,
5048
+ copyToolContextRuntimeCapability: () => copyToolContextRuntimeCapability,
4955
5049
  createContextCheckpointTool: () => createContextCheckpointTool,
4956
5050
  ensureToolContextRuntimeCapability: () => ensureToolContextRuntimeCapability,
4957
5051
  findCachedToolOutputByIdempotencyKey: () => findCachedToolOutputByIdempotencyKey,
@@ -5145,7 +5239,7 @@ function createContextCheckpointTool(options) {
5145
5239
  function isRecord15(value) {
5146
5240
  return !!value && typeof value === "object" && !Array.isArray(value);
5147
5241
  }
5148
- function readNonEmptyString4(value) {
5242
+ function readNonEmptyString5(value) {
5149
5243
  if (typeof value !== "string") {
5150
5244
  return void 0;
5151
5245
  }
@@ -5165,13 +5259,13 @@ function readToolContextUserQuery(context) {
5165
5259
  if (!context) {
5166
5260
  return void 0;
5167
5261
  }
5168
- return readNonEmptyString4(context["user_query"]);
5262
+ return readNonEmptyString5(context["user_query"]);
5169
5263
  }
5170
5264
  function readToolContextModelId(context) {
5171
5265
  if (!context) {
5172
5266
  return void 0;
5173
5267
  }
5174
- return readNonEmptyString4(context["modelId"]);
5268
+ return readNonEmptyString5(context["modelId"]);
5175
5269
  }
5176
5270
  function readToolContextRunContext(context) {
5177
5271
  if (!context) {
@@ -5378,18 +5472,18 @@ function createClassification(category, reason, suggestedDelay, extras) {
5378
5472
  }
5379
5473
  var ErrorClassifier = class {
5380
5474
  static classify(error, context) {
5381
- const isRecord23 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
5475
+ const isRecord24 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
5382
5476
  const baseMsg = (error.message || "").toLowerCase();
5383
5477
  const causeMsg = (() => {
5384
5478
  const cause = error.cause;
5385
5479
  if (typeof cause === "string") return cause.toLowerCase();
5386
5480
  if (cause instanceof Error) return (cause.message || "").toLowerCase();
5387
- if (isRecord23(cause) && typeof cause["message"] === "string") return String(cause["message"]).toLowerCase();
5481
+ if (isRecord24(cause) && typeof cause["message"] === "string") return String(cause["message"]).toLowerCase();
5388
5482
  return "";
5389
5483
  })();
5390
5484
  const causeCode = (() => {
5391
5485
  const cause = error.cause;
5392
- if (isRecord23(cause) && typeof cause["code"] === "string") return String(cause["code"]);
5486
+ if (isRecord24(cause) && typeof cause["code"] === "string") return String(cause["code"]);
5393
5487
  return "";
5394
5488
  })();
5395
5489
  const errorMessage = `${baseMsg} ${causeMsg}`.trim();
@@ -5881,6 +5975,9 @@ __export(llm_exports, {
5881
5975
  LLMPolicyEngine: () => LLMPolicyEngine,
5882
5976
  LlmCaller: () => LlmCaller,
5883
5977
  ModelResolver: () => ModelResolver,
5978
+ appendStreamingProviderReasoningDetails: () => appendStreamingProviderReasoningDetails,
5979
+ compactProviderReasoningDetails: () => compactProviderReasoningDetails,
5980
+ compactReasoningDetailsInValue: () => compactReasoningDetailsInValue,
5884
5981
  createDefaultTokenizerPort: () => createDefaultTokenizerPort,
5885
5982
  defaultPolicyEngine: () => defaultPolicyEngine
5886
5983
  });
@@ -6270,6 +6367,90 @@ function assertToolCallsHaveValidJsonArguments(toolCalls) {
6270
6367
  }
6271
6368
  }
6272
6369
 
6370
+ // src/runtime-kernel/llm/reasoning-details.ts
6371
+ var mergeableTextFields = ["reasoning_content"];
6372
+ function isRecord20(value) {
6373
+ return !!value && typeof value === "object" && !Array.isArray(value);
6374
+ }
6375
+ function findMergeableTextField(detail) {
6376
+ if (!isRecord20(detail)) return void 0;
6377
+ if (typeof detail.provider !== "string") return void 0;
6378
+ if (typeof detail.type !== "string") return void 0;
6379
+ for (const field of mergeableTextFields) {
6380
+ if (typeof detail[field] === "string") {
6381
+ return field;
6382
+ }
6383
+ }
6384
+ return void 0;
6385
+ }
6386
+ function hasOnlyStableTextDetailFields(detail, textField) {
6387
+ const allowedKeys = /* @__PURE__ */ new Set(["provider", "type", textField]);
6388
+ return Object.keys(detail).every((key) => allowedKeys.has(key));
6389
+ }
6390
+ function canMergeTextDetails(previous, incoming) {
6391
+ if (!isRecord20(previous) || !isRecord20(incoming)) return false;
6392
+ const previousField = findMergeableTextField(previous);
6393
+ const incomingField = findMergeableTextField(incoming);
6394
+ if (!previousField || previousField !== incomingField) return false;
6395
+ return previous.provider === incoming.provider && previous.type === incoming.type && hasOnlyStableTextDetailFields(previous, previousField) && hasOnlyStableTextDetailFields(incoming, incomingField);
6396
+ }
6397
+ function mergeStreamingText(previous, incoming) {
6398
+ if (!previous) return incoming;
6399
+ if (!incoming) return previous;
6400
+ if (incoming.startsWith(previous)) {
6401
+ return incoming;
6402
+ }
6403
+ if (previous.endsWith(incoming)) {
6404
+ return previous;
6405
+ }
6406
+ return `${previous}${incoming}`;
6407
+ }
6408
+ function appendStreamingProviderReasoningDetails(existing, incoming) {
6409
+ const next = [...existing];
6410
+ for (const detail of incoming) {
6411
+ const previous = next[next.length - 1];
6412
+ if (canMergeTextDetails(previous, detail)) {
6413
+ const textField = findMergeableTextField(previous);
6414
+ if (textField && isRecord20(detail)) {
6415
+ const mergedText = mergeStreamingText(String(previous[textField]), String(detail[textField]));
6416
+ if (mergedText === previous[textField]) {
6417
+ continue;
6418
+ }
6419
+ next[next.length - 1] = {
6420
+ ...previous,
6421
+ [textField]: mergedText
6422
+ };
6423
+ continue;
6424
+ }
6425
+ }
6426
+ next.push(detail);
6427
+ }
6428
+ return next;
6429
+ }
6430
+ function compactProviderReasoningDetails(reasoningDetails) {
6431
+ return appendStreamingProviderReasoningDetails([], reasoningDetails);
6432
+ }
6433
+ function compactReasoningDetailsInValue(value) {
6434
+ return compactValue(value);
6435
+ }
6436
+ function compactValue(value) {
6437
+ if (Array.isArray(value)) {
6438
+ return value.map((item) => compactValue(item));
6439
+ }
6440
+ if (!isRecord20(value)) {
6441
+ return value;
6442
+ }
6443
+ const compacted = {};
6444
+ for (const [key, childValue] of Object.entries(value)) {
6445
+ if (key === "reasoning_details" && Array.isArray(childValue)) {
6446
+ compacted[key] = compactProviderReasoningDetails(childValue);
6447
+ continue;
6448
+ }
6449
+ compacted[key] = compactValue(childValue);
6450
+ }
6451
+ return compacted;
6452
+ }
6453
+
6273
6454
  // src/runtime-kernel/llm/streaming-adapter.ts
6274
6455
  async function callLlmStream(params) {
6275
6456
  const {
@@ -6282,7 +6463,7 @@ async function callLlmStream(params) {
6282
6463
  } = params;
6283
6464
  let fullResponse = "";
6284
6465
  let streamError = null;
6285
- const reasoningDetails = [];
6466
+ let reasoningDetails = [];
6286
6467
  const streamAnswerId = generateMessageId();
6287
6468
  let streamChunkSeq = 0;
6288
6469
  let capturedUsage = void 0;
@@ -6352,13 +6533,21 @@ async function callLlmStream(params) {
6352
6533
  const reasoning = isRecord19(chunk) ? chunk["reasoning_details"] : void 0;
6353
6534
  if (reasoning !== void 0) {
6354
6535
  const newReasoningDetails = Array.isArray(reasoning) ? reasoning : [reasoning];
6355
- reasoningDetails.push(...newReasoningDetails);
6356
- eventHandler({
6357
- type: "provider_sidecar",
6358
- id: generateMessageId(),
6359
- timestamp: Date.now(),
6360
- reasoning_details: newReasoningDetails
6361
- });
6536
+ const previousReasoningDetails = reasoningDetails;
6537
+ const previousLength = previousReasoningDetails.length;
6538
+ const compactedReasoningDetails = appendStreamingProviderReasoningDetails(reasoningDetails, newReasoningDetails);
6539
+ reasoningDetails = compactedReasoningDetails;
6540
+ const previousLastChanged = previousLength > 0 && compactedReasoningDetails[previousLength - 1] !== previousReasoningDetails[previousLength - 1];
6541
+ const emitFromIndex = previousLastChanged ? previousLength - 1 : previousLength;
6542
+ const emittedReasoningDetails = compactedReasoningDetails.slice(Math.max(0, emitFromIndex));
6543
+ if (emittedReasoningDetails.length > 0) {
6544
+ eventHandler({
6545
+ type: "provider_sidecar",
6546
+ id: generateMessageId(),
6547
+ timestamp: Date.now(),
6548
+ reasoning_details: emittedReasoningDetails
6549
+ });
6550
+ }
6362
6551
  }
6363
6552
  if (chunk.tool_calls) {
6364
6553
  emitThoughtComplete(thoughtSegmenter.onBoundary());
@@ -6812,7 +7001,6 @@ __export(child_runs_exports, {
6812
7001
 
6813
7002
  // src/runtime-kernel/child-runs/childToolContext.ts
6814
7003
  function createChildRunToolContext(params) {
6815
- const inheritedConversationId = typeof params.parentToolContext.conversationId === "string" && params.parentToolContext.conversationId.trim().length > 0 ? params.parentToolContext.conversationId.trim() : void 0;
6816
7004
  const inheritedContext = stripRuntimeReservedToolContextPatch(params.parentToolContext);
6817
7005
  const childToolContext = {
6818
7006
  ...inheritedContext,
@@ -6824,7 +7012,7 @@ function createChildRunToolContext(params) {
6824
7012
  persistedHistory: params.seedHistory,
6825
7013
  workingHistory: params.seedHistory,
6826
7014
  executionMeta: {
6827
- conversationId: inheritedConversationId ?? params.internalConversationId,
7015
+ conversationId: params.conversationId,
6828
7016
  turnId: params.turnId,
6829
7017
  runId: params.runId,
6830
7018
  parentRunId: params.parentRunId
@@ -6975,7 +7163,7 @@ var FinalAnswerCollector = class {
6975
7163
  };
6976
7164
 
6977
7165
  // src/runtime-kernel/child-runs/childRunTraceSink.ts
6978
- function isRecord20(v) {
7166
+ function isRecord21(v) {
6979
7167
  return !!v && typeof v === "object" && !Array.isArray(v);
6980
7168
  }
6981
7169
  function getString2(obj, key) {
@@ -7008,7 +7196,7 @@ function createChildRunTraceSink(params) {
7008
7196
  const { publisher, conversationId, turnId } = params;
7009
7197
  const finalAnswerCollector = new FinalAnswerCollector(conversationId, turnId);
7010
7198
  const sink = (evt) => {
7011
- if (!isRecord20(evt)) {
7199
+ if (!isRecord21(evt)) {
7012
7200
  return [];
7013
7201
  }
7014
7202
  const type = getString2(evt, "type");
@@ -7144,7 +7332,7 @@ function readCheckpointHistory(checkpoint) {
7144
7332
  });
7145
7333
  }
7146
7334
  async function recoverChildRunEventsFromCheckpoint(params) {
7147
- const checkpoint = await params.checkpointer.load(params.conversationId);
7335
+ const checkpoint = await params.checkpointer.load(params.checkpointKey);
7148
7336
  const history = readCheckpointHistory(checkpoint);
7149
7337
  if (history.length === 0) {
7150
7338
  return [];
@@ -7152,7 +7340,7 @@ async function recoverChildRunEventsFromCheckpoint(params) {
7152
7340
  if (hasSeedHistoryPrefix(history, params.seedHistory)) {
7153
7341
  return history.slice(params.seedHistory.length);
7154
7342
  }
7155
- return history.filter((event) => event.conversation_id === params.internalConversationId);
7343
+ return history.filter((event) => event.conversation_id === params.childConversationId);
7156
7344
  }
7157
7345
 
7158
7346
  // src/runtime-kernel/child-runs/childRunInvoker.ts
@@ -7181,6 +7369,7 @@ var ChildRunInvoker = class {
7181
7369
  agentConfig,
7182
7370
  userMessage,
7183
7371
  parentToolContext,
7372
+ conversationId,
7184
7373
  runId,
7185
7374
  parentRunId,
7186
7375
  subrunTracePublisher,
@@ -7189,12 +7378,18 @@ var ChildRunInvoker = class {
7189
7378
  modelId,
7190
7379
  abortSignal
7191
7380
  } = config;
7192
- const internalConversationId = `internal_${generateMessageId()}`;
7381
+ const internalCheckpointKey = `internal_${generateMessageId()}`;
7382
+ const runtimeConversationId = resolveChildRunConversationId({
7383
+ explicitConversationId: conversationId,
7384
+ parentToolContext,
7385
+ fallbackConversationId: internalCheckpointKey
7386
+ });
7193
7387
  const turnId = `turn_${Date.now()}`;
7194
- const childRunId = typeof runId === "string" && runId.trim().length > 0 ? runId.trim() : internalConversationId;
7388
+ const childRunId = typeof runId === "string" && runId.trim().length > 0 ? runId.trim() : internalCheckpointKey;
7195
7389
  const resolvedParentRunId = typeof parentRunId === "string" && parentRunId.trim().length > 0 ? parentRunId.trim() : typeof parentToolContext.runId === "string" && parentToolContext.runId.trim().length > 0 ? parentToolContext.runId.trim() : void 0;
7196
7390
  logger13.info(`\u542F\u52A8 child-run: ${agentConfig.id}`, {
7197
- conversationId: internalConversationId,
7391
+ conversationId: runtimeConversationId,
7392
+ checkpointKey: internalCheckpointKey,
7198
7393
  maxSteps,
7199
7394
  userMessage: userMessage.slice(0, 100) + (userMessage.length > 100 ? "..." : "")
7200
7395
  });
@@ -7255,7 +7450,7 @@ var ChildRunInvoker = class {
7255
7450
  const seedHistory = Array.isArray(seedHistoryEvents) ? seedHistoryEvents : [];
7256
7451
  const childToolContext = createChildRunToolContext({
7257
7452
  parentToolContext,
7258
- internalConversationId,
7453
+ conversationId: runtimeConversationId,
7259
7454
  turnId,
7260
7455
  runId: childRunId,
7261
7456
  parentRunId: resolvedParentRunId,
@@ -7264,13 +7459,13 @@ var ChildRunInvoker = class {
7264
7459
  });
7265
7460
  const subrunSseSink = subrunTracePublisher ? createChildRunTraceSink({
7266
7461
  publisher: subrunTracePublisher,
7267
- conversationId: internalConversationId,
7462
+ conversationId: runtimeConversationId,
7268
7463
  turnId
7269
7464
  }) : void 0;
7270
7465
  const initialLocal = {
7271
7466
  request,
7272
7467
  history: seedHistory,
7273
- conversationId: internalConversationId,
7468
+ conversationId: runtimeConversationId,
7274
7469
  turnId,
7275
7470
  toolContext: childToolContext,
7276
7471
  ...abortSignal ? { signal: abortSignal } : {},
@@ -7278,7 +7473,7 @@ var ChildRunInvoker = class {
7278
7473
  ...subrunSseSink ? { sseSink: subrunSseSink } : {},
7279
7474
  systemPrompt
7280
7475
  };
7281
- await graphExecutor.prime(internalConversationId, initialLocal, "llm");
7476
+ await graphExecutor.prime(internalCheckpointKey, initialLocal, "llm");
7282
7477
  const allEvents = [];
7283
7478
  let stepCount = 0;
7284
7479
  let finalAnswer;
@@ -7290,7 +7485,7 @@ var ChildRunInvoker = class {
7290
7485
  err.name = "AbortError";
7291
7486
  throw err;
7292
7487
  }
7293
- const result = await graphExecutor.runUntilYield(internalConversationId);
7488
+ const result = await graphExecutor.runUntilYield(internalCheckpointKey);
7294
7489
  appendUniqueEvents(allEvents, result.events);
7295
7490
  stepCount = result.stepCount;
7296
7491
  if (subrunSseSink && typeof subrunSseSink.finalize === "function") {
@@ -7324,8 +7519,8 @@ var ChildRunInvoker = class {
7324
7519
  }
7325
7520
  const recoveredEvents = await recoverChildRunEventsFromCheckpoint({
7326
7521
  checkpointer,
7327
- conversationId: internalConversationId,
7328
- internalConversationId,
7522
+ checkpointKey: internalCheckpointKey,
7523
+ childConversationId: runtimeConversationId,
7329
7524
  seedHistory
7330
7525
  });
7331
7526
  appendUniqueEvents(allEvents, recoveredEvents);
@@ -7342,7 +7537,7 @@ var ChildRunInvoker = class {
7342
7537
  stack: err.stack
7343
7538
  } : { error: String(err) });
7344
7539
  }
7345
- await checkpointer.clear(internalConversationId);
7540
+ await checkpointer.clear(internalCheckpointKey);
7346
7541
  return {
7347
7542
  success: !error,
7348
7543
  runId: childRunId,
@@ -7355,6 +7550,16 @@ var ChildRunInvoker = class {
7355
7550
  };
7356
7551
  }
7357
7552
  };
7553
+ function readNonEmptyString6(value) {
7554
+ if (typeof value !== "string") {
7555
+ return void 0;
7556
+ }
7557
+ const trimmed = value.trim();
7558
+ return trimmed.length > 0 ? trimmed : void 0;
7559
+ }
7560
+ function resolveChildRunConversationId(params) {
7561
+ return readNonEmptyString6(params.explicitConversationId) ?? readNonEmptyString6(params.parentToolContext.conversationId) ?? params.fallbackConversationId;
7562
+ }
7358
7563
  function resolveChildRunSystemReminderPolicy(agentConfig) {
7359
7564
  const configured = agentConfig.systemReminderPolicy ?? agentConfig.contextPolicy?.systemReminder;
7360
7565
  const threshold = agentConfig.stepPolicy?.lastStepsHintThreshold;
@@ -7545,7 +7750,7 @@ function cloneRunRecord(record) {
7545
7750
  ...record,
7546
7751
  iterationBudget: record.iterationBudget ? { ...record.iterationBudget } : void 0,
7547
7752
  errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0,
7548
- metadata: record.metadata ? { ...record.metadata } : void 0
7753
+ metadata: record.metadata ? structuredClone(record.metadata) : void 0
7549
7754
  };
7550
7755
  }
7551
7756
  function matchesStatus(candidate, filter) {
@@ -7677,7 +7882,7 @@ function runRecordToMeta(record) {
7677
7882
  errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0
7678
7883
  };
7679
7884
  }
7680
- function isRecord21(value) {
7885
+ function isRecord22(value) {
7681
7886
  return typeof value === "object" && value !== null && !Array.isArray(value);
7682
7887
  }
7683
7888
  function readStringField(record, key) {
@@ -7698,7 +7903,7 @@ function getRunIdFromMetadata(event) {
7698
7903
  return snakeCaseRunId;
7699
7904
  }
7700
7905
  const runContext = metadata["run_context"];
7701
- if (isRecord21(runContext)) {
7906
+ if (isRecord22(runContext)) {
7702
7907
  return readStringField(runContext, "runId") ?? readStringField(runContext, "run_id");
7703
7908
  }
7704
7909
  return void 0;
@@ -7916,7 +8121,7 @@ function runMetaFromRecord(record) {
7916
8121
  }
7917
8122
 
7918
8123
  // src/runtime-kernel/run-supervisor/runSupervisor.ts
7919
- function isRecord22(value) {
8124
+ function isRecord23(value) {
7920
8125
  return typeof value === "object" && value !== null && !Array.isArray(value);
7921
8126
  }
7922
8127
  function readStringField2(record, key) {
@@ -7933,7 +8138,7 @@ function readRunIdFromRuntimeEvent(event) {
7933
8138
  return directRunId;
7934
8139
  }
7935
8140
  const runContext = metadata["run_context"];
7936
- if (!isRecord22(runContext)) {
8141
+ if (!isRecord23(runContext)) {
7937
8142
  return void 0;
7938
8143
  }
7939
8144
  return readStringField2(runContext, "runId") ?? readStringField2(runContext, "run_id");
@@ -7945,7 +8150,7 @@ function readAwaitingUserReason(event) {
7945
8150
  if (typeof event.prompt === "string" && event.prompt.trim().length > 0) {
7946
8151
  return event.prompt;
7947
8152
  }
7948
- if (isRecord22(event.form)) {
8153
+ if (isRecord23(event.form)) {
7949
8154
  const prompt = readStringField2(event.form, "prompt");
7950
8155
  if (prompt && prompt.trim().length > 0) {
7951
8156
  return prompt;
@@ -7957,7 +8162,7 @@ function isTerminalStatus(status) {
7957
8162
  return status === "completed" || status === "failed" || status === "cancelled";
7958
8163
  }
7959
8164
  function cloneMetadata(metadata) {
7960
- return metadata ? { ...metadata } : void 0;
8165
+ return metadata ? structuredClone(metadata) : void 0;
7961
8166
  }
7962
8167
  function recordToSnapshot(record) {
7963
8168
  return {
@@ -8044,7 +8249,7 @@ var DefaultRunSupervisor = class {
8044
8249
  startedAt,
8045
8250
  updatedAt: startedAt,
8046
8251
  iterationBudget: spec.iterationBudget ? { ...spec.iterationBudget } : void 0,
8047
- metadata: spec.metadata ? { ...spec.metadata } : void 0
8252
+ metadata: cloneMetadata(spec.metadata)
8048
8253
  };
8049
8254
  await this.registryStore.save(record);
8050
8255
  const handle = new DefaultRunHandle({
@@ -8218,12 +8423,13 @@ var DefaultRunSupervisor = class {
8218
8423
  }
8219
8424
  try {
8220
8425
  await handle.markRunning({ currentNode: "detached" });
8426
+ const registeredRecord = await this.registryStore.load(handle.runId);
8221
8427
  const executorOutcome = await this.executor.execute({
8222
8428
  runId: handle.runId,
8223
- parentRunId: spec.parentRunId,
8224
- conversationId: spec.conversationId,
8225
- agentSpec: spec.agentSpec,
8226
- request: spec.request,
8429
+ parentRunId: handle.parentRunId,
8430
+ conversationId: registeredRecord?.conversationId ?? spec.conversationId,
8431
+ agentSpec: await handle.spec(),
8432
+ request: await handle.request(),
8227
8433
  signal: handle.signal,
8228
8434
  eventBus: spec.eventBus,
8229
8435
  eventStore: spec.eventStore,
@@ -8232,7 +8438,7 @@ var DefaultRunSupervisor = class {
8232
8438
  contextFences: spec.contextFences,
8233
8439
  wakeSource: spec.wakeSource,
8234
8440
  ephemeral: spec.ephemeral,
8235
- metadata: spec.metadata
8441
+ metadata: cloneMetadata(registeredRecord?.metadata ?? spec.metadata)
8236
8442
  });
8237
8443
  const outcome = await this.persistExecutorOutcome(handle, executorOutcome);
8238
8444
  this.notifyTerminalWaiters(outcome);
@@ -8296,10 +8502,14 @@ var DefaultRunSupervisor = class {
8296
8502
  await this.registryStore.save(record);
8297
8503
  }
8298
8504
  const completedAt = executorOutcome?.completedAt ?? this.now();
8505
+ const fallbackMeta = record ? void 0 : await handle.meta();
8299
8506
  const outcome = recordToTerminalOutcome(record ?? {
8300
8507
  runId: handle.runId,
8301
8508
  parentRunId: handle.parentRunId,
8302
- status: executorOutcome?.status ?? "completed"}, completedAt);
8509
+ conversationId: fallbackMeta?.conversationId ?? "",
8510
+ agentSpecId: fallbackMeta?.agentSpecId,
8511
+ status: executorOutcome?.status ?? "completed",
8512
+ startedAt: fallbackMeta?.startedAt ?? completedAt}, completedAt);
8303
8513
  const nextOutcome = {
8304
8514
  ...outcome,
8305
8515
  metadata: {
@@ -8527,6 +8737,7 @@ function createGraphLoopHarness(options) {
8527
8737
  };
8528
8738
  return {
8529
8739
  async run() {
8740
+ const checkpointKey = options.conversationId;
8530
8741
  const executor = createDefaultGraphExecutor({
8531
8742
  llmNode: options.createLlmNode({
8532
8743
  llmCaller: options.llmCaller,
@@ -8555,8 +8766,8 @@ function createGraphLoopHarness(options) {
8555
8766
  signal: options.signal ?? options.toolContext.abortSignal,
8556
8767
  executorLocal
8557
8768
  };
8558
- await executor.prime(options.conversationId, local, "user");
8559
- const result = await executor.runUntilYield(options.conversationId);
8769
+ await executor.prime(checkpointKey, local, "user");
8770
+ const result = await executor.runUntilYield(checkpointKey);
8560
8771
  return {
8561
8772
  checkpointNodeId: result.checkpoint.nodeId,
8562
8773
  stepCount: result.stepCount
@@ -8594,14 +8805,18 @@ exports.ToolNode = ToolNode;
8594
8805
  exports.UserNode = UserNode;
8595
8806
  exports.WaitUserNode = WaitUserNode;
8596
8807
  exports.agentHasToolTrigger = agentHasToolTrigger;
8808
+ exports.appendStreamingProviderReasoningDetails = appendStreamingProviderReasoningDetails;
8597
8809
  exports.applySystemReminders = applySystemReminders;
8598
8810
  exports.audit = audit_exports;
8599
8811
  exports.budgetWarningTrigger = budgetWarningTrigger;
8600
8812
  exports.childRunTrace = child_run_trace_exports;
8601
8813
  exports.childRuns = child_runs_exports;
8814
+ exports.compactProviderReasoningDetails = compactProviderReasoningDetails;
8815
+ exports.compactReasoningDetailsInValue = compactReasoningDetailsInValue;
8602
8816
  exports.computeToolIdempotencyKey = computeToolIdempotencyKey;
8603
8817
  exports.consoleAudit = consoleAudit;
8604
8818
  exports.contextBudgetWarningTemplate = contextBudgetWarningTemplate;
8819
+ exports.copyToolContextRuntimeCapability = copyToolContextRuntimeCapability;
8605
8820
  exports.countToolCallsInCurrentRequest = countToolCallsInCurrentRequest;
8606
8821
  exports.createCompositeAudit = createCompositeAudit;
8607
8822
  exports.createConsoleAudit = createConsoleAudit;