@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.
- package/CHANGELOG.md +31 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/bin/linnkit.cjs +7 -0
- package/dist/{agentSpec-EkmviZjy.d.cts → agentSpec-Du4Iye0q.d.cts} +16 -1
- package/dist/{agentSpec-EkmviZjy.d.ts → agentSpec-Du4Iye0q.d.ts} +16 -1
- package/dist/cli.cjs +234 -91
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +234 -91
- package/dist/cli.js.map +1 -1
- package/dist/context-manager.cjs +230 -32
- package/dist/context-manager.cjs.map +1 -1
- package/dist/context-manager.d.cts +52 -15
- package/dist/context-manager.d.ts +52 -15
- package/dist/context-manager.js +230 -33
- package/dist/context-manager.js.map +1 -1
- package/dist/{context-trace-HE2qY5Q-.d.cts → context-trace-BHKDS-eq.d.cts} +2 -2
- package/dist/{context-trace-DRi5M4lX.d.ts → context-trace-CHbqHmyE.d.ts} +2 -2
- package/dist/contracts.cjs +3 -1
- package/dist/contracts.cjs.map +1 -1
- package/dist/contracts.d.cts +3 -3
- package/dist/contracts.d.ts +3 -3
- package/dist/contracts.js +3 -1
- package/dist/contracts.js.map +1 -1
- package/dist/{defaultGraphExecutor-BBswR8wn.d.ts → defaultGraphExecutor-B29_qTHy.d.ts} +16 -15
- package/dist/{defaultGraphExecutor-BIjJj7WF.d.cts → defaultGraphExecutor-C2E59v_R.d.cts} +16 -15
- package/dist/{index-Cm-JbzTH.d.cts → index-BAaUP9yU.d.cts} +38 -15
- package/dist/{index-DRBWi1fy.d.ts → index-BaVpVNi2.d.ts} +38 -15
- package/dist/{index-DO4dQgf2.d.cts → index-BnYCS8Zg.d.cts} +2 -2
- package/dist/{index-CJeWHopy.d.ts → index-C0DAjsdX.d.ts} +2 -2
- package/dist/{index-Dl5PLgAv.d.cts → index-CKQzzZ5Y.d.cts} +2 -2
- package/dist/{index-CHqwkvGp.d.ts → index-D0mKxTR5.d.ts} +2 -2
- package/dist/index.cjs +327 -110
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +327 -110
- package/dist/index.js.map +1 -1
- package/dist/{ports-DnLuKfpE.d.ts → ports-DpPTFhSd.d.ts} +2 -2
- package/dist/{ports-DaatKJXp.d.cts → ports-s-tSp3sB.d.cts} +2 -2
- package/dist/quickstart.cjs +232 -88
- package/dist/quickstart.cjs.map +1 -1
- package/dist/quickstart.d.cts +7 -7
- package/dist/quickstart.d.ts +7 -7
- package/dist/quickstart.js +232 -88
- package/dist/quickstart.js.map +1 -1
- package/dist/{runAgent-CPj_9e58.d.ts → runAgent-C6F-399C.d.ts} +5 -5
- package/dist/{runAgent-HYKlXbVr.d.cts → runAgent-ilEj66Ik.d.cts} +5 -5
- package/dist/{runHandle-D3gPsD7B.d.cts → runHandle-BNOqS-Bl.d.cts} +3 -3
- package/dist/{runHandle-CyXvzgzk.d.ts → runHandle-BdLXOFqF.d.ts} +3 -3
- package/dist/runtime-kernel/events.cjs +1 -0
- package/dist/runtime-kernel/events.cjs.map +1 -1
- package/dist/runtime-kernel/events.d.cts +4 -4
- package/dist/runtime-kernel/events.d.ts +4 -4
- package/dist/runtime-kernel/events.js +1 -0
- package/dist/runtime-kernel/events.js.map +1 -1
- package/dist/runtime-kernel.cjs +318 -103
- package/dist/runtime-kernel.cjs.map +1 -1
- package/dist/runtime-kernel.d.cts +8 -8
- package/dist/runtime-kernel.d.ts +8 -8
- package/dist/runtime-kernel.js +315 -104
- package/dist/runtime-kernel.js.map +1 -1
- package/dist/testkit.cjs +331 -116
- package/dist/testkit.cjs.map +1 -1
- package/dist/testkit.d.cts +8 -8
- package/dist/testkit.d.ts +8 -8
- package/dist/testkit.js +331 -116
- package/dist/testkit.js.map +1 -1
- package/dist/{todo-B1PmDlp3.d.cts → todo-Ca8llpRQ.d.cts} +1 -1
- package/dist/{todo-B1PmDlp3.d.ts → todo-Ca8llpRQ.d.ts} +1 -1
- package/dist/{toolContracts-CLkQmhTG.d.cts → toolContracts-Bm3EZ1UM.d.cts} +13 -2
- package/dist/{toolContracts-Blll0241.d.ts → toolContracts-f8lzZBNa.d.ts} +13 -2
- package/docs/integration/README.md +1 -1
- package/docs/integration/agent-registration-guide.md +1 -1
- package/docs/integration/child-runs.md +4 -1
- package/docs/integration/context-engineering.md +30 -15
- package/docs/integration/context-fences.md +32 -3
- package/docs/integration/llm-provider.md +1 -1
- package/docs/integration/persistence.md +1 -0
- package/docs/integration/run-supervisor.md +3 -0
- package/docs/integration/tool-development-guide.md +7 -5
- package/docs/integration/tool-history.md +43 -17
- package/package.json +5 -4
package/dist/testkit.cjs
CHANGED
|
@@ -107,14 +107,18 @@ __export(runtime_kernel_exports, {
|
|
|
107
107
|
UserNode: () => UserNode,
|
|
108
108
|
WaitUserNode: () => WaitUserNode,
|
|
109
109
|
agentHasToolTrigger: () => agentHasToolTrigger,
|
|
110
|
+
appendStreamingProviderReasoningDetails: () => appendStreamingProviderReasoningDetails,
|
|
110
111
|
applySystemReminders: () => applySystemReminders,
|
|
111
112
|
audit: () => audit_exports,
|
|
112
113
|
budgetWarningTrigger: () => budgetWarningTrigger,
|
|
113
114
|
childRunTrace: () => child_run_trace_exports,
|
|
114
115
|
childRuns: () => child_runs_exports,
|
|
116
|
+
compactProviderReasoningDetails: () => compactProviderReasoningDetails,
|
|
117
|
+
compactReasoningDetailsInValue: () => compactReasoningDetailsInValue,
|
|
115
118
|
computeToolIdempotencyKey: () => computeToolIdempotencyKey,
|
|
116
119
|
consoleAudit: () => consoleAudit,
|
|
117
120
|
contextBudgetWarningTemplate: () => contextBudgetWarningTemplate,
|
|
121
|
+
copyToolContextRuntimeCapability: () => copyToolContextRuntimeCapability,
|
|
118
122
|
countToolCallsInCurrentRequest: () => countToolCallsInCurrentRequest,
|
|
119
123
|
createCompositeAudit: () => createCompositeAudit,
|
|
120
124
|
createConsoleAudit: () => createConsoleAudit,
|
|
@@ -419,6 +423,7 @@ var AgentSpecBudgetPolicy = zod.z.object({
|
|
|
419
423
|
});
|
|
420
424
|
var AgentSpecToolHistoryPolicy = zod.z.object({
|
|
421
425
|
strategy: zod.z.enum(["per-pair", "per-run", "none"]).optional(),
|
|
426
|
+
retentionMode: zod.z.enum(["drop", "compress"]).optional(),
|
|
422
427
|
keepLatestToolPairs: zod.z.number().int().nonnegative().optional(),
|
|
423
428
|
keepLatestRuns: zod.z.number().int().nonnegative().optional(),
|
|
424
429
|
maxInteractionGroups: zod.z.number().int().nonnegative().optional(),
|
|
@@ -1175,6 +1180,17 @@ var logger = new Logger("GraphExecutor");
|
|
|
1175
1180
|
function asLocalRecord(local) {
|
|
1176
1181
|
return local && typeof local === "object" ? { ...local } : {};
|
|
1177
1182
|
}
|
|
1183
|
+
function readNonEmptyString(value) {
|
|
1184
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1185
|
+
}
|
|
1186
|
+
function readRuntimeConversationId(state) {
|
|
1187
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1188
|
+
return readNonEmptyString(local?.conversationId);
|
|
1189
|
+
}
|
|
1190
|
+
function readRuntimeTurnId(state) {
|
|
1191
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1192
|
+
return readNonEmptyString(local?.turnId);
|
|
1193
|
+
}
|
|
1178
1194
|
var GraphExecutor = class {
|
|
1179
1195
|
constructor(checkpointer, config = {}) {
|
|
1180
1196
|
this.checkpointer = checkpointer;
|
|
@@ -1192,8 +1208,8 @@ var GraphExecutor = class {
|
|
|
1192
1208
|
registerNode(node) {
|
|
1193
1209
|
this.nodes.set(node.id, node);
|
|
1194
1210
|
}
|
|
1195
|
-
async peekCheckpoint(
|
|
1196
|
-
return await this.checkpointer.load(
|
|
1211
|
+
async peekCheckpoint(checkpointKey) {
|
|
1212
|
+
return await this.checkpointer.load(checkpointKey);
|
|
1197
1213
|
}
|
|
1198
1214
|
sanitize(state) {
|
|
1199
1215
|
const local = asLocalRecord(state.local);
|
|
@@ -1205,8 +1221,8 @@ var GraphExecutor = class {
|
|
|
1205
1221
|
local
|
|
1206
1222
|
};
|
|
1207
1223
|
}
|
|
1208
|
-
async prime(
|
|
1209
|
-
this.ephemeralLocals.set(
|
|
1224
|
+
async prime(checkpointKey, local, nodeId = "user") {
|
|
1225
|
+
this.ephemeralLocals.set(checkpointKey, { ...local || {} });
|
|
1210
1226
|
const localSansMemory = { ...local || {} };
|
|
1211
1227
|
if ("memory" in localSansMemory) delete localSansMemory.memory;
|
|
1212
1228
|
const state = {
|
|
@@ -1214,10 +1230,10 @@ var GraphExecutor = class {
|
|
|
1214
1230
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1215
1231
|
local: localSansMemory
|
|
1216
1232
|
};
|
|
1217
|
-
await this.checkpointer.save(
|
|
1233
|
+
await this.checkpointer.save(checkpointKey, state);
|
|
1218
1234
|
}
|
|
1219
|
-
async setNode(
|
|
1220
|
-
const current = await this.checkpointer.load(
|
|
1235
|
+
async setNode(checkpointKey, nodeId, localPatch) {
|
|
1236
|
+
const current = await this.checkpointer.load(checkpointKey) || {
|
|
1221
1237
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1222
1238
|
local: {}
|
|
1223
1239
|
};
|
|
@@ -1228,19 +1244,46 @@ var GraphExecutor = class {
|
|
|
1228
1244
|
schemaVersion: current.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
1229
1245
|
local: mergedLocal
|
|
1230
1246
|
};
|
|
1231
|
-
await this.checkpointer.save(
|
|
1247
|
+
await this.checkpointer.save(checkpointKey, next);
|
|
1232
1248
|
}
|
|
1233
|
-
async runUntilYield(
|
|
1249
|
+
async runUntilYield(checkpointKey) {
|
|
1234
1250
|
const runId = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1235
1251
|
let lifecyclePhase = "completed";
|
|
1252
|
+
let initialState = null;
|
|
1253
|
+
try {
|
|
1254
|
+
initialState = await this.loadInitialState(checkpointKey);
|
|
1255
|
+
} catch (err) {
|
|
1256
|
+
lifecyclePhase = "failed";
|
|
1257
|
+
this.telemetryPort.emit({
|
|
1258
|
+
kind: "run_lifecycle",
|
|
1259
|
+
runId,
|
|
1260
|
+
phase: "spawned",
|
|
1261
|
+
scope: {}
|
|
1262
|
+
});
|
|
1263
|
+
this.telemetryPort.emit({
|
|
1264
|
+
kind: "run_lifecycle",
|
|
1265
|
+
runId,
|
|
1266
|
+
phase: lifecyclePhase,
|
|
1267
|
+
scope: {}
|
|
1268
|
+
});
|
|
1269
|
+
throw err;
|
|
1270
|
+
}
|
|
1271
|
+
let lifecycleConversationId = readRuntimeConversationId(initialState);
|
|
1272
|
+
let lifecycleTurnId = readRuntimeTurnId(initialState);
|
|
1236
1273
|
this.telemetryPort.emit({
|
|
1237
1274
|
kind: "run_lifecycle",
|
|
1238
1275
|
runId,
|
|
1239
1276
|
phase: "spawned",
|
|
1240
|
-
scope: {
|
|
1277
|
+
scope: {
|
|
1278
|
+
conversationId: lifecycleConversationId,
|
|
1279
|
+
turnId: lifecycleTurnId
|
|
1280
|
+
}
|
|
1241
1281
|
});
|
|
1242
1282
|
try {
|
|
1243
|
-
|
|
1283
|
+
const result = await this.runUntilYieldInternal(checkpointKey, initialState);
|
|
1284
|
+
lifecycleConversationId = readRuntimeConversationId(result.checkpoint);
|
|
1285
|
+
lifecycleTurnId = readRuntimeTurnId(result.checkpoint);
|
|
1286
|
+
return result;
|
|
1244
1287
|
} catch (err) {
|
|
1245
1288
|
lifecyclePhase = err?.name === "AbortError" ? "cancelled" : "failed";
|
|
1246
1289
|
throw err;
|
|
@@ -1249,17 +1292,23 @@ var GraphExecutor = class {
|
|
|
1249
1292
|
kind: "run_lifecycle",
|
|
1250
1293
|
runId,
|
|
1251
1294
|
phase: lifecyclePhase,
|
|
1252
|
-
scope: {
|
|
1295
|
+
scope: {
|
|
1296
|
+
conversationId: lifecycleConversationId,
|
|
1297
|
+
turnId: lifecycleTurnId
|
|
1298
|
+
}
|
|
1253
1299
|
});
|
|
1254
1300
|
}
|
|
1255
1301
|
}
|
|
1256
|
-
async
|
|
1257
|
-
|
|
1302
|
+
async loadInitialState(checkpointKey) {
|
|
1303
|
+
return await this.checkpointer.load(checkpointKey) || {
|
|
1258
1304
|
nodeId: "user",
|
|
1259
1305
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1260
1306
|
local: {}
|
|
1261
1307
|
};
|
|
1262
|
-
|
|
1308
|
+
}
|
|
1309
|
+
async runUntilYieldInternal(checkpointKey, initialState) {
|
|
1310
|
+
let state = initialState;
|
|
1311
|
+
const ephemeral = this.ephemeralLocals.get(checkpointKey) || {};
|
|
1263
1312
|
state = {
|
|
1264
1313
|
...state,
|
|
1265
1314
|
schemaVersion: state.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
@@ -1288,7 +1337,7 @@ var GraphExecutor = class {
|
|
|
1288
1337
|
const signalRaw = state.local?.signal;
|
|
1289
1338
|
if (isAbortSignal2(signalRaw) && signalRaw.aborted) {
|
|
1290
1339
|
logger.warn("[GraphExecutor] \u6536\u5230 AbortSignal\uFF0C\u7ACB\u5373\u505C\u6B62\u63A8\u7406\u5FAA\u73AF");
|
|
1291
|
-
this.ephemeralLocals.delete(
|
|
1340
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1292
1341
|
throwAbortError();
|
|
1293
1342
|
}
|
|
1294
1343
|
const isLastStep = cycleStepCount >= this.config.maxSteps;
|
|
@@ -1336,8 +1385,8 @@ var GraphExecutor = class {
|
|
|
1336
1385
|
checkpointCount
|
|
1337
1386
|
});
|
|
1338
1387
|
const cp2 = this.sanitize(state);
|
|
1339
|
-
await this.checkpointer.save(
|
|
1340
|
-
this.ephemeralLocals.delete(
|
|
1388
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1389
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1341
1390
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1342
1391
|
}
|
|
1343
1392
|
logger.info("[GraphExecutor] \u8282\u70B9\u5207\u6362", {
|
|
@@ -1348,18 +1397,18 @@ var GraphExecutor = class {
|
|
|
1348
1397
|
});
|
|
1349
1398
|
const nodeRunStartedAt = Date.now();
|
|
1350
1399
|
const nodeIdForTelemetry = state.nodeId;
|
|
1400
|
+
const conversationIdForTelemetry = readRuntimeConversationId(state);
|
|
1351
1401
|
let result;
|
|
1352
1402
|
try {
|
|
1353
1403
|
result = await node.run(state);
|
|
1354
1404
|
} finally {
|
|
1355
|
-
const turnIdForTelemetry = typeof state.local?.turnId === "string" ? state.local.turnId : void 0;
|
|
1356
1405
|
this.telemetryPort.emit({
|
|
1357
1406
|
kind: "graph_node",
|
|
1358
1407
|
nodeId: nodeIdForTelemetry,
|
|
1359
1408
|
durationMs: Date.now() - nodeRunStartedAt,
|
|
1360
1409
|
scope: {
|
|
1361
|
-
conversationId:
|
|
1362
|
-
turnId:
|
|
1410
|
+
conversationId: conversationIdForTelemetry,
|
|
1411
|
+
turnId: readRuntimeTurnId(state)
|
|
1363
1412
|
}
|
|
1364
1413
|
});
|
|
1365
1414
|
}
|
|
@@ -1398,7 +1447,7 @@ var GraphExecutor = class {
|
|
|
1398
1447
|
});
|
|
1399
1448
|
state = { ...state, nodeId: nextNodeId };
|
|
1400
1449
|
const cp2 = this.sanitize(state);
|
|
1401
|
-
await this.checkpointer.save(
|
|
1450
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1402
1451
|
continue;
|
|
1403
1452
|
}
|
|
1404
1453
|
if (result.kind === "yield") {
|
|
@@ -1409,7 +1458,7 @@ var GraphExecutor = class {
|
|
|
1409
1458
|
checkpointCount
|
|
1410
1459
|
});
|
|
1411
1460
|
const cp2 = this.sanitize(state);
|
|
1412
|
-
await this.checkpointer.save(
|
|
1461
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1413
1462
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1414
1463
|
}
|
|
1415
1464
|
if (result.kind === "pause") {
|
|
@@ -1420,7 +1469,7 @@ var GraphExecutor = class {
|
|
|
1420
1469
|
checkpointCount
|
|
1421
1470
|
});
|
|
1422
1471
|
const cp2 = this.sanitize(state);
|
|
1423
|
-
await this.checkpointer.save(
|
|
1472
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1424
1473
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1425
1474
|
}
|
|
1426
1475
|
}
|
|
@@ -1431,8 +1480,8 @@ var GraphExecutor = class {
|
|
|
1431
1480
|
checkpointCount
|
|
1432
1481
|
});
|
|
1433
1482
|
const cp = this.sanitize(state);
|
|
1434
|
-
await this.checkpointer.save(
|
|
1435
|
-
this.ephemeralLocals.delete(
|
|
1483
|
+
await this.checkpointer.save(checkpointKey, cp);
|
|
1484
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1436
1485
|
return { events: allEvents, checkpoint: cp, stepCount };
|
|
1437
1486
|
}
|
|
1438
1487
|
};
|
|
@@ -1629,15 +1678,15 @@ function splitConcatenatedJsonObjects(input) {
|
|
|
1629
1678
|
}
|
|
1630
1679
|
|
|
1631
1680
|
// src/runtime-kernel/graph-engine/tick-pipeline/helpers.ts
|
|
1632
|
-
function
|
|
1681
|
+
function readNonEmptyString2(value) {
|
|
1633
1682
|
if (typeof value !== "string") return void 0;
|
|
1634
1683
|
const trimmed = value.trim();
|
|
1635
1684
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
1636
1685
|
}
|
|
1637
1686
|
function resolveConversationIdForRuntimeEvents(toolContext) {
|
|
1638
|
-
const fromCamel =
|
|
1687
|
+
const fromCamel = readNonEmptyString2(toolContext?.conversationId);
|
|
1639
1688
|
if (fromCamel) return fromCamel;
|
|
1640
|
-
const fromSnake = toolContext ?
|
|
1689
|
+
const fromSnake = toolContext ? readNonEmptyString2(toolContext["conversation_id"]) : void 0;
|
|
1641
1690
|
if (fromSnake) return fromSnake;
|
|
1642
1691
|
return generateMessageId();
|
|
1643
1692
|
}
|
|
@@ -1996,7 +2045,7 @@ var runModelLockMiddleware = async (ctx, stage, next) => {
|
|
|
1996
2045
|
if (stage.id !== "execute_llm") {
|
|
1997
2046
|
return;
|
|
1998
2047
|
}
|
|
1999
|
-
const normalized =
|
|
2048
|
+
const normalized = readNonEmptyString2(ctx.cloudQuotaFallbackAppliedModelId);
|
|
2000
2049
|
if (!normalized) {
|
|
2001
2050
|
return;
|
|
2002
2051
|
}
|
|
@@ -2597,7 +2646,7 @@ function createExecuteLlmStage(dependencies) {
|
|
|
2597
2646
|
streamEventHandler,
|
|
2598
2647
|
ctx.signal,
|
|
2599
2648
|
(fallbackModelId) => {
|
|
2600
|
-
ctx.cloudQuotaFallbackAppliedModelId =
|
|
2649
|
+
ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString2(fallbackModelId);
|
|
2601
2650
|
},
|
|
2602
2651
|
(info) => {
|
|
2603
2652
|
ctx.modelFallbackAudit = info;
|
|
@@ -2641,7 +2690,7 @@ function createPrepareCallStage(dependencies) {
|
|
|
2641
2690
|
return {
|
|
2642
2691
|
id: "prepare_call",
|
|
2643
2692
|
async run(ctx) {
|
|
2644
|
-
const lockedRunModelId =
|
|
2693
|
+
const lockedRunModelId = readNonEmptyString2(ctx.executorLocal?.runLockedModelId);
|
|
2645
2694
|
const requestedModelId = lockedRunModelId ?? ctx.request.model_id;
|
|
2646
2695
|
ctx.modelId = dependencies.modelResolver.resolveModelId(requestedModelId);
|
|
2647
2696
|
await emitAuditEnvelope(ctx.audit, {
|
|
@@ -2713,7 +2762,7 @@ var GraphAgentExecutor = class {
|
|
|
2713
2762
|
this.llmCaller = dependencies.llmCaller;
|
|
2714
2763
|
this.toolRuntime = dependencies.toolRuntime;
|
|
2715
2764
|
this.contextBuilder = dependencies.contextBuilder;
|
|
2716
|
-
this.cloudQuotaFallbackModelId =
|
|
2765
|
+
this.cloudQuotaFallbackModelId = readNonEmptyString2(dependencies.cloudQuotaFallbackModelId);
|
|
2717
2766
|
this.modelCatalog = dependencies.modelCatalog ?? createEmptyModelCatalog();
|
|
2718
2767
|
this.modelResolver = dependencies.modelResolver ?? new ModelResolver({
|
|
2719
2768
|
modelCatalog: this.modelCatalog
|
|
@@ -2761,7 +2810,7 @@ var GraphAgentExecutor = class {
|
|
|
2761
2810
|
llmMessages: [],
|
|
2762
2811
|
mode: input.request.mode === "chat" ? "chat" : "agent",
|
|
2763
2812
|
conversationId: resolveConversationIdForRuntimeEvents(input.toolContext),
|
|
2764
|
-
turnId:
|
|
2813
|
+
turnId: readNonEmptyString2(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
|
|
2765
2814
|
telemetry: this.telemetryPort,
|
|
2766
2815
|
audit: this.auditPort
|
|
2767
2816
|
};
|
|
@@ -2811,18 +2860,18 @@ function isSummarizationCallbacks(value) {
|
|
|
2811
2860
|
function isGraphSseSink(value) {
|
|
2812
2861
|
return typeof value === "function";
|
|
2813
2862
|
}
|
|
2814
|
-
function
|
|
2863
|
+
function readNonEmptyString3(value) {
|
|
2815
2864
|
if (typeof value !== "string") return void 0;
|
|
2816
2865
|
const trimmed = value.trim();
|
|
2817
2866
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
2818
2867
|
}
|
|
2819
2868
|
function readGraphAgentLocal(local) {
|
|
2820
2869
|
const source = local ?? {};
|
|
2821
|
-
const answerId =
|
|
2870
|
+
const answerId = readNonEmptyString3(source.answerId);
|
|
2822
2871
|
const chunkSeq = Number.isInteger(source.chunkSeq) ? Number(source.chunkSeq) : 0;
|
|
2823
2872
|
return {
|
|
2824
|
-
conversationId:
|
|
2825
|
-
turnId:
|
|
2873
|
+
conversationId: readNonEmptyString3(source.conversationId) ?? "",
|
|
2874
|
+
turnId: readNonEmptyString3(source.turnId),
|
|
2826
2875
|
request: isAgentInvocationRequest(source.request) ? source.request : void 0,
|
|
2827
2876
|
toolContext: isToolExecutionContext(source.toolContext) ? source.toolContext : void 0,
|
|
2828
2877
|
history: isRuntimeEventArray(source.history) ? source.history : [],
|
|
@@ -3587,7 +3636,7 @@ var LlmNode = class {
|
|
|
3587
3636
|
function isRecord8(value) {
|
|
3588
3637
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3589
3638
|
}
|
|
3590
|
-
function
|
|
3639
|
+
function readNonEmptyString4(value) {
|
|
3591
3640
|
if (typeof value !== "string") {
|
|
3592
3641
|
return void 0;
|
|
3593
3642
|
}
|
|
@@ -3609,7 +3658,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3609
3658
|
return void 0;
|
|
3610
3659
|
}
|
|
3611
3660
|
if (toolName === "write_report") {
|
|
3612
|
-
const report =
|
|
3661
|
+
const report = readNonEmptyString4(data.report);
|
|
3613
3662
|
if (!report) {
|
|
3614
3663
|
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");
|
|
3615
3664
|
}
|
|
@@ -3619,7 +3668,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3619
3668
|
if (data.success !== true) {
|
|
3620
3669
|
return void 0;
|
|
3621
3670
|
}
|
|
3622
|
-
const finalAnswer =
|
|
3671
|
+
const finalAnswer = readNonEmptyString4(data.final_answer);
|
|
3623
3672
|
if (!finalAnswer) {
|
|
3624
3673
|
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");
|
|
3625
3674
|
}
|
|
@@ -4164,6 +4213,31 @@ function ensureToolContextRuntimeCapability(params) {
|
|
|
4164
4213
|
function getToolContextRuntimeBinding(context) {
|
|
4165
4214
|
return readBinding(context);
|
|
4166
4215
|
}
|
|
4216
|
+
function copyToolContextRuntimeCapability(source, target) {
|
|
4217
|
+
const sourceBinding = readBinding(source);
|
|
4218
|
+
if (!sourceBinding) {
|
|
4219
|
+
return void 0;
|
|
4220
|
+
}
|
|
4221
|
+
const existingTargetBinding = readBinding(target);
|
|
4222
|
+
if (existingTargetBinding) {
|
|
4223
|
+
exposeCompatibilitySurface(target, existingTargetBinding);
|
|
4224
|
+
return existingTargetBinding;
|
|
4225
|
+
}
|
|
4226
|
+
const targetBinding = createRuntimeBinding({
|
|
4227
|
+
context: target,
|
|
4228
|
+
persistedHistory: () => sourceBinding.getPersistedHistoryEvents(),
|
|
4229
|
+
workingHistory: () => sourceBinding.getWorkingHistoryEvents(),
|
|
4230
|
+
executionMeta: sourceBinding.readExecutionMeta()
|
|
4231
|
+
});
|
|
4232
|
+
Object.defineProperty(target, TOOL_CONTEXT_RUNTIME_BINDING_KEY, {
|
|
4233
|
+
value: targetBinding,
|
|
4234
|
+
enumerable: false,
|
|
4235
|
+
configurable: true,
|
|
4236
|
+
writable: false
|
|
4237
|
+
});
|
|
4238
|
+
exposeCompatibilitySurface(target, targetBinding);
|
|
4239
|
+
return targetBinding;
|
|
4240
|
+
}
|
|
4167
4241
|
function readToolContextWorkingHistory(context) {
|
|
4168
4242
|
if (context.conversationView) {
|
|
4169
4243
|
return context.conversationView.getWorkingHistoryEvents();
|
|
@@ -4577,6 +4651,22 @@ var ToolNode = class {
|
|
|
4577
4651
|
});
|
|
4578
4652
|
}
|
|
4579
4653
|
async run(state) {
|
|
4654
|
+
const events = [];
|
|
4655
|
+
while (true) {
|
|
4656
|
+
const result = await this.runNextPendingToolCall(state);
|
|
4657
|
+
if (Array.isArray(result.events) && result.events.length > 0) {
|
|
4658
|
+
events.push(...result.events);
|
|
4659
|
+
}
|
|
4660
|
+
if (result.kind === "route" && result.nextNodeId === "tool") {
|
|
4661
|
+
continue;
|
|
4662
|
+
}
|
|
4663
|
+
return {
|
|
4664
|
+
...result,
|
|
4665
|
+
events
|
|
4666
|
+
};
|
|
4667
|
+
}
|
|
4668
|
+
}
|
|
4669
|
+
async runNextPendingToolCall(state) {
|
|
4580
4670
|
const calls = state.local?.pendingToolCalls ?? [];
|
|
4581
4671
|
const signalRaw = state.local?.signal;
|
|
4582
4672
|
if (isAbortSignal(signalRaw) && signalRaw.aborted) {
|
|
@@ -4784,18 +4874,25 @@ var ToolNode = class {
|
|
|
4784
4874
|
rawArguments: context.call.function?.arguments,
|
|
4785
4875
|
parsedArguments: context.toolArgs
|
|
4786
4876
|
});
|
|
4877
|
+
const remainingCalls = context.calls.slice(1);
|
|
4787
4878
|
context.state.local = buildErrorLocalState({
|
|
4788
4879
|
local: context.local,
|
|
4789
|
-
remainingCalls
|
|
4880
|
+
remainingCalls,
|
|
4790
4881
|
conversationId: context.conversationId,
|
|
4791
4882
|
turnId: context.turnId,
|
|
4792
4883
|
runtimeEvents: context.bridge.getRuntimeEvents(),
|
|
4793
4884
|
nextProtocolErrorCount: fuse.nextCount
|
|
4794
4885
|
});
|
|
4795
|
-
if (fuse.shouldFuse) {
|
|
4886
|
+
if (fuse.shouldFuse && remainingCalls.length === 0) {
|
|
4796
4887
|
throw createToolProtocolFuseError(fuse.nextCount, context.exec.error);
|
|
4797
4888
|
}
|
|
4798
|
-
return {
|
|
4889
|
+
return {
|
|
4890
|
+
kind: "route",
|
|
4891
|
+
// 同一个 assistant.tool_calls batch 必须为每个 call 产出 tool_output。
|
|
4892
|
+
// 出错时也继续消费剩余 call,ToolNode.run 会在本节点内 drain 完 batch 再回 LLM。
|
|
4893
|
+
nextNodeId: remainingCalls.length > 0 ? "tool" : "llm",
|
|
4894
|
+
events: context.bridge.getRuntimeEvents()
|
|
4895
|
+
};
|
|
4799
4896
|
}
|
|
4800
4897
|
};
|
|
4801
4898
|
|
|
@@ -4992,12 +5089,12 @@ function asRecord(value) {
|
|
|
4992
5089
|
}
|
|
4993
5090
|
return value;
|
|
4994
5091
|
}
|
|
4995
|
-
function summarizeCheckpoint(
|
|
5092
|
+
function summarizeCheckpoint(checkpointKey, state, savedAt) {
|
|
4996
5093
|
const local = asRecord(state.local);
|
|
4997
5094
|
const executorLocal = asRecord(local?.executorLocal);
|
|
4998
5095
|
const pendingToolCalls = local?.pendingToolCalls;
|
|
4999
5096
|
return {
|
|
5000
|
-
|
|
5097
|
+
checkpointKey,
|
|
5001
5098
|
schemaVersion: state.schemaVersion ?? 1,
|
|
5002
5099
|
savedAt,
|
|
5003
5100
|
currentNode: state.nodeId,
|
|
@@ -5016,25 +5113,25 @@ var MemoryCheckpointer = class {
|
|
|
5016
5113
|
local: state.local && typeof state.local === "object" && !Array.isArray(state.local) ? { ...state.local } : state.local
|
|
5017
5114
|
};
|
|
5018
5115
|
}
|
|
5019
|
-
async load(
|
|
5020
|
-
const entry = this.store.get(
|
|
5116
|
+
async load(checkpointKey) {
|
|
5117
|
+
const entry = this.store.get(checkpointKey);
|
|
5021
5118
|
return entry ? this.cloneState(entry.state) : null;
|
|
5022
5119
|
}
|
|
5023
|
-
async save(
|
|
5024
|
-
this.store.set(
|
|
5120
|
+
async save(checkpointKey, state) {
|
|
5121
|
+
this.store.set(checkpointKey, {
|
|
5025
5122
|
state: this.cloneState(state),
|
|
5026
5123
|
savedAt: Date.now()
|
|
5027
5124
|
});
|
|
5028
5125
|
}
|
|
5029
|
-
async clear(
|
|
5030
|
-
this.store.delete(
|
|
5126
|
+
async clear(checkpointKey) {
|
|
5127
|
+
this.store.delete(checkpointKey);
|
|
5031
5128
|
}
|
|
5032
|
-
async peekMeta(
|
|
5033
|
-
const entry = this.store.get(
|
|
5034
|
-
return entry ? summarizeCheckpoint(
|
|
5129
|
+
async peekMeta(checkpointKey) {
|
|
5130
|
+
const entry = this.store.get(checkpointKey);
|
|
5131
|
+
return entry ? summarizeCheckpoint(checkpointKey, entry.state, entry.savedAt) : null;
|
|
5035
5132
|
}
|
|
5036
5133
|
async list(filter = {}) {
|
|
5037
|
-
const summaries = Array.from(this.store.entries()).map(([
|
|
5134
|
+
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);
|
|
5038
5135
|
if (filter.limit === void 0) {
|
|
5039
5136
|
return summaries;
|
|
5040
5137
|
}
|
|
@@ -5106,6 +5203,7 @@ __export(tools_exports, {
|
|
|
5106
5203
|
CommonParameterTypes: () => CommonParameterTypes,
|
|
5107
5204
|
ContextCheckpointTool: () => ContextCheckpointTool,
|
|
5108
5205
|
computeToolIdempotencyKey: () => computeToolIdempotencyKey,
|
|
5206
|
+
copyToolContextRuntimeCapability: () => copyToolContextRuntimeCapability,
|
|
5109
5207
|
createContextCheckpointTool: () => createContextCheckpointTool,
|
|
5110
5208
|
ensureToolContextRuntimeCapability: () => ensureToolContextRuntimeCapability,
|
|
5111
5209
|
findCachedToolOutputByIdempotencyKey: () => findCachedToolOutputByIdempotencyKey,
|
|
@@ -5299,7 +5397,7 @@ function createContextCheckpointTool(options) {
|
|
|
5299
5397
|
function isRecord15(value) {
|
|
5300
5398
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
5301
5399
|
}
|
|
5302
|
-
function
|
|
5400
|
+
function readNonEmptyString5(value) {
|
|
5303
5401
|
if (typeof value !== "string") {
|
|
5304
5402
|
return void 0;
|
|
5305
5403
|
}
|
|
@@ -5319,13 +5417,13 @@ function readToolContextUserQuery(context) {
|
|
|
5319
5417
|
if (!context) {
|
|
5320
5418
|
return void 0;
|
|
5321
5419
|
}
|
|
5322
|
-
return
|
|
5420
|
+
return readNonEmptyString5(context["user_query"]);
|
|
5323
5421
|
}
|
|
5324
5422
|
function readToolContextModelId(context) {
|
|
5325
5423
|
if (!context) {
|
|
5326
5424
|
return void 0;
|
|
5327
5425
|
}
|
|
5328
|
-
return
|
|
5426
|
+
return readNonEmptyString5(context["modelId"]);
|
|
5329
5427
|
}
|
|
5330
5428
|
function readToolContextRunContext(context) {
|
|
5331
5429
|
if (!context) {
|
|
@@ -5532,18 +5630,18 @@ function createClassification(category, reason, suggestedDelay, extras) {
|
|
|
5532
5630
|
}
|
|
5533
5631
|
var ErrorClassifier = class {
|
|
5534
5632
|
static classify(error, context) {
|
|
5535
|
-
const
|
|
5633
|
+
const isRecord27 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
5536
5634
|
const baseMsg = (error.message || "").toLowerCase();
|
|
5537
5635
|
const causeMsg = (() => {
|
|
5538
5636
|
const cause = error.cause;
|
|
5539
5637
|
if (typeof cause === "string") return cause.toLowerCase();
|
|
5540
5638
|
if (cause instanceof Error) return (cause.message || "").toLowerCase();
|
|
5541
|
-
if (
|
|
5639
|
+
if (isRecord27(cause) && typeof cause["message"] === "string") return String(cause["message"]).toLowerCase();
|
|
5542
5640
|
return "";
|
|
5543
5641
|
})();
|
|
5544
5642
|
const causeCode = (() => {
|
|
5545
5643
|
const cause = error.cause;
|
|
5546
|
-
if (
|
|
5644
|
+
if (isRecord27(cause) && typeof cause["code"] === "string") return String(cause["code"]);
|
|
5547
5645
|
return "";
|
|
5548
5646
|
})();
|
|
5549
5647
|
const errorMessage = `${baseMsg} ${causeMsg}`.trim();
|
|
@@ -6035,6 +6133,9 @@ __export(llm_exports, {
|
|
|
6035
6133
|
LLMPolicyEngine: () => LLMPolicyEngine,
|
|
6036
6134
|
LlmCaller: () => LlmCaller,
|
|
6037
6135
|
ModelResolver: () => ModelResolver,
|
|
6136
|
+
appendStreamingProviderReasoningDetails: () => appendStreamingProviderReasoningDetails,
|
|
6137
|
+
compactProviderReasoningDetails: () => compactProviderReasoningDetails,
|
|
6138
|
+
compactReasoningDetailsInValue: () => compactReasoningDetailsInValue,
|
|
6038
6139
|
createDefaultTokenizerPort: () => createDefaultTokenizerPort,
|
|
6039
6140
|
defaultPolicyEngine: () => defaultPolicyEngine
|
|
6040
6141
|
});
|
|
@@ -6424,6 +6525,90 @@ function assertToolCallsHaveValidJsonArguments(toolCalls) {
|
|
|
6424
6525
|
}
|
|
6425
6526
|
}
|
|
6426
6527
|
|
|
6528
|
+
// src/runtime-kernel/llm/reasoning-details.ts
|
|
6529
|
+
var mergeableTextFields = ["reasoning_content"];
|
|
6530
|
+
function isRecord20(value) {
|
|
6531
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
6532
|
+
}
|
|
6533
|
+
function findMergeableTextField(detail) {
|
|
6534
|
+
if (!isRecord20(detail)) return void 0;
|
|
6535
|
+
if (typeof detail.provider !== "string") return void 0;
|
|
6536
|
+
if (typeof detail.type !== "string") return void 0;
|
|
6537
|
+
for (const field of mergeableTextFields) {
|
|
6538
|
+
if (typeof detail[field] === "string") {
|
|
6539
|
+
return field;
|
|
6540
|
+
}
|
|
6541
|
+
}
|
|
6542
|
+
return void 0;
|
|
6543
|
+
}
|
|
6544
|
+
function hasOnlyStableTextDetailFields(detail, textField) {
|
|
6545
|
+
const allowedKeys = /* @__PURE__ */ new Set(["provider", "type", textField]);
|
|
6546
|
+
return Object.keys(detail).every((key) => allowedKeys.has(key));
|
|
6547
|
+
}
|
|
6548
|
+
function canMergeTextDetails(previous, incoming) {
|
|
6549
|
+
if (!isRecord20(previous) || !isRecord20(incoming)) return false;
|
|
6550
|
+
const previousField = findMergeableTextField(previous);
|
|
6551
|
+
const incomingField = findMergeableTextField(incoming);
|
|
6552
|
+
if (!previousField || previousField !== incomingField) return false;
|
|
6553
|
+
return previous.provider === incoming.provider && previous.type === incoming.type && hasOnlyStableTextDetailFields(previous, previousField) && hasOnlyStableTextDetailFields(incoming, incomingField);
|
|
6554
|
+
}
|
|
6555
|
+
function mergeStreamingText(previous, incoming) {
|
|
6556
|
+
if (!previous) return incoming;
|
|
6557
|
+
if (!incoming) return previous;
|
|
6558
|
+
if (incoming.startsWith(previous)) {
|
|
6559
|
+
return incoming;
|
|
6560
|
+
}
|
|
6561
|
+
if (previous.endsWith(incoming)) {
|
|
6562
|
+
return previous;
|
|
6563
|
+
}
|
|
6564
|
+
return `${previous}${incoming}`;
|
|
6565
|
+
}
|
|
6566
|
+
function appendStreamingProviderReasoningDetails(existing, incoming) {
|
|
6567
|
+
const next = [...existing];
|
|
6568
|
+
for (const detail of incoming) {
|
|
6569
|
+
const previous = next[next.length - 1];
|
|
6570
|
+
if (canMergeTextDetails(previous, detail)) {
|
|
6571
|
+
const textField = findMergeableTextField(previous);
|
|
6572
|
+
if (textField && isRecord20(detail)) {
|
|
6573
|
+
const mergedText = mergeStreamingText(String(previous[textField]), String(detail[textField]));
|
|
6574
|
+
if (mergedText === previous[textField]) {
|
|
6575
|
+
continue;
|
|
6576
|
+
}
|
|
6577
|
+
next[next.length - 1] = {
|
|
6578
|
+
...previous,
|
|
6579
|
+
[textField]: mergedText
|
|
6580
|
+
};
|
|
6581
|
+
continue;
|
|
6582
|
+
}
|
|
6583
|
+
}
|
|
6584
|
+
next.push(detail);
|
|
6585
|
+
}
|
|
6586
|
+
return next;
|
|
6587
|
+
}
|
|
6588
|
+
function compactProviderReasoningDetails(reasoningDetails) {
|
|
6589
|
+
return appendStreamingProviderReasoningDetails([], reasoningDetails);
|
|
6590
|
+
}
|
|
6591
|
+
function compactReasoningDetailsInValue(value) {
|
|
6592
|
+
return compactValue(value);
|
|
6593
|
+
}
|
|
6594
|
+
function compactValue(value) {
|
|
6595
|
+
if (Array.isArray(value)) {
|
|
6596
|
+
return value.map((item) => compactValue(item));
|
|
6597
|
+
}
|
|
6598
|
+
if (!isRecord20(value)) {
|
|
6599
|
+
return value;
|
|
6600
|
+
}
|
|
6601
|
+
const compacted = {};
|
|
6602
|
+
for (const [key, childValue] of Object.entries(value)) {
|
|
6603
|
+
if (key === "reasoning_details" && Array.isArray(childValue)) {
|
|
6604
|
+
compacted[key] = compactProviderReasoningDetails(childValue);
|
|
6605
|
+
continue;
|
|
6606
|
+
}
|
|
6607
|
+
compacted[key] = compactValue(childValue);
|
|
6608
|
+
}
|
|
6609
|
+
return compacted;
|
|
6610
|
+
}
|
|
6611
|
+
|
|
6427
6612
|
// src/runtime-kernel/llm/streaming-adapter.ts
|
|
6428
6613
|
async function callLlmStream(params) {
|
|
6429
6614
|
const {
|
|
@@ -6436,7 +6621,7 @@ async function callLlmStream(params) {
|
|
|
6436
6621
|
} = params;
|
|
6437
6622
|
let fullResponse = "";
|
|
6438
6623
|
let streamError = null;
|
|
6439
|
-
|
|
6624
|
+
let reasoningDetails = [];
|
|
6440
6625
|
const streamAnswerId = generateMessageId();
|
|
6441
6626
|
let streamChunkSeq = 0;
|
|
6442
6627
|
let capturedUsage = void 0;
|
|
@@ -6506,13 +6691,21 @@ async function callLlmStream(params) {
|
|
|
6506
6691
|
const reasoning = isRecord19(chunk) ? chunk["reasoning_details"] : void 0;
|
|
6507
6692
|
if (reasoning !== void 0) {
|
|
6508
6693
|
const newReasoningDetails = Array.isArray(reasoning) ? reasoning : [reasoning];
|
|
6509
|
-
reasoningDetails
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6694
|
+
const previousReasoningDetails = reasoningDetails;
|
|
6695
|
+
const previousLength = previousReasoningDetails.length;
|
|
6696
|
+
const compactedReasoningDetails = appendStreamingProviderReasoningDetails(reasoningDetails, newReasoningDetails);
|
|
6697
|
+
reasoningDetails = compactedReasoningDetails;
|
|
6698
|
+
const previousLastChanged = previousLength > 0 && compactedReasoningDetails[previousLength - 1] !== previousReasoningDetails[previousLength - 1];
|
|
6699
|
+
const emitFromIndex = previousLastChanged ? previousLength - 1 : previousLength;
|
|
6700
|
+
const emittedReasoningDetails = compactedReasoningDetails.slice(Math.max(0, emitFromIndex));
|
|
6701
|
+
if (emittedReasoningDetails.length > 0) {
|
|
6702
|
+
eventHandler({
|
|
6703
|
+
type: "provider_sidecar",
|
|
6704
|
+
id: generateMessageId(),
|
|
6705
|
+
timestamp: Date.now(),
|
|
6706
|
+
reasoning_details: emittedReasoningDetails
|
|
6707
|
+
});
|
|
6708
|
+
}
|
|
6516
6709
|
}
|
|
6517
6710
|
if (chunk.tool_calls) {
|
|
6518
6711
|
emitThoughtComplete(thoughtSegmenter.onBoundary());
|
|
@@ -6966,7 +7159,6 @@ __export(child_runs_exports, {
|
|
|
6966
7159
|
|
|
6967
7160
|
// src/runtime-kernel/child-runs/childToolContext.ts
|
|
6968
7161
|
function createChildRunToolContext(params) {
|
|
6969
|
-
const inheritedConversationId = typeof params.parentToolContext.conversationId === "string" && params.parentToolContext.conversationId.trim().length > 0 ? params.parentToolContext.conversationId.trim() : void 0;
|
|
6970
7162
|
const inheritedContext = stripRuntimeReservedToolContextPatch(params.parentToolContext);
|
|
6971
7163
|
const childToolContext = {
|
|
6972
7164
|
...inheritedContext,
|
|
@@ -6978,7 +7170,7 @@ function createChildRunToolContext(params) {
|
|
|
6978
7170
|
persistedHistory: params.seedHistory,
|
|
6979
7171
|
workingHistory: params.seedHistory,
|
|
6980
7172
|
executionMeta: {
|
|
6981
|
-
conversationId:
|
|
7173
|
+
conversationId: params.conversationId,
|
|
6982
7174
|
turnId: params.turnId,
|
|
6983
7175
|
runId: params.runId,
|
|
6984
7176
|
parentRunId: params.parentRunId
|
|
@@ -7129,7 +7321,7 @@ var FinalAnswerCollector = class {
|
|
|
7129
7321
|
};
|
|
7130
7322
|
|
|
7131
7323
|
// src/runtime-kernel/child-runs/childRunTraceSink.ts
|
|
7132
|
-
function
|
|
7324
|
+
function isRecord21(v) {
|
|
7133
7325
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
7134
7326
|
}
|
|
7135
7327
|
function getString2(obj, key) {
|
|
@@ -7162,7 +7354,7 @@ function createChildRunTraceSink(params) {
|
|
|
7162
7354
|
const { publisher, conversationId, turnId } = params;
|
|
7163
7355
|
const finalAnswerCollector = new FinalAnswerCollector(conversationId, turnId);
|
|
7164
7356
|
const sink = (evt) => {
|
|
7165
|
-
if (!
|
|
7357
|
+
if (!isRecord21(evt)) {
|
|
7166
7358
|
return [];
|
|
7167
7359
|
}
|
|
7168
7360
|
const type = getString2(evt, "type");
|
|
@@ -7298,7 +7490,7 @@ function readCheckpointHistory(checkpoint) {
|
|
|
7298
7490
|
});
|
|
7299
7491
|
}
|
|
7300
7492
|
async function recoverChildRunEventsFromCheckpoint(params) {
|
|
7301
|
-
const checkpoint = await params.checkpointer.load(params.
|
|
7493
|
+
const checkpoint = await params.checkpointer.load(params.checkpointKey);
|
|
7302
7494
|
const history = readCheckpointHistory(checkpoint);
|
|
7303
7495
|
if (history.length === 0) {
|
|
7304
7496
|
return [];
|
|
@@ -7306,7 +7498,7 @@ async function recoverChildRunEventsFromCheckpoint(params) {
|
|
|
7306
7498
|
if (hasSeedHistoryPrefix(history, params.seedHistory)) {
|
|
7307
7499
|
return history.slice(params.seedHistory.length);
|
|
7308
7500
|
}
|
|
7309
|
-
return history.filter((event) => event.conversation_id === params.
|
|
7501
|
+
return history.filter((event) => event.conversation_id === params.childConversationId);
|
|
7310
7502
|
}
|
|
7311
7503
|
|
|
7312
7504
|
// src/runtime-kernel/child-runs/childRunInvoker.ts
|
|
@@ -7335,6 +7527,7 @@ var ChildRunInvoker = class {
|
|
|
7335
7527
|
agentConfig,
|
|
7336
7528
|
userMessage,
|
|
7337
7529
|
parentToolContext,
|
|
7530
|
+
conversationId,
|
|
7338
7531
|
runId,
|
|
7339
7532
|
parentRunId,
|
|
7340
7533
|
subrunTracePublisher,
|
|
@@ -7343,12 +7536,18 @@ var ChildRunInvoker = class {
|
|
|
7343
7536
|
modelId,
|
|
7344
7537
|
abortSignal
|
|
7345
7538
|
} = config;
|
|
7346
|
-
const
|
|
7539
|
+
const internalCheckpointKey = `internal_${generateMessageId()}`;
|
|
7540
|
+
const runtimeConversationId = resolveChildRunConversationId({
|
|
7541
|
+
explicitConversationId: conversationId,
|
|
7542
|
+
parentToolContext,
|
|
7543
|
+
fallbackConversationId: internalCheckpointKey
|
|
7544
|
+
});
|
|
7347
7545
|
const turnId = `turn_${Date.now()}`;
|
|
7348
|
-
const childRunId = typeof runId === "string" && runId.trim().length > 0 ? runId.trim() :
|
|
7546
|
+
const childRunId = typeof runId === "string" && runId.trim().length > 0 ? runId.trim() : internalCheckpointKey;
|
|
7349
7547
|
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;
|
|
7350
7548
|
logger13.info(`\u542F\u52A8 child-run: ${agentConfig.id}`, {
|
|
7351
|
-
conversationId:
|
|
7549
|
+
conversationId: runtimeConversationId,
|
|
7550
|
+
checkpointKey: internalCheckpointKey,
|
|
7352
7551
|
maxSteps,
|
|
7353
7552
|
userMessage: userMessage.slice(0, 100) + (userMessage.length > 100 ? "..." : "")
|
|
7354
7553
|
});
|
|
@@ -7409,7 +7608,7 @@ var ChildRunInvoker = class {
|
|
|
7409
7608
|
const seedHistory = Array.isArray(seedHistoryEvents) ? seedHistoryEvents : [];
|
|
7410
7609
|
const childToolContext = createChildRunToolContext({
|
|
7411
7610
|
parentToolContext,
|
|
7412
|
-
|
|
7611
|
+
conversationId: runtimeConversationId,
|
|
7413
7612
|
turnId,
|
|
7414
7613
|
runId: childRunId,
|
|
7415
7614
|
parentRunId: resolvedParentRunId,
|
|
@@ -7418,13 +7617,13 @@ var ChildRunInvoker = class {
|
|
|
7418
7617
|
});
|
|
7419
7618
|
const subrunSseSink = subrunTracePublisher ? createChildRunTraceSink({
|
|
7420
7619
|
publisher: subrunTracePublisher,
|
|
7421
|
-
conversationId:
|
|
7620
|
+
conversationId: runtimeConversationId,
|
|
7422
7621
|
turnId
|
|
7423
7622
|
}) : void 0;
|
|
7424
7623
|
const initialLocal = {
|
|
7425
7624
|
request,
|
|
7426
7625
|
history: seedHistory,
|
|
7427
|
-
conversationId:
|
|
7626
|
+
conversationId: runtimeConversationId,
|
|
7428
7627
|
turnId,
|
|
7429
7628
|
toolContext: childToolContext,
|
|
7430
7629
|
...abortSignal ? { signal: abortSignal } : {},
|
|
@@ -7432,7 +7631,7 @@ var ChildRunInvoker = class {
|
|
|
7432
7631
|
...subrunSseSink ? { sseSink: subrunSseSink } : {},
|
|
7433
7632
|
systemPrompt
|
|
7434
7633
|
};
|
|
7435
|
-
await graphExecutor.prime(
|
|
7634
|
+
await graphExecutor.prime(internalCheckpointKey, initialLocal, "llm");
|
|
7436
7635
|
const allEvents = [];
|
|
7437
7636
|
let stepCount = 0;
|
|
7438
7637
|
let finalAnswer;
|
|
@@ -7444,7 +7643,7 @@ var ChildRunInvoker = class {
|
|
|
7444
7643
|
err.name = "AbortError";
|
|
7445
7644
|
throw err;
|
|
7446
7645
|
}
|
|
7447
|
-
const result = await graphExecutor.runUntilYield(
|
|
7646
|
+
const result = await graphExecutor.runUntilYield(internalCheckpointKey);
|
|
7448
7647
|
appendUniqueEvents(allEvents, result.events);
|
|
7449
7648
|
stepCount = result.stepCount;
|
|
7450
7649
|
if (subrunSseSink && typeof subrunSseSink.finalize === "function") {
|
|
@@ -7478,8 +7677,8 @@ var ChildRunInvoker = class {
|
|
|
7478
7677
|
}
|
|
7479
7678
|
const recoveredEvents = await recoverChildRunEventsFromCheckpoint({
|
|
7480
7679
|
checkpointer,
|
|
7481
|
-
|
|
7482
|
-
|
|
7680
|
+
checkpointKey: internalCheckpointKey,
|
|
7681
|
+
childConversationId: runtimeConversationId,
|
|
7483
7682
|
seedHistory
|
|
7484
7683
|
});
|
|
7485
7684
|
appendUniqueEvents(allEvents, recoveredEvents);
|
|
@@ -7496,7 +7695,7 @@ var ChildRunInvoker = class {
|
|
|
7496
7695
|
stack: err.stack
|
|
7497
7696
|
} : { error: String(err) });
|
|
7498
7697
|
}
|
|
7499
|
-
await checkpointer.clear(
|
|
7698
|
+
await checkpointer.clear(internalCheckpointKey);
|
|
7500
7699
|
return {
|
|
7501
7700
|
success: !error,
|
|
7502
7701
|
runId: childRunId,
|
|
@@ -7509,6 +7708,16 @@ var ChildRunInvoker = class {
|
|
|
7509
7708
|
};
|
|
7510
7709
|
}
|
|
7511
7710
|
};
|
|
7711
|
+
function readNonEmptyString6(value) {
|
|
7712
|
+
if (typeof value !== "string") {
|
|
7713
|
+
return void 0;
|
|
7714
|
+
}
|
|
7715
|
+
const trimmed = value.trim();
|
|
7716
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
7717
|
+
}
|
|
7718
|
+
function resolveChildRunConversationId(params) {
|
|
7719
|
+
return readNonEmptyString6(params.explicitConversationId) ?? readNonEmptyString6(params.parentToolContext.conversationId) ?? params.fallbackConversationId;
|
|
7720
|
+
}
|
|
7512
7721
|
function resolveChildRunSystemReminderPolicy(agentConfig) {
|
|
7513
7722
|
const configured = agentConfig.systemReminderPolicy ?? agentConfig.contextPolicy?.systemReminder;
|
|
7514
7723
|
const threshold = agentConfig.stepPolicy?.lastStepsHintThreshold;
|
|
@@ -7699,7 +7908,7 @@ function cloneRunRecord(record) {
|
|
|
7699
7908
|
...record,
|
|
7700
7909
|
iterationBudget: record.iterationBudget ? { ...record.iterationBudget } : void 0,
|
|
7701
7910
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0,
|
|
7702
|
-
metadata: record.metadata ?
|
|
7911
|
+
metadata: record.metadata ? structuredClone(record.metadata) : void 0
|
|
7703
7912
|
};
|
|
7704
7913
|
}
|
|
7705
7914
|
function matchesStatus(candidate, filter) {
|
|
@@ -7831,7 +8040,7 @@ function runRecordToMeta(record) {
|
|
|
7831
8040
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0
|
|
7832
8041
|
};
|
|
7833
8042
|
}
|
|
7834
|
-
function
|
|
8043
|
+
function isRecord22(value) {
|
|
7835
8044
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7836
8045
|
}
|
|
7837
8046
|
function readStringField(record, key) {
|
|
@@ -7852,7 +8061,7 @@ function getRunIdFromMetadata(event) {
|
|
|
7852
8061
|
return snakeCaseRunId;
|
|
7853
8062
|
}
|
|
7854
8063
|
const runContext = metadata["run_context"];
|
|
7855
|
-
if (
|
|
8064
|
+
if (isRecord22(runContext)) {
|
|
7856
8065
|
return readStringField(runContext, "runId") ?? readStringField(runContext, "run_id");
|
|
7857
8066
|
}
|
|
7858
8067
|
return void 0;
|
|
@@ -8070,7 +8279,7 @@ function runMetaFromRecord(record) {
|
|
|
8070
8279
|
}
|
|
8071
8280
|
|
|
8072
8281
|
// src/runtime-kernel/run-supervisor/runSupervisor.ts
|
|
8073
|
-
function
|
|
8282
|
+
function isRecord23(value) {
|
|
8074
8283
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8075
8284
|
}
|
|
8076
8285
|
function readStringField2(record, key) {
|
|
@@ -8087,7 +8296,7 @@ function readRunIdFromRuntimeEvent(event) {
|
|
|
8087
8296
|
return directRunId;
|
|
8088
8297
|
}
|
|
8089
8298
|
const runContext = metadata["run_context"];
|
|
8090
|
-
if (!
|
|
8299
|
+
if (!isRecord23(runContext)) {
|
|
8091
8300
|
return void 0;
|
|
8092
8301
|
}
|
|
8093
8302
|
return readStringField2(runContext, "runId") ?? readStringField2(runContext, "run_id");
|
|
@@ -8099,7 +8308,7 @@ function readAwaitingUserReason(event) {
|
|
|
8099
8308
|
if (typeof event.prompt === "string" && event.prompt.trim().length > 0) {
|
|
8100
8309
|
return event.prompt;
|
|
8101
8310
|
}
|
|
8102
|
-
if (
|
|
8311
|
+
if (isRecord23(event.form)) {
|
|
8103
8312
|
const prompt = readStringField2(event.form, "prompt");
|
|
8104
8313
|
if (prompt && prompt.trim().length > 0) {
|
|
8105
8314
|
return prompt;
|
|
@@ -8111,7 +8320,7 @@ function isTerminalStatus(status) {
|
|
|
8111
8320
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
8112
8321
|
}
|
|
8113
8322
|
function cloneMetadata(metadata) {
|
|
8114
|
-
return metadata ?
|
|
8323
|
+
return metadata ? structuredClone(metadata) : void 0;
|
|
8115
8324
|
}
|
|
8116
8325
|
function recordToSnapshot(record) {
|
|
8117
8326
|
return {
|
|
@@ -8198,7 +8407,7 @@ var DefaultRunSupervisor = class {
|
|
|
8198
8407
|
startedAt,
|
|
8199
8408
|
updatedAt: startedAt,
|
|
8200
8409
|
iterationBudget: spec.iterationBudget ? { ...spec.iterationBudget } : void 0,
|
|
8201
|
-
metadata: spec.metadata
|
|
8410
|
+
metadata: cloneMetadata(spec.metadata)
|
|
8202
8411
|
};
|
|
8203
8412
|
await this.registryStore.save(record);
|
|
8204
8413
|
const handle = new DefaultRunHandle({
|
|
@@ -8372,12 +8581,13 @@ var DefaultRunSupervisor = class {
|
|
|
8372
8581
|
}
|
|
8373
8582
|
try {
|
|
8374
8583
|
await handle.markRunning({ currentNode: "detached" });
|
|
8584
|
+
const registeredRecord = await this.registryStore.load(handle.runId);
|
|
8375
8585
|
const executorOutcome = await this.executor.execute({
|
|
8376
8586
|
runId: handle.runId,
|
|
8377
|
-
parentRunId:
|
|
8378
|
-
conversationId: spec.conversationId,
|
|
8379
|
-
agentSpec: spec
|
|
8380
|
-
request:
|
|
8587
|
+
parentRunId: handle.parentRunId,
|
|
8588
|
+
conversationId: registeredRecord?.conversationId ?? spec.conversationId,
|
|
8589
|
+
agentSpec: await handle.spec(),
|
|
8590
|
+
request: await handle.request(),
|
|
8381
8591
|
signal: handle.signal,
|
|
8382
8592
|
eventBus: spec.eventBus,
|
|
8383
8593
|
eventStore: spec.eventStore,
|
|
@@ -8386,7 +8596,7 @@ var DefaultRunSupervisor = class {
|
|
|
8386
8596
|
contextFences: spec.contextFences,
|
|
8387
8597
|
wakeSource: spec.wakeSource,
|
|
8388
8598
|
ephemeral: spec.ephemeral,
|
|
8389
|
-
metadata: spec.metadata
|
|
8599
|
+
metadata: cloneMetadata(registeredRecord?.metadata ?? spec.metadata)
|
|
8390
8600
|
});
|
|
8391
8601
|
const outcome = await this.persistExecutorOutcome(handle, executorOutcome);
|
|
8392
8602
|
this.notifyTerminalWaiters(outcome);
|
|
@@ -8450,10 +8660,14 @@ var DefaultRunSupervisor = class {
|
|
|
8450
8660
|
await this.registryStore.save(record);
|
|
8451
8661
|
}
|
|
8452
8662
|
const completedAt = executorOutcome?.completedAt ?? this.now();
|
|
8663
|
+
const fallbackMeta = record ? void 0 : await handle.meta();
|
|
8453
8664
|
const outcome = recordToTerminalOutcome(record ?? {
|
|
8454
8665
|
runId: handle.runId,
|
|
8455
8666
|
parentRunId: handle.parentRunId,
|
|
8456
|
-
|
|
8667
|
+
conversationId: fallbackMeta?.conversationId ?? "",
|
|
8668
|
+
agentSpecId: fallbackMeta?.agentSpecId,
|
|
8669
|
+
status: executorOutcome?.status ?? "completed",
|
|
8670
|
+
startedAt: fallbackMeta?.startedAt ?? completedAt}, completedAt);
|
|
8457
8671
|
const nextOutcome = {
|
|
8458
8672
|
...outcome,
|
|
8459
8673
|
metadata: {
|
|
@@ -8681,6 +8895,7 @@ function createGraphLoopHarness(options) {
|
|
|
8681
8895
|
};
|
|
8682
8896
|
return {
|
|
8683
8897
|
async run() {
|
|
8898
|
+
const checkpointKey = options.conversationId;
|
|
8684
8899
|
const executor = createDefaultGraphExecutor({
|
|
8685
8900
|
llmNode: options.createLlmNode({
|
|
8686
8901
|
llmCaller: options.llmCaller,
|
|
@@ -8709,8 +8924,8 @@ function createGraphLoopHarness(options) {
|
|
|
8709
8924
|
signal: options.signal ?? options.toolContext.abortSignal,
|
|
8710
8925
|
executorLocal
|
|
8711
8926
|
};
|
|
8712
|
-
await executor.prime(
|
|
8713
|
-
const result = await executor.runUntilYield(
|
|
8927
|
+
await executor.prime(checkpointKey, local, "user");
|
|
8928
|
+
const result = await executor.runUntilYield(checkpointKey);
|
|
8714
8929
|
return {
|
|
8715
8930
|
checkpointNodeId: result.checkpoint.nodeId,
|
|
8716
8931
|
stepCount: result.stepCount
|
|
@@ -8985,11 +9200,11 @@ new MessageFormatter();
|
|
|
8985
9200
|
|
|
8986
9201
|
// src/context-manager/profiles/agent/utils/toolInteractionGroup.ts
|
|
8987
9202
|
var CHECKPOINT_TOOL_NAME = "context_checkpoint";
|
|
8988
|
-
function
|
|
9203
|
+
function isRecord24(value) {
|
|
8989
9204
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8990
9205
|
}
|
|
8991
9206
|
function isToolCallRecord(value) {
|
|
8992
|
-
if (!
|
|
9207
|
+
if (!isRecord24(value)) {
|
|
8993
9208
|
return false;
|
|
8994
9209
|
}
|
|
8995
9210
|
return typeof value.id === "string" && value.id.trim().length > 0;
|
|
@@ -9007,7 +9222,7 @@ function safeParseArgs(rawArgs) {
|
|
|
9007
9222
|
}
|
|
9008
9223
|
try {
|
|
9009
9224
|
const parsed = JSON.parse(rawArgs);
|
|
9010
|
-
return
|
|
9225
|
+
return isRecord24(parsed) ? parsed : {};
|
|
9011
9226
|
} catch {
|
|
9012
9227
|
return {};
|
|
9013
9228
|
}
|
|
@@ -9301,7 +9516,7 @@ var summarizeToolOutput = (toolName, output, toolSummaryProvider, toolArgs, conf
|
|
|
9301
9516
|
};
|
|
9302
9517
|
|
|
9303
9518
|
// src/context-manager/profiles/agent/utils/eventConverter.ts
|
|
9304
|
-
function
|
|
9519
|
+
function isRecord25(value) {
|
|
9305
9520
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9306
9521
|
}
|
|
9307
9522
|
function isHistorySummaryEvent2(event) {
|
|
@@ -9359,10 +9574,10 @@ function convertEventToAiMessage(event) {
|
|
|
9359
9574
|
timestamp: event.timestamp,
|
|
9360
9575
|
metadata: {
|
|
9361
9576
|
tool_calls: (() => {
|
|
9362
|
-
const
|
|
9577
|
+
const isRecord27 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
9363
9578
|
const payload = event.payload;
|
|
9364
9579
|
const toolCallsFromPayload = (() => {
|
|
9365
|
-
if (!
|
|
9580
|
+
if (!isRecord27(payload)) return void 0;
|
|
9366
9581
|
const raw = payload["tool_calls"];
|
|
9367
9582
|
return Array.isArray(raw) ? raw : void 0;
|
|
9368
9583
|
})();
|
|
@@ -9381,9 +9596,9 @@ function convertEventToAiMessage(event) {
|
|
|
9381
9596
|
];
|
|
9382
9597
|
})(),
|
|
9383
9598
|
reasoning_details: (() => {
|
|
9384
|
-
const
|
|
9599
|
+
const isRecord27 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
9385
9600
|
const payload = event.payload;
|
|
9386
|
-
if (!
|
|
9601
|
+
if (!isRecord27(payload)) return void 0;
|
|
9387
9602
|
const rd = payload["reasoning_details"];
|
|
9388
9603
|
return Array.isArray(rd) ? rd : void 0;
|
|
9389
9604
|
})()
|
|
@@ -9392,15 +9607,15 @@ function convertEventToAiMessage(event) {
|
|
|
9392
9607
|
case "tool_output": {
|
|
9393
9608
|
const observationFromPayload = (() => {
|
|
9394
9609
|
const payload = event.payload;
|
|
9395
|
-
if (!
|
|
9610
|
+
if (!isRecord25(payload)) return void 0;
|
|
9396
9611
|
const result = payload["result"];
|
|
9397
|
-
if (!
|
|
9612
|
+
if (!isRecord25(result)) return void 0;
|
|
9398
9613
|
const obs = result["observation"];
|
|
9399
9614
|
return typeof obs === "string" && obs.trim().length > 0 ? obs : void 0;
|
|
9400
9615
|
})();
|
|
9401
9616
|
const rawOutput = (() => {
|
|
9402
9617
|
const payload = event.payload;
|
|
9403
|
-
if (
|
|
9618
|
+
if (isRecord25(payload)) {
|
|
9404
9619
|
const out = payload["output"];
|
|
9405
9620
|
if (typeof out === "string" && out.trim().length > 0) {
|
|
9406
9621
|
return out;
|
|
@@ -9525,7 +9740,7 @@ __export(utils_exports, {
|
|
|
9525
9740
|
});
|
|
9526
9741
|
|
|
9527
9742
|
// src/testkit/context-harness/replayHarness.ts
|
|
9528
|
-
function
|
|
9743
|
+
function isRecord26(value) {
|
|
9529
9744
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9530
9745
|
}
|
|
9531
9746
|
function createReplayHarness(events) {
|
|
@@ -9537,7 +9752,7 @@ function createReplayHarness(events) {
|
|
|
9537
9752
|
if (message.role !== "assistant" || message.type !== "tool_calls") {
|
|
9538
9753
|
return false;
|
|
9539
9754
|
}
|
|
9540
|
-
if (!
|
|
9755
|
+
if (!isRecord26(message.metadata)) {
|
|
9541
9756
|
return false;
|
|
9542
9757
|
}
|
|
9543
9758
|
return Array.isArray(message.metadata.tool_calls);
|