@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.js
CHANGED
|
@@ -105,14 +105,18 @@ __export(runtime_kernel_exports, {
|
|
|
105
105
|
UserNode: () => UserNode,
|
|
106
106
|
WaitUserNode: () => WaitUserNode,
|
|
107
107
|
agentHasToolTrigger: () => agentHasToolTrigger,
|
|
108
|
+
appendStreamingProviderReasoningDetails: () => appendStreamingProviderReasoningDetails,
|
|
108
109
|
applySystemReminders: () => applySystemReminders,
|
|
109
110
|
audit: () => audit_exports,
|
|
110
111
|
budgetWarningTrigger: () => budgetWarningTrigger,
|
|
111
112
|
childRunTrace: () => child_run_trace_exports,
|
|
112
113
|
childRuns: () => child_runs_exports,
|
|
114
|
+
compactProviderReasoningDetails: () => compactProviderReasoningDetails,
|
|
115
|
+
compactReasoningDetailsInValue: () => compactReasoningDetailsInValue,
|
|
113
116
|
computeToolIdempotencyKey: () => computeToolIdempotencyKey,
|
|
114
117
|
consoleAudit: () => consoleAudit,
|
|
115
118
|
contextBudgetWarningTemplate: () => contextBudgetWarningTemplate,
|
|
119
|
+
copyToolContextRuntimeCapability: () => copyToolContextRuntimeCapability,
|
|
116
120
|
countToolCallsInCurrentRequest: () => countToolCallsInCurrentRequest,
|
|
117
121
|
createCompositeAudit: () => createCompositeAudit,
|
|
118
122
|
createConsoleAudit: () => createConsoleAudit,
|
|
@@ -417,6 +421,7 @@ var AgentSpecBudgetPolicy = z.object({
|
|
|
417
421
|
});
|
|
418
422
|
var AgentSpecToolHistoryPolicy = z.object({
|
|
419
423
|
strategy: z.enum(["per-pair", "per-run", "none"]).optional(),
|
|
424
|
+
retentionMode: z.enum(["drop", "compress"]).optional(),
|
|
420
425
|
keepLatestToolPairs: z.number().int().nonnegative().optional(),
|
|
421
426
|
keepLatestRuns: z.number().int().nonnegative().optional(),
|
|
422
427
|
maxInteractionGroups: z.number().int().nonnegative().optional(),
|
|
@@ -1173,6 +1178,17 @@ var logger = new Logger("GraphExecutor");
|
|
|
1173
1178
|
function asLocalRecord(local) {
|
|
1174
1179
|
return local && typeof local === "object" ? { ...local } : {};
|
|
1175
1180
|
}
|
|
1181
|
+
function readNonEmptyString(value) {
|
|
1182
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1183
|
+
}
|
|
1184
|
+
function readRuntimeConversationId(state) {
|
|
1185
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1186
|
+
return readNonEmptyString(local?.conversationId);
|
|
1187
|
+
}
|
|
1188
|
+
function readRuntimeTurnId(state) {
|
|
1189
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1190
|
+
return readNonEmptyString(local?.turnId);
|
|
1191
|
+
}
|
|
1176
1192
|
var GraphExecutor = class {
|
|
1177
1193
|
constructor(checkpointer, config = {}) {
|
|
1178
1194
|
this.checkpointer = checkpointer;
|
|
@@ -1190,8 +1206,8 @@ var GraphExecutor = class {
|
|
|
1190
1206
|
registerNode(node) {
|
|
1191
1207
|
this.nodes.set(node.id, node);
|
|
1192
1208
|
}
|
|
1193
|
-
async peekCheckpoint(
|
|
1194
|
-
return await this.checkpointer.load(
|
|
1209
|
+
async peekCheckpoint(checkpointKey) {
|
|
1210
|
+
return await this.checkpointer.load(checkpointKey);
|
|
1195
1211
|
}
|
|
1196
1212
|
sanitize(state) {
|
|
1197
1213
|
const local = asLocalRecord(state.local);
|
|
@@ -1203,8 +1219,8 @@ var GraphExecutor = class {
|
|
|
1203
1219
|
local
|
|
1204
1220
|
};
|
|
1205
1221
|
}
|
|
1206
|
-
async prime(
|
|
1207
|
-
this.ephemeralLocals.set(
|
|
1222
|
+
async prime(checkpointKey, local, nodeId = "user") {
|
|
1223
|
+
this.ephemeralLocals.set(checkpointKey, { ...local || {} });
|
|
1208
1224
|
const localSansMemory = { ...local || {} };
|
|
1209
1225
|
if ("memory" in localSansMemory) delete localSansMemory.memory;
|
|
1210
1226
|
const state = {
|
|
@@ -1212,10 +1228,10 @@ var GraphExecutor = class {
|
|
|
1212
1228
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1213
1229
|
local: localSansMemory
|
|
1214
1230
|
};
|
|
1215
|
-
await this.checkpointer.save(
|
|
1231
|
+
await this.checkpointer.save(checkpointKey, state);
|
|
1216
1232
|
}
|
|
1217
|
-
async setNode(
|
|
1218
|
-
const current = await this.checkpointer.load(
|
|
1233
|
+
async setNode(checkpointKey, nodeId, localPatch) {
|
|
1234
|
+
const current = await this.checkpointer.load(checkpointKey) || {
|
|
1219
1235
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1220
1236
|
local: {}
|
|
1221
1237
|
};
|
|
@@ -1226,19 +1242,46 @@ var GraphExecutor = class {
|
|
|
1226
1242
|
schemaVersion: current.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
1227
1243
|
local: mergedLocal
|
|
1228
1244
|
};
|
|
1229
|
-
await this.checkpointer.save(
|
|
1245
|
+
await this.checkpointer.save(checkpointKey, next);
|
|
1230
1246
|
}
|
|
1231
|
-
async runUntilYield(
|
|
1247
|
+
async runUntilYield(checkpointKey) {
|
|
1232
1248
|
const runId = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1233
1249
|
let lifecyclePhase = "completed";
|
|
1250
|
+
let initialState = null;
|
|
1251
|
+
try {
|
|
1252
|
+
initialState = await this.loadInitialState(checkpointKey);
|
|
1253
|
+
} catch (err) {
|
|
1254
|
+
lifecyclePhase = "failed";
|
|
1255
|
+
this.telemetryPort.emit({
|
|
1256
|
+
kind: "run_lifecycle",
|
|
1257
|
+
runId,
|
|
1258
|
+
phase: "spawned",
|
|
1259
|
+
scope: {}
|
|
1260
|
+
});
|
|
1261
|
+
this.telemetryPort.emit({
|
|
1262
|
+
kind: "run_lifecycle",
|
|
1263
|
+
runId,
|
|
1264
|
+
phase: lifecyclePhase,
|
|
1265
|
+
scope: {}
|
|
1266
|
+
});
|
|
1267
|
+
throw err;
|
|
1268
|
+
}
|
|
1269
|
+
let lifecycleConversationId = readRuntimeConversationId(initialState);
|
|
1270
|
+
let lifecycleTurnId = readRuntimeTurnId(initialState);
|
|
1234
1271
|
this.telemetryPort.emit({
|
|
1235
1272
|
kind: "run_lifecycle",
|
|
1236
1273
|
runId,
|
|
1237
1274
|
phase: "spawned",
|
|
1238
|
-
scope: {
|
|
1275
|
+
scope: {
|
|
1276
|
+
conversationId: lifecycleConversationId,
|
|
1277
|
+
turnId: lifecycleTurnId
|
|
1278
|
+
}
|
|
1239
1279
|
});
|
|
1240
1280
|
try {
|
|
1241
|
-
|
|
1281
|
+
const result = await this.runUntilYieldInternal(checkpointKey, initialState);
|
|
1282
|
+
lifecycleConversationId = readRuntimeConversationId(result.checkpoint);
|
|
1283
|
+
lifecycleTurnId = readRuntimeTurnId(result.checkpoint);
|
|
1284
|
+
return result;
|
|
1242
1285
|
} catch (err) {
|
|
1243
1286
|
lifecyclePhase = err?.name === "AbortError" ? "cancelled" : "failed";
|
|
1244
1287
|
throw err;
|
|
@@ -1247,17 +1290,23 @@ var GraphExecutor = class {
|
|
|
1247
1290
|
kind: "run_lifecycle",
|
|
1248
1291
|
runId,
|
|
1249
1292
|
phase: lifecyclePhase,
|
|
1250
|
-
scope: {
|
|
1293
|
+
scope: {
|
|
1294
|
+
conversationId: lifecycleConversationId,
|
|
1295
|
+
turnId: lifecycleTurnId
|
|
1296
|
+
}
|
|
1251
1297
|
});
|
|
1252
1298
|
}
|
|
1253
1299
|
}
|
|
1254
|
-
async
|
|
1255
|
-
|
|
1300
|
+
async loadInitialState(checkpointKey) {
|
|
1301
|
+
return await this.checkpointer.load(checkpointKey) || {
|
|
1256
1302
|
nodeId: "user",
|
|
1257
1303
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1258
1304
|
local: {}
|
|
1259
1305
|
};
|
|
1260
|
-
|
|
1306
|
+
}
|
|
1307
|
+
async runUntilYieldInternal(checkpointKey, initialState) {
|
|
1308
|
+
let state = initialState;
|
|
1309
|
+
const ephemeral = this.ephemeralLocals.get(checkpointKey) || {};
|
|
1261
1310
|
state = {
|
|
1262
1311
|
...state,
|
|
1263
1312
|
schemaVersion: state.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
@@ -1286,7 +1335,7 @@ var GraphExecutor = class {
|
|
|
1286
1335
|
const signalRaw = state.local?.signal;
|
|
1287
1336
|
if (isAbortSignal2(signalRaw) && signalRaw.aborted) {
|
|
1288
1337
|
logger.warn("[GraphExecutor] \u6536\u5230 AbortSignal\uFF0C\u7ACB\u5373\u505C\u6B62\u63A8\u7406\u5FAA\u73AF");
|
|
1289
|
-
this.ephemeralLocals.delete(
|
|
1338
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1290
1339
|
throwAbortError();
|
|
1291
1340
|
}
|
|
1292
1341
|
const isLastStep = cycleStepCount >= this.config.maxSteps;
|
|
@@ -1334,8 +1383,8 @@ var GraphExecutor = class {
|
|
|
1334
1383
|
checkpointCount
|
|
1335
1384
|
});
|
|
1336
1385
|
const cp2 = this.sanitize(state);
|
|
1337
|
-
await this.checkpointer.save(
|
|
1338
|
-
this.ephemeralLocals.delete(
|
|
1386
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1387
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1339
1388
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1340
1389
|
}
|
|
1341
1390
|
logger.info("[GraphExecutor] \u8282\u70B9\u5207\u6362", {
|
|
@@ -1346,18 +1395,18 @@ var GraphExecutor = class {
|
|
|
1346
1395
|
});
|
|
1347
1396
|
const nodeRunStartedAt = Date.now();
|
|
1348
1397
|
const nodeIdForTelemetry = state.nodeId;
|
|
1398
|
+
const conversationIdForTelemetry = readRuntimeConversationId(state);
|
|
1349
1399
|
let result;
|
|
1350
1400
|
try {
|
|
1351
1401
|
result = await node.run(state);
|
|
1352
1402
|
} finally {
|
|
1353
|
-
const turnIdForTelemetry = typeof state.local?.turnId === "string" ? state.local.turnId : void 0;
|
|
1354
1403
|
this.telemetryPort.emit({
|
|
1355
1404
|
kind: "graph_node",
|
|
1356
1405
|
nodeId: nodeIdForTelemetry,
|
|
1357
1406
|
durationMs: Date.now() - nodeRunStartedAt,
|
|
1358
1407
|
scope: {
|
|
1359
|
-
conversationId:
|
|
1360
|
-
turnId:
|
|
1408
|
+
conversationId: conversationIdForTelemetry,
|
|
1409
|
+
turnId: readRuntimeTurnId(state)
|
|
1361
1410
|
}
|
|
1362
1411
|
});
|
|
1363
1412
|
}
|
|
@@ -1396,7 +1445,7 @@ var GraphExecutor = class {
|
|
|
1396
1445
|
});
|
|
1397
1446
|
state = { ...state, nodeId: nextNodeId };
|
|
1398
1447
|
const cp2 = this.sanitize(state);
|
|
1399
|
-
await this.checkpointer.save(
|
|
1448
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1400
1449
|
continue;
|
|
1401
1450
|
}
|
|
1402
1451
|
if (result.kind === "yield") {
|
|
@@ -1407,7 +1456,7 @@ var GraphExecutor = class {
|
|
|
1407
1456
|
checkpointCount
|
|
1408
1457
|
});
|
|
1409
1458
|
const cp2 = this.sanitize(state);
|
|
1410
|
-
await this.checkpointer.save(
|
|
1459
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1411
1460
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1412
1461
|
}
|
|
1413
1462
|
if (result.kind === "pause") {
|
|
@@ -1418,7 +1467,7 @@ var GraphExecutor = class {
|
|
|
1418
1467
|
checkpointCount
|
|
1419
1468
|
});
|
|
1420
1469
|
const cp2 = this.sanitize(state);
|
|
1421
|
-
await this.checkpointer.save(
|
|
1470
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1422
1471
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1423
1472
|
}
|
|
1424
1473
|
}
|
|
@@ -1429,8 +1478,8 @@ var GraphExecutor = class {
|
|
|
1429
1478
|
checkpointCount
|
|
1430
1479
|
});
|
|
1431
1480
|
const cp = this.sanitize(state);
|
|
1432
|
-
await this.checkpointer.save(
|
|
1433
|
-
this.ephemeralLocals.delete(
|
|
1481
|
+
await this.checkpointer.save(checkpointKey, cp);
|
|
1482
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1434
1483
|
return { events: allEvents, checkpoint: cp, stepCount };
|
|
1435
1484
|
}
|
|
1436
1485
|
};
|
|
@@ -1627,15 +1676,15 @@ function splitConcatenatedJsonObjects(input) {
|
|
|
1627
1676
|
}
|
|
1628
1677
|
|
|
1629
1678
|
// src/runtime-kernel/graph-engine/tick-pipeline/helpers.ts
|
|
1630
|
-
function
|
|
1679
|
+
function readNonEmptyString2(value) {
|
|
1631
1680
|
if (typeof value !== "string") return void 0;
|
|
1632
1681
|
const trimmed = value.trim();
|
|
1633
1682
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
1634
1683
|
}
|
|
1635
1684
|
function resolveConversationIdForRuntimeEvents(toolContext) {
|
|
1636
|
-
const fromCamel =
|
|
1685
|
+
const fromCamel = readNonEmptyString2(toolContext?.conversationId);
|
|
1637
1686
|
if (fromCamel) return fromCamel;
|
|
1638
|
-
const fromSnake = toolContext ?
|
|
1687
|
+
const fromSnake = toolContext ? readNonEmptyString2(toolContext["conversation_id"]) : void 0;
|
|
1639
1688
|
if (fromSnake) return fromSnake;
|
|
1640
1689
|
return generateMessageId();
|
|
1641
1690
|
}
|
|
@@ -1994,7 +2043,7 @@ var runModelLockMiddleware = async (ctx, stage, next) => {
|
|
|
1994
2043
|
if (stage.id !== "execute_llm") {
|
|
1995
2044
|
return;
|
|
1996
2045
|
}
|
|
1997
|
-
const normalized =
|
|
2046
|
+
const normalized = readNonEmptyString2(ctx.cloudQuotaFallbackAppliedModelId);
|
|
1998
2047
|
if (!normalized) {
|
|
1999
2048
|
return;
|
|
2000
2049
|
}
|
|
@@ -2595,7 +2644,7 @@ function createExecuteLlmStage(dependencies) {
|
|
|
2595
2644
|
streamEventHandler,
|
|
2596
2645
|
ctx.signal,
|
|
2597
2646
|
(fallbackModelId) => {
|
|
2598
|
-
ctx.cloudQuotaFallbackAppliedModelId =
|
|
2647
|
+
ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString2(fallbackModelId);
|
|
2599
2648
|
},
|
|
2600
2649
|
(info) => {
|
|
2601
2650
|
ctx.modelFallbackAudit = info;
|
|
@@ -2639,7 +2688,7 @@ function createPrepareCallStage(dependencies) {
|
|
|
2639
2688
|
return {
|
|
2640
2689
|
id: "prepare_call",
|
|
2641
2690
|
async run(ctx) {
|
|
2642
|
-
const lockedRunModelId =
|
|
2691
|
+
const lockedRunModelId = readNonEmptyString2(ctx.executorLocal?.runLockedModelId);
|
|
2643
2692
|
const requestedModelId = lockedRunModelId ?? ctx.request.model_id;
|
|
2644
2693
|
ctx.modelId = dependencies.modelResolver.resolveModelId(requestedModelId);
|
|
2645
2694
|
await emitAuditEnvelope(ctx.audit, {
|
|
@@ -2711,7 +2760,7 @@ var GraphAgentExecutor = class {
|
|
|
2711
2760
|
this.llmCaller = dependencies.llmCaller;
|
|
2712
2761
|
this.toolRuntime = dependencies.toolRuntime;
|
|
2713
2762
|
this.contextBuilder = dependencies.contextBuilder;
|
|
2714
|
-
this.cloudQuotaFallbackModelId =
|
|
2763
|
+
this.cloudQuotaFallbackModelId = readNonEmptyString2(dependencies.cloudQuotaFallbackModelId);
|
|
2715
2764
|
this.modelCatalog = dependencies.modelCatalog ?? createEmptyModelCatalog();
|
|
2716
2765
|
this.modelResolver = dependencies.modelResolver ?? new ModelResolver({
|
|
2717
2766
|
modelCatalog: this.modelCatalog
|
|
@@ -2759,7 +2808,7 @@ var GraphAgentExecutor = class {
|
|
|
2759
2808
|
llmMessages: [],
|
|
2760
2809
|
mode: input.request.mode === "chat" ? "chat" : "agent",
|
|
2761
2810
|
conversationId: resolveConversationIdForRuntimeEvents(input.toolContext),
|
|
2762
|
-
turnId:
|
|
2811
|
+
turnId: readNonEmptyString2(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
|
|
2763
2812
|
telemetry: this.telemetryPort,
|
|
2764
2813
|
audit: this.auditPort
|
|
2765
2814
|
};
|
|
@@ -2809,18 +2858,18 @@ function isSummarizationCallbacks(value) {
|
|
|
2809
2858
|
function isGraphSseSink(value) {
|
|
2810
2859
|
return typeof value === "function";
|
|
2811
2860
|
}
|
|
2812
|
-
function
|
|
2861
|
+
function readNonEmptyString3(value) {
|
|
2813
2862
|
if (typeof value !== "string") return void 0;
|
|
2814
2863
|
const trimmed = value.trim();
|
|
2815
2864
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
2816
2865
|
}
|
|
2817
2866
|
function readGraphAgentLocal(local) {
|
|
2818
2867
|
const source = local ?? {};
|
|
2819
|
-
const answerId =
|
|
2868
|
+
const answerId = readNonEmptyString3(source.answerId);
|
|
2820
2869
|
const chunkSeq = Number.isInteger(source.chunkSeq) ? Number(source.chunkSeq) : 0;
|
|
2821
2870
|
return {
|
|
2822
|
-
conversationId:
|
|
2823
|
-
turnId:
|
|
2871
|
+
conversationId: readNonEmptyString3(source.conversationId) ?? "",
|
|
2872
|
+
turnId: readNonEmptyString3(source.turnId),
|
|
2824
2873
|
request: isAgentInvocationRequest(source.request) ? source.request : void 0,
|
|
2825
2874
|
toolContext: isToolExecutionContext(source.toolContext) ? source.toolContext : void 0,
|
|
2826
2875
|
history: isRuntimeEventArray(source.history) ? source.history : [],
|
|
@@ -3585,7 +3634,7 @@ var LlmNode = class {
|
|
|
3585
3634
|
function isRecord8(value) {
|
|
3586
3635
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3587
3636
|
}
|
|
3588
|
-
function
|
|
3637
|
+
function readNonEmptyString4(value) {
|
|
3589
3638
|
if (typeof value !== "string") {
|
|
3590
3639
|
return void 0;
|
|
3591
3640
|
}
|
|
@@ -3607,7 +3656,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3607
3656
|
return void 0;
|
|
3608
3657
|
}
|
|
3609
3658
|
if (toolName === "write_report") {
|
|
3610
|
-
const report =
|
|
3659
|
+
const report = readNonEmptyString4(data.report);
|
|
3611
3660
|
if (!report) {
|
|
3612
3661
|
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");
|
|
3613
3662
|
}
|
|
@@ -3617,7 +3666,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3617
3666
|
if (data.success !== true) {
|
|
3618
3667
|
return void 0;
|
|
3619
3668
|
}
|
|
3620
|
-
const finalAnswer =
|
|
3669
|
+
const finalAnswer = readNonEmptyString4(data.final_answer);
|
|
3621
3670
|
if (!finalAnswer) {
|
|
3622
3671
|
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");
|
|
3623
3672
|
}
|
|
@@ -4162,6 +4211,31 @@ function ensureToolContextRuntimeCapability(params) {
|
|
|
4162
4211
|
function getToolContextRuntimeBinding(context) {
|
|
4163
4212
|
return readBinding(context);
|
|
4164
4213
|
}
|
|
4214
|
+
function copyToolContextRuntimeCapability(source, target) {
|
|
4215
|
+
const sourceBinding = readBinding(source);
|
|
4216
|
+
if (!sourceBinding) {
|
|
4217
|
+
return void 0;
|
|
4218
|
+
}
|
|
4219
|
+
const existingTargetBinding = readBinding(target);
|
|
4220
|
+
if (existingTargetBinding) {
|
|
4221
|
+
exposeCompatibilitySurface(target, existingTargetBinding);
|
|
4222
|
+
return existingTargetBinding;
|
|
4223
|
+
}
|
|
4224
|
+
const targetBinding = createRuntimeBinding({
|
|
4225
|
+
context: target,
|
|
4226
|
+
persistedHistory: () => sourceBinding.getPersistedHistoryEvents(),
|
|
4227
|
+
workingHistory: () => sourceBinding.getWorkingHistoryEvents(),
|
|
4228
|
+
executionMeta: sourceBinding.readExecutionMeta()
|
|
4229
|
+
});
|
|
4230
|
+
Object.defineProperty(target, TOOL_CONTEXT_RUNTIME_BINDING_KEY, {
|
|
4231
|
+
value: targetBinding,
|
|
4232
|
+
enumerable: false,
|
|
4233
|
+
configurable: true,
|
|
4234
|
+
writable: false
|
|
4235
|
+
});
|
|
4236
|
+
exposeCompatibilitySurface(target, targetBinding);
|
|
4237
|
+
return targetBinding;
|
|
4238
|
+
}
|
|
4165
4239
|
function readToolContextWorkingHistory(context) {
|
|
4166
4240
|
if (context.conversationView) {
|
|
4167
4241
|
return context.conversationView.getWorkingHistoryEvents();
|
|
@@ -4575,6 +4649,22 @@ var ToolNode = class {
|
|
|
4575
4649
|
});
|
|
4576
4650
|
}
|
|
4577
4651
|
async run(state) {
|
|
4652
|
+
const events = [];
|
|
4653
|
+
while (true) {
|
|
4654
|
+
const result = await this.runNextPendingToolCall(state);
|
|
4655
|
+
if (Array.isArray(result.events) && result.events.length > 0) {
|
|
4656
|
+
events.push(...result.events);
|
|
4657
|
+
}
|
|
4658
|
+
if (result.kind === "route" && result.nextNodeId === "tool") {
|
|
4659
|
+
continue;
|
|
4660
|
+
}
|
|
4661
|
+
return {
|
|
4662
|
+
...result,
|
|
4663
|
+
events
|
|
4664
|
+
};
|
|
4665
|
+
}
|
|
4666
|
+
}
|
|
4667
|
+
async runNextPendingToolCall(state) {
|
|
4578
4668
|
const calls = state.local?.pendingToolCalls ?? [];
|
|
4579
4669
|
const signalRaw = state.local?.signal;
|
|
4580
4670
|
if (isAbortSignal(signalRaw) && signalRaw.aborted) {
|
|
@@ -4782,18 +4872,25 @@ var ToolNode = class {
|
|
|
4782
4872
|
rawArguments: context.call.function?.arguments,
|
|
4783
4873
|
parsedArguments: context.toolArgs
|
|
4784
4874
|
});
|
|
4875
|
+
const remainingCalls = context.calls.slice(1);
|
|
4785
4876
|
context.state.local = buildErrorLocalState({
|
|
4786
4877
|
local: context.local,
|
|
4787
|
-
remainingCalls
|
|
4878
|
+
remainingCalls,
|
|
4788
4879
|
conversationId: context.conversationId,
|
|
4789
4880
|
turnId: context.turnId,
|
|
4790
4881
|
runtimeEvents: context.bridge.getRuntimeEvents(),
|
|
4791
4882
|
nextProtocolErrorCount: fuse.nextCount
|
|
4792
4883
|
});
|
|
4793
|
-
if (fuse.shouldFuse) {
|
|
4884
|
+
if (fuse.shouldFuse && remainingCalls.length === 0) {
|
|
4794
4885
|
throw createToolProtocolFuseError(fuse.nextCount, context.exec.error);
|
|
4795
4886
|
}
|
|
4796
|
-
return {
|
|
4887
|
+
return {
|
|
4888
|
+
kind: "route",
|
|
4889
|
+
// 同一个 assistant.tool_calls batch 必须为每个 call 产出 tool_output。
|
|
4890
|
+
// 出错时也继续消费剩余 call,ToolNode.run 会在本节点内 drain 完 batch 再回 LLM。
|
|
4891
|
+
nextNodeId: remainingCalls.length > 0 ? "tool" : "llm",
|
|
4892
|
+
events: context.bridge.getRuntimeEvents()
|
|
4893
|
+
};
|
|
4797
4894
|
}
|
|
4798
4895
|
};
|
|
4799
4896
|
|
|
@@ -4990,12 +5087,12 @@ function asRecord(value) {
|
|
|
4990
5087
|
}
|
|
4991
5088
|
return value;
|
|
4992
5089
|
}
|
|
4993
|
-
function summarizeCheckpoint(
|
|
5090
|
+
function summarizeCheckpoint(checkpointKey, state, savedAt) {
|
|
4994
5091
|
const local = asRecord(state.local);
|
|
4995
5092
|
const executorLocal = asRecord(local?.executorLocal);
|
|
4996
5093
|
const pendingToolCalls = local?.pendingToolCalls;
|
|
4997
5094
|
return {
|
|
4998
|
-
|
|
5095
|
+
checkpointKey,
|
|
4999
5096
|
schemaVersion: state.schemaVersion ?? 1,
|
|
5000
5097
|
savedAt,
|
|
5001
5098
|
currentNode: state.nodeId,
|
|
@@ -5014,25 +5111,25 @@ var MemoryCheckpointer = class {
|
|
|
5014
5111
|
local: state.local && typeof state.local === "object" && !Array.isArray(state.local) ? { ...state.local } : state.local
|
|
5015
5112
|
};
|
|
5016
5113
|
}
|
|
5017
|
-
async load(
|
|
5018
|
-
const entry = this.store.get(
|
|
5114
|
+
async load(checkpointKey) {
|
|
5115
|
+
const entry = this.store.get(checkpointKey);
|
|
5019
5116
|
return entry ? this.cloneState(entry.state) : null;
|
|
5020
5117
|
}
|
|
5021
|
-
async save(
|
|
5022
|
-
this.store.set(
|
|
5118
|
+
async save(checkpointKey, state) {
|
|
5119
|
+
this.store.set(checkpointKey, {
|
|
5023
5120
|
state: this.cloneState(state),
|
|
5024
5121
|
savedAt: Date.now()
|
|
5025
5122
|
});
|
|
5026
5123
|
}
|
|
5027
|
-
async clear(
|
|
5028
|
-
this.store.delete(
|
|
5124
|
+
async clear(checkpointKey) {
|
|
5125
|
+
this.store.delete(checkpointKey);
|
|
5029
5126
|
}
|
|
5030
|
-
async peekMeta(
|
|
5031
|
-
const entry = this.store.get(
|
|
5032
|
-
return entry ? summarizeCheckpoint(
|
|
5127
|
+
async peekMeta(checkpointKey) {
|
|
5128
|
+
const entry = this.store.get(checkpointKey);
|
|
5129
|
+
return entry ? summarizeCheckpoint(checkpointKey, entry.state, entry.savedAt) : null;
|
|
5033
5130
|
}
|
|
5034
5131
|
async list(filter = {}) {
|
|
5035
|
-
const summaries = Array.from(this.store.entries()).map(([
|
|
5132
|
+
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);
|
|
5036
5133
|
if (filter.limit === void 0) {
|
|
5037
5134
|
return summaries;
|
|
5038
5135
|
}
|
|
@@ -5104,6 +5201,7 @@ __export(tools_exports, {
|
|
|
5104
5201
|
CommonParameterTypes: () => CommonParameterTypes,
|
|
5105
5202
|
ContextCheckpointTool: () => ContextCheckpointTool,
|
|
5106
5203
|
computeToolIdempotencyKey: () => computeToolIdempotencyKey,
|
|
5204
|
+
copyToolContextRuntimeCapability: () => copyToolContextRuntimeCapability,
|
|
5107
5205
|
createContextCheckpointTool: () => createContextCheckpointTool,
|
|
5108
5206
|
ensureToolContextRuntimeCapability: () => ensureToolContextRuntimeCapability,
|
|
5109
5207
|
findCachedToolOutputByIdempotencyKey: () => findCachedToolOutputByIdempotencyKey,
|
|
@@ -5297,7 +5395,7 @@ function createContextCheckpointTool(options) {
|
|
|
5297
5395
|
function isRecord15(value) {
|
|
5298
5396
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
5299
5397
|
}
|
|
5300
|
-
function
|
|
5398
|
+
function readNonEmptyString5(value) {
|
|
5301
5399
|
if (typeof value !== "string") {
|
|
5302
5400
|
return void 0;
|
|
5303
5401
|
}
|
|
@@ -5317,13 +5415,13 @@ function readToolContextUserQuery(context) {
|
|
|
5317
5415
|
if (!context) {
|
|
5318
5416
|
return void 0;
|
|
5319
5417
|
}
|
|
5320
|
-
return
|
|
5418
|
+
return readNonEmptyString5(context["user_query"]);
|
|
5321
5419
|
}
|
|
5322
5420
|
function readToolContextModelId(context) {
|
|
5323
5421
|
if (!context) {
|
|
5324
5422
|
return void 0;
|
|
5325
5423
|
}
|
|
5326
|
-
return
|
|
5424
|
+
return readNonEmptyString5(context["modelId"]);
|
|
5327
5425
|
}
|
|
5328
5426
|
function readToolContextRunContext(context) {
|
|
5329
5427
|
if (!context) {
|
|
@@ -5530,18 +5628,18 @@ function createClassification(category, reason, suggestedDelay, extras) {
|
|
|
5530
5628
|
}
|
|
5531
5629
|
var ErrorClassifier = class {
|
|
5532
5630
|
static classify(error, context) {
|
|
5533
|
-
const
|
|
5631
|
+
const isRecord27 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
5534
5632
|
const baseMsg = (error.message || "").toLowerCase();
|
|
5535
5633
|
const causeMsg = (() => {
|
|
5536
5634
|
const cause = error.cause;
|
|
5537
5635
|
if (typeof cause === "string") return cause.toLowerCase();
|
|
5538
5636
|
if (cause instanceof Error) return (cause.message || "").toLowerCase();
|
|
5539
|
-
if (
|
|
5637
|
+
if (isRecord27(cause) && typeof cause["message"] === "string") return String(cause["message"]).toLowerCase();
|
|
5540
5638
|
return "";
|
|
5541
5639
|
})();
|
|
5542
5640
|
const causeCode = (() => {
|
|
5543
5641
|
const cause = error.cause;
|
|
5544
|
-
if (
|
|
5642
|
+
if (isRecord27(cause) && typeof cause["code"] === "string") return String(cause["code"]);
|
|
5545
5643
|
return "";
|
|
5546
5644
|
})();
|
|
5547
5645
|
const errorMessage = `${baseMsg} ${causeMsg}`.trim();
|
|
@@ -6033,6 +6131,9 @@ __export(llm_exports, {
|
|
|
6033
6131
|
LLMPolicyEngine: () => LLMPolicyEngine,
|
|
6034
6132
|
LlmCaller: () => LlmCaller,
|
|
6035
6133
|
ModelResolver: () => ModelResolver,
|
|
6134
|
+
appendStreamingProviderReasoningDetails: () => appendStreamingProviderReasoningDetails,
|
|
6135
|
+
compactProviderReasoningDetails: () => compactProviderReasoningDetails,
|
|
6136
|
+
compactReasoningDetailsInValue: () => compactReasoningDetailsInValue,
|
|
6036
6137
|
createDefaultTokenizerPort: () => createDefaultTokenizerPort,
|
|
6037
6138
|
defaultPolicyEngine: () => defaultPolicyEngine
|
|
6038
6139
|
});
|
|
@@ -6422,6 +6523,90 @@ function assertToolCallsHaveValidJsonArguments(toolCalls) {
|
|
|
6422
6523
|
}
|
|
6423
6524
|
}
|
|
6424
6525
|
|
|
6526
|
+
// src/runtime-kernel/llm/reasoning-details.ts
|
|
6527
|
+
var mergeableTextFields = ["reasoning_content"];
|
|
6528
|
+
function isRecord20(value) {
|
|
6529
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
6530
|
+
}
|
|
6531
|
+
function findMergeableTextField(detail) {
|
|
6532
|
+
if (!isRecord20(detail)) return void 0;
|
|
6533
|
+
if (typeof detail.provider !== "string") return void 0;
|
|
6534
|
+
if (typeof detail.type !== "string") return void 0;
|
|
6535
|
+
for (const field of mergeableTextFields) {
|
|
6536
|
+
if (typeof detail[field] === "string") {
|
|
6537
|
+
return field;
|
|
6538
|
+
}
|
|
6539
|
+
}
|
|
6540
|
+
return void 0;
|
|
6541
|
+
}
|
|
6542
|
+
function hasOnlyStableTextDetailFields(detail, textField) {
|
|
6543
|
+
const allowedKeys = /* @__PURE__ */ new Set(["provider", "type", textField]);
|
|
6544
|
+
return Object.keys(detail).every((key) => allowedKeys.has(key));
|
|
6545
|
+
}
|
|
6546
|
+
function canMergeTextDetails(previous, incoming) {
|
|
6547
|
+
if (!isRecord20(previous) || !isRecord20(incoming)) return false;
|
|
6548
|
+
const previousField = findMergeableTextField(previous);
|
|
6549
|
+
const incomingField = findMergeableTextField(incoming);
|
|
6550
|
+
if (!previousField || previousField !== incomingField) return false;
|
|
6551
|
+
return previous.provider === incoming.provider && previous.type === incoming.type && hasOnlyStableTextDetailFields(previous, previousField) && hasOnlyStableTextDetailFields(incoming, incomingField);
|
|
6552
|
+
}
|
|
6553
|
+
function mergeStreamingText(previous, incoming) {
|
|
6554
|
+
if (!previous) return incoming;
|
|
6555
|
+
if (!incoming) return previous;
|
|
6556
|
+
if (incoming.startsWith(previous)) {
|
|
6557
|
+
return incoming;
|
|
6558
|
+
}
|
|
6559
|
+
if (previous.endsWith(incoming)) {
|
|
6560
|
+
return previous;
|
|
6561
|
+
}
|
|
6562
|
+
return `${previous}${incoming}`;
|
|
6563
|
+
}
|
|
6564
|
+
function appendStreamingProviderReasoningDetails(existing, incoming) {
|
|
6565
|
+
const next = [...existing];
|
|
6566
|
+
for (const detail of incoming) {
|
|
6567
|
+
const previous = next[next.length - 1];
|
|
6568
|
+
if (canMergeTextDetails(previous, detail)) {
|
|
6569
|
+
const textField = findMergeableTextField(previous);
|
|
6570
|
+
if (textField && isRecord20(detail)) {
|
|
6571
|
+
const mergedText = mergeStreamingText(String(previous[textField]), String(detail[textField]));
|
|
6572
|
+
if (mergedText === previous[textField]) {
|
|
6573
|
+
continue;
|
|
6574
|
+
}
|
|
6575
|
+
next[next.length - 1] = {
|
|
6576
|
+
...previous,
|
|
6577
|
+
[textField]: mergedText
|
|
6578
|
+
};
|
|
6579
|
+
continue;
|
|
6580
|
+
}
|
|
6581
|
+
}
|
|
6582
|
+
next.push(detail);
|
|
6583
|
+
}
|
|
6584
|
+
return next;
|
|
6585
|
+
}
|
|
6586
|
+
function compactProviderReasoningDetails(reasoningDetails) {
|
|
6587
|
+
return appendStreamingProviderReasoningDetails([], reasoningDetails);
|
|
6588
|
+
}
|
|
6589
|
+
function compactReasoningDetailsInValue(value) {
|
|
6590
|
+
return compactValue(value);
|
|
6591
|
+
}
|
|
6592
|
+
function compactValue(value) {
|
|
6593
|
+
if (Array.isArray(value)) {
|
|
6594
|
+
return value.map((item) => compactValue(item));
|
|
6595
|
+
}
|
|
6596
|
+
if (!isRecord20(value)) {
|
|
6597
|
+
return value;
|
|
6598
|
+
}
|
|
6599
|
+
const compacted = {};
|
|
6600
|
+
for (const [key, childValue] of Object.entries(value)) {
|
|
6601
|
+
if (key === "reasoning_details" && Array.isArray(childValue)) {
|
|
6602
|
+
compacted[key] = compactProviderReasoningDetails(childValue);
|
|
6603
|
+
continue;
|
|
6604
|
+
}
|
|
6605
|
+
compacted[key] = compactValue(childValue);
|
|
6606
|
+
}
|
|
6607
|
+
return compacted;
|
|
6608
|
+
}
|
|
6609
|
+
|
|
6425
6610
|
// src/runtime-kernel/llm/streaming-adapter.ts
|
|
6426
6611
|
async function callLlmStream(params) {
|
|
6427
6612
|
const {
|
|
@@ -6434,7 +6619,7 @@ async function callLlmStream(params) {
|
|
|
6434
6619
|
} = params;
|
|
6435
6620
|
let fullResponse = "";
|
|
6436
6621
|
let streamError = null;
|
|
6437
|
-
|
|
6622
|
+
let reasoningDetails = [];
|
|
6438
6623
|
const streamAnswerId = generateMessageId();
|
|
6439
6624
|
let streamChunkSeq = 0;
|
|
6440
6625
|
let capturedUsage = void 0;
|
|
@@ -6504,13 +6689,21 @@ async function callLlmStream(params) {
|
|
|
6504
6689
|
const reasoning = isRecord19(chunk) ? chunk["reasoning_details"] : void 0;
|
|
6505
6690
|
if (reasoning !== void 0) {
|
|
6506
6691
|
const newReasoningDetails = Array.isArray(reasoning) ? reasoning : [reasoning];
|
|
6507
|
-
reasoningDetails
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6692
|
+
const previousReasoningDetails = reasoningDetails;
|
|
6693
|
+
const previousLength = previousReasoningDetails.length;
|
|
6694
|
+
const compactedReasoningDetails = appendStreamingProviderReasoningDetails(reasoningDetails, newReasoningDetails);
|
|
6695
|
+
reasoningDetails = compactedReasoningDetails;
|
|
6696
|
+
const previousLastChanged = previousLength > 0 && compactedReasoningDetails[previousLength - 1] !== previousReasoningDetails[previousLength - 1];
|
|
6697
|
+
const emitFromIndex = previousLastChanged ? previousLength - 1 : previousLength;
|
|
6698
|
+
const emittedReasoningDetails = compactedReasoningDetails.slice(Math.max(0, emitFromIndex));
|
|
6699
|
+
if (emittedReasoningDetails.length > 0) {
|
|
6700
|
+
eventHandler({
|
|
6701
|
+
type: "provider_sidecar",
|
|
6702
|
+
id: generateMessageId(),
|
|
6703
|
+
timestamp: Date.now(),
|
|
6704
|
+
reasoning_details: emittedReasoningDetails
|
|
6705
|
+
});
|
|
6706
|
+
}
|
|
6514
6707
|
}
|
|
6515
6708
|
if (chunk.tool_calls) {
|
|
6516
6709
|
emitThoughtComplete(thoughtSegmenter.onBoundary());
|
|
@@ -6964,7 +7157,6 @@ __export(child_runs_exports, {
|
|
|
6964
7157
|
|
|
6965
7158
|
// src/runtime-kernel/child-runs/childToolContext.ts
|
|
6966
7159
|
function createChildRunToolContext(params) {
|
|
6967
|
-
const inheritedConversationId = typeof params.parentToolContext.conversationId === "string" && params.parentToolContext.conversationId.trim().length > 0 ? params.parentToolContext.conversationId.trim() : void 0;
|
|
6968
7160
|
const inheritedContext = stripRuntimeReservedToolContextPatch(params.parentToolContext);
|
|
6969
7161
|
const childToolContext = {
|
|
6970
7162
|
...inheritedContext,
|
|
@@ -6976,7 +7168,7 @@ function createChildRunToolContext(params) {
|
|
|
6976
7168
|
persistedHistory: params.seedHistory,
|
|
6977
7169
|
workingHistory: params.seedHistory,
|
|
6978
7170
|
executionMeta: {
|
|
6979
|
-
conversationId:
|
|
7171
|
+
conversationId: params.conversationId,
|
|
6980
7172
|
turnId: params.turnId,
|
|
6981
7173
|
runId: params.runId,
|
|
6982
7174
|
parentRunId: params.parentRunId
|
|
@@ -7127,7 +7319,7 @@ var FinalAnswerCollector = class {
|
|
|
7127
7319
|
};
|
|
7128
7320
|
|
|
7129
7321
|
// src/runtime-kernel/child-runs/childRunTraceSink.ts
|
|
7130
|
-
function
|
|
7322
|
+
function isRecord21(v) {
|
|
7131
7323
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
7132
7324
|
}
|
|
7133
7325
|
function getString2(obj, key) {
|
|
@@ -7160,7 +7352,7 @@ function createChildRunTraceSink(params) {
|
|
|
7160
7352
|
const { publisher, conversationId, turnId } = params;
|
|
7161
7353
|
const finalAnswerCollector = new FinalAnswerCollector(conversationId, turnId);
|
|
7162
7354
|
const sink = (evt) => {
|
|
7163
|
-
if (!
|
|
7355
|
+
if (!isRecord21(evt)) {
|
|
7164
7356
|
return [];
|
|
7165
7357
|
}
|
|
7166
7358
|
const type = getString2(evt, "type");
|
|
@@ -7296,7 +7488,7 @@ function readCheckpointHistory(checkpoint) {
|
|
|
7296
7488
|
});
|
|
7297
7489
|
}
|
|
7298
7490
|
async function recoverChildRunEventsFromCheckpoint(params) {
|
|
7299
|
-
const checkpoint = await params.checkpointer.load(params.
|
|
7491
|
+
const checkpoint = await params.checkpointer.load(params.checkpointKey);
|
|
7300
7492
|
const history = readCheckpointHistory(checkpoint);
|
|
7301
7493
|
if (history.length === 0) {
|
|
7302
7494
|
return [];
|
|
@@ -7304,7 +7496,7 @@ async function recoverChildRunEventsFromCheckpoint(params) {
|
|
|
7304
7496
|
if (hasSeedHistoryPrefix(history, params.seedHistory)) {
|
|
7305
7497
|
return history.slice(params.seedHistory.length);
|
|
7306
7498
|
}
|
|
7307
|
-
return history.filter((event) => event.conversation_id === params.
|
|
7499
|
+
return history.filter((event) => event.conversation_id === params.childConversationId);
|
|
7308
7500
|
}
|
|
7309
7501
|
|
|
7310
7502
|
// src/runtime-kernel/child-runs/childRunInvoker.ts
|
|
@@ -7333,6 +7525,7 @@ var ChildRunInvoker = class {
|
|
|
7333
7525
|
agentConfig,
|
|
7334
7526
|
userMessage,
|
|
7335
7527
|
parentToolContext,
|
|
7528
|
+
conversationId,
|
|
7336
7529
|
runId,
|
|
7337
7530
|
parentRunId,
|
|
7338
7531
|
subrunTracePublisher,
|
|
@@ -7341,12 +7534,18 @@ var ChildRunInvoker = class {
|
|
|
7341
7534
|
modelId,
|
|
7342
7535
|
abortSignal
|
|
7343
7536
|
} = config;
|
|
7344
|
-
const
|
|
7537
|
+
const internalCheckpointKey = `internal_${generateMessageId()}`;
|
|
7538
|
+
const runtimeConversationId = resolveChildRunConversationId({
|
|
7539
|
+
explicitConversationId: conversationId,
|
|
7540
|
+
parentToolContext,
|
|
7541
|
+
fallbackConversationId: internalCheckpointKey
|
|
7542
|
+
});
|
|
7345
7543
|
const turnId = `turn_${Date.now()}`;
|
|
7346
|
-
const childRunId = typeof runId === "string" && runId.trim().length > 0 ? runId.trim() :
|
|
7544
|
+
const childRunId = typeof runId === "string" && runId.trim().length > 0 ? runId.trim() : internalCheckpointKey;
|
|
7347
7545
|
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;
|
|
7348
7546
|
logger13.info(`\u542F\u52A8 child-run: ${agentConfig.id}`, {
|
|
7349
|
-
conversationId:
|
|
7547
|
+
conversationId: runtimeConversationId,
|
|
7548
|
+
checkpointKey: internalCheckpointKey,
|
|
7350
7549
|
maxSteps,
|
|
7351
7550
|
userMessage: userMessage.slice(0, 100) + (userMessage.length > 100 ? "..." : "")
|
|
7352
7551
|
});
|
|
@@ -7407,7 +7606,7 @@ var ChildRunInvoker = class {
|
|
|
7407
7606
|
const seedHistory = Array.isArray(seedHistoryEvents) ? seedHistoryEvents : [];
|
|
7408
7607
|
const childToolContext = createChildRunToolContext({
|
|
7409
7608
|
parentToolContext,
|
|
7410
|
-
|
|
7609
|
+
conversationId: runtimeConversationId,
|
|
7411
7610
|
turnId,
|
|
7412
7611
|
runId: childRunId,
|
|
7413
7612
|
parentRunId: resolvedParentRunId,
|
|
@@ -7416,13 +7615,13 @@ var ChildRunInvoker = class {
|
|
|
7416
7615
|
});
|
|
7417
7616
|
const subrunSseSink = subrunTracePublisher ? createChildRunTraceSink({
|
|
7418
7617
|
publisher: subrunTracePublisher,
|
|
7419
|
-
conversationId:
|
|
7618
|
+
conversationId: runtimeConversationId,
|
|
7420
7619
|
turnId
|
|
7421
7620
|
}) : void 0;
|
|
7422
7621
|
const initialLocal = {
|
|
7423
7622
|
request,
|
|
7424
7623
|
history: seedHistory,
|
|
7425
|
-
conversationId:
|
|
7624
|
+
conversationId: runtimeConversationId,
|
|
7426
7625
|
turnId,
|
|
7427
7626
|
toolContext: childToolContext,
|
|
7428
7627
|
...abortSignal ? { signal: abortSignal } : {},
|
|
@@ -7430,7 +7629,7 @@ var ChildRunInvoker = class {
|
|
|
7430
7629
|
...subrunSseSink ? { sseSink: subrunSseSink } : {},
|
|
7431
7630
|
systemPrompt
|
|
7432
7631
|
};
|
|
7433
|
-
await graphExecutor.prime(
|
|
7632
|
+
await graphExecutor.prime(internalCheckpointKey, initialLocal, "llm");
|
|
7434
7633
|
const allEvents = [];
|
|
7435
7634
|
let stepCount = 0;
|
|
7436
7635
|
let finalAnswer;
|
|
@@ -7442,7 +7641,7 @@ var ChildRunInvoker = class {
|
|
|
7442
7641
|
err.name = "AbortError";
|
|
7443
7642
|
throw err;
|
|
7444
7643
|
}
|
|
7445
|
-
const result = await graphExecutor.runUntilYield(
|
|
7644
|
+
const result = await graphExecutor.runUntilYield(internalCheckpointKey);
|
|
7446
7645
|
appendUniqueEvents(allEvents, result.events);
|
|
7447
7646
|
stepCount = result.stepCount;
|
|
7448
7647
|
if (subrunSseSink && typeof subrunSseSink.finalize === "function") {
|
|
@@ -7476,8 +7675,8 @@ var ChildRunInvoker = class {
|
|
|
7476
7675
|
}
|
|
7477
7676
|
const recoveredEvents = await recoverChildRunEventsFromCheckpoint({
|
|
7478
7677
|
checkpointer,
|
|
7479
|
-
|
|
7480
|
-
|
|
7678
|
+
checkpointKey: internalCheckpointKey,
|
|
7679
|
+
childConversationId: runtimeConversationId,
|
|
7481
7680
|
seedHistory
|
|
7482
7681
|
});
|
|
7483
7682
|
appendUniqueEvents(allEvents, recoveredEvents);
|
|
@@ -7494,7 +7693,7 @@ var ChildRunInvoker = class {
|
|
|
7494
7693
|
stack: err.stack
|
|
7495
7694
|
} : { error: String(err) });
|
|
7496
7695
|
}
|
|
7497
|
-
await checkpointer.clear(
|
|
7696
|
+
await checkpointer.clear(internalCheckpointKey);
|
|
7498
7697
|
return {
|
|
7499
7698
|
success: !error,
|
|
7500
7699
|
runId: childRunId,
|
|
@@ -7507,6 +7706,16 @@ var ChildRunInvoker = class {
|
|
|
7507
7706
|
};
|
|
7508
7707
|
}
|
|
7509
7708
|
};
|
|
7709
|
+
function readNonEmptyString6(value) {
|
|
7710
|
+
if (typeof value !== "string") {
|
|
7711
|
+
return void 0;
|
|
7712
|
+
}
|
|
7713
|
+
const trimmed = value.trim();
|
|
7714
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
7715
|
+
}
|
|
7716
|
+
function resolveChildRunConversationId(params) {
|
|
7717
|
+
return readNonEmptyString6(params.explicitConversationId) ?? readNonEmptyString6(params.parentToolContext.conversationId) ?? params.fallbackConversationId;
|
|
7718
|
+
}
|
|
7510
7719
|
function resolveChildRunSystemReminderPolicy(agentConfig) {
|
|
7511
7720
|
const configured = agentConfig.systemReminderPolicy ?? agentConfig.contextPolicy?.systemReminder;
|
|
7512
7721
|
const threshold = agentConfig.stepPolicy?.lastStepsHintThreshold;
|
|
@@ -7697,7 +7906,7 @@ function cloneRunRecord(record) {
|
|
|
7697
7906
|
...record,
|
|
7698
7907
|
iterationBudget: record.iterationBudget ? { ...record.iterationBudget } : void 0,
|
|
7699
7908
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0,
|
|
7700
|
-
metadata: record.metadata ?
|
|
7909
|
+
metadata: record.metadata ? structuredClone(record.metadata) : void 0
|
|
7701
7910
|
};
|
|
7702
7911
|
}
|
|
7703
7912
|
function matchesStatus(candidate, filter) {
|
|
@@ -7829,7 +8038,7 @@ function runRecordToMeta(record) {
|
|
|
7829
8038
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0
|
|
7830
8039
|
};
|
|
7831
8040
|
}
|
|
7832
|
-
function
|
|
8041
|
+
function isRecord22(value) {
|
|
7833
8042
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7834
8043
|
}
|
|
7835
8044
|
function readStringField(record, key) {
|
|
@@ -7850,7 +8059,7 @@ function getRunIdFromMetadata(event) {
|
|
|
7850
8059
|
return snakeCaseRunId;
|
|
7851
8060
|
}
|
|
7852
8061
|
const runContext = metadata["run_context"];
|
|
7853
|
-
if (
|
|
8062
|
+
if (isRecord22(runContext)) {
|
|
7854
8063
|
return readStringField(runContext, "runId") ?? readStringField(runContext, "run_id");
|
|
7855
8064
|
}
|
|
7856
8065
|
return void 0;
|
|
@@ -8068,7 +8277,7 @@ function runMetaFromRecord(record) {
|
|
|
8068
8277
|
}
|
|
8069
8278
|
|
|
8070
8279
|
// src/runtime-kernel/run-supervisor/runSupervisor.ts
|
|
8071
|
-
function
|
|
8280
|
+
function isRecord23(value) {
|
|
8072
8281
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8073
8282
|
}
|
|
8074
8283
|
function readStringField2(record, key) {
|
|
@@ -8085,7 +8294,7 @@ function readRunIdFromRuntimeEvent(event) {
|
|
|
8085
8294
|
return directRunId;
|
|
8086
8295
|
}
|
|
8087
8296
|
const runContext = metadata["run_context"];
|
|
8088
|
-
if (!
|
|
8297
|
+
if (!isRecord23(runContext)) {
|
|
8089
8298
|
return void 0;
|
|
8090
8299
|
}
|
|
8091
8300
|
return readStringField2(runContext, "runId") ?? readStringField2(runContext, "run_id");
|
|
@@ -8097,7 +8306,7 @@ function readAwaitingUserReason(event) {
|
|
|
8097
8306
|
if (typeof event.prompt === "string" && event.prompt.trim().length > 0) {
|
|
8098
8307
|
return event.prompt;
|
|
8099
8308
|
}
|
|
8100
|
-
if (
|
|
8309
|
+
if (isRecord23(event.form)) {
|
|
8101
8310
|
const prompt = readStringField2(event.form, "prompt");
|
|
8102
8311
|
if (prompt && prompt.trim().length > 0) {
|
|
8103
8312
|
return prompt;
|
|
@@ -8109,7 +8318,7 @@ function isTerminalStatus(status) {
|
|
|
8109
8318
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
8110
8319
|
}
|
|
8111
8320
|
function cloneMetadata(metadata) {
|
|
8112
|
-
return metadata ?
|
|
8321
|
+
return metadata ? structuredClone(metadata) : void 0;
|
|
8113
8322
|
}
|
|
8114
8323
|
function recordToSnapshot(record) {
|
|
8115
8324
|
return {
|
|
@@ -8196,7 +8405,7 @@ var DefaultRunSupervisor = class {
|
|
|
8196
8405
|
startedAt,
|
|
8197
8406
|
updatedAt: startedAt,
|
|
8198
8407
|
iterationBudget: spec.iterationBudget ? { ...spec.iterationBudget } : void 0,
|
|
8199
|
-
metadata: spec.metadata
|
|
8408
|
+
metadata: cloneMetadata(spec.metadata)
|
|
8200
8409
|
};
|
|
8201
8410
|
await this.registryStore.save(record);
|
|
8202
8411
|
const handle = new DefaultRunHandle({
|
|
@@ -8370,12 +8579,13 @@ var DefaultRunSupervisor = class {
|
|
|
8370
8579
|
}
|
|
8371
8580
|
try {
|
|
8372
8581
|
await handle.markRunning({ currentNode: "detached" });
|
|
8582
|
+
const registeredRecord = await this.registryStore.load(handle.runId);
|
|
8373
8583
|
const executorOutcome = await this.executor.execute({
|
|
8374
8584
|
runId: handle.runId,
|
|
8375
|
-
parentRunId:
|
|
8376
|
-
conversationId: spec.conversationId,
|
|
8377
|
-
agentSpec: spec
|
|
8378
|
-
request:
|
|
8585
|
+
parentRunId: handle.parentRunId,
|
|
8586
|
+
conversationId: registeredRecord?.conversationId ?? spec.conversationId,
|
|
8587
|
+
agentSpec: await handle.spec(),
|
|
8588
|
+
request: await handle.request(),
|
|
8379
8589
|
signal: handle.signal,
|
|
8380
8590
|
eventBus: spec.eventBus,
|
|
8381
8591
|
eventStore: spec.eventStore,
|
|
@@ -8384,7 +8594,7 @@ var DefaultRunSupervisor = class {
|
|
|
8384
8594
|
contextFences: spec.contextFences,
|
|
8385
8595
|
wakeSource: spec.wakeSource,
|
|
8386
8596
|
ephemeral: spec.ephemeral,
|
|
8387
|
-
metadata: spec.metadata
|
|
8597
|
+
metadata: cloneMetadata(registeredRecord?.metadata ?? spec.metadata)
|
|
8388
8598
|
});
|
|
8389
8599
|
const outcome = await this.persistExecutorOutcome(handle, executorOutcome);
|
|
8390
8600
|
this.notifyTerminalWaiters(outcome);
|
|
@@ -8448,10 +8658,14 @@ var DefaultRunSupervisor = class {
|
|
|
8448
8658
|
await this.registryStore.save(record);
|
|
8449
8659
|
}
|
|
8450
8660
|
const completedAt = executorOutcome?.completedAt ?? this.now();
|
|
8661
|
+
const fallbackMeta = record ? void 0 : await handle.meta();
|
|
8451
8662
|
const outcome = recordToTerminalOutcome(record ?? {
|
|
8452
8663
|
runId: handle.runId,
|
|
8453
8664
|
parentRunId: handle.parentRunId,
|
|
8454
|
-
|
|
8665
|
+
conversationId: fallbackMeta?.conversationId ?? "",
|
|
8666
|
+
agentSpecId: fallbackMeta?.agentSpecId,
|
|
8667
|
+
status: executorOutcome?.status ?? "completed",
|
|
8668
|
+
startedAt: fallbackMeta?.startedAt ?? completedAt}, completedAt);
|
|
8455
8669
|
const nextOutcome = {
|
|
8456
8670
|
...outcome,
|
|
8457
8671
|
metadata: {
|
|
@@ -8679,6 +8893,7 @@ function createGraphLoopHarness(options) {
|
|
|
8679
8893
|
};
|
|
8680
8894
|
return {
|
|
8681
8895
|
async run() {
|
|
8896
|
+
const checkpointKey = options.conversationId;
|
|
8682
8897
|
const executor = createDefaultGraphExecutor({
|
|
8683
8898
|
llmNode: options.createLlmNode({
|
|
8684
8899
|
llmCaller: options.llmCaller,
|
|
@@ -8707,8 +8922,8 @@ function createGraphLoopHarness(options) {
|
|
|
8707
8922
|
signal: options.signal ?? options.toolContext.abortSignal,
|
|
8708
8923
|
executorLocal
|
|
8709
8924
|
};
|
|
8710
|
-
await executor.prime(
|
|
8711
|
-
const result = await executor.runUntilYield(
|
|
8925
|
+
await executor.prime(checkpointKey, local, "user");
|
|
8926
|
+
const result = await executor.runUntilYield(checkpointKey);
|
|
8712
8927
|
return {
|
|
8713
8928
|
checkpointNodeId: result.checkpoint.nodeId,
|
|
8714
8929
|
stepCount: result.stepCount
|
|
@@ -8983,11 +9198,11 @@ new MessageFormatter();
|
|
|
8983
9198
|
|
|
8984
9199
|
// src/context-manager/profiles/agent/utils/toolInteractionGroup.ts
|
|
8985
9200
|
var CHECKPOINT_TOOL_NAME = "context_checkpoint";
|
|
8986
|
-
function
|
|
9201
|
+
function isRecord24(value) {
|
|
8987
9202
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8988
9203
|
}
|
|
8989
9204
|
function isToolCallRecord(value) {
|
|
8990
|
-
if (!
|
|
9205
|
+
if (!isRecord24(value)) {
|
|
8991
9206
|
return false;
|
|
8992
9207
|
}
|
|
8993
9208
|
return typeof value.id === "string" && value.id.trim().length > 0;
|
|
@@ -9005,7 +9220,7 @@ function safeParseArgs(rawArgs) {
|
|
|
9005
9220
|
}
|
|
9006
9221
|
try {
|
|
9007
9222
|
const parsed = JSON.parse(rawArgs);
|
|
9008
|
-
return
|
|
9223
|
+
return isRecord24(parsed) ? parsed : {};
|
|
9009
9224
|
} catch {
|
|
9010
9225
|
return {};
|
|
9011
9226
|
}
|
|
@@ -9299,7 +9514,7 @@ var summarizeToolOutput = (toolName, output, toolSummaryProvider, toolArgs, conf
|
|
|
9299
9514
|
};
|
|
9300
9515
|
|
|
9301
9516
|
// src/context-manager/profiles/agent/utils/eventConverter.ts
|
|
9302
|
-
function
|
|
9517
|
+
function isRecord25(value) {
|
|
9303
9518
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9304
9519
|
}
|
|
9305
9520
|
function isHistorySummaryEvent2(event) {
|
|
@@ -9357,10 +9572,10 @@ function convertEventToAiMessage(event) {
|
|
|
9357
9572
|
timestamp: event.timestamp,
|
|
9358
9573
|
metadata: {
|
|
9359
9574
|
tool_calls: (() => {
|
|
9360
|
-
const
|
|
9575
|
+
const isRecord27 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
9361
9576
|
const payload = event.payload;
|
|
9362
9577
|
const toolCallsFromPayload = (() => {
|
|
9363
|
-
if (!
|
|
9578
|
+
if (!isRecord27(payload)) return void 0;
|
|
9364
9579
|
const raw = payload["tool_calls"];
|
|
9365
9580
|
return Array.isArray(raw) ? raw : void 0;
|
|
9366
9581
|
})();
|
|
@@ -9379,9 +9594,9 @@ function convertEventToAiMessage(event) {
|
|
|
9379
9594
|
];
|
|
9380
9595
|
})(),
|
|
9381
9596
|
reasoning_details: (() => {
|
|
9382
|
-
const
|
|
9597
|
+
const isRecord27 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
9383
9598
|
const payload = event.payload;
|
|
9384
|
-
if (!
|
|
9599
|
+
if (!isRecord27(payload)) return void 0;
|
|
9385
9600
|
const rd = payload["reasoning_details"];
|
|
9386
9601
|
return Array.isArray(rd) ? rd : void 0;
|
|
9387
9602
|
})()
|
|
@@ -9390,15 +9605,15 @@ function convertEventToAiMessage(event) {
|
|
|
9390
9605
|
case "tool_output": {
|
|
9391
9606
|
const observationFromPayload = (() => {
|
|
9392
9607
|
const payload = event.payload;
|
|
9393
|
-
if (!
|
|
9608
|
+
if (!isRecord25(payload)) return void 0;
|
|
9394
9609
|
const result = payload["result"];
|
|
9395
|
-
if (!
|
|
9610
|
+
if (!isRecord25(result)) return void 0;
|
|
9396
9611
|
const obs = result["observation"];
|
|
9397
9612
|
return typeof obs === "string" && obs.trim().length > 0 ? obs : void 0;
|
|
9398
9613
|
})();
|
|
9399
9614
|
const rawOutput = (() => {
|
|
9400
9615
|
const payload = event.payload;
|
|
9401
|
-
if (
|
|
9616
|
+
if (isRecord25(payload)) {
|
|
9402
9617
|
const out = payload["output"];
|
|
9403
9618
|
if (typeof out === "string" && out.trim().length > 0) {
|
|
9404
9619
|
return out;
|
|
@@ -9523,7 +9738,7 @@ __export(utils_exports, {
|
|
|
9523
9738
|
});
|
|
9524
9739
|
|
|
9525
9740
|
// src/testkit/context-harness/replayHarness.ts
|
|
9526
|
-
function
|
|
9741
|
+
function isRecord26(value) {
|
|
9527
9742
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9528
9743
|
}
|
|
9529
9744
|
function createReplayHarness(events) {
|
|
@@ -9535,7 +9750,7 @@ function createReplayHarness(events) {
|
|
|
9535
9750
|
if (message.role !== "assistant" || message.type !== "tool_calls") {
|
|
9536
9751
|
return false;
|
|
9537
9752
|
}
|
|
9538
|
-
if (!
|
|
9753
|
+
if (!isRecord26(message.metadata)) {
|
|
9539
9754
|
return false;
|
|
9540
9755
|
}
|
|
9541
9756
|
return Array.isArray(message.metadata.tool_calls);
|