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