@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/quickstart.js
CHANGED
|
@@ -166,6 +166,7 @@ var AgentSpecBudgetPolicy = z.object({
|
|
|
166
166
|
});
|
|
167
167
|
var AgentSpecToolHistoryPolicy = z.object({
|
|
168
168
|
strategy: z.enum(["per-pair", "per-run", "none"]).optional(),
|
|
169
|
+
retentionMode: z.enum(["drop", "compress"]).optional(),
|
|
169
170
|
keepLatestToolPairs: z.number().int().nonnegative().optional(),
|
|
170
171
|
keepLatestRuns: z.number().int().nonnegative().optional(),
|
|
171
172
|
maxInteractionGroups: z.number().int().nonnegative().optional(),
|
|
@@ -280,12 +281,13 @@ var AgentSpecContextPolicy = z.object({
|
|
|
280
281
|
var DEFAULT_CONTEXT_POLICY = {
|
|
281
282
|
profileId: "agent",
|
|
282
283
|
budget: {
|
|
283
|
-
maxTokens:
|
|
284
|
+
maxTokens: 232e3,
|
|
284
285
|
reservedForResponse: 2400,
|
|
285
286
|
workingMemoryBudgetPercentage: 0.7
|
|
286
287
|
},
|
|
287
288
|
toolHistory: {
|
|
288
289
|
strategy: "per-run",
|
|
290
|
+
retentionMode: "drop",
|
|
289
291
|
keepLatestToolPairs: 2,
|
|
290
292
|
keepLatestRuns: 1,
|
|
291
293
|
maxInteractionGroups: 12,
|
|
@@ -1271,6 +1273,17 @@ var logger = new Logger("GraphExecutor");
|
|
|
1271
1273
|
function asLocalRecord(local) {
|
|
1272
1274
|
return local && typeof local === "object" ? { ...local } : {};
|
|
1273
1275
|
}
|
|
1276
|
+
function readNonEmptyString(value) {
|
|
1277
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1278
|
+
}
|
|
1279
|
+
function readRuntimeConversationId(state) {
|
|
1280
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1281
|
+
return readNonEmptyString(local?.conversationId);
|
|
1282
|
+
}
|
|
1283
|
+
function readRuntimeTurnId(state) {
|
|
1284
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1285
|
+
return readNonEmptyString(local?.turnId);
|
|
1286
|
+
}
|
|
1274
1287
|
var GraphExecutor = class {
|
|
1275
1288
|
constructor(checkpointer, config = {}) {
|
|
1276
1289
|
this.checkpointer = checkpointer;
|
|
@@ -1288,8 +1301,8 @@ var GraphExecutor = class {
|
|
|
1288
1301
|
registerNode(node) {
|
|
1289
1302
|
this.nodes.set(node.id, node);
|
|
1290
1303
|
}
|
|
1291
|
-
async peekCheckpoint(
|
|
1292
|
-
return await this.checkpointer.load(
|
|
1304
|
+
async peekCheckpoint(checkpointKey) {
|
|
1305
|
+
return await this.checkpointer.load(checkpointKey);
|
|
1293
1306
|
}
|
|
1294
1307
|
sanitize(state) {
|
|
1295
1308
|
const local = asLocalRecord(state.local);
|
|
@@ -1301,8 +1314,8 @@ var GraphExecutor = class {
|
|
|
1301
1314
|
local
|
|
1302
1315
|
};
|
|
1303
1316
|
}
|
|
1304
|
-
async prime(
|
|
1305
|
-
this.ephemeralLocals.set(
|
|
1317
|
+
async prime(checkpointKey, local, nodeId = "user") {
|
|
1318
|
+
this.ephemeralLocals.set(checkpointKey, { ...local || {} });
|
|
1306
1319
|
const localSansMemory = { ...local || {} };
|
|
1307
1320
|
if ("memory" in localSansMemory) delete localSansMemory.memory;
|
|
1308
1321
|
const state = {
|
|
@@ -1310,10 +1323,10 @@ var GraphExecutor = class {
|
|
|
1310
1323
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1311
1324
|
local: localSansMemory
|
|
1312
1325
|
};
|
|
1313
|
-
await this.checkpointer.save(
|
|
1326
|
+
await this.checkpointer.save(checkpointKey, state);
|
|
1314
1327
|
}
|
|
1315
|
-
async setNode(
|
|
1316
|
-
const current = await this.checkpointer.load(
|
|
1328
|
+
async setNode(checkpointKey, nodeId, localPatch) {
|
|
1329
|
+
const current = await this.checkpointer.load(checkpointKey) || {
|
|
1317
1330
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1318
1331
|
local: {}
|
|
1319
1332
|
};
|
|
@@ -1324,19 +1337,46 @@ var GraphExecutor = class {
|
|
|
1324
1337
|
schemaVersion: current.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
1325
1338
|
local: mergedLocal
|
|
1326
1339
|
};
|
|
1327
|
-
await this.checkpointer.save(
|
|
1340
|
+
await this.checkpointer.save(checkpointKey, next);
|
|
1328
1341
|
}
|
|
1329
|
-
async runUntilYield(
|
|
1342
|
+
async runUntilYield(checkpointKey) {
|
|
1330
1343
|
const runId = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1331
1344
|
let lifecyclePhase = "completed";
|
|
1345
|
+
let initialState = null;
|
|
1346
|
+
try {
|
|
1347
|
+
initialState = await this.loadInitialState(checkpointKey);
|
|
1348
|
+
} catch (err) {
|
|
1349
|
+
lifecyclePhase = "failed";
|
|
1350
|
+
this.telemetryPort.emit({
|
|
1351
|
+
kind: "run_lifecycle",
|
|
1352
|
+
runId,
|
|
1353
|
+
phase: "spawned",
|
|
1354
|
+
scope: {}
|
|
1355
|
+
});
|
|
1356
|
+
this.telemetryPort.emit({
|
|
1357
|
+
kind: "run_lifecycle",
|
|
1358
|
+
runId,
|
|
1359
|
+
phase: lifecyclePhase,
|
|
1360
|
+
scope: {}
|
|
1361
|
+
});
|
|
1362
|
+
throw err;
|
|
1363
|
+
}
|
|
1364
|
+
let lifecycleConversationId = readRuntimeConversationId(initialState);
|
|
1365
|
+
let lifecycleTurnId = readRuntimeTurnId(initialState);
|
|
1332
1366
|
this.telemetryPort.emit({
|
|
1333
1367
|
kind: "run_lifecycle",
|
|
1334
1368
|
runId,
|
|
1335
1369
|
phase: "spawned",
|
|
1336
|
-
scope: {
|
|
1370
|
+
scope: {
|
|
1371
|
+
conversationId: lifecycleConversationId,
|
|
1372
|
+
turnId: lifecycleTurnId
|
|
1373
|
+
}
|
|
1337
1374
|
});
|
|
1338
1375
|
try {
|
|
1339
|
-
|
|
1376
|
+
const result = await this.runUntilYieldInternal(checkpointKey, initialState);
|
|
1377
|
+
lifecycleConversationId = readRuntimeConversationId(result.checkpoint);
|
|
1378
|
+
lifecycleTurnId = readRuntimeTurnId(result.checkpoint);
|
|
1379
|
+
return result;
|
|
1340
1380
|
} catch (err) {
|
|
1341
1381
|
lifecyclePhase = err?.name === "AbortError" ? "cancelled" : "failed";
|
|
1342
1382
|
throw err;
|
|
@@ -1345,17 +1385,23 @@ var GraphExecutor = class {
|
|
|
1345
1385
|
kind: "run_lifecycle",
|
|
1346
1386
|
runId,
|
|
1347
1387
|
phase: lifecyclePhase,
|
|
1348
|
-
scope: {
|
|
1388
|
+
scope: {
|
|
1389
|
+
conversationId: lifecycleConversationId,
|
|
1390
|
+
turnId: lifecycleTurnId
|
|
1391
|
+
}
|
|
1349
1392
|
});
|
|
1350
1393
|
}
|
|
1351
1394
|
}
|
|
1352
|
-
async
|
|
1353
|
-
|
|
1395
|
+
async loadInitialState(checkpointKey) {
|
|
1396
|
+
return await this.checkpointer.load(checkpointKey) || {
|
|
1354
1397
|
nodeId: "user",
|
|
1355
1398
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1356
1399
|
local: {}
|
|
1357
1400
|
};
|
|
1358
|
-
|
|
1401
|
+
}
|
|
1402
|
+
async runUntilYieldInternal(checkpointKey, initialState) {
|
|
1403
|
+
let state = initialState;
|
|
1404
|
+
const ephemeral = this.ephemeralLocals.get(checkpointKey) || {};
|
|
1359
1405
|
state = {
|
|
1360
1406
|
...state,
|
|
1361
1407
|
schemaVersion: state.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
@@ -1384,7 +1430,7 @@ var GraphExecutor = class {
|
|
|
1384
1430
|
const signalRaw = state.local?.signal;
|
|
1385
1431
|
if (isAbortSignal2(signalRaw) && signalRaw.aborted) {
|
|
1386
1432
|
logger.warn("[GraphExecutor] \u6536\u5230 AbortSignal\uFF0C\u7ACB\u5373\u505C\u6B62\u63A8\u7406\u5FAA\u73AF");
|
|
1387
|
-
this.ephemeralLocals.delete(
|
|
1433
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1388
1434
|
throwAbortError();
|
|
1389
1435
|
}
|
|
1390
1436
|
const isLastStep = cycleStepCount >= this.config.maxSteps;
|
|
@@ -1432,8 +1478,8 @@ var GraphExecutor = class {
|
|
|
1432
1478
|
checkpointCount
|
|
1433
1479
|
});
|
|
1434
1480
|
const cp2 = this.sanitize(state);
|
|
1435
|
-
await this.checkpointer.save(
|
|
1436
|
-
this.ephemeralLocals.delete(
|
|
1481
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1482
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1437
1483
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1438
1484
|
}
|
|
1439
1485
|
logger.info("[GraphExecutor] \u8282\u70B9\u5207\u6362", {
|
|
@@ -1444,18 +1490,18 @@ var GraphExecutor = class {
|
|
|
1444
1490
|
});
|
|
1445
1491
|
const nodeRunStartedAt = Date.now();
|
|
1446
1492
|
const nodeIdForTelemetry = state.nodeId;
|
|
1493
|
+
const conversationIdForTelemetry = readRuntimeConversationId(state);
|
|
1447
1494
|
let result;
|
|
1448
1495
|
try {
|
|
1449
1496
|
result = await node.run(state);
|
|
1450
1497
|
} finally {
|
|
1451
|
-
const turnIdForTelemetry = typeof state.local?.turnId === "string" ? state.local.turnId : void 0;
|
|
1452
1498
|
this.telemetryPort.emit({
|
|
1453
1499
|
kind: "graph_node",
|
|
1454
1500
|
nodeId: nodeIdForTelemetry,
|
|
1455
1501
|
durationMs: Date.now() - nodeRunStartedAt,
|
|
1456
1502
|
scope: {
|
|
1457
|
-
conversationId:
|
|
1458
|
-
turnId:
|
|
1503
|
+
conversationId: conversationIdForTelemetry,
|
|
1504
|
+
turnId: readRuntimeTurnId(state)
|
|
1459
1505
|
}
|
|
1460
1506
|
});
|
|
1461
1507
|
}
|
|
@@ -1494,7 +1540,7 @@ var GraphExecutor = class {
|
|
|
1494
1540
|
});
|
|
1495
1541
|
state = { ...state, nodeId: nextNodeId };
|
|
1496
1542
|
const cp2 = this.sanitize(state);
|
|
1497
|
-
await this.checkpointer.save(
|
|
1543
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1498
1544
|
continue;
|
|
1499
1545
|
}
|
|
1500
1546
|
if (result.kind === "yield") {
|
|
@@ -1505,7 +1551,7 @@ var GraphExecutor = class {
|
|
|
1505
1551
|
checkpointCount
|
|
1506
1552
|
});
|
|
1507
1553
|
const cp2 = this.sanitize(state);
|
|
1508
|
-
await this.checkpointer.save(
|
|
1554
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1509
1555
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1510
1556
|
}
|
|
1511
1557
|
if (result.kind === "pause") {
|
|
@@ -1516,7 +1562,7 @@ var GraphExecutor = class {
|
|
|
1516
1562
|
checkpointCount
|
|
1517
1563
|
});
|
|
1518
1564
|
const cp2 = this.sanitize(state);
|
|
1519
|
-
await this.checkpointer.save(
|
|
1565
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1520
1566
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1521
1567
|
}
|
|
1522
1568
|
}
|
|
@@ -1527,8 +1573,8 @@ var GraphExecutor = class {
|
|
|
1527
1573
|
checkpointCount
|
|
1528
1574
|
});
|
|
1529
1575
|
const cp = this.sanitize(state);
|
|
1530
|
-
await this.checkpointer.save(
|
|
1531
|
-
this.ephemeralLocals.delete(
|
|
1576
|
+
await this.checkpointer.save(checkpointKey, cp);
|
|
1577
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1532
1578
|
return { events: allEvents, checkpoint: cp, stepCount };
|
|
1533
1579
|
}
|
|
1534
1580
|
};
|
|
@@ -1691,15 +1737,15 @@ function splitConcatenatedJsonObjects(input) {
|
|
|
1691
1737
|
}
|
|
1692
1738
|
|
|
1693
1739
|
// src/runtime-kernel/graph-engine/tick-pipeline/helpers.ts
|
|
1694
|
-
function
|
|
1740
|
+
function readNonEmptyString2(value) {
|
|
1695
1741
|
if (typeof value !== "string") return void 0;
|
|
1696
1742
|
const trimmed = value.trim();
|
|
1697
1743
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
1698
1744
|
}
|
|
1699
1745
|
function resolveConversationIdForRuntimeEvents(toolContext) {
|
|
1700
|
-
const fromCamel =
|
|
1746
|
+
const fromCamel = readNonEmptyString2(toolContext?.conversationId);
|
|
1701
1747
|
if (fromCamel) return fromCamel;
|
|
1702
|
-
const fromSnake = toolContext ?
|
|
1748
|
+
const fromSnake = toolContext ? readNonEmptyString2(toolContext["conversation_id"]) : void 0;
|
|
1703
1749
|
if (fromSnake) return fromSnake;
|
|
1704
1750
|
return generateMessageId();
|
|
1705
1751
|
}
|
|
@@ -2056,7 +2102,7 @@ var runModelLockMiddleware = async (ctx, stage, next) => {
|
|
|
2056
2102
|
if (stage.id !== "execute_llm") {
|
|
2057
2103
|
return;
|
|
2058
2104
|
}
|
|
2059
|
-
const normalized =
|
|
2105
|
+
const normalized = readNonEmptyString2(ctx.cloudQuotaFallbackAppliedModelId);
|
|
2060
2106
|
if (!normalized) {
|
|
2061
2107
|
return;
|
|
2062
2108
|
}
|
|
@@ -2644,7 +2690,7 @@ function createExecuteLlmStage(dependencies) {
|
|
|
2644
2690
|
streamEventHandler,
|
|
2645
2691
|
ctx.signal,
|
|
2646
2692
|
(fallbackModelId) => {
|
|
2647
|
-
ctx.cloudQuotaFallbackAppliedModelId =
|
|
2693
|
+
ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString2(fallbackModelId);
|
|
2648
2694
|
},
|
|
2649
2695
|
(info) => {
|
|
2650
2696
|
ctx.modelFallbackAudit = info;
|
|
@@ -2688,7 +2734,7 @@ function createPrepareCallStage(dependencies) {
|
|
|
2688
2734
|
return {
|
|
2689
2735
|
id: "prepare_call",
|
|
2690
2736
|
async run(ctx) {
|
|
2691
|
-
const lockedRunModelId =
|
|
2737
|
+
const lockedRunModelId = readNonEmptyString2(ctx.executorLocal?.runLockedModelId);
|
|
2692
2738
|
const requestedModelId = lockedRunModelId ?? ctx.request.model_id;
|
|
2693
2739
|
ctx.modelId = dependencies.modelResolver.resolveModelId(requestedModelId);
|
|
2694
2740
|
await emitAuditEnvelope(ctx.audit, {
|
|
@@ -2760,7 +2806,7 @@ var GraphAgentExecutor = class {
|
|
|
2760
2806
|
this.llmCaller = dependencies.llmCaller;
|
|
2761
2807
|
this.toolRuntime = dependencies.toolRuntime;
|
|
2762
2808
|
this.contextBuilder = dependencies.contextBuilder;
|
|
2763
|
-
this.cloudQuotaFallbackModelId =
|
|
2809
|
+
this.cloudQuotaFallbackModelId = readNonEmptyString2(dependencies.cloudQuotaFallbackModelId);
|
|
2764
2810
|
this.modelCatalog = dependencies.modelCatalog ?? createEmptyModelCatalog();
|
|
2765
2811
|
this.modelResolver = dependencies.modelResolver ?? new ModelResolver({
|
|
2766
2812
|
modelCatalog: this.modelCatalog
|
|
@@ -2808,7 +2854,7 @@ var GraphAgentExecutor = class {
|
|
|
2808
2854
|
llmMessages: [],
|
|
2809
2855
|
mode: input.request.mode === "chat" ? "chat" : "agent",
|
|
2810
2856
|
conversationId: resolveConversationIdForRuntimeEvents(input.toolContext),
|
|
2811
|
-
turnId:
|
|
2857
|
+
turnId: readNonEmptyString2(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
|
|
2812
2858
|
telemetry: this.telemetryPort,
|
|
2813
2859
|
audit: this.auditPort
|
|
2814
2860
|
};
|
|
@@ -2858,18 +2904,18 @@ function isSummarizationCallbacks(value) {
|
|
|
2858
2904
|
function isGraphSseSink(value) {
|
|
2859
2905
|
return typeof value === "function";
|
|
2860
2906
|
}
|
|
2861
|
-
function
|
|
2907
|
+
function readNonEmptyString3(value) {
|
|
2862
2908
|
if (typeof value !== "string") return void 0;
|
|
2863
2909
|
const trimmed = value.trim();
|
|
2864
2910
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
2865
2911
|
}
|
|
2866
2912
|
function readGraphAgentLocal(local) {
|
|
2867
2913
|
const source = local ?? {};
|
|
2868
|
-
const answerId =
|
|
2914
|
+
const answerId = readNonEmptyString3(source.answerId);
|
|
2869
2915
|
const chunkSeq = Number.isInteger(source.chunkSeq) ? Number(source.chunkSeq) : 0;
|
|
2870
2916
|
return {
|
|
2871
|
-
conversationId:
|
|
2872
|
-
turnId:
|
|
2917
|
+
conversationId: readNonEmptyString3(source.conversationId) ?? "",
|
|
2918
|
+
turnId: readNonEmptyString3(source.turnId),
|
|
2873
2919
|
request: isAgentInvocationRequest(source.request) ? source.request : void 0,
|
|
2874
2920
|
toolContext: isToolExecutionContext(source.toolContext) ? source.toolContext : void 0,
|
|
2875
2921
|
history: isRuntimeEventArray(source.history) ? source.history : [],
|
|
@@ -3634,7 +3680,7 @@ var LlmNode = class {
|
|
|
3634
3680
|
function isRecord8(value) {
|
|
3635
3681
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3636
3682
|
}
|
|
3637
|
-
function
|
|
3683
|
+
function readNonEmptyString4(value) {
|
|
3638
3684
|
if (typeof value !== "string") {
|
|
3639
3685
|
return void 0;
|
|
3640
3686
|
}
|
|
@@ -3656,7 +3702,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3656
3702
|
return void 0;
|
|
3657
3703
|
}
|
|
3658
3704
|
if (toolName === "write_report") {
|
|
3659
|
-
const report =
|
|
3705
|
+
const report = readNonEmptyString4(data.report);
|
|
3660
3706
|
if (!report) {
|
|
3661
3707
|
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");
|
|
3662
3708
|
}
|
|
@@ -3666,7 +3712,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3666
3712
|
if (data.success !== true) {
|
|
3667
3713
|
return void 0;
|
|
3668
3714
|
}
|
|
3669
|
-
const finalAnswer =
|
|
3715
|
+
const finalAnswer = readNonEmptyString4(data.final_answer);
|
|
3670
3716
|
if (!finalAnswer) {
|
|
3671
3717
|
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");
|
|
3672
3718
|
}
|
|
@@ -4562,6 +4608,22 @@ var ToolNode = class {
|
|
|
4562
4608
|
});
|
|
4563
4609
|
}
|
|
4564
4610
|
async run(state) {
|
|
4611
|
+
const events = [];
|
|
4612
|
+
while (true) {
|
|
4613
|
+
const result = await this.runNextPendingToolCall(state);
|
|
4614
|
+
if (Array.isArray(result.events) && result.events.length > 0) {
|
|
4615
|
+
events.push(...result.events);
|
|
4616
|
+
}
|
|
4617
|
+
if (result.kind === "route" && result.nextNodeId === "tool") {
|
|
4618
|
+
continue;
|
|
4619
|
+
}
|
|
4620
|
+
return {
|
|
4621
|
+
...result,
|
|
4622
|
+
events
|
|
4623
|
+
};
|
|
4624
|
+
}
|
|
4625
|
+
}
|
|
4626
|
+
async runNextPendingToolCall(state) {
|
|
4565
4627
|
const calls = state.local?.pendingToolCalls ?? [];
|
|
4566
4628
|
const signalRaw = state.local?.signal;
|
|
4567
4629
|
if (isAbortSignal(signalRaw) && signalRaw.aborted) {
|
|
@@ -4769,18 +4831,25 @@ var ToolNode = class {
|
|
|
4769
4831
|
rawArguments: context.call.function?.arguments,
|
|
4770
4832
|
parsedArguments: context.toolArgs
|
|
4771
4833
|
});
|
|
4834
|
+
const remainingCalls = context.calls.slice(1);
|
|
4772
4835
|
context.state.local = buildErrorLocalState({
|
|
4773
4836
|
local: context.local,
|
|
4774
|
-
remainingCalls
|
|
4837
|
+
remainingCalls,
|
|
4775
4838
|
conversationId: context.conversationId,
|
|
4776
4839
|
turnId: context.turnId,
|
|
4777
4840
|
runtimeEvents: context.bridge.getRuntimeEvents(),
|
|
4778
4841
|
nextProtocolErrorCount: fuse.nextCount
|
|
4779
4842
|
});
|
|
4780
|
-
if (fuse.shouldFuse) {
|
|
4843
|
+
if (fuse.shouldFuse && remainingCalls.length === 0) {
|
|
4781
4844
|
throw createToolProtocolFuseError(fuse.nextCount, context.exec.error);
|
|
4782
4845
|
}
|
|
4783
|
-
return {
|
|
4846
|
+
return {
|
|
4847
|
+
kind: "route",
|
|
4848
|
+
// 同一个 assistant.tool_calls batch 必须为每个 call 产出 tool_output。
|
|
4849
|
+
// 出错时也继续消费剩余 call,ToolNode.run 会在本节点内 drain 完 batch 再回 LLM。
|
|
4850
|
+
nextNodeId: remainingCalls.length > 0 ? "tool" : "llm",
|
|
4851
|
+
events: context.bridge.getRuntimeEvents()
|
|
4852
|
+
};
|
|
4784
4853
|
}
|
|
4785
4854
|
};
|
|
4786
4855
|
|
|
@@ -4977,12 +5046,12 @@ function asRecord(value) {
|
|
|
4977
5046
|
}
|
|
4978
5047
|
return value;
|
|
4979
5048
|
}
|
|
4980
|
-
function summarizeCheckpoint(
|
|
5049
|
+
function summarizeCheckpoint(checkpointKey, state, savedAt) {
|
|
4981
5050
|
const local = asRecord(state.local);
|
|
4982
5051
|
const executorLocal = asRecord(local?.executorLocal);
|
|
4983
5052
|
const pendingToolCalls = local?.pendingToolCalls;
|
|
4984
5053
|
return {
|
|
4985
|
-
|
|
5054
|
+
checkpointKey,
|
|
4986
5055
|
schemaVersion: state.schemaVersion ?? 1,
|
|
4987
5056
|
savedAt,
|
|
4988
5057
|
currentNode: state.nodeId,
|
|
@@ -5001,25 +5070,25 @@ var MemoryCheckpointer = class {
|
|
|
5001
5070
|
local: state.local && typeof state.local === "object" && !Array.isArray(state.local) ? { ...state.local } : state.local
|
|
5002
5071
|
};
|
|
5003
5072
|
}
|
|
5004
|
-
async load(
|
|
5005
|
-
const entry = this.store.get(
|
|
5073
|
+
async load(checkpointKey) {
|
|
5074
|
+
const entry = this.store.get(checkpointKey);
|
|
5006
5075
|
return entry ? this.cloneState(entry.state) : null;
|
|
5007
5076
|
}
|
|
5008
|
-
async save(
|
|
5009
|
-
this.store.set(
|
|
5077
|
+
async save(checkpointKey, state) {
|
|
5078
|
+
this.store.set(checkpointKey, {
|
|
5010
5079
|
state: this.cloneState(state),
|
|
5011
5080
|
savedAt: Date.now()
|
|
5012
5081
|
});
|
|
5013
5082
|
}
|
|
5014
|
-
async clear(
|
|
5015
|
-
this.store.delete(
|
|
5083
|
+
async clear(checkpointKey) {
|
|
5084
|
+
this.store.delete(checkpointKey);
|
|
5016
5085
|
}
|
|
5017
|
-
async peekMeta(
|
|
5018
|
-
const entry = this.store.get(
|
|
5019
|
-
return entry ? summarizeCheckpoint(
|
|
5086
|
+
async peekMeta(checkpointKey) {
|
|
5087
|
+
const entry = this.store.get(checkpointKey);
|
|
5088
|
+
return entry ? summarizeCheckpoint(checkpointKey, entry.state, entry.savedAt) : null;
|
|
5020
5089
|
}
|
|
5021
5090
|
async list(filter = {}) {
|
|
5022
|
-
const summaries = Array.from(this.store.entries()).map(([
|
|
5091
|
+
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);
|
|
5023
5092
|
if (filter.limit === void 0) {
|
|
5024
5093
|
return summaries;
|
|
5025
5094
|
}
|
|
@@ -5276,18 +5345,18 @@ function createClassification(category, reason, suggestedDelay, extras) {
|
|
|
5276
5345
|
}
|
|
5277
5346
|
var ErrorClassifier = class {
|
|
5278
5347
|
static classify(error, context) {
|
|
5279
|
-
const
|
|
5348
|
+
const isRecord22 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
5280
5349
|
const baseMsg = (error.message || "").toLowerCase();
|
|
5281
5350
|
const causeMsg = (() => {
|
|
5282
5351
|
const cause = error.cause;
|
|
5283
5352
|
if (typeof cause === "string") return cause.toLowerCase();
|
|
5284
5353
|
if (cause instanceof Error) return (cause.message || "").toLowerCase();
|
|
5285
|
-
if (
|
|
5354
|
+
if (isRecord22(cause) && typeof cause["message"] === "string") return String(cause["message"]).toLowerCase();
|
|
5286
5355
|
return "";
|
|
5287
5356
|
})();
|
|
5288
5357
|
const causeCode = (() => {
|
|
5289
5358
|
const cause = error.cause;
|
|
5290
|
-
if (
|
|
5359
|
+
if (isRecord22(cause) && typeof cause["code"] === "string") return String(cause["code"]);
|
|
5291
5360
|
return "";
|
|
5292
5361
|
})();
|
|
5293
5362
|
const errorMessage = `${baseMsg} ${causeMsg}`.trim();
|
|
@@ -5963,6 +6032,67 @@ function assertToolCallsHaveValidJsonArguments(toolCalls) {
|
|
|
5963
6032
|
}
|
|
5964
6033
|
}
|
|
5965
6034
|
|
|
6035
|
+
// src/runtime-kernel/llm/reasoning-details.ts
|
|
6036
|
+
var mergeableTextFields = ["reasoning_content"];
|
|
6037
|
+
function isRecord18(value) {
|
|
6038
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
6039
|
+
}
|
|
6040
|
+
function findMergeableTextField(detail) {
|
|
6041
|
+
if (!isRecord18(detail)) return void 0;
|
|
6042
|
+
if (typeof detail.provider !== "string") return void 0;
|
|
6043
|
+
if (typeof detail.type !== "string") return void 0;
|
|
6044
|
+
for (const field of mergeableTextFields) {
|
|
6045
|
+
if (typeof detail[field] === "string") {
|
|
6046
|
+
return field;
|
|
6047
|
+
}
|
|
6048
|
+
}
|
|
6049
|
+
return void 0;
|
|
6050
|
+
}
|
|
6051
|
+
function hasOnlyStableTextDetailFields(detail, textField) {
|
|
6052
|
+
const allowedKeys = /* @__PURE__ */ new Set(["provider", "type", textField]);
|
|
6053
|
+
return Object.keys(detail).every((key) => allowedKeys.has(key));
|
|
6054
|
+
}
|
|
6055
|
+
function canMergeTextDetails(previous, incoming) {
|
|
6056
|
+
if (!isRecord18(previous) || !isRecord18(incoming)) return false;
|
|
6057
|
+
const previousField = findMergeableTextField(previous);
|
|
6058
|
+
const incomingField = findMergeableTextField(incoming);
|
|
6059
|
+
if (!previousField || previousField !== incomingField) return false;
|
|
6060
|
+
return previous.provider === incoming.provider && previous.type === incoming.type && hasOnlyStableTextDetailFields(previous, previousField) && hasOnlyStableTextDetailFields(incoming, incomingField);
|
|
6061
|
+
}
|
|
6062
|
+
function mergeStreamingText(previous, incoming) {
|
|
6063
|
+
if (!previous) return incoming;
|
|
6064
|
+
if (!incoming) return previous;
|
|
6065
|
+
if (incoming.startsWith(previous)) {
|
|
6066
|
+
return incoming;
|
|
6067
|
+
}
|
|
6068
|
+
if (previous.endsWith(incoming)) {
|
|
6069
|
+
return previous;
|
|
6070
|
+
}
|
|
6071
|
+
return `${previous}${incoming}`;
|
|
6072
|
+
}
|
|
6073
|
+
function appendStreamingProviderReasoningDetails(existing, incoming) {
|
|
6074
|
+
const next = [...existing];
|
|
6075
|
+
for (const detail of incoming) {
|
|
6076
|
+
const previous = next[next.length - 1];
|
|
6077
|
+
if (canMergeTextDetails(previous, detail)) {
|
|
6078
|
+
const textField = findMergeableTextField(previous);
|
|
6079
|
+
if (textField && isRecord18(detail)) {
|
|
6080
|
+
const mergedText = mergeStreamingText(String(previous[textField]), String(detail[textField]));
|
|
6081
|
+
if (mergedText === previous[textField]) {
|
|
6082
|
+
continue;
|
|
6083
|
+
}
|
|
6084
|
+
next[next.length - 1] = {
|
|
6085
|
+
...previous,
|
|
6086
|
+
[textField]: mergedText
|
|
6087
|
+
};
|
|
6088
|
+
continue;
|
|
6089
|
+
}
|
|
6090
|
+
}
|
|
6091
|
+
next.push(detail);
|
|
6092
|
+
}
|
|
6093
|
+
return next;
|
|
6094
|
+
}
|
|
6095
|
+
|
|
5966
6096
|
// src/runtime-kernel/llm/streaming-adapter.ts
|
|
5967
6097
|
async function callLlmStream(params) {
|
|
5968
6098
|
const {
|
|
@@ -5975,7 +6105,7 @@ async function callLlmStream(params) {
|
|
|
5975
6105
|
} = params;
|
|
5976
6106
|
let fullResponse = "";
|
|
5977
6107
|
let streamError = null;
|
|
5978
|
-
|
|
6108
|
+
let reasoningDetails = [];
|
|
5979
6109
|
const streamAnswerId = generateMessageId();
|
|
5980
6110
|
let streamChunkSeq = 0;
|
|
5981
6111
|
let capturedUsage = void 0;
|
|
@@ -6045,13 +6175,21 @@ async function callLlmStream(params) {
|
|
|
6045
6175
|
const reasoning = isRecord17(chunk) ? chunk["reasoning_details"] : void 0;
|
|
6046
6176
|
if (reasoning !== void 0) {
|
|
6047
6177
|
const newReasoningDetails = Array.isArray(reasoning) ? reasoning : [reasoning];
|
|
6048
|
-
reasoningDetails
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6178
|
+
const previousReasoningDetails = reasoningDetails;
|
|
6179
|
+
const previousLength = previousReasoningDetails.length;
|
|
6180
|
+
const compactedReasoningDetails = appendStreamingProviderReasoningDetails(reasoningDetails, newReasoningDetails);
|
|
6181
|
+
reasoningDetails = compactedReasoningDetails;
|
|
6182
|
+
const previousLastChanged = previousLength > 0 && compactedReasoningDetails[previousLength - 1] !== previousReasoningDetails[previousLength - 1];
|
|
6183
|
+
const emitFromIndex = previousLastChanged ? previousLength - 1 : previousLength;
|
|
6184
|
+
const emittedReasoningDetails = compactedReasoningDetails.slice(Math.max(0, emitFromIndex));
|
|
6185
|
+
if (emittedReasoningDetails.length > 0) {
|
|
6186
|
+
eventHandler({
|
|
6187
|
+
type: "provider_sidecar",
|
|
6188
|
+
id: generateMessageId(),
|
|
6189
|
+
timestamp: Date.now(),
|
|
6190
|
+
reasoning_details: emittedReasoningDetails
|
|
6191
|
+
});
|
|
6192
|
+
}
|
|
6055
6193
|
}
|
|
6056
6194
|
if (chunk.tool_calls) {
|
|
6057
6195
|
emitThoughtComplete(thoughtSegmenter.onBoundary());
|
|
@@ -6490,7 +6628,7 @@ function cloneRunRecord(record) {
|
|
|
6490
6628
|
...record,
|
|
6491
6629
|
iterationBudget: record.iterationBudget ? { ...record.iterationBudget } : void 0,
|
|
6492
6630
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0,
|
|
6493
|
-
metadata: record.metadata ?
|
|
6631
|
+
metadata: record.metadata ? structuredClone(record.metadata) : void 0
|
|
6494
6632
|
};
|
|
6495
6633
|
}
|
|
6496
6634
|
function matchesStatus(candidate, filter) {
|
|
@@ -6622,7 +6760,7 @@ function runRecordToMeta(record) {
|
|
|
6622
6760
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0
|
|
6623
6761
|
};
|
|
6624
6762
|
}
|
|
6625
|
-
function
|
|
6763
|
+
function isRecord19(value) {
|
|
6626
6764
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6627
6765
|
}
|
|
6628
6766
|
function readStringField(record, key) {
|
|
@@ -6643,7 +6781,7 @@ function getRunIdFromMetadata(event) {
|
|
|
6643
6781
|
return snakeCaseRunId;
|
|
6644
6782
|
}
|
|
6645
6783
|
const runContext = metadata["run_context"];
|
|
6646
|
-
if (
|
|
6784
|
+
if (isRecord19(runContext)) {
|
|
6647
6785
|
return readStringField(runContext, "runId") ?? readStringField(runContext, "run_id");
|
|
6648
6786
|
}
|
|
6649
6787
|
return void 0;
|
|
@@ -6861,7 +6999,7 @@ function runMetaFromRecord(record) {
|
|
|
6861
6999
|
}
|
|
6862
7000
|
|
|
6863
7001
|
// src/runtime-kernel/run-supervisor/runSupervisor.ts
|
|
6864
|
-
function
|
|
7002
|
+
function isRecord20(value) {
|
|
6865
7003
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6866
7004
|
}
|
|
6867
7005
|
function readStringField2(record, key) {
|
|
@@ -6878,7 +7016,7 @@ function readRunIdFromRuntimeEvent(event) {
|
|
|
6878
7016
|
return directRunId;
|
|
6879
7017
|
}
|
|
6880
7018
|
const runContext = metadata["run_context"];
|
|
6881
|
-
if (!
|
|
7019
|
+
if (!isRecord20(runContext)) {
|
|
6882
7020
|
return void 0;
|
|
6883
7021
|
}
|
|
6884
7022
|
return readStringField2(runContext, "runId") ?? readStringField2(runContext, "run_id");
|
|
@@ -6890,7 +7028,7 @@ function readAwaitingUserReason(event) {
|
|
|
6890
7028
|
if (typeof event.prompt === "string" && event.prompt.trim().length > 0) {
|
|
6891
7029
|
return event.prompt;
|
|
6892
7030
|
}
|
|
6893
|
-
if (
|
|
7031
|
+
if (isRecord20(event.form)) {
|
|
6894
7032
|
const prompt = readStringField2(event.form, "prompt");
|
|
6895
7033
|
if (prompt && prompt.trim().length > 0) {
|
|
6896
7034
|
return prompt;
|
|
@@ -6902,7 +7040,7 @@ function isTerminalStatus(status) {
|
|
|
6902
7040
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
6903
7041
|
}
|
|
6904
7042
|
function cloneMetadata(metadata) {
|
|
6905
|
-
return metadata ?
|
|
7043
|
+
return metadata ? structuredClone(metadata) : void 0;
|
|
6906
7044
|
}
|
|
6907
7045
|
function recordToSnapshot(record) {
|
|
6908
7046
|
return {
|
|
@@ -6989,7 +7127,7 @@ var DefaultRunSupervisor = class {
|
|
|
6989
7127
|
startedAt,
|
|
6990
7128
|
updatedAt: startedAt,
|
|
6991
7129
|
iterationBudget: spec.iterationBudget ? { ...spec.iterationBudget } : void 0,
|
|
6992
|
-
metadata: spec.metadata
|
|
7130
|
+
metadata: cloneMetadata(spec.metadata)
|
|
6993
7131
|
};
|
|
6994
7132
|
await this.registryStore.save(record);
|
|
6995
7133
|
const handle = new DefaultRunHandle({
|
|
@@ -7163,12 +7301,13 @@ var DefaultRunSupervisor = class {
|
|
|
7163
7301
|
}
|
|
7164
7302
|
try {
|
|
7165
7303
|
await handle.markRunning({ currentNode: "detached" });
|
|
7304
|
+
const registeredRecord = await this.registryStore.load(handle.runId);
|
|
7166
7305
|
const executorOutcome = await this.executor.execute({
|
|
7167
7306
|
runId: handle.runId,
|
|
7168
|
-
parentRunId:
|
|
7169
|
-
conversationId: spec.conversationId,
|
|
7170
|
-
agentSpec: spec
|
|
7171
|
-
request:
|
|
7307
|
+
parentRunId: handle.parentRunId,
|
|
7308
|
+
conversationId: registeredRecord?.conversationId ?? spec.conversationId,
|
|
7309
|
+
agentSpec: await handle.spec(),
|
|
7310
|
+
request: await handle.request(),
|
|
7172
7311
|
signal: handle.signal,
|
|
7173
7312
|
eventBus: spec.eventBus,
|
|
7174
7313
|
eventStore: spec.eventStore,
|
|
@@ -7177,7 +7316,7 @@ var DefaultRunSupervisor = class {
|
|
|
7177
7316
|
contextFences: spec.contextFences,
|
|
7178
7317
|
wakeSource: spec.wakeSource,
|
|
7179
7318
|
ephemeral: spec.ephemeral,
|
|
7180
|
-
metadata: spec.metadata
|
|
7319
|
+
metadata: cloneMetadata(registeredRecord?.metadata ?? spec.metadata)
|
|
7181
7320
|
});
|
|
7182
7321
|
const outcome = await this.persistExecutorOutcome(handle, executorOutcome);
|
|
7183
7322
|
this.notifyTerminalWaiters(outcome);
|
|
@@ -7241,10 +7380,14 @@ var DefaultRunSupervisor = class {
|
|
|
7241
7380
|
await this.registryStore.save(record);
|
|
7242
7381
|
}
|
|
7243
7382
|
const completedAt = executorOutcome?.completedAt ?? this.now();
|
|
7383
|
+
const fallbackMeta = record ? void 0 : await handle.meta();
|
|
7244
7384
|
const outcome = recordToTerminalOutcome(record ?? {
|
|
7245
7385
|
runId: handle.runId,
|
|
7246
7386
|
parentRunId: handle.parentRunId,
|
|
7247
|
-
|
|
7387
|
+
conversationId: fallbackMeta?.conversationId ?? "",
|
|
7388
|
+
agentSpecId: fallbackMeta?.agentSpecId,
|
|
7389
|
+
status: executorOutcome?.status ?? "completed",
|
|
7390
|
+
startedAt: fallbackMeta?.startedAt ?? completedAt}, completedAt);
|
|
7248
7391
|
const nextOutcome = {
|
|
7249
7392
|
...outcome,
|
|
7250
7393
|
metadata: {
|
|
@@ -7500,7 +7643,7 @@ function createQuickstartTelemetryPort(collector) {
|
|
|
7500
7643
|
}
|
|
7501
7644
|
|
|
7502
7645
|
// src/quickstart/runAgent.ts
|
|
7503
|
-
function
|
|
7646
|
+
function isRecord21(value) {
|
|
7504
7647
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7505
7648
|
}
|
|
7506
7649
|
function readString4(value) {
|
|
@@ -7514,7 +7657,7 @@ function resolveModelId(agent, options) {
|
|
|
7514
7657
|
return modelId;
|
|
7515
7658
|
}
|
|
7516
7659
|
function isQuickstartStreamChunkEvent(value) {
|
|
7517
|
-
return
|
|
7660
|
+
return isRecord21(value) && value.type === "stream_chunk" && typeof value.content === "string";
|
|
7518
7661
|
}
|
|
7519
7662
|
function createNoopObservationPreview() {
|
|
7520
7663
|
return {
|
|
@@ -7554,7 +7697,7 @@ function readFinalAnswer(events, checkpointLocal) {
|
|
|
7554
7697
|
if (chunks.length > 0) {
|
|
7555
7698
|
return chunks.join("");
|
|
7556
7699
|
}
|
|
7557
|
-
if (
|
|
7700
|
+
if (isRecord21(checkpointLocal)) {
|
|
7558
7701
|
const finalAnswer = checkpointLocal["finalAnswer"];
|
|
7559
7702
|
if (typeof finalAnswer === "string") {
|
|
7560
7703
|
return finalAnswer;
|
|
@@ -7563,7 +7706,7 @@ function readFinalAnswer(events, checkpointLocal) {
|
|
|
7563
7706
|
return "";
|
|
7564
7707
|
}
|
|
7565
7708
|
function readContextTrace(checkpointLocal) {
|
|
7566
|
-
if (!
|
|
7709
|
+
if (!isRecord21(checkpointLocal)) return void 0;
|
|
7567
7710
|
return checkpointLocal["contextTrace"];
|
|
7568
7711
|
}
|
|
7569
7712
|
async function emitRunEvent(event, sink) {
|
|
@@ -7572,6 +7715,7 @@ async function emitRunEvent(event, sink) {
|
|
|
7572
7715
|
async function runAgent(agent, options) {
|
|
7573
7716
|
const modelId = resolveModelId(agent, options);
|
|
7574
7717
|
const conversationId = options.conversationId ?? `conv_${Date.now()}`;
|
|
7718
|
+
const checkpointKey = conversationId;
|
|
7575
7719
|
const runId = options.runId ?? generateRunId();
|
|
7576
7720
|
const turnId = runId;
|
|
7577
7721
|
const costCollector = new QuickstartRunCostCollector();
|
|
@@ -7626,7 +7770,7 @@ async function runAgent(agent, options) {
|
|
|
7626
7770
|
};
|
|
7627
7771
|
await handle.markRunning({ currentNode: "user" });
|
|
7628
7772
|
try {
|
|
7629
|
-
await executor.prime(
|
|
7773
|
+
await executor.prime(checkpointKey, {
|
|
7630
7774
|
conversationId,
|
|
7631
7775
|
turnId,
|
|
7632
7776
|
request: {
|
|
@@ -7651,7 +7795,7 @@ async function runAgent(agent, options) {
|
|
|
7651
7795
|
return void 0;
|
|
7652
7796
|
}
|
|
7653
7797
|
});
|
|
7654
|
-
const result = await executor.runUntilYield(
|
|
7798
|
+
const result = await executor.runUntilYield(checkpointKey);
|
|
7655
7799
|
runtimeEvents.push(...result.events);
|
|
7656
7800
|
for (const event of result.events) {
|
|
7657
7801
|
if (event.type === "final_answer_chunk") continue;
|