@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
@@ -263,6 +263,7 @@ var AgentSpecBudgetPolicy = z.object({
263
263
  });
264
264
  var AgentSpecToolHistoryPolicy = z.object({
265
265
  strategy: z.enum(["per-pair", "per-run", "none"]).optional(),
266
+ retentionMode: z.enum(["drop", "compress"]).optional(),
266
267
  keepLatestToolPairs: z.number().int().nonnegative().optional(),
267
268
  keepLatestRuns: z.number().int().nonnegative().optional(),
268
269
  maxInteractionGroups: z.number().int().nonnegative().optional(),
@@ -1019,6 +1020,17 @@ var logger = new Logger("GraphExecutor");
1019
1020
  function asLocalRecord(local) {
1020
1021
  return local && typeof local === "object" ? { ...local } : {};
1021
1022
  }
1023
+ function readNonEmptyString(value) {
1024
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1025
+ }
1026
+ function readRuntimeConversationId(state) {
1027
+ const local = state?.local && typeof state.local === "object" ? state.local : void 0;
1028
+ return readNonEmptyString(local?.conversationId);
1029
+ }
1030
+ function readRuntimeTurnId(state) {
1031
+ const local = state?.local && typeof state.local === "object" ? state.local : void 0;
1032
+ return readNonEmptyString(local?.turnId);
1033
+ }
1022
1034
  var GraphExecutor = class {
1023
1035
  constructor(checkpointer, config = {}) {
1024
1036
  this.checkpointer = checkpointer;
@@ -1036,8 +1048,8 @@ var GraphExecutor = class {
1036
1048
  registerNode(node) {
1037
1049
  this.nodes.set(node.id, node);
1038
1050
  }
1039
- async peekCheckpoint(conversationId) {
1040
- return await this.checkpointer.load(conversationId);
1051
+ async peekCheckpoint(checkpointKey) {
1052
+ return await this.checkpointer.load(checkpointKey);
1041
1053
  }
1042
1054
  sanitize(state) {
1043
1055
  const local = asLocalRecord(state.local);
@@ -1049,8 +1061,8 @@ var GraphExecutor = class {
1049
1061
  local
1050
1062
  };
1051
1063
  }
1052
- async prime(conversationId, local, nodeId = "user") {
1053
- this.ephemeralLocals.set(conversationId, { ...local || {} });
1064
+ async prime(checkpointKey, local, nodeId = "user") {
1065
+ this.ephemeralLocals.set(checkpointKey, { ...local || {} });
1054
1066
  const localSansMemory = { ...local || {} };
1055
1067
  if ("memory" in localSansMemory) delete localSansMemory.memory;
1056
1068
  const state = {
@@ -1058,10 +1070,10 @@ var GraphExecutor = class {
1058
1070
  schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
1059
1071
  local: localSansMemory
1060
1072
  };
1061
- await this.checkpointer.save(conversationId, state);
1073
+ await this.checkpointer.save(checkpointKey, state);
1062
1074
  }
1063
- async setNode(conversationId, nodeId, localPatch) {
1064
- const current = await this.checkpointer.load(conversationId) || {
1075
+ async setNode(checkpointKey, nodeId, localPatch) {
1076
+ const current = await this.checkpointer.load(checkpointKey) || {
1065
1077
  schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
1066
1078
  local: {}
1067
1079
  };
@@ -1072,19 +1084,46 @@ var GraphExecutor = class {
1072
1084
  schemaVersion: current.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
1073
1085
  local: mergedLocal
1074
1086
  };
1075
- await this.checkpointer.save(conversationId, next);
1087
+ await this.checkpointer.save(checkpointKey, next);
1076
1088
  }
1077
- async runUntilYield(conversationId) {
1089
+ async runUntilYield(checkpointKey) {
1078
1090
  const runId = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
1079
1091
  let lifecyclePhase = "completed";
1092
+ let initialState = null;
1093
+ try {
1094
+ initialState = await this.loadInitialState(checkpointKey);
1095
+ } catch (err) {
1096
+ lifecyclePhase = "failed";
1097
+ this.telemetryPort.emit({
1098
+ kind: "run_lifecycle",
1099
+ runId,
1100
+ phase: "spawned",
1101
+ scope: {}
1102
+ });
1103
+ this.telemetryPort.emit({
1104
+ kind: "run_lifecycle",
1105
+ runId,
1106
+ phase: lifecyclePhase,
1107
+ scope: {}
1108
+ });
1109
+ throw err;
1110
+ }
1111
+ let lifecycleConversationId = readRuntimeConversationId(initialState);
1112
+ let lifecycleTurnId = readRuntimeTurnId(initialState);
1080
1113
  this.telemetryPort.emit({
1081
1114
  kind: "run_lifecycle",
1082
1115
  runId,
1083
1116
  phase: "spawned",
1084
- scope: { conversationId: conversationId || void 0 }
1117
+ scope: {
1118
+ conversationId: lifecycleConversationId,
1119
+ turnId: lifecycleTurnId
1120
+ }
1085
1121
  });
1086
1122
  try {
1087
- return await this.runUntilYieldInternal(conversationId);
1123
+ const result = await this.runUntilYieldInternal(checkpointKey, initialState);
1124
+ lifecycleConversationId = readRuntimeConversationId(result.checkpoint);
1125
+ lifecycleTurnId = readRuntimeTurnId(result.checkpoint);
1126
+ return result;
1088
1127
  } catch (err) {
1089
1128
  lifecyclePhase = err?.name === "AbortError" ? "cancelled" : "failed";
1090
1129
  throw err;
@@ -1093,17 +1132,23 @@ var GraphExecutor = class {
1093
1132
  kind: "run_lifecycle",
1094
1133
  runId,
1095
1134
  phase: lifecyclePhase,
1096
- scope: { conversationId: conversationId || void 0 }
1135
+ scope: {
1136
+ conversationId: lifecycleConversationId,
1137
+ turnId: lifecycleTurnId
1138
+ }
1097
1139
  });
1098
1140
  }
1099
1141
  }
1100
- async runUntilYieldInternal(conversationId) {
1101
- let state = await this.checkpointer.load(conversationId) || {
1142
+ async loadInitialState(checkpointKey) {
1143
+ return await this.checkpointer.load(checkpointKey) || {
1102
1144
  nodeId: "user",
1103
1145
  schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
1104
1146
  local: {}
1105
1147
  };
1106
- const ephemeral = this.ephemeralLocals.get(conversationId) || {};
1148
+ }
1149
+ async runUntilYieldInternal(checkpointKey, initialState) {
1150
+ let state = initialState;
1151
+ const ephemeral = this.ephemeralLocals.get(checkpointKey) || {};
1107
1152
  state = {
1108
1153
  ...state,
1109
1154
  schemaVersion: state.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
@@ -1132,7 +1177,7 @@ var GraphExecutor = class {
1132
1177
  const signalRaw = state.local?.signal;
1133
1178
  if (isAbortSignal2(signalRaw) && signalRaw.aborted) {
1134
1179
  logger.warn("[GraphExecutor] \u6536\u5230 AbortSignal\uFF0C\u7ACB\u5373\u505C\u6B62\u63A8\u7406\u5FAA\u73AF");
1135
- this.ephemeralLocals.delete(conversationId);
1180
+ this.ephemeralLocals.delete(checkpointKey);
1136
1181
  throwAbortError();
1137
1182
  }
1138
1183
  const isLastStep = cycleStepCount >= this.config.maxSteps;
@@ -1180,8 +1225,8 @@ var GraphExecutor = class {
1180
1225
  checkpointCount
1181
1226
  });
1182
1227
  const cp2 = this.sanitize(state);
1183
- await this.checkpointer.save(conversationId, cp2);
1184
- this.ephemeralLocals.delete(conversationId);
1228
+ await this.checkpointer.save(checkpointKey, cp2);
1229
+ this.ephemeralLocals.delete(checkpointKey);
1185
1230
  return { events: allEvents, checkpoint: cp2, stepCount };
1186
1231
  }
1187
1232
  logger.info("[GraphExecutor] \u8282\u70B9\u5207\u6362", {
@@ -1192,18 +1237,18 @@ var GraphExecutor = class {
1192
1237
  });
1193
1238
  const nodeRunStartedAt = Date.now();
1194
1239
  const nodeIdForTelemetry = state.nodeId;
1240
+ const conversationIdForTelemetry = readRuntimeConversationId(state);
1195
1241
  let result;
1196
1242
  try {
1197
1243
  result = await node.run(state);
1198
1244
  } finally {
1199
- const turnIdForTelemetry = typeof state.local?.turnId === "string" ? state.local.turnId : void 0;
1200
1245
  this.telemetryPort.emit({
1201
1246
  kind: "graph_node",
1202
1247
  nodeId: nodeIdForTelemetry,
1203
1248
  durationMs: Date.now() - nodeRunStartedAt,
1204
1249
  scope: {
1205
- conversationId: conversationId || void 0,
1206
- turnId: turnIdForTelemetry
1250
+ conversationId: conversationIdForTelemetry,
1251
+ turnId: readRuntimeTurnId(state)
1207
1252
  }
1208
1253
  });
1209
1254
  }
@@ -1242,7 +1287,7 @@ var GraphExecutor = class {
1242
1287
  });
1243
1288
  state = { ...state, nodeId: nextNodeId };
1244
1289
  const cp2 = this.sanitize(state);
1245
- await this.checkpointer.save(conversationId, cp2);
1290
+ await this.checkpointer.save(checkpointKey, cp2);
1246
1291
  continue;
1247
1292
  }
1248
1293
  if (result.kind === "yield") {
@@ -1253,7 +1298,7 @@ var GraphExecutor = class {
1253
1298
  checkpointCount
1254
1299
  });
1255
1300
  const cp2 = this.sanitize(state);
1256
- await this.checkpointer.save(conversationId, cp2);
1301
+ await this.checkpointer.save(checkpointKey, cp2);
1257
1302
  return { events: allEvents, checkpoint: cp2, stepCount };
1258
1303
  }
1259
1304
  if (result.kind === "pause") {
@@ -1264,7 +1309,7 @@ var GraphExecutor = class {
1264
1309
  checkpointCount
1265
1310
  });
1266
1311
  const cp2 = this.sanitize(state);
1267
- await this.checkpointer.save(conversationId, cp2);
1312
+ await this.checkpointer.save(checkpointKey, cp2);
1268
1313
  return { events: allEvents, checkpoint: cp2, stepCount };
1269
1314
  }
1270
1315
  }
@@ -1275,8 +1320,8 @@ var GraphExecutor = class {
1275
1320
  checkpointCount
1276
1321
  });
1277
1322
  const cp = this.sanitize(state);
1278
- await this.checkpointer.save(conversationId, cp);
1279
- this.ephemeralLocals.delete(conversationId);
1323
+ await this.checkpointer.save(checkpointKey, cp);
1324
+ this.ephemeralLocals.delete(checkpointKey);
1280
1325
  return { events: allEvents, checkpoint: cp, stepCount };
1281
1326
  }
1282
1327
  };
@@ -1473,15 +1518,15 @@ function splitConcatenatedJsonObjects(input) {
1473
1518
  }
1474
1519
 
1475
1520
  // src/runtime-kernel/graph-engine/tick-pipeline/helpers.ts
1476
- function readNonEmptyString(value) {
1521
+ function readNonEmptyString2(value) {
1477
1522
  if (typeof value !== "string") return void 0;
1478
1523
  const trimmed = value.trim();
1479
1524
  return trimmed.length > 0 ? trimmed : void 0;
1480
1525
  }
1481
1526
  function resolveConversationIdForRuntimeEvents(toolContext) {
1482
- const fromCamel = readNonEmptyString(toolContext?.conversationId);
1527
+ const fromCamel = readNonEmptyString2(toolContext?.conversationId);
1483
1528
  if (fromCamel) return fromCamel;
1484
- const fromSnake = toolContext ? readNonEmptyString(toolContext["conversation_id"]) : void 0;
1529
+ const fromSnake = toolContext ? readNonEmptyString2(toolContext["conversation_id"]) : void 0;
1485
1530
  if (fromSnake) return fromSnake;
1486
1531
  return generateMessageId();
1487
1532
  }
@@ -1840,7 +1885,7 @@ var runModelLockMiddleware = async (ctx, stage, next) => {
1840
1885
  if (stage.id !== "execute_llm") {
1841
1886
  return;
1842
1887
  }
1843
- const normalized = readNonEmptyString(ctx.cloudQuotaFallbackAppliedModelId);
1888
+ const normalized = readNonEmptyString2(ctx.cloudQuotaFallbackAppliedModelId);
1844
1889
  if (!normalized) {
1845
1890
  return;
1846
1891
  }
@@ -2441,7 +2486,7 @@ function createExecuteLlmStage(dependencies) {
2441
2486
  streamEventHandler,
2442
2487
  ctx.signal,
2443
2488
  (fallbackModelId) => {
2444
- ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString(fallbackModelId);
2489
+ ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString2(fallbackModelId);
2445
2490
  },
2446
2491
  (info) => {
2447
2492
  ctx.modelFallbackAudit = info;
@@ -2485,7 +2530,7 @@ function createPrepareCallStage(dependencies) {
2485
2530
  return {
2486
2531
  id: "prepare_call",
2487
2532
  async run(ctx) {
2488
- const lockedRunModelId = readNonEmptyString(ctx.executorLocal?.runLockedModelId);
2533
+ const lockedRunModelId = readNonEmptyString2(ctx.executorLocal?.runLockedModelId);
2489
2534
  const requestedModelId = lockedRunModelId ?? ctx.request.model_id;
2490
2535
  ctx.modelId = dependencies.modelResolver.resolveModelId(requestedModelId);
2491
2536
  await emitAuditEnvelope(ctx.audit, {
@@ -2557,7 +2602,7 @@ var GraphAgentExecutor = class {
2557
2602
  this.llmCaller = dependencies.llmCaller;
2558
2603
  this.toolRuntime = dependencies.toolRuntime;
2559
2604
  this.contextBuilder = dependencies.contextBuilder;
2560
- this.cloudQuotaFallbackModelId = readNonEmptyString(dependencies.cloudQuotaFallbackModelId);
2605
+ this.cloudQuotaFallbackModelId = readNonEmptyString2(dependencies.cloudQuotaFallbackModelId);
2561
2606
  this.modelCatalog = dependencies.modelCatalog ?? createEmptyModelCatalog();
2562
2607
  this.modelResolver = dependencies.modelResolver ?? new ModelResolver({
2563
2608
  modelCatalog: this.modelCatalog
@@ -2605,7 +2650,7 @@ var GraphAgentExecutor = class {
2605
2650
  llmMessages: [],
2606
2651
  mode: input.request.mode === "chat" ? "chat" : "agent",
2607
2652
  conversationId: resolveConversationIdForRuntimeEvents(input.toolContext),
2608
- turnId: readNonEmptyString(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
2653
+ turnId: readNonEmptyString2(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
2609
2654
  telemetry: this.telemetryPort,
2610
2655
  audit: this.auditPort
2611
2656
  };
@@ -2655,18 +2700,18 @@ function isSummarizationCallbacks(value) {
2655
2700
  function isGraphSseSink(value) {
2656
2701
  return typeof value === "function";
2657
2702
  }
2658
- function readNonEmptyString2(value) {
2703
+ function readNonEmptyString3(value) {
2659
2704
  if (typeof value !== "string") return void 0;
2660
2705
  const trimmed = value.trim();
2661
2706
  return trimmed.length > 0 ? trimmed : void 0;
2662
2707
  }
2663
2708
  function readGraphAgentLocal(local) {
2664
2709
  const source = local ?? {};
2665
- const answerId = readNonEmptyString2(source.answerId);
2710
+ const answerId = readNonEmptyString3(source.answerId);
2666
2711
  const chunkSeq = Number.isInteger(source.chunkSeq) ? Number(source.chunkSeq) : 0;
2667
2712
  return {
2668
- conversationId: readNonEmptyString2(source.conversationId) ?? "",
2669
- turnId: readNonEmptyString2(source.turnId),
2713
+ conversationId: readNonEmptyString3(source.conversationId) ?? "",
2714
+ turnId: readNonEmptyString3(source.turnId),
2670
2715
  request: isAgentInvocationRequest(source.request) ? source.request : void 0,
2671
2716
  toolContext: isToolExecutionContext(source.toolContext) ? source.toolContext : void 0,
2672
2717
  history: isRuntimeEventArray(source.history) ? source.history : [],
@@ -3431,7 +3476,7 @@ var LlmNode = class {
3431
3476
  function isRecord8(value) {
3432
3477
  return typeof value === "object" && value !== null && !Array.isArray(value);
3433
3478
  }
3434
- function readNonEmptyString3(value) {
3479
+ function readNonEmptyString4(value) {
3435
3480
  if (typeof value !== "string") {
3436
3481
  return void 0;
3437
3482
  }
@@ -3453,7 +3498,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
3453
3498
  return void 0;
3454
3499
  }
3455
3500
  if (toolName === "write_report") {
3456
- const report = readNonEmptyString3(data.report);
3501
+ const report = readNonEmptyString4(data.report);
3457
3502
  if (!report) {
3458
3503
  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");
3459
3504
  }
@@ -3463,7 +3508,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
3463
3508
  if (data.success !== true) {
3464
3509
  return void 0;
3465
3510
  }
3466
- const finalAnswer = readNonEmptyString3(data.final_answer);
3511
+ const finalAnswer = readNonEmptyString4(data.final_answer);
3467
3512
  if (!finalAnswer) {
3468
3513
  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");
3469
3514
  }
@@ -4008,6 +4053,31 @@ function ensureToolContextRuntimeCapability(params) {
4008
4053
  function getToolContextRuntimeBinding(context) {
4009
4054
  return readBinding(context);
4010
4055
  }
4056
+ function copyToolContextRuntimeCapability(source, target) {
4057
+ const sourceBinding = readBinding(source);
4058
+ if (!sourceBinding) {
4059
+ return void 0;
4060
+ }
4061
+ const existingTargetBinding = readBinding(target);
4062
+ if (existingTargetBinding) {
4063
+ exposeCompatibilitySurface(target, existingTargetBinding);
4064
+ return existingTargetBinding;
4065
+ }
4066
+ const targetBinding = createRuntimeBinding({
4067
+ context: target,
4068
+ persistedHistory: () => sourceBinding.getPersistedHistoryEvents(),
4069
+ workingHistory: () => sourceBinding.getWorkingHistoryEvents(),
4070
+ executionMeta: sourceBinding.readExecutionMeta()
4071
+ });
4072
+ Object.defineProperty(target, TOOL_CONTEXT_RUNTIME_BINDING_KEY, {
4073
+ value: targetBinding,
4074
+ enumerable: false,
4075
+ configurable: true,
4076
+ writable: false
4077
+ });
4078
+ exposeCompatibilitySurface(target, targetBinding);
4079
+ return targetBinding;
4080
+ }
4011
4081
  function readToolContextWorkingHistory(context) {
4012
4082
  if (context.conversationView) {
4013
4083
  return context.conversationView.getWorkingHistoryEvents();
@@ -4421,6 +4491,22 @@ var ToolNode = class {
4421
4491
  });
4422
4492
  }
4423
4493
  async run(state) {
4494
+ const events = [];
4495
+ while (true) {
4496
+ const result = await this.runNextPendingToolCall(state);
4497
+ if (Array.isArray(result.events) && result.events.length > 0) {
4498
+ events.push(...result.events);
4499
+ }
4500
+ if (result.kind === "route" && result.nextNodeId === "tool") {
4501
+ continue;
4502
+ }
4503
+ return {
4504
+ ...result,
4505
+ events
4506
+ };
4507
+ }
4508
+ }
4509
+ async runNextPendingToolCall(state) {
4424
4510
  const calls = state.local?.pendingToolCalls ?? [];
4425
4511
  const signalRaw = state.local?.signal;
4426
4512
  if (isAbortSignal(signalRaw) && signalRaw.aborted) {
@@ -4628,18 +4714,25 @@ var ToolNode = class {
4628
4714
  rawArguments: context.call.function?.arguments,
4629
4715
  parsedArguments: context.toolArgs
4630
4716
  });
4717
+ const remainingCalls = context.calls.slice(1);
4631
4718
  context.state.local = buildErrorLocalState({
4632
4719
  local: context.local,
4633
- remainingCalls: context.calls.slice(1),
4720
+ remainingCalls,
4634
4721
  conversationId: context.conversationId,
4635
4722
  turnId: context.turnId,
4636
4723
  runtimeEvents: context.bridge.getRuntimeEvents(),
4637
4724
  nextProtocolErrorCount: fuse.nextCount
4638
4725
  });
4639
- if (fuse.shouldFuse) {
4726
+ if (fuse.shouldFuse && remainingCalls.length === 0) {
4640
4727
  throw createToolProtocolFuseError(fuse.nextCount, context.exec.error);
4641
4728
  }
4642
- return { kind: "route", nextNodeId: "llm", events: context.bridge.getRuntimeEvents() };
4729
+ return {
4730
+ kind: "route",
4731
+ // 同一个 assistant.tool_calls batch 必须为每个 call 产出 tool_output。
4732
+ // 出错时也继续消费剩余 call,ToolNode.run 会在本节点内 drain 完 batch 再回 LLM。
4733
+ nextNodeId: remainingCalls.length > 0 ? "tool" : "llm",
4734
+ events: context.bridge.getRuntimeEvents()
4735
+ };
4643
4736
  }
4644
4737
  };
4645
4738
 
@@ -4836,12 +4929,12 @@ function asRecord(value) {
4836
4929
  }
4837
4930
  return value;
4838
4931
  }
4839
- function summarizeCheckpoint(conversationId, state, savedAt) {
4932
+ function summarizeCheckpoint(checkpointKey, state, savedAt) {
4840
4933
  const local = asRecord(state.local);
4841
4934
  const executorLocal = asRecord(local?.executorLocal);
4842
4935
  const pendingToolCalls = local?.pendingToolCalls;
4843
4936
  return {
4844
- conversationId,
4937
+ checkpointKey,
4845
4938
  schemaVersion: state.schemaVersion ?? 1,
4846
4939
  savedAt,
4847
4940
  currentNode: state.nodeId,
@@ -4860,25 +4953,25 @@ var MemoryCheckpointer = class {
4860
4953
  local: state.local && typeof state.local === "object" && !Array.isArray(state.local) ? { ...state.local } : state.local
4861
4954
  };
4862
4955
  }
4863
- async load(conversationId) {
4864
- const entry = this.store.get(conversationId);
4956
+ async load(checkpointKey) {
4957
+ const entry = this.store.get(checkpointKey);
4865
4958
  return entry ? this.cloneState(entry.state) : null;
4866
4959
  }
4867
- async save(conversationId, state) {
4868
- this.store.set(conversationId, {
4960
+ async save(checkpointKey, state) {
4961
+ this.store.set(checkpointKey, {
4869
4962
  state: this.cloneState(state),
4870
4963
  savedAt: Date.now()
4871
4964
  });
4872
4965
  }
4873
- async clear(conversationId) {
4874
- this.store.delete(conversationId);
4966
+ async clear(checkpointKey) {
4967
+ this.store.delete(checkpointKey);
4875
4968
  }
4876
- async peekMeta(conversationId) {
4877
- const entry = this.store.get(conversationId);
4878
- return entry ? summarizeCheckpoint(conversationId, entry.state, entry.savedAt) : null;
4969
+ async peekMeta(checkpointKey) {
4970
+ const entry = this.store.get(checkpointKey);
4971
+ return entry ? summarizeCheckpoint(checkpointKey, entry.state, entry.savedAt) : null;
4879
4972
  }
4880
4973
  async list(filter = {}) {
4881
- 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);
4974
+ 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);
4882
4975
  if (filter.limit === void 0) {
4883
4976
  return summaries;
4884
4977
  }
@@ -4950,6 +5043,7 @@ __export(tools_exports, {
4950
5043
  CommonParameterTypes: () => CommonParameterTypes,
4951
5044
  ContextCheckpointTool: () => ContextCheckpointTool,
4952
5045
  computeToolIdempotencyKey: () => computeToolIdempotencyKey,
5046
+ copyToolContextRuntimeCapability: () => copyToolContextRuntimeCapability,
4953
5047
  createContextCheckpointTool: () => createContextCheckpointTool,
4954
5048
  ensureToolContextRuntimeCapability: () => ensureToolContextRuntimeCapability,
4955
5049
  findCachedToolOutputByIdempotencyKey: () => findCachedToolOutputByIdempotencyKey,
@@ -5143,7 +5237,7 @@ function createContextCheckpointTool(options) {
5143
5237
  function isRecord15(value) {
5144
5238
  return !!value && typeof value === "object" && !Array.isArray(value);
5145
5239
  }
5146
- function readNonEmptyString4(value) {
5240
+ function readNonEmptyString5(value) {
5147
5241
  if (typeof value !== "string") {
5148
5242
  return void 0;
5149
5243
  }
@@ -5163,13 +5257,13 @@ function readToolContextUserQuery(context) {
5163
5257
  if (!context) {
5164
5258
  return void 0;
5165
5259
  }
5166
- return readNonEmptyString4(context["user_query"]);
5260
+ return readNonEmptyString5(context["user_query"]);
5167
5261
  }
5168
5262
  function readToolContextModelId(context) {
5169
5263
  if (!context) {
5170
5264
  return void 0;
5171
5265
  }
5172
- return readNonEmptyString4(context["modelId"]);
5266
+ return readNonEmptyString5(context["modelId"]);
5173
5267
  }
5174
5268
  function readToolContextRunContext(context) {
5175
5269
  if (!context) {
@@ -5376,18 +5470,18 @@ function createClassification(category, reason, suggestedDelay, extras) {
5376
5470
  }
5377
5471
  var ErrorClassifier = class {
5378
5472
  static classify(error, context) {
5379
- const isRecord23 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
5473
+ const isRecord24 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
5380
5474
  const baseMsg = (error.message || "").toLowerCase();
5381
5475
  const causeMsg = (() => {
5382
5476
  const cause = error.cause;
5383
5477
  if (typeof cause === "string") return cause.toLowerCase();
5384
5478
  if (cause instanceof Error) return (cause.message || "").toLowerCase();
5385
- if (isRecord23(cause) && typeof cause["message"] === "string") return String(cause["message"]).toLowerCase();
5479
+ if (isRecord24(cause) && typeof cause["message"] === "string") return String(cause["message"]).toLowerCase();
5386
5480
  return "";
5387
5481
  })();
5388
5482
  const causeCode = (() => {
5389
5483
  const cause = error.cause;
5390
- if (isRecord23(cause) && typeof cause["code"] === "string") return String(cause["code"]);
5484
+ if (isRecord24(cause) && typeof cause["code"] === "string") return String(cause["code"]);
5391
5485
  return "";
5392
5486
  })();
5393
5487
  const errorMessage = `${baseMsg} ${causeMsg}`.trim();
@@ -5879,6 +5973,9 @@ __export(llm_exports, {
5879
5973
  LLMPolicyEngine: () => LLMPolicyEngine,
5880
5974
  LlmCaller: () => LlmCaller,
5881
5975
  ModelResolver: () => ModelResolver,
5976
+ appendStreamingProviderReasoningDetails: () => appendStreamingProviderReasoningDetails,
5977
+ compactProviderReasoningDetails: () => compactProviderReasoningDetails,
5978
+ compactReasoningDetailsInValue: () => compactReasoningDetailsInValue,
5882
5979
  createDefaultTokenizerPort: () => createDefaultTokenizerPort,
5883
5980
  defaultPolicyEngine: () => defaultPolicyEngine
5884
5981
  });
@@ -6268,6 +6365,90 @@ function assertToolCallsHaveValidJsonArguments(toolCalls) {
6268
6365
  }
6269
6366
  }
6270
6367
 
6368
+ // src/runtime-kernel/llm/reasoning-details.ts
6369
+ var mergeableTextFields = ["reasoning_content"];
6370
+ function isRecord20(value) {
6371
+ return !!value && typeof value === "object" && !Array.isArray(value);
6372
+ }
6373
+ function findMergeableTextField(detail) {
6374
+ if (!isRecord20(detail)) return void 0;
6375
+ if (typeof detail.provider !== "string") return void 0;
6376
+ if (typeof detail.type !== "string") return void 0;
6377
+ for (const field of mergeableTextFields) {
6378
+ if (typeof detail[field] === "string") {
6379
+ return field;
6380
+ }
6381
+ }
6382
+ return void 0;
6383
+ }
6384
+ function hasOnlyStableTextDetailFields(detail, textField) {
6385
+ const allowedKeys = /* @__PURE__ */ new Set(["provider", "type", textField]);
6386
+ return Object.keys(detail).every((key) => allowedKeys.has(key));
6387
+ }
6388
+ function canMergeTextDetails(previous, incoming) {
6389
+ if (!isRecord20(previous) || !isRecord20(incoming)) return false;
6390
+ const previousField = findMergeableTextField(previous);
6391
+ const incomingField = findMergeableTextField(incoming);
6392
+ if (!previousField || previousField !== incomingField) return false;
6393
+ return previous.provider === incoming.provider && previous.type === incoming.type && hasOnlyStableTextDetailFields(previous, previousField) && hasOnlyStableTextDetailFields(incoming, incomingField);
6394
+ }
6395
+ function mergeStreamingText(previous, incoming) {
6396
+ if (!previous) return incoming;
6397
+ if (!incoming) return previous;
6398
+ if (incoming.startsWith(previous)) {
6399
+ return incoming;
6400
+ }
6401
+ if (previous.endsWith(incoming)) {
6402
+ return previous;
6403
+ }
6404
+ return `${previous}${incoming}`;
6405
+ }
6406
+ function appendStreamingProviderReasoningDetails(existing, incoming) {
6407
+ const next = [...existing];
6408
+ for (const detail of incoming) {
6409
+ const previous = next[next.length - 1];
6410
+ if (canMergeTextDetails(previous, detail)) {
6411
+ const textField = findMergeableTextField(previous);
6412
+ if (textField && isRecord20(detail)) {
6413
+ const mergedText = mergeStreamingText(String(previous[textField]), String(detail[textField]));
6414
+ if (mergedText === previous[textField]) {
6415
+ continue;
6416
+ }
6417
+ next[next.length - 1] = {
6418
+ ...previous,
6419
+ [textField]: mergedText
6420
+ };
6421
+ continue;
6422
+ }
6423
+ }
6424
+ next.push(detail);
6425
+ }
6426
+ return next;
6427
+ }
6428
+ function compactProviderReasoningDetails(reasoningDetails) {
6429
+ return appendStreamingProviderReasoningDetails([], reasoningDetails);
6430
+ }
6431
+ function compactReasoningDetailsInValue(value) {
6432
+ return compactValue(value);
6433
+ }
6434
+ function compactValue(value) {
6435
+ if (Array.isArray(value)) {
6436
+ return value.map((item) => compactValue(item));
6437
+ }
6438
+ if (!isRecord20(value)) {
6439
+ return value;
6440
+ }
6441
+ const compacted = {};
6442
+ for (const [key, childValue] of Object.entries(value)) {
6443
+ if (key === "reasoning_details" && Array.isArray(childValue)) {
6444
+ compacted[key] = compactProviderReasoningDetails(childValue);
6445
+ continue;
6446
+ }
6447
+ compacted[key] = compactValue(childValue);
6448
+ }
6449
+ return compacted;
6450
+ }
6451
+
6271
6452
  // src/runtime-kernel/llm/streaming-adapter.ts
6272
6453
  async function callLlmStream(params) {
6273
6454
  const {
@@ -6280,7 +6461,7 @@ async function callLlmStream(params) {
6280
6461
  } = params;
6281
6462
  let fullResponse = "";
6282
6463
  let streamError = null;
6283
- const reasoningDetails = [];
6464
+ let reasoningDetails = [];
6284
6465
  const streamAnswerId = generateMessageId();
6285
6466
  let streamChunkSeq = 0;
6286
6467
  let capturedUsage = void 0;
@@ -6350,13 +6531,21 @@ async function callLlmStream(params) {
6350
6531
  const reasoning = isRecord19(chunk) ? chunk["reasoning_details"] : void 0;
6351
6532
  if (reasoning !== void 0) {
6352
6533
  const newReasoningDetails = Array.isArray(reasoning) ? reasoning : [reasoning];
6353
- reasoningDetails.push(...newReasoningDetails);
6354
- eventHandler({
6355
- type: "provider_sidecar",
6356
- id: generateMessageId(),
6357
- timestamp: Date.now(),
6358
- reasoning_details: newReasoningDetails
6359
- });
6534
+ const previousReasoningDetails = reasoningDetails;
6535
+ const previousLength = previousReasoningDetails.length;
6536
+ const compactedReasoningDetails = appendStreamingProviderReasoningDetails(reasoningDetails, newReasoningDetails);
6537
+ reasoningDetails = compactedReasoningDetails;
6538
+ const previousLastChanged = previousLength > 0 && compactedReasoningDetails[previousLength - 1] !== previousReasoningDetails[previousLength - 1];
6539
+ const emitFromIndex = previousLastChanged ? previousLength - 1 : previousLength;
6540
+ const emittedReasoningDetails = compactedReasoningDetails.slice(Math.max(0, emitFromIndex));
6541
+ if (emittedReasoningDetails.length > 0) {
6542
+ eventHandler({
6543
+ type: "provider_sidecar",
6544
+ id: generateMessageId(),
6545
+ timestamp: Date.now(),
6546
+ reasoning_details: emittedReasoningDetails
6547
+ });
6548
+ }
6360
6549
  }
6361
6550
  if (chunk.tool_calls) {
6362
6551
  emitThoughtComplete(thoughtSegmenter.onBoundary());
@@ -6810,7 +6999,6 @@ __export(child_runs_exports, {
6810
6999
 
6811
7000
  // src/runtime-kernel/child-runs/childToolContext.ts
6812
7001
  function createChildRunToolContext(params) {
6813
- const inheritedConversationId = typeof params.parentToolContext.conversationId === "string" && params.parentToolContext.conversationId.trim().length > 0 ? params.parentToolContext.conversationId.trim() : void 0;
6814
7002
  const inheritedContext = stripRuntimeReservedToolContextPatch(params.parentToolContext);
6815
7003
  const childToolContext = {
6816
7004
  ...inheritedContext,
@@ -6822,7 +7010,7 @@ function createChildRunToolContext(params) {
6822
7010
  persistedHistory: params.seedHistory,
6823
7011
  workingHistory: params.seedHistory,
6824
7012
  executionMeta: {
6825
- conversationId: inheritedConversationId ?? params.internalConversationId,
7013
+ conversationId: params.conversationId,
6826
7014
  turnId: params.turnId,
6827
7015
  runId: params.runId,
6828
7016
  parentRunId: params.parentRunId
@@ -6973,7 +7161,7 @@ var FinalAnswerCollector = class {
6973
7161
  };
6974
7162
 
6975
7163
  // src/runtime-kernel/child-runs/childRunTraceSink.ts
6976
- function isRecord20(v) {
7164
+ function isRecord21(v) {
6977
7165
  return !!v && typeof v === "object" && !Array.isArray(v);
6978
7166
  }
6979
7167
  function getString2(obj, key) {
@@ -7006,7 +7194,7 @@ function createChildRunTraceSink(params) {
7006
7194
  const { publisher, conversationId, turnId } = params;
7007
7195
  const finalAnswerCollector = new FinalAnswerCollector(conversationId, turnId);
7008
7196
  const sink = (evt) => {
7009
- if (!isRecord20(evt)) {
7197
+ if (!isRecord21(evt)) {
7010
7198
  return [];
7011
7199
  }
7012
7200
  const type = getString2(evt, "type");
@@ -7142,7 +7330,7 @@ function readCheckpointHistory(checkpoint) {
7142
7330
  });
7143
7331
  }
7144
7332
  async function recoverChildRunEventsFromCheckpoint(params) {
7145
- const checkpoint = await params.checkpointer.load(params.conversationId);
7333
+ const checkpoint = await params.checkpointer.load(params.checkpointKey);
7146
7334
  const history = readCheckpointHistory(checkpoint);
7147
7335
  if (history.length === 0) {
7148
7336
  return [];
@@ -7150,7 +7338,7 @@ async function recoverChildRunEventsFromCheckpoint(params) {
7150
7338
  if (hasSeedHistoryPrefix(history, params.seedHistory)) {
7151
7339
  return history.slice(params.seedHistory.length);
7152
7340
  }
7153
- return history.filter((event) => event.conversation_id === params.internalConversationId);
7341
+ return history.filter((event) => event.conversation_id === params.childConversationId);
7154
7342
  }
7155
7343
 
7156
7344
  // src/runtime-kernel/child-runs/childRunInvoker.ts
@@ -7179,6 +7367,7 @@ var ChildRunInvoker = class {
7179
7367
  agentConfig,
7180
7368
  userMessage,
7181
7369
  parentToolContext,
7370
+ conversationId,
7182
7371
  runId,
7183
7372
  parentRunId,
7184
7373
  subrunTracePublisher,
@@ -7187,12 +7376,18 @@ var ChildRunInvoker = class {
7187
7376
  modelId,
7188
7377
  abortSignal
7189
7378
  } = config;
7190
- const internalConversationId = `internal_${generateMessageId()}`;
7379
+ const internalCheckpointKey = `internal_${generateMessageId()}`;
7380
+ const runtimeConversationId = resolveChildRunConversationId({
7381
+ explicitConversationId: conversationId,
7382
+ parentToolContext,
7383
+ fallbackConversationId: internalCheckpointKey
7384
+ });
7191
7385
  const turnId = `turn_${Date.now()}`;
7192
- const childRunId = typeof runId === "string" && runId.trim().length > 0 ? runId.trim() : internalConversationId;
7386
+ const childRunId = typeof runId === "string" && runId.trim().length > 0 ? runId.trim() : internalCheckpointKey;
7193
7387
  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;
7194
7388
  logger13.info(`\u542F\u52A8 child-run: ${agentConfig.id}`, {
7195
- conversationId: internalConversationId,
7389
+ conversationId: runtimeConversationId,
7390
+ checkpointKey: internalCheckpointKey,
7196
7391
  maxSteps,
7197
7392
  userMessage: userMessage.slice(0, 100) + (userMessage.length > 100 ? "..." : "")
7198
7393
  });
@@ -7253,7 +7448,7 @@ var ChildRunInvoker = class {
7253
7448
  const seedHistory = Array.isArray(seedHistoryEvents) ? seedHistoryEvents : [];
7254
7449
  const childToolContext = createChildRunToolContext({
7255
7450
  parentToolContext,
7256
- internalConversationId,
7451
+ conversationId: runtimeConversationId,
7257
7452
  turnId,
7258
7453
  runId: childRunId,
7259
7454
  parentRunId: resolvedParentRunId,
@@ -7262,13 +7457,13 @@ var ChildRunInvoker = class {
7262
7457
  });
7263
7458
  const subrunSseSink = subrunTracePublisher ? createChildRunTraceSink({
7264
7459
  publisher: subrunTracePublisher,
7265
- conversationId: internalConversationId,
7460
+ conversationId: runtimeConversationId,
7266
7461
  turnId
7267
7462
  }) : void 0;
7268
7463
  const initialLocal = {
7269
7464
  request,
7270
7465
  history: seedHistory,
7271
- conversationId: internalConversationId,
7466
+ conversationId: runtimeConversationId,
7272
7467
  turnId,
7273
7468
  toolContext: childToolContext,
7274
7469
  ...abortSignal ? { signal: abortSignal } : {},
@@ -7276,7 +7471,7 @@ var ChildRunInvoker = class {
7276
7471
  ...subrunSseSink ? { sseSink: subrunSseSink } : {},
7277
7472
  systemPrompt
7278
7473
  };
7279
- await graphExecutor.prime(internalConversationId, initialLocal, "llm");
7474
+ await graphExecutor.prime(internalCheckpointKey, initialLocal, "llm");
7280
7475
  const allEvents = [];
7281
7476
  let stepCount = 0;
7282
7477
  let finalAnswer;
@@ -7288,7 +7483,7 @@ var ChildRunInvoker = class {
7288
7483
  err.name = "AbortError";
7289
7484
  throw err;
7290
7485
  }
7291
- const result = await graphExecutor.runUntilYield(internalConversationId);
7486
+ const result = await graphExecutor.runUntilYield(internalCheckpointKey);
7292
7487
  appendUniqueEvents(allEvents, result.events);
7293
7488
  stepCount = result.stepCount;
7294
7489
  if (subrunSseSink && typeof subrunSseSink.finalize === "function") {
@@ -7322,8 +7517,8 @@ var ChildRunInvoker = class {
7322
7517
  }
7323
7518
  const recoveredEvents = await recoverChildRunEventsFromCheckpoint({
7324
7519
  checkpointer,
7325
- conversationId: internalConversationId,
7326
- internalConversationId,
7520
+ checkpointKey: internalCheckpointKey,
7521
+ childConversationId: runtimeConversationId,
7327
7522
  seedHistory
7328
7523
  });
7329
7524
  appendUniqueEvents(allEvents, recoveredEvents);
@@ -7340,7 +7535,7 @@ var ChildRunInvoker = class {
7340
7535
  stack: err.stack
7341
7536
  } : { error: String(err) });
7342
7537
  }
7343
- await checkpointer.clear(internalConversationId);
7538
+ await checkpointer.clear(internalCheckpointKey);
7344
7539
  return {
7345
7540
  success: !error,
7346
7541
  runId: childRunId,
@@ -7353,6 +7548,16 @@ var ChildRunInvoker = class {
7353
7548
  };
7354
7549
  }
7355
7550
  };
7551
+ function readNonEmptyString6(value) {
7552
+ if (typeof value !== "string") {
7553
+ return void 0;
7554
+ }
7555
+ const trimmed = value.trim();
7556
+ return trimmed.length > 0 ? trimmed : void 0;
7557
+ }
7558
+ function resolveChildRunConversationId(params) {
7559
+ return readNonEmptyString6(params.explicitConversationId) ?? readNonEmptyString6(params.parentToolContext.conversationId) ?? params.fallbackConversationId;
7560
+ }
7356
7561
  function resolveChildRunSystemReminderPolicy(agentConfig) {
7357
7562
  const configured = agentConfig.systemReminderPolicy ?? agentConfig.contextPolicy?.systemReminder;
7358
7563
  const threshold = agentConfig.stepPolicy?.lastStepsHintThreshold;
@@ -7543,7 +7748,7 @@ function cloneRunRecord(record) {
7543
7748
  ...record,
7544
7749
  iterationBudget: record.iterationBudget ? { ...record.iterationBudget } : void 0,
7545
7750
  errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0,
7546
- metadata: record.metadata ? { ...record.metadata } : void 0
7751
+ metadata: record.metadata ? structuredClone(record.metadata) : void 0
7547
7752
  };
7548
7753
  }
7549
7754
  function matchesStatus(candidate, filter) {
@@ -7675,7 +7880,7 @@ function runRecordToMeta(record) {
7675
7880
  errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0
7676
7881
  };
7677
7882
  }
7678
- function isRecord21(value) {
7883
+ function isRecord22(value) {
7679
7884
  return typeof value === "object" && value !== null && !Array.isArray(value);
7680
7885
  }
7681
7886
  function readStringField(record, key) {
@@ -7696,7 +7901,7 @@ function getRunIdFromMetadata(event) {
7696
7901
  return snakeCaseRunId;
7697
7902
  }
7698
7903
  const runContext = metadata["run_context"];
7699
- if (isRecord21(runContext)) {
7904
+ if (isRecord22(runContext)) {
7700
7905
  return readStringField(runContext, "runId") ?? readStringField(runContext, "run_id");
7701
7906
  }
7702
7907
  return void 0;
@@ -7914,7 +8119,7 @@ function runMetaFromRecord(record) {
7914
8119
  }
7915
8120
 
7916
8121
  // src/runtime-kernel/run-supervisor/runSupervisor.ts
7917
- function isRecord22(value) {
8122
+ function isRecord23(value) {
7918
8123
  return typeof value === "object" && value !== null && !Array.isArray(value);
7919
8124
  }
7920
8125
  function readStringField2(record, key) {
@@ -7931,7 +8136,7 @@ function readRunIdFromRuntimeEvent(event) {
7931
8136
  return directRunId;
7932
8137
  }
7933
8138
  const runContext = metadata["run_context"];
7934
- if (!isRecord22(runContext)) {
8139
+ if (!isRecord23(runContext)) {
7935
8140
  return void 0;
7936
8141
  }
7937
8142
  return readStringField2(runContext, "runId") ?? readStringField2(runContext, "run_id");
@@ -7943,7 +8148,7 @@ function readAwaitingUserReason(event) {
7943
8148
  if (typeof event.prompt === "string" && event.prompt.trim().length > 0) {
7944
8149
  return event.prompt;
7945
8150
  }
7946
- if (isRecord22(event.form)) {
8151
+ if (isRecord23(event.form)) {
7947
8152
  const prompt = readStringField2(event.form, "prompt");
7948
8153
  if (prompt && prompt.trim().length > 0) {
7949
8154
  return prompt;
@@ -7955,7 +8160,7 @@ function isTerminalStatus(status) {
7955
8160
  return status === "completed" || status === "failed" || status === "cancelled";
7956
8161
  }
7957
8162
  function cloneMetadata(metadata) {
7958
- return metadata ? { ...metadata } : void 0;
8163
+ return metadata ? structuredClone(metadata) : void 0;
7959
8164
  }
7960
8165
  function recordToSnapshot(record) {
7961
8166
  return {
@@ -8042,7 +8247,7 @@ var DefaultRunSupervisor = class {
8042
8247
  startedAt,
8043
8248
  updatedAt: startedAt,
8044
8249
  iterationBudget: spec.iterationBudget ? { ...spec.iterationBudget } : void 0,
8045
- metadata: spec.metadata ? { ...spec.metadata } : void 0
8250
+ metadata: cloneMetadata(spec.metadata)
8046
8251
  };
8047
8252
  await this.registryStore.save(record);
8048
8253
  const handle = new DefaultRunHandle({
@@ -8216,12 +8421,13 @@ var DefaultRunSupervisor = class {
8216
8421
  }
8217
8422
  try {
8218
8423
  await handle.markRunning({ currentNode: "detached" });
8424
+ const registeredRecord = await this.registryStore.load(handle.runId);
8219
8425
  const executorOutcome = await this.executor.execute({
8220
8426
  runId: handle.runId,
8221
- parentRunId: spec.parentRunId,
8222
- conversationId: spec.conversationId,
8223
- agentSpec: spec.agentSpec,
8224
- request: spec.request,
8427
+ parentRunId: handle.parentRunId,
8428
+ conversationId: registeredRecord?.conversationId ?? spec.conversationId,
8429
+ agentSpec: await handle.spec(),
8430
+ request: await handle.request(),
8225
8431
  signal: handle.signal,
8226
8432
  eventBus: spec.eventBus,
8227
8433
  eventStore: spec.eventStore,
@@ -8230,7 +8436,7 @@ var DefaultRunSupervisor = class {
8230
8436
  contextFences: spec.contextFences,
8231
8437
  wakeSource: spec.wakeSource,
8232
8438
  ephemeral: spec.ephemeral,
8233
- metadata: spec.metadata
8439
+ metadata: cloneMetadata(registeredRecord?.metadata ?? spec.metadata)
8234
8440
  });
8235
8441
  const outcome = await this.persistExecutorOutcome(handle, executorOutcome);
8236
8442
  this.notifyTerminalWaiters(outcome);
@@ -8294,10 +8500,14 @@ var DefaultRunSupervisor = class {
8294
8500
  await this.registryStore.save(record);
8295
8501
  }
8296
8502
  const completedAt = executorOutcome?.completedAt ?? this.now();
8503
+ const fallbackMeta = record ? void 0 : await handle.meta();
8297
8504
  const outcome = recordToTerminalOutcome(record ?? {
8298
8505
  runId: handle.runId,
8299
8506
  parentRunId: handle.parentRunId,
8300
- status: executorOutcome?.status ?? "completed"}, completedAt);
8507
+ conversationId: fallbackMeta?.conversationId ?? "",
8508
+ agentSpecId: fallbackMeta?.agentSpecId,
8509
+ status: executorOutcome?.status ?? "completed",
8510
+ startedAt: fallbackMeta?.startedAt ?? completedAt}, completedAt);
8301
8511
  const nextOutcome = {
8302
8512
  ...outcome,
8303
8513
  metadata: {
@@ -8525,6 +8735,7 @@ function createGraphLoopHarness(options) {
8525
8735
  };
8526
8736
  return {
8527
8737
  async run() {
8738
+ const checkpointKey = options.conversationId;
8528
8739
  const executor = createDefaultGraphExecutor({
8529
8740
  llmNode: options.createLlmNode({
8530
8741
  llmCaller: options.llmCaller,
@@ -8553,8 +8764,8 @@ function createGraphLoopHarness(options) {
8553
8764
  signal: options.signal ?? options.toolContext.abortSignal,
8554
8765
  executorLocal
8555
8766
  };
8556
- await executor.prime(options.conversationId, local, "user");
8557
- const result = await executor.runUntilYield(options.conversationId);
8767
+ await executor.prime(checkpointKey, local, "user");
8768
+ const result = await executor.runUntilYield(checkpointKey);
8558
8769
  return {
8559
8770
  checkpointNodeId: result.checkpoint.nodeId,
8560
8771
  stepCount: result.stepCount
@@ -8563,6 +8774,6 @@ function createGraphLoopHarness(options) {
8563
8774
  };
8564
8775
  }
8565
8776
 
8566
- export { AnswerNode, AuditEnvelopePersistenceError, BUILTIN_SYSTEM_REMINDER_TEMPLATES, BUILTIN_SYSTEM_REMINDER_TRIGGERS, BaseTool, CommonParameterTypes, CompositeAuditPort, ContextCheckpointTool, DEFAULT_CONTEXT_CHECKPOINT_TOOL_NAME, DefaultTokenizerPort, ENGINE_ERROR_CODES, ENGINE_STATE_SCHEMA_VERSION, EventBusSubRunTracePublisher, EventStoreAuditPort, FileAuditPort, GraphAgentExecutor, GraphExecutor, LLMPolicyEngine, LlmCaller, LlmNode, MemoryCheckpointer, MemoryEventStore, ModelResolver, SYSTEM_REMINDER_RULES, SystemReminderRegistry, ToolNode, UserNode, WaitUserNode, agentHasToolTrigger, applySystemReminders, audit_exports as audit, budgetWarningTrigger, child_run_trace_exports as childRunTrace, child_runs_exports as childRuns, computeToolIdempotencyKey, consoleAudit, contextBudgetWarningTemplate, countToolCallsInCurrentRequest, createCompositeAudit, createConsoleAudit, createContextCheckpointTool, createDefaultGraphExecutor, createDefaultSystemReminderRegistry, createDefaultTokenizerPort, createEventStoreAudit, createFileAudit, createGraphLoopHarness, createMonotonicEventIdFactory, createSystemReminderRules, defaultPolicyEngine, defaultSystemReminderRegistry, emitAuditEnvelope, emitSandboxDecisionAudit, enrichment_exports as enrichment, ensureToolContextRuntimeCapability, events_exports as events, execution_exports as execution, findCachedToolOutputByIdempotencyKey, getToolContextRuntimeBinding, graph_engine_exports as graph, lastStepsHintTemplate, llm_exports as llm, maxStepsForceFinalAnswerTemplate, noopAudit, normalizeToolArgs, periodicTaskstateReflectionTemplate, phaseEqualsTrigger, readContextCheckpointToolName, readNonEmptyStrings, readToolContextModelId, readToolContextPersistedHistory, readToolContextRunContext, readToolContextUserQuery, readToolContextWorkingHistory, remainingStepsLeqTrigger, requestEnricherRegistry, run_context_exports as runContext, run_supervisor_exports as runSupervisor, stepCountModuloTrigger, stripRuntimeReservedToolContextPatch, summarizeCheckpoint, system_reminder_exports as systemReminder, telemetry_exports as telemetry, toDisplayStep, toolCallStreakTemplate, toolCallStreakTrigger, tools_exports as tools };
8777
+ export { AnswerNode, AuditEnvelopePersistenceError, BUILTIN_SYSTEM_REMINDER_TEMPLATES, BUILTIN_SYSTEM_REMINDER_TRIGGERS, BaseTool, CommonParameterTypes, CompositeAuditPort, ContextCheckpointTool, DEFAULT_CONTEXT_CHECKPOINT_TOOL_NAME, DefaultTokenizerPort, ENGINE_ERROR_CODES, ENGINE_STATE_SCHEMA_VERSION, EventBusSubRunTracePublisher, EventStoreAuditPort, FileAuditPort, GraphAgentExecutor, GraphExecutor, LLMPolicyEngine, LlmCaller, LlmNode, MemoryCheckpointer, MemoryEventStore, ModelResolver, SYSTEM_REMINDER_RULES, SystemReminderRegistry, ToolNode, UserNode, WaitUserNode, agentHasToolTrigger, appendStreamingProviderReasoningDetails, applySystemReminders, audit_exports as audit, budgetWarningTrigger, child_run_trace_exports as childRunTrace, child_runs_exports as childRuns, compactProviderReasoningDetails, compactReasoningDetailsInValue, computeToolIdempotencyKey, consoleAudit, contextBudgetWarningTemplate, copyToolContextRuntimeCapability, countToolCallsInCurrentRequest, createCompositeAudit, createConsoleAudit, createContextCheckpointTool, createDefaultGraphExecutor, createDefaultSystemReminderRegistry, createDefaultTokenizerPort, createEventStoreAudit, createFileAudit, createGraphLoopHarness, createMonotonicEventIdFactory, createSystemReminderRules, defaultPolicyEngine, defaultSystemReminderRegistry, emitAuditEnvelope, emitSandboxDecisionAudit, enrichment_exports as enrichment, ensureToolContextRuntimeCapability, events_exports as events, execution_exports as execution, findCachedToolOutputByIdempotencyKey, getToolContextRuntimeBinding, graph_engine_exports as graph, lastStepsHintTemplate, llm_exports as llm, maxStepsForceFinalAnswerTemplate, noopAudit, normalizeToolArgs, periodicTaskstateReflectionTemplate, phaseEqualsTrigger, readContextCheckpointToolName, readNonEmptyStrings, readToolContextModelId, readToolContextPersistedHistory, readToolContextRunContext, readToolContextUserQuery, readToolContextWorkingHistory, remainingStepsLeqTrigger, requestEnricherRegistry, run_context_exports as runContext, run_supervisor_exports as runSupervisor, stepCountModuloTrigger, stripRuntimeReservedToolContextPatch, summarizeCheckpoint, system_reminder_exports as systemReminder, telemetry_exports as telemetry, toDisplayStep, toolCallStreakTemplate, toolCallStreakTrigger, tools_exports as tools };
8567
8778
  //# sourceMappingURL=runtime-kernel.js.map
8568
8779
  //# sourceMappingURL=runtime-kernel.js.map