@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/cli.js
CHANGED
|
@@ -200,6 +200,7 @@ var AgentSpecBudgetPolicy = z.object({
|
|
|
200
200
|
});
|
|
201
201
|
var AgentSpecToolHistoryPolicy = z.object({
|
|
202
202
|
strategy: z.enum(["per-pair", "per-run", "none"]).optional(),
|
|
203
|
+
retentionMode: z.enum(["drop", "compress"]).optional(),
|
|
203
204
|
keepLatestToolPairs: z.number().int().nonnegative().optional(),
|
|
204
205
|
keepLatestRuns: z.number().int().nonnegative().optional(),
|
|
205
206
|
maxInteractionGroups: z.number().int().nonnegative().optional(),
|
|
@@ -1154,6 +1155,17 @@ var logger = new Logger("GraphExecutor");
|
|
|
1154
1155
|
function asLocalRecord(local) {
|
|
1155
1156
|
return local && typeof local === "object" ? { ...local } : {};
|
|
1156
1157
|
}
|
|
1158
|
+
function readNonEmptyString(value) {
|
|
1159
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1160
|
+
}
|
|
1161
|
+
function readRuntimeConversationId(state) {
|
|
1162
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1163
|
+
return readNonEmptyString(local?.conversationId);
|
|
1164
|
+
}
|
|
1165
|
+
function readRuntimeTurnId(state) {
|
|
1166
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1167
|
+
return readNonEmptyString(local?.turnId);
|
|
1168
|
+
}
|
|
1157
1169
|
var GraphExecutor = class {
|
|
1158
1170
|
constructor(checkpointer, config = {}) {
|
|
1159
1171
|
this.checkpointer = checkpointer;
|
|
@@ -1171,8 +1183,8 @@ var GraphExecutor = class {
|
|
|
1171
1183
|
registerNode(node) {
|
|
1172
1184
|
this.nodes.set(node.id, node);
|
|
1173
1185
|
}
|
|
1174
|
-
async peekCheckpoint(
|
|
1175
|
-
return await this.checkpointer.load(
|
|
1186
|
+
async peekCheckpoint(checkpointKey) {
|
|
1187
|
+
return await this.checkpointer.load(checkpointKey);
|
|
1176
1188
|
}
|
|
1177
1189
|
sanitize(state) {
|
|
1178
1190
|
const local = asLocalRecord(state.local);
|
|
@@ -1184,8 +1196,8 @@ var GraphExecutor = class {
|
|
|
1184
1196
|
local
|
|
1185
1197
|
};
|
|
1186
1198
|
}
|
|
1187
|
-
async prime(
|
|
1188
|
-
this.ephemeralLocals.set(
|
|
1199
|
+
async prime(checkpointKey, local, nodeId = "user") {
|
|
1200
|
+
this.ephemeralLocals.set(checkpointKey, { ...local || {} });
|
|
1189
1201
|
const localSansMemory = { ...local || {} };
|
|
1190
1202
|
if ("memory" in localSansMemory) delete localSansMemory.memory;
|
|
1191
1203
|
const state = {
|
|
@@ -1193,10 +1205,10 @@ var GraphExecutor = class {
|
|
|
1193
1205
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1194
1206
|
local: localSansMemory
|
|
1195
1207
|
};
|
|
1196
|
-
await this.checkpointer.save(
|
|
1208
|
+
await this.checkpointer.save(checkpointKey, state);
|
|
1197
1209
|
}
|
|
1198
|
-
async setNode(
|
|
1199
|
-
const current = await this.checkpointer.load(
|
|
1210
|
+
async setNode(checkpointKey, nodeId, localPatch) {
|
|
1211
|
+
const current = await this.checkpointer.load(checkpointKey) || {
|
|
1200
1212
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1201
1213
|
local: {}
|
|
1202
1214
|
};
|
|
@@ -1207,19 +1219,46 @@ var GraphExecutor = class {
|
|
|
1207
1219
|
schemaVersion: current.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
1208
1220
|
local: mergedLocal
|
|
1209
1221
|
};
|
|
1210
|
-
await this.checkpointer.save(
|
|
1222
|
+
await this.checkpointer.save(checkpointKey, next);
|
|
1211
1223
|
}
|
|
1212
|
-
async runUntilYield(
|
|
1224
|
+
async runUntilYield(checkpointKey) {
|
|
1213
1225
|
const runId = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1214
1226
|
let lifecyclePhase = "completed";
|
|
1227
|
+
let initialState = null;
|
|
1228
|
+
try {
|
|
1229
|
+
initialState = await this.loadInitialState(checkpointKey);
|
|
1230
|
+
} catch (err) {
|
|
1231
|
+
lifecyclePhase = "failed";
|
|
1232
|
+
this.telemetryPort.emit({
|
|
1233
|
+
kind: "run_lifecycle",
|
|
1234
|
+
runId,
|
|
1235
|
+
phase: "spawned",
|
|
1236
|
+
scope: {}
|
|
1237
|
+
});
|
|
1238
|
+
this.telemetryPort.emit({
|
|
1239
|
+
kind: "run_lifecycle",
|
|
1240
|
+
runId,
|
|
1241
|
+
phase: lifecyclePhase,
|
|
1242
|
+
scope: {}
|
|
1243
|
+
});
|
|
1244
|
+
throw err;
|
|
1245
|
+
}
|
|
1246
|
+
let lifecycleConversationId = readRuntimeConversationId(initialState);
|
|
1247
|
+
let lifecycleTurnId = readRuntimeTurnId(initialState);
|
|
1215
1248
|
this.telemetryPort.emit({
|
|
1216
1249
|
kind: "run_lifecycle",
|
|
1217
1250
|
runId,
|
|
1218
1251
|
phase: "spawned",
|
|
1219
|
-
scope: {
|
|
1252
|
+
scope: {
|
|
1253
|
+
conversationId: lifecycleConversationId,
|
|
1254
|
+
turnId: lifecycleTurnId
|
|
1255
|
+
}
|
|
1220
1256
|
});
|
|
1221
1257
|
try {
|
|
1222
|
-
|
|
1258
|
+
const result = await this.runUntilYieldInternal(checkpointKey, initialState);
|
|
1259
|
+
lifecycleConversationId = readRuntimeConversationId(result.checkpoint);
|
|
1260
|
+
lifecycleTurnId = readRuntimeTurnId(result.checkpoint);
|
|
1261
|
+
return result;
|
|
1223
1262
|
} catch (err) {
|
|
1224
1263
|
lifecyclePhase = err?.name === "AbortError" ? "cancelled" : "failed";
|
|
1225
1264
|
throw err;
|
|
@@ -1228,17 +1267,23 @@ var GraphExecutor = class {
|
|
|
1228
1267
|
kind: "run_lifecycle",
|
|
1229
1268
|
runId,
|
|
1230
1269
|
phase: lifecyclePhase,
|
|
1231
|
-
scope: {
|
|
1270
|
+
scope: {
|
|
1271
|
+
conversationId: lifecycleConversationId,
|
|
1272
|
+
turnId: lifecycleTurnId
|
|
1273
|
+
}
|
|
1232
1274
|
});
|
|
1233
1275
|
}
|
|
1234
1276
|
}
|
|
1235
|
-
async
|
|
1236
|
-
|
|
1277
|
+
async loadInitialState(checkpointKey) {
|
|
1278
|
+
return await this.checkpointer.load(checkpointKey) || {
|
|
1237
1279
|
nodeId: "user",
|
|
1238
1280
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1239
1281
|
local: {}
|
|
1240
1282
|
};
|
|
1241
|
-
|
|
1283
|
+
}
|
|
1284
|
+
async runUntilYieldInternal(checkpointKey, initialState) {
|
|
1285
|
+
let state = initialState;
|
|
1286
|
+
const ephemeral = this.ephemeralLocals.get(checkpointKey) || {};
|
|
1242
1287
|
state = {
|
|
1243
1288
|
...state,
|
|
1244
1289
|
schemaVersion: state.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
@@ -1267,7 +1312,7 @@ var GraphExecutor = class {
|
|
|
1267
1312
|
const signalRaw = state.local?.signal;
|
|
1268
1313
|
if (isAbortSignal2(signalRaw) && signalRaw.aborted) {
|
|
1269
1314
|
logger.warn("[GraphExecutor] \u6536\u5230 AbortSignal\uFF0C\u7ACB\u5373\u505C\u6B62\u63A8\u7406\u5FAA\u73AF");
|
|
1270
|
-
this.ephemeralLocals.delete(
|
|
1315
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1271
1316
|
throwAbortError();
|
|
1272
1317
|
}
|
|
1273
1318
|
const isLastStep = cycleStepCount >= this.config.maxSteps;
|
|
@@ -1315,8 +1360,8 @@ var GraphExecutor = class {
|
|
|
1315
1360
|
checkpointCount
|
|
1316
1361
|
});
|
|
1317
1362
|
const cp2 = this.sanitize(state);
|
|
1318
|
-
await this.checkpointer.save(
|
|
1319
|
-
this.ephemeralLocals.delete(
|
|
1363
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1364
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1320
1365
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1321
1366
|
}
|
|
1322
1367
|
logger.info("[GraphExecutor] \u8282\u70B9\u5207\u6362", {
|
|
@@ -1327,18 +1372,18 @@ var GraphExecutor = class {
|
|
|
1327
1372
|
});
|
|
1328
1373
|
const nodeRunStartedAt = Date.now();
|
|
1329
1374
|
const nodeIdForTelemetry = state.nodeId;
|
|
1375
|
+
const conversationIdForTelemetry = readRuntimeConversationId(state);
|
|
1330
1376
|
let result;
|
|
1331
1377
|
try {
|
|
1332
1378
|
result = await node.run(state);
|
|
1333
1379
|
} finally {
|
|
1334
|
-
const turnIdForTelemetry = typeof state.local?.turnId === "string" ? state.local.turnId : void 0;
|
|
1335
1380
|
this.telemetryPort.emit({
|
|
1336
1381
|
kind: "graph_node",
|
|
1337
1382
|
nodeId: nodeIdForTelemetry,
|
|
1338
1383
|
durationMs: Date.now() - nodeRunStartedAt,
|
|
1339
1384
|
scope: {
|
|
1340
|
-
conversationId:
|
|
1341
|
-
turnId:
|
|
1385
|
+
conversationId: conversationIdForTelemetry,
|
|
1386
|
+
turnId: readRuntimeTurnId(state)
|
|
1342
1387
|
}
|
|
1343
1388
|
});
|
|
1344
1389
|
}
|
|
@@ -1377,7 +1422,7 @@ var GraphExecutor = class {
|
|
|
1377
1422
|
});
|
|
1378
1423
|
state = { ...state, nodeId: nextNodeId };
|
|
1379
1424
|
const cp2 = this.sanitize(state);
|
|
1380
|
-
await this.checkpointer.save(
|
|
1425
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1381
1426
|
continue;
|
|
1382
1427
|
}
|
|
1383
1428
|
if (result.kind === "yield") {
|
|
@@ -1388,7 +1433,7 @@ var GraphExecutor = class {
|
|
|
1388
1433
|
checkpointCount
|
|
1389
1434
|
});
|
|
1390
1435
|
const cp2 = this.sanitize(state);
|
|
1391
|
-
await this.checkpointer.save(
|
|
1436
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1392
1437
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1393
1438
|
}
|
|
1394
1439
|
if (result.kind === "pause") {
|
|
@@ -1399,7 +1444,7 @@ var GraphExecutor = class {
|
|
|
1399
1444
|
checkpointCount
|
|
1400
1445
|
});
|
|
1401
1446
|
const cp2 = this.sanitize(state);
|
|
1402
|
-
await this.checkpointer.save(
|
|
1447
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1403
1448
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1404
1449
|
}
|
|
1405
1450
|
}
|
|
@@ -1410,8 +1455,8 @@ var GraphExecutor = class {
|
|
|
1410
1455
|
checkpointCount
|
|
1411
1456
|
});
|
|
1412
1457
|
const cp = this.sanitize(state);
|
|
1413
|
-
await this.checkpointer.save(
|
|
1414
|
-
this.ephemeralLocals.delete(
|
|
1458
|
+
await this.checkpointer.save(checkpointKey, cp);
|
|
1459
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1415
1460
|
return { events: allEvents, checkpoint: cp, stepCount };
|
|
1416
1461
|
}
|
|
1417
1462
|
};
|
|
@@ -1574,15 +1619,15 @@ function splitConcatenatedJsonObjects(input) {
|
|
|
1574
1619
|
}
|
|
1575
1620
|
|
|
1576
1621
|
// src/runtime-kernel/graph-engine/tick-pipeline/helpers.ts
|
|
1577
|
-
function
|
|
1622
|
+
function readNonEmptyString2(value) {
|
|
1578
1623
|
if (typeof value !== "string") return void 0;
|
|
1579
1624
|
const trimmed = value.trim();
|
|
1580
1625
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
1581
1626
|
}
|
|
1582
1627
|
function resolveConversationIdForRuntimeEvents(toolContext) {
|
|
1583
|
-
const fromCamel =
|
|
1628
|
+
const fromCamel = readNonEmptyString2(toolContext?.conversationId);
|
|
1584
1629
|
if (fromCamel) return fromCamel;
|
|
1585
|
-
const fromSnake = toolContext ?
|
|
1630
|
+
const fromSnake = toolContext ? readNonEmptyString2(toolContext["conversation_id"]) : void 0;
|
|
1586
1631
|
if (fromSnake) return fromSnake;
|
|
1587
1632
|
return generateMessageId();
|
|
1588
1633
|
}
|
|
@@ -1939,7 +1984,7 @@ var runModelLockMiddleware = async (ctx, stage, next) => {
|
|
|
1939
1984
|
if (stage.id !== "execute_llm") {
|
|
1940
1985
|
return;
|
|
1941
1986
|
}
|
|
1942
|
-
const normalized =
|
|
1987
|
+
const normalized = readNonEmptyString2(ctx.cloudQuotaFallbackAppliedModelId);
|
|
1943
1988
|
if (!normalized) {
|
|
1944
1989
|
return;
|
|
1945
1990
|
}
|
|
@@ -2527,7 +2572,7 @@ function createExecuteLlmStage(dependencies) {
|
|
|
2527
2572
|
streamEventHandler,
|
|
2528
2573
|
ctx.signal,
|
|
2529
2574
|
(fallbackModelId) => {
|
|
2530
|
-
ctx.cloudQuotaFallbackAppliedModelId =
|
|
2575
|
+
ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString2(fallbackModelId);
|
|
2531
2576
|
},
|
|
2532
2577
|
(info) => {
|
|
2533
2578
|
ctx.modelFallbackAudit = info;
|
|
@@ -2571,7 +2616,7 @@ function createPrepareCallStage(dependencies) {
|
|
|
2571
2616
|
return {
|
|
2572
2617
|
id: "prepare_call",
|
|
2573
2618
|
async run(ctx) {
|
|
2574
|
-
const lockedRunModelId =
|
|
2619
|
+
const lockedRunModelId = readNonEmptyString2(ctx.executorLocal?.runLockedModelId);
|
|
2575
2620
|
const requestedModelId = lockedRunModelId ?? ctx.request.model_id;
|
|
2576
2621
|
ctx.modelId = dependencies.modelResolver.resolveModelId(requestedModelId);
|
|
2577
2622
|
await emitAuditEnvelope(ctx.audit, {
|
|
@@ -2643,7 +2688,7 @@ var GraphAgentExecutor = class {
|
|
|
2643
2688
|
this.llmCaller = dependencies.llmCaller;
|
|
2644
2689
|
this.toolRuntime = dependencies.toolRuntime;
|
|
2645
2690
|
this.contextBuilder = dependencies.contextBuilder;
|
|
2646
|
-
this.cloudQuotaFallbackModelId =
|
|
2691
|
+
this.cloudQuotaFallbackModelId = readNonEmptyString2(dependencies.cloudQuotaFallbackModelId);
|
|
2647
2692
|
this.modelCatalog = dependencies.modelCatalog ?? createEmptyModelCatalog();
|
|
2648
2693
|
this.modelResolver = dependencies.modelResolver ?? new ModelResolver({
|
|
2649
2694
|
modelCatalog: this.modelCatalog
|
|
@@ -2691,7 +2736,7 @@ var GraphAgentExecutor = class {
|
|
|
2691
2736
|
llmMessages: [],
|
|
2692
2737
|
mode: input.request.mode === "chat" ? "chat" : "agent",
|
|
2693
2738
|
conversationId: resolveConversationIdForRuntimeEvents(input.toolContext),
|
|
2694
|
-
turnId:
|
|
2739
|
+
turnId: readNonEmptyString2(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
|
|
2695
2740
|
telemetry: this.telemetryPort,
|
|
2696
2741
|
audit: this.auditPort
|
|
2697
2742
|
};
|
|
@@ -2741,18 +2786,18 @@ function isSummarizationCallbacks(value) {
|
|
|
2741
2786
|
function isGraphSseSink(value) {
|
|
2742
2787
|
return typeof value === "function";
|
|
2743
2788
|
}
|
|
2744
|
-
function
|
|
2789
|
+
function readNonEmptyString3(value) {
|
|
2745
2790
|
if (typeof value !== "string") return void 0;
|
|
2746
2791
|
const trimmed = value.trim();
|
|
2747
2792
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
2748
2793
|
}
|
|
2749
2794
|
function readGraphAgentLocal(local) {
|
|
2750
2795
|
const source = local ?? {};
|
|
2751
|
-
const answerId =
|
|
2796
|
+
const answerId = readNonEmptyString3(source.answerId);
|
|
2752
2797
|
const chunkSeq = Number.isInteger(source.chunkSeq) ? Number(source.chunkSeq) : 0;
|
|
2753
2798
|
return {
|
|
2754
|
-
conversationId:
|
|
2755
|
-
turnId:
|
|
2799
|
+
conversationId: readNonEmptyString3(source.conversationId) ?? "",
|
|
2800
|
+
turnId: readNonEmptyString3(source.turnId),
|
|
2756
2801
|
request: isAgentInvocationRequest(source.request) ? source.request : void 0,
|
|
2757
2802
|
toolContext: isToolExecutionContext(source.toolContext) ? source.toolContext : void 0,
|
|
2758
2803
|
history: isRuntimeEventArray(source.history) ? source.history : [],
|
|
@@ -3517,7 +3562,7 @@ var LlmNode = class {
|
|
|
3517
3562
|
function isRecord8(value) {
|
|
3518
3563
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3519
3564
|
}
|
|
3520
|
-
function
|
|
3565
|
+
function readNonEmptyString4(value) {
|
|
3521
3566
|
if (typeof value !== "string") {
|
|
3522
3567
|
return void 0;
|
|
3523
3568
|
}
|
|
@@ -3539,7 +3584,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3539
3584
|
return void 0;
|
|
3540
3585
|
}
|
|
3541
3586
|
if (toolName === "write_report") {
|
|
3542
|
-
const report =
|
|
3587
|
+
const report = readNonEmptyString4(data.report);
|
|
3543
3588
|
if (!report) {
|
|
3544
3589
|
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");
|
|
3545
3590
|
}
|
|
@@ -3549,7 +3594,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3549
3594
|
if (data.success !== true) {
|
|
3550
3595
|
return void 0;
|
|
3551
3596
|
}
|
|
3552
|
-
const finalAnswer =
|
|
3597
|
+
const finalAnswer = readNonEmptyString4(data.final_answer);
|
|
3553
3598
|
if (!finalAnswer) {
|
|
3554
3599
|
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");
|
|
3555
3600
|
}
|
|
@@ -4445,6 +4490,22 @@ var ToolNode = class {
|
|
|
4445
4490
|
});
|
|
4446
4491
|
}
|
|
4447
4492
|
async run(state) {
|
|
4493
|
+
const events = [];
|
|
4494
|
+
while (true) {
|
|
4495
|
+
const result = await this.runNextPendingToolCall(state);
|
|
4496
|
+
if (Array.isArray(result.events) && result.events.length > 0) {
|
|
4497
|
+
events.push(...result.events);
|
|
4498
|
+
}
|
|
4499
|
+
if (result.kind === "route" && result.nextNodeId === "tool") {
|
|
4500
|
+
continue;
|
|
4501
|
+
}
|
|
4502
|
+
return {
|
|
4503
|
+
...result,
|
|
4504
|
+
events
|
|
4505
|
+
};
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
async runNextPendingToolCall(state) {
|
|
4448
4509
|
const calls = state.local?.pendingToolCalls ?? [];
|
|
4449
4510
|
const signalRaw = state.local?.signal;
|
|
4450
4511
|
if (isAbortSignal(signalRaw) && signalRaw.aborted) {
|
|
@@ -4652,18 +4713,25 @@ var ToolNode = class {
|
|
|
4652
4713
|
rawArguments: context.call.function?.arguments,
|
|
4653
4714
|
parsedArguments: context.toolArgs
|
|
4654
4715
|
});
|
|
4716
|
+
const remainingCalls = context.calls.slice(1);
|
|
4655
4717
|
context.state.local = buildErrorLocalState({
|
|
4656
4718
|
local: context.local,
|
|
4657
|
-
remainingCalls
|
|
4719
|
+
remainingCalls,
|
|
4658
4720
|
conversationId: context.conversationId,
|
|
4659
4721
|
turnId: context.turnId,
|
|
4660
4722
|
runtimeEvents: context.bridge.getRuntimeEvents(),
|
|
4661
4723
|
nextProtocolErrorCount: fuse.nextCount
|
|
4662
4724
|
});
|
|
4663
|
-
if (fuse.shouldFuse) {
|
|
4725
|
+
if (fuse.shouldFuse && remainingCalls.length === 0) {
|
|
4664
4726
|
throw createToolProtocolFuseError(fuse.nextCount, context.exec.error);
|
|
4665
4727
|
}
|
|
4666
|
-
return {
|
|
4728
|
+
return {
|
|
4729
|
+
kind: "route",
|
|
4730
|
+
// 同一个 assistant.tool_calls batch 必须为每个 call 产出 tool_output。
|
|
4731
|
+
// 出错时也继续消费剩余 call,ToolNode.run 会在本节点内 drain 完 batch 再回 LLM。
|
|
4732
|
+
nextNodeId: remainingCalls.length > 0 ? "tool" : "llm",
|
|
4733
|
+
events: context.bridge.getRuntimeEvents()
|
|
4734
|
+
};
|
|
4667
4735
|
}
|
|
4668
4736
|
};
|
|
4669
4737
|
|
|
@@ -4860,12 +4928,12 @@ function asRecord(value) {
|
|
|
4860
4928
|
}
|
|
4861
4929
|
return value;
|
|
4862
4930
|
}
|
|
4863
|
-
function summarizeCheckpoint(
|
|
4931
|
+
function summarizeCheckpoint(checkpointKey, state, savedAt) {
|
|
4864
4932
|
const local = asRecord(state.local);
|
|
4865
4933
|
const executorLocal = asRecord(local?.executorLocal);
|
|
4866
4934
|
const pendingToolCalls = local?.pendingToolCalls;
|
|
4867
4935
|
return {
|
|
4868
|
-
|
|
4936
|
+
checkpointKey,
|
|
4869
4937
|
schemaVersion: state.schemaVersion ?? 1,
|
|
4870
4938
|
savedAt,
|
|
4871
4939
|
currentNode: state.nodeId,
|
|
@@ -4884,25 +4952,25 @@ var MemoryCheckpointer = class {
|
|
|
4884
4952
|
local: state.local && typeof state.local === "object" && !Array.isArray(state.local) ? { ...state.local } : state.local
|
|
4885
4953
|
};
|
|
4886
4954
|
}
|
|
4887
|
-
async load(
|
|
4888
|
-
const entry = this.store.get(
|
|
4955
|
+
async load(checkpointKey) {
|
|
4956
|
+
const entry = this.store.get(checkpointKey);
|
|
4889
4957
|
return entry ? this.cloneState(entry.state) : null;
|
|
4890
4958
|
}
|
|
4891
|
-
async save(
|
|
4892
|
-
this.store.set(
|
|
4959
|
+
async save(checkpointKey, state) {
|
|
4960
|
+
this.store.set(checkpointKey, {
|
|
4893
4961
|
state: this.cloneState(state),
|
|
4894
4962
|
savedAt: Date.now()
|
|
4895
4963
|
});
|
|
4896
4964
|
}
|
|
4897
|
-
async clear(
|
|
4898
|
-
this.store.delete(
|
|
4965
|
+
async clear(checkpointKey) {
|
|
4966
|
+
this.store.delete(checkpointKey);
|
|
4899
4967
|
}
|
|
4900
|
-
async peekMeta(
|
|
4901
|
-
const entry = this.store.get(
|
|
4902
|
-
return entry ? summarizeCheckpoint(
|
|
4968
|
+
async peekMeta(checkpointKey) {
|
|
4969
|
+
const entry = this.store.get(checkpointKey);
|
|
4970
|
+
return entry ? summarizeCheckpoint(checkpointKey, entry.state, entry.savedAt) : null;
|
|
4903
4971
|
}
|
|
4904
4972
|
async list(filter = {}) {
|
|
4905
|
-
const summaries = Array.from(this.store.entries()).map(([
|
|
4973
|
+
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);
|
|
4906
4974
|
if (filter.limit === void 0) {
|
|
4907
4975
|
return summaries;
|
|
4908
4976
|
}
|
|
@@ -5159,18 +5227,18 @@ function createClassification(category, reason, suggestedDelay, extras) {
|
|
|
5159
5227
|
}
|
|
5160
5228
|
var ErrorClassifier = class {
|
|
5161
5229
|
static classify(error, context) {
|
|
5162
|
-
const
|
|
5230
|
+
const isRecord23 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
5163
5231
|
const baseMsg = (error.message || "").toLowerCase();
|
|
5164
5232
|
const causeMsg = (() => {
|
|
5165
5233
|
const cause = error.cause;
|
|
5166
5234
|
if (typeof cause === "string") return cause.toLowerCase();
|
|
5167
5235
|
if (cause instanceof Error) return (cause.message || "").toLowerCase();
|
|
5168
|
-
if (
|
|
5236
|
+
if (isRecord23(cause) && typeof cause["message"] === "string") return String(cause["message"]).toLowerCase();
|
|
5169
5237
|
return "";
|
|
5170
5238
|
})();
|
|
5171
5239
|
const causeCode = (() => {
|
|
5172
5240
|
const cause = error.cause;
|
|
5173
|
-
if (
|
|
5241
|
+
if (isRecord23(cause) && typeof cause["code"] === "string") return String(cause["code"]);
|
|
5174
5242
|
return "";
|
|
5175
5243
|
})();
|
|
5176
5244
|
const errorMessage = `${baseMsg} ${causeMsg}`.trim();
|
|
@@ -5846,6 +5914,67 @@ function assertToolCallsHaveValidJsonArguments(toolCalls) {
|
|
|
5846
5914
|
}
|
|
5847
5915
|
}
|
|
5848
5916
|
|
|
5917
|
+
// src/runtime-kernel/llm/reasoning-details.ts
|
|
5918
|
+
var mergeableTextFields = ["reasoning_content"];
|
|
5919
|
+
function isRecord18(value) {
|
|
5920
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
5921
|
+
}
|
|
5922
|
+
function findMergeableTextField(detail) {
|
|
5923
|
+
if (!isRecord18(detail)) return void 0;
|
|
5924
|
+
if (typeof detail.provider !== "string") return void 0;
|
|
5925
|
+
if (typeof detail.type !== "string") return void 0;
|
|
5926
|
+
for (const field of mergeableTextFields) {
|
|
5927
|
+
if (typeof detail[field] === "string") {
|
|
5928
|
+
return field;
|
|
5929
|
+
}
|
|
5930
|
+
}
|
|
5931
|
+
return void 0;
|
|
5932
|
+
}
|
|
5933
|
+
function hasOnlyStableTextDetailFields(detail, textField) {
|
|
5934
|
+
const allowedKeys = /* @__PURE__ */ new Set(["provider", "type", textField]);
|
|
5935
|
+
return Object.keys(detail).every((key) => allowedKeys.has(key));
|
|
5936
|
+
}
|
|
5937
|
+
function canMergeTextDetails(previous, incoming) {
|
|
5938
|
+
if (!isRecord18(previous) || !isRecord18(incoming)) return false;
|
|
5939
|
+
const previousField = findMergeableTextField(previous);
|
|
5940
|
+
const incomingField = findMergeableTextField(incoming);
|
|
5941
|
+
if (!previousField || previousField !== incomingField) return false;
|
|
5942
|
+
return previous.provider === incoming.provider && previous.type === incoming.type && hasOnlyStableTextDetailFields(previous, previousField) && hasOnlyStableTextDetailFields(incoming, incomingField);
|
|
5943
|
+
}
|
|
5944
|
+
function mergeStreamingText(previous, incoming) {
|
|
5945
|
+
if (!previous) return incoming;
|
|
5946
|
+
if (!incoming) return previous;
|
|
5947
|
+
if (incoming.startsWith(previous)) {
|
|
5948
|
+
return incoming;
|
|
5949
|
+
}
|
|
5950
|
+
if (previous.endsWith(incoming)) {
|
|
5951
|
+
return previous;
|
|
5952
|
+
}
|
|
5953
|
+
return `${previous}${incoming}`;
|
|
5954
|
+
}
|
|
5955
|
+
function appendStreamingProviderReasoningDetails(existing, incoming) {
|
|
5956
|
+
const next = [...existing];
|
|
5957
|
+
for (const detail of incoming) {
|
|
5958
|
+
const previous = next[next.length - 1];
|
|
5959
|
+
if (canMergeTextDetails(previous, detail)) {
|
|
5960
|
+
const textField = findMergeableTextField(previous);
|
|
5961
|
+
if (textField && isRecord18(detail)) {
|
|
5962
|
+
const mergedText = mergeStreamingText(String(previous[textField]), String(detail[textField]));
|
|
5963
|
+
if (mergedText === previous[textField]) {
|
|
5964
|
+
continue;
|
|
5965
|
+
}
|
|
5966
|
+
next[next.length - 1] = {
|
|
5967
|
+
...previous,
|
|
5968
|
+
[textField]: mergedText
|
|
5969
|
+
};
|
|
5970
|
+
continue;
|
|
5971
|
+
}
|
|
5972
|
+
}
|
|
5973
|
+
next.push(detail);
|
|
5974
|
+
}
|
|
5975
|
+
return next;
|
|
5976
|
+
}
|
|
5977
|
+
|
|
5849
5978
|
// src/runtime-kernel/llm/streaming-adapter.ts
|
|
5850
5979
|
async function callLlmStream(params) {
|
|
5851
5980
|
const {
|
|
@@ -5858,7 +5987,7 @@ async function callLlmStream(params) {
|
|
|
5858
5987
|
} = params;
|
|
5859
5988
|
let fullResponse = "";
|
|
5860
5989
|
let streamError = null;
|
|
5861
|
-
|
|
5990
|
+
let reasoningDetails = [];
|
|
5862
5991
|
const streamAnswerId = generateMessageId();
|
|
5863
5992
|
let streamChunkSeq = 0;
|
|
5864
5993
|
let capturedUsage = void 0;
|
|
@@ -5928,13 +6057,21 @@ async function callLlmStream(params) {
|
|
|
5928
6057
|
const reasoning = isRecord17(chunk) ? chunk["reasoning_details"] : void 0;
|
|
5929
6058
|
if (reasoning !== void 0) {
|
|
5930
6059
|
const newReasoningDetails = Array.isArray(reasoning) ? reasoning : [reasoning];
|
|
5931
|
-
reasoningDetails
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
6060
|
+
const previousReasoningDetails = reasoningDetails;
|
|
6061
|
+
const previousLength = previousReasoningDetails.length;
|
|
6062
|
+
const compactedReasoningDetails = appendStreamingProviderReasoningDetails(reasoningDetails, newReasoningDetails);
|
|
6063
|
+
reasoningDetails = compactedReasoningDetails;
|
|
6064
|
+
const previousLastChanged = previousLength > 0 && compactedReasoningDetails[previousLength - 1] !== previousReasoningDetails[previousLength - 1];
|
|
6065
|
+
const emitFromIndex = previousLastChanged ? previousLength - 1 : previousLength;
|
|
6066
|
+
const emittedReasoningDetails = compactedReasoningDetails.slice(Math.max(0, emitFromIndex));
|
|
6067
|
+
if (emittedReasoningDetails.length > 0) {
|
|
6068
|
+
eventHandler({
|
|
6069
|
+
type: "provider_sidecar",
|
|
6070
|
+
id: generateMessageId(),
|
|
6071
|
+
timestamp: Date.now(),
|
|
6072
|
+
reasoning_details: emittedReasoningDetails
|
|
6073
|
+
});
|
|
6074
|
+
}
|
|
5938
6075
|
}
|
|
5939
6076
|
if (chunk.tool_calls) {
|
|
5940
6077
|
emitThoughtComplete(thoughtSegmenter.onBoundary());
|
|
@@ -6373,7 +6510,7 @@ function cloneRunRecord(record) {
|
|
|
6373
6510
|
...record,
|
|
6374
6511
|
iterationBudget: record.iterationBudget ? { ...record.iterationBudget } : void 0,
|
|
6375
6512
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0,
|
|
6376
|
-
metadata: record.metadata ?
|
|
6513
|
+
metadata: record.metadata ? structuredClone(record.metadata) : void 0
|
|
6377
6514
|
};
|
|
6378
6515
|
}
|
|
6379
6516
|
function matchesStatus(candidate, filter) {
|
|
@@ -6505,7 +6642,7 @@ function runRecordToMeta(record) {
|
|
|
6505
6642
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0
|
|
6506
6643
|
};
|
|
6507
6644
|
}
|
|
6508
|
-
function
|
|
6645
|
+
function isRecord19(value) {
|
|
6509
6646
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6510
6647
|
}
|
|
6511
6648
|
function readStringField(record, key) {
|
|
@@ -6526,7 +6663,7 @@ function getRunIdFromMetadata(event) {
|
|
|
6526
6663
|
return snakeCaseRunId;
|
|
6527
6664
|
}
|
|
6528
6665
|
const runContext = metadata["run_context"];
|
|
6529
|
-
if (
|
|
6666
|
+
if (isRecord19(runContext)) {
|
|
6530
6667
|
return readStringField(runContext, "runId") ?? readStringField(runContext, "run_id");
|
|
6531
6668
|
}
|
|
6532
6669
|
return void 0;
|
|
@@ -6744,7 +6881,7 @@ function runMetaFromRecord(record) {
|
|
|
6744
6881
|
}
|
|
6745
6882
|
|
|
6746
6883
|
// src/runtime-kernel/run-supervisor/runSupervisor.ts
|
|
6747
|
-
function
|
|
6884
|
+
function isRecord20(value) {
|
|
6748
6885
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6749
6886
|
}
|
|
6750
6887
|
function readStringField2(record, key) {
|
|
@@ -6761,7 +6898,7 @@ function readRunIdFromRuntimeEvent(event) {
|
|
|
6761
6898
|
return directRunId;
|
|
6762
6899
|
}
|
|
6763
6900
|
const runContext = metadata["run_context"];
|
|
6764
|
-
if (!
|
|
6901
|
+
if (!isRecord20(runContext)) {
|
|
6765
6902
|
return void 0;
|
|
6766
6903
|
}
|
|
6767
6904
|
return readStringField2(runContext, "runId") ?? readStringField2(runContext, "run_id");
|
|
@@ -6773,7 +6910,7 @@ function readAwaitingUserReason(event) {
|
|
|
6773
6910
|
if (typeof event.prompt === "string" && event.prompt.trim().length > 0) {
|
|
6774
6911
|
return event.prompt;
|
|
6775
6912
|
}
|
|
6776
|
-
if (
|
|
6913
|
+
if (isRecord20(event.form)) {
|
|
6777
6914
|
const prompt = readStringField2(event.form, "prompt");
|
|
6778
6915
|
if (prompt && prompt.trim().length > 0) {
|
|
6779
6916
|
return prompt;
|
|
@@ -6785,7 +6922,7 @@ function isTerminalStatus(status) {
|
|
|
6785
6922
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
6786
6923
|
}
|
|
6787
6924
|
function cloneMetadata(metadata) {
|
|
6788
|
-
return metadata ?
|
|
6925
|
+
return metadata ? structuredClone(metadata) : void 0;
|
|
6789
6926
|
}
|
|
6790
6927
|
function recordToSnapshot(record) {
|
|
6791
6928
|
return {
|
|
@@ -6872,7 +7009,7 @@ var DefaultRunSupervisor = class {
|
|
|
6872
7009
|
startedAt,
|
|
6873
7010
|
updatedAt: startedAt,
|
|
6874
7011
|
iterationBudget: spec.iterationBudget ? { ...spec.iterationBudget } : void 0,
|
|
6875
|
-
metadata: spec.metadata
|
|
7012
|
+
metadata: cloneMetadata(spec.metadata)
|
|
6876
7013
|
};
|
|
6877
7014
|
await this.registryStore.save(record);
|
|
6878
7015
|
const handle = new DefaultRunHandle({
|
|
@@ -7046,12 +7183,13 @@ var DefaultRunSupervisor = class {
|
|
|
7046
7183
|
}
|
|
7047
7184
|
try {
|
|
7048
7185
|
await handle.markRunning({ currentNode: "detached" });
|
|
7186
|
+
const registeredRecord = await this.registryStore.load(handle.runId);
|
|
7049
7187
|
const executorOutcome = await this.executor.execute({
|
|
7050
7188
|
runId: handle.runId,
|
|
7051
|
-
parentRunId:
|
|
7052
|
-
conversationId: spec.conversationId,
|
|
7053
|
-
agentSpec: spec
|
|
7054
|
-
request:
|
|
7189
|
+
parentRunId: handle.parentRunId,
|
|
7190
|
+
conversationId: registeredRecord?.conversationId ?? spec.conversationId,
|
|
7191
|
+
agentSpec: await handle.spec(),
|
|
7192
|
+
request: await handle.request(),
|
|
7055
7193
|
signal: handle.signal,
|
|
7056
7194
|
eventBus: spec.eventBus,
|
|
7057
7195
|
eventStore: spec.eventStore,
|
|
@@ -7060,7 +7198,7 @@ var DefaultRunSupervisor = class {
|
|
|
7060
7198
|
contextFences: spec.contextFences,
|
|
7061
7199
|
wakeSource: spec.wakeSource,
|
|
7062
7200
|
ephemeral: spec.ephemeral,
|
|
7063
|
-
metadata: spec.metadata
|
|
7201
|
+
metadata: cloneMetadata(registeredRecord?.metadata ?? spec.metadata)
|
|
7064
7202
|
});
|
|
7065
7203
|
const outcome = await this.persistExecutorOutcome(handle, executorOutcome);
|
|
7066
7204
|
this.notifyTerminalWaiters(outcome);
|
|
@@ -7124,10 +7262,14 @@ var DefaultRunSupervisor = class {
|
|
|
7124
7262
|
await this.registryStore.save(record);
|
|
7125
7263
|
}
|
|
7126
7264
|
const completedAt = executorOutcome?.completedAt ?? this.now();
|
|
7265
|
+
const fallbackMeta = record ? void 0 : await handle.meta();
|
|
7127
7266
|
const outcome = recordToTerminalOutcome(record ?? {
|
|
7128
7267
|
runId: handle.runId,
|
|
7129
7268
|
parentRunId: handle.parentRunId,
|
|
7130
|
-
|
|
7269
|
+
conversationId: fallbackMeta?.conversationId ?? "",
|
|
7270
|
+
agentSpecId: fallbackMeta?.agentSpecId,
|
|
7271
|
+
status: executorOutcome?.status ?? "completed",
|
|
7272
|
+
startedAt: fallbackMeta?.startedAt ?? completedAt}, completedAt);
|
|
7131
7273
|
const nextOutcome = {
|
|
7132
7274
|
...outcome,
|
|
7133
7275
|
metadata: {
|
|
@@ -7383,7 +7525,7 @@ function createQuickstartTelemetryPort(collector) {
|
|
|
7383
7525
|
}
|
|
7384
7526
|
|
|
7385
7527
|
// src/quickstart/runAgent.ts
|
|
7386
|
-
function
|
|
7528
|
+
function isRecord21(value) {
|
|
7387
7529
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7388
7530
|
}
|
|
7389
7531
|
function readString4(value) {
|
|
@@ -7397,7 +7539,7 @@ function resolveModelId(agent, options) {
|
|
|
7397
7539
|
return modelId;
|
|
7398
7540
|
}
|
|
7399
7541
|
function isQuickstartStreamChunkEvent(value) {
|
|
7400
|
-
return
|
|
7542
|
+
return isRecord21(value) && value.type === "stream_chunk" && typeof value.content === "string";
|
|
7401
7543
|
}
|
|
7402
7544
|
function createNoopObservationPreview() {
|
|
7403
7545
|
return {
|
|
@@ -7437,7 +7579,7 @@ function readFinalAnswer(events, checkpointLocal) {
|
|
|
7437
7579
|
if (chunks.length > 0) {
|
|
7438
7580
|
return chunks.join("");
|
|
7439
7581
|
}
|
|
7440
|
-
if (
|
|
7582
|
+
if (isRecord21(checkpointLocal)) {
|
|
7441
7583
|
const finalAnswer = checkpointLocal["finalAnswer"];
|
|
7442
7584
|
if (typeof finalAnswer === "string") {
|
|
7443
7585
|
return finalAnswer;
|
|
@@ -7446,7 +7588,7 @@ function readFinalAnswer(events, checkpointLocal) {
|
|
|
7446
7588
|
return "";
|
|
7447
7589
|
}
|
|
7448
7590
|
function readContextTrace(checkpointLocal) {
|
|
7449
|
-
if (!
|
|
7591
|
+
if (!isRecord21(checkpointLocal)) return void 0;
|
|
7450
7592
|
return checkpointLocal["contextTrace"];
|
|
7451
7593
|
}
|
|
7452
7594
|
async function emitRunEvent(event, sink) {
|
|
@@ -7455,6 +7597,7 @@ async function emitRunEvent(event, sink) {
|
|
|
7455
7597
|
async function runAgent(agent, options) {
|
|
7456
7598
|
const modelId = resolveModelId(agent, options);
|
|
7457
7599
|
const conversationId = options.conversationId ?? `conv_${Date.now()}`;
|
|
7600
|
+
const checkpointKey = conversationId;
|
|
7458
7601
|
const runId = options.runId ?? generateRunId();
|
|
7459
7602
|
const turnId = runId;
|
|
7460
7603
|
const costCollector = new QuickstartRunCostCollector();
|
|
@@ -7509,7 +7652,7 @@ async function runAgent(agent, options) {
|
|
|
7509
7652
|
};
|
|
7510
7653
|
await handle.markRunning({ currentNode: "user" });
|
|
7511
7654
|
try {
|
|
7512
|
-
await executor.prime(
|
|
7655
|
+
await executor.prime(checkpointKey, {
|
|
7513
7656
|
conversationId,
|
|
7514
7657
|
turnId,
|
|
7515
7658
|
request: {
|
|
@@ -7534,7 +7677,7 @@ async function runAgent(agent, options) {
|
|
|
7534
7677
|
return void 0;
|
|
7535
7678
|
}
|
|
7536
7679
|
});
|
|
7537
|
-
const result = await executor.runUntilYield(
|
|
7680
|
+
const result = await executor.runUntilYield(checkpointKey);
|
|
7538
7681
|
runtimeEvents.push(...result.events);
|
|
7539
7682
|
for (const event of result.events) {
|
|
7540
7683
|
if (event.type === "final_answer_chunk") continue;
|
|
@@ -7570,11 +7713,11 @@ async function runAgent(agent, options) {
|
|
|
7570
7713
|
}
|
|
7571
7714
|
|
|
7572
7715
|
// src/cli/configLoader.ts
|
|
7573
|
-
function
|
|
7716
|
+
function isRecord22(value) {
|
|
7574
7717
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7575
7718
|
}
|
|
7576
7719
|
function readDefaultExport(moduleValue) {
|
|
7577
|
-
if (
|
|
7720
|
+
if (isRecord22(moduleValue) && "default" in moduleValue) {
|
|
7578
7721
|
return moduleValue.default;
|
|
7579
7722
|
}
|
|
7580
7723
|
return moduleValue;
|
|
@@ -7585,7 +7728,7 @@ async function loadConfig(configPath, cwd) {
|
|
|
7585
7728
|
moduleUrl.searchParams.set("t", String(Date.now()));
|
|
7586
7729
|
const loaded = await import(moduleUrl.href);
|
|
7587
7730
|
const config = readDefaultExport(loaded);
|
|
7588
|
-
if (!
|
|
7731
|
+
if (!isRecord22(config)) {
|
|
7589
7732
|
throw new Error(`[linnkit] config must export an object: ${absolutePath}`);
|
|
7590
7733
|
}
|
|
7591
7734
|
return defineConfig(config);
|
|
@@ -7697,7 +7840,7 @@ function createQuickstartTemplateFiles(projectName) {
|
|
|
7697
7840
|
start: 'linnkit run hello --input "\u4F60\u597D\uFF0C\u4ECB\u7ECD\u4E00\u4E0B\u4F60\u81EA\u5DF1"'
|
|
7698
7841
|
},
|
|
7699
7842
|
dependencies: {
|
|
7700
|
-
"@linnlabs/linnkit": "^0.
|
|
7843
|
+
"@linnlabs/linnkit": "^0.10.0",
|
|
7701
7844
|
zod: "^3.22.0"
|
|
7702
7845
|
},
|
|
7703
7846
|
devDependencies: {}
|