@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.cjs
CHANGED
|
@@ -203,6 +203,7 @@ var AgentSpecBudgetPolicy = zod.z.object({
|
|
|
203
203
|
});
|
|
204
204
|
var AgentSpecToolHistoryPolicy = zod.z.object({
|
|
205
205
|
strategy: zod.z.enum(["per-pair", "per-run", "none"]).optional(),
|
|
206
|
+
retentionMode: zod.z.enum(["drop", "compress"]).optional(),
|
|
206
207
|
keepLatestToolPairs: zod.z.number().int().nonnegative().optional(),
|
|
207
208
|
keepLatestRuns: zod.z.number().int().nonnegative().optional(),
|
|
208
209
|
maxInteractionGroups: zod.z.number().int().nonnegative().optional(),
|
|
@@ -1157,6 +1158,17 @@ var logger = new Logger("GraphExecutor");
|
|
|
1157
1158
|
function asLocalRecord(local) {
|
|
1158
1159
|
return local && typeof local === "object" ? { ...local } : {};
|
|
1159
1160
|
}
|
|
1161
|
+
function readNonEmptyString(value) {
|
|
1162
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1163
|
+
}
|
|
1164
|
+
function readRuntimeConversationId(state) {
|
|
1165
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1166
|
+
return readNonEmptyString(local?.conversationId);
|
|
1167
|
+
}
|
|
1168
|
+
function readRuntimeTurnId(state) {
|
|
1169
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1170
|
+
return readNonEmptyString(local?.turnId);
|
|
1171
|
+
}
|
|
1160
1172
|
var GraphExecutor = class {
|
|
1161
1173
|
constructor(checkpointer, config = {}) {
|
|
1162
1174
|
this.checkpointer = checkpointer;
|
|
@@ -1174,8 +1186,8 @@ var GraphExecutor = class {
|
|
|
1174
1186
|
registerNode(node) {
|
|
1175
1187
|
this.nodes.set(node.id, node);
|
|
1176
1188
|
}
|
|
1177
|
-
async peekCheckpoint(
|
|
1178
|
-
return await this.checkpointer.load(
|
|
1189
|
+
async peekCheckpoint(checkpointKey) {
|
|
1190
|
+
return await this.checkpointer.load(checkpointKey);
|
|
1179
1191
|
}
|
|
1180
1192
|
sanitize(state) {
|
|
1181
1193
|
const local = asLocalRecord(state.local);
|
|
@@ -1187,8 +1199,8 @@ var GraphExecutor = class {
|
|
|
1187
1199
|
local
|
|
1188
1200
|
};
|
|
1189
1201
|
}
|
|
1190
|
-
async prime(
|
|
1191
|
-
this.ephemeralLocals.set(
|
|
1202
|
+
async prime(checkpointKey, local, nodeId = "user") {
|
|
1203
|
+
this.ephemeralLocals.set(checkpointKey, { ...local || {} });
|
|
1192
1204
|
const localSansMemory = { ...local || {} };
|
|
1193
1205
|
if ("memory" in localSansMemory) delete localSansMemory.memory;
|
|
1194
1206
|
const state = {
|
|
@@ -1196,10 +1208,10 @@ var GraphExecutor = class {
|
|
|
1196
1208
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1197
1209
|
local: localSansMemory
|
|
1198
1210
|
};
|
|
1199
|
-
await this.checkpointer.save(
|
|
1211
|
+
await this.checkpointer.save(checkpointKey, state);
|
|
1200
1212
|
}
|
|
1201
|
-
async setNode(
|
|
1202
|
-
const current = await this.checkpointer.load(
|
|
1213
|
+
async setNode(checkpointKey, nodeId, localPatch) {
|
|
1214
|
+
const current = await this.checkpointer.load(checkpointKey) || {
|
|
1203
1215
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1204
1216
|
local: {}
|
|
1205
1217
|
};
|
|
@@ -1210,19 +1222,46 @@ var GraphExecutor = class {
|
|
|
1210
1222
|
schemaVersion: current.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
1211
1223
|
local: mergedLocal
|
|
1212
1224
|
};
|
|
1213
|
-
await this.checkpointer.save(
|
|
1225
|
+
await this.checkpointer.save(checkpointKey, next);
|
|
1214
1226
|
}
|
|
1215
|
-
async runUntilYield(
|
|
1227
|
+
async runUntilYield(checkpointKey) {
|
|
1216
1228
|
const runId = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1217
1229
|
let lifecyclePhase = "completed";
|
|
1230
|
+
let initialState = null;
|
|
1231
|
+
try {
|
|
1232
|
+
initialState = await this.loadInitialState(checkpointKey);
|
|
1233
|
+
} catch (err) {
|
|
1234
|
+
lifecyclePhase = "failed";
|
|
1235
|
+
this.telemetryPort.emit({
|
|
1236
|
+
kind: "run_lifecycle",
|
|
1237
|
+
runId,
|
|
1238
|
+
phase: "spawned",
|
|
1239
|
+
scope: {}
|
|
1240
|
+
});
|
|
1241
|
+
this.telemetryPort.emit({
|
|
1242
|
+
kind: "run_lifecycle",
|
|
1243
|
+
runId,
|
|
1244
|
+
phase: lifecyclePhase,
|
|
1245
|
+
scope: {}
|
|
1246
|
+
});
|
|
1247
|
+
throw err;
|
|
1248
|
+
}
|
|
1249
|
+
let lifecycleConversationId = readRuntimeConversationId(initialState);
|
|
1250
|
+
let lifecycleTurnId = readRuntimeTurnId(initialState);
|
|
1218
1251
|
this.telemetryPort.emit({
|
|
1219
1252
|
kind: "run_lifecycle",
|
|
1220
1253
|
runId,
|
|
1221
1254
|
phase: "spawned",
|
|
1222
|
-
scope: {
|
|
1255
|
+
scope: {
|
|
1256
|
+
conversationId: lifecycleConversationId,
|
|
1257
|
+
turnId: lifecycleTurnId
|
|
1258
|
+
}
|
|
1223
1259
|
});
|
|
1224
1260
|
try {
|
|
1225
|
-
|
|
1261
|
+
const result = await this.runUntilYieldInternal(checkpointKey, initialState);
|
|
1262
|
+
lifecycleConversationId = readRuntimeConversationId(result.checkpoint);
|
|
1263
|
+
lifecycleTurnId = readRuntimeTurnId(result.checkpoint);
|
|
1264
|
+
return result;
|
|
1226
1265
|
} catch (err) {
|
|
1227
1266
|
lifecyclePhase = err?.name === "AbortError" ? "cancelled" : "failed";
|
|
1228
1267
|
throw err;
|
|
@@ -1231,17 +1270,23 @@ var GraphExecutor = class {
|
|
|
1231
1270
|
kind: "run_lifecycle",
|
|
1232
1271
|
runId,
|
|
1233
1272
|
phase: lifecyclePhase,
|
|
1234
|
-
scope: {
|
|
1273
|
+
scope: {
|
|
1274
|
+
conversationId: lifecycleConversationId,
|
|
1275
|
+
turnId: lifecycleTurnId
|
|
1276
|
+
}
|
|
1235
1277
|
});
|
|
1236
1278
|
}
|
|
1237
1279
|
}
|
|
1238
|
-
async
|
|
1239
|
-
|
|
1280
|
+
async loadInitialState(checkpointKey) {
|
|
1281
|
+
return await this.checkpointer.load(checkpointKey) || {
|
|
1240
1282
|
nodeId: "user",
|
|
1241
1283
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1242
1284
|
local: {}
|
|
1243
1285
|
};
|
|
1244
|
-
|
|
1286
|
+
}
|
|
1287
|
+
async runUntilYieldInternal(checkpointKey, initialState) {
|
|
1288
|
+
let state = initialState;
|
|
1289
|
+
const ephemeral = this.ephemeralLocals.get(checkpointKey) || {};
|
|
1245
1290
|
state = {
|
|
1246
1291
|
...state,
|
|
1247
1292
|
schemaVersion: state.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
@@ -1270,7 +1315,7 @@ var GraphExecutor = class {
|
|
|
1270
1315
|
const signalRaw = state.local?.signal;
|
|
1271
1316
|
if (isAbortSignal2(signalRaw) && signalRaw.aborted) {
|
|
1272
1317
|
logger.warn("[GraphExecutor] \u6536\u5230 AbortSignal\uFF0C\u7ACB\u5373\u505C\u6B62\u63A8\u7406\u5FAA\u73AF");
|
|
1273
|
-
this.ephemeralLocals.delete(
|
|
1318
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1274
1319
|
throwAbortError();
|
|
1275
1320
|
}
|
|
1276
1321
|
const isLastStep = cycleStepCount >= this.config.maxSteps;
|
|
@@ -1318,8 +1363,8 @@ var GraphExecutor = class {
|
|
|
1318
1363
|
checkpointCount
|
|
1319
1364
|
});
|
|
1320
1365
|
const cp2 = this.sanitize(state);
|
|
1321
|
-
await this.checkpointer.save(
|
|
1322
|
-
this.ephemeralLocals.delete(
|
|
1366
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1367
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1323
1368
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1324
1369
|
}
|
|
1325
1370
|
logger.info("[GraphExecutor] \u8282\u70B9\u5207\u6362", {
|
|
@@ -1330,18 +1375,18 @@ var GraphExecutor = class {
|
|
|
1330
1375
|
});
|
|
1331
1376
|
const nodeRunStartedAt = Date.now();
|
|
1332
1377
|
const nodeIdForTelemetry = state.nodeId;
|
|
1378
|
+
const conversationIdForTelemetry = readRuntimeConversationId(state);
|
|
1333
1379
|
let result;
|
|
1334
1380
|
try {
|
|
1335
1381
|
result = await node.run(state);
|
|
1336
1382
|
} finally {
|
|
1337
|
-
const turnIdForTelemetry = typeof state.local?.turnId === "string" ? state.local.turnId : void 0;
|
|
1338
1383
|
this.telemetryPort.emit({
|
|
1339
1384
|
kind: "graph_node",
|
|
1340
1385
|
nodeId: nodeIdForTelemetry,
|
|
1341
1386
|
durationMs: Date.now() - nodeRunStartedAt,
|
|
1342
1387
|
scope: {
|
|
1343
|
-
conversationId:
|
|
1344
|
-
turnId:
|
|
1388
|
+
conversationId: conversationIdForTelemetry,
|
|
1389
|
+
turnId: readRuntimeTurnId(state)
|
|
1345
1390
|
}
|
|
1346
1391
|
});
|
|
1347
1392
|
}
|
|
@@ -1380,7 +1425,7 @@ var GraphExecutor = class {
|
|
|
1380
1425
|
});
|
|
1381
1426
|
state = { ...state, nodeId: nextNodeId };
|
|
1382
1427
|
const cp2 = this.sanitize(state);
|
|
1383
|
-
await this.checkpointer.save(
|
|
1428
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1384
1429
|
continue;
|
|
1385
1430
|
}
|
|
1386
1431
|
if (result.kind === "yield") {
|
|
@@ -1391,7 +1436,7 @@ var GraphExecutor = class {
|
|
|
1391
1436
|
checkpointCount
|
|
1392
1437
|
});
|
|
1393
1438
|
const cp2 = this.sanitize(state);
|
|
1394
|
-
await this.checkpointer.save(
|
|
1439
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1395
1440
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1396
1441
|
}
|
|
1397
1442
|
if (result.kind === "pause") {
|
|
@@ -1402,7 +1447,7 @@ var GraphExecutor = class {
|
|
|
1402
1447
|
checkpointCount
|
|
1403
1448
|
});
|
|
1404
1449
|
const cp2 = this.sanitize(state);
|
|
1405
|
-
await this.checkpointer.save(
|
|
1450
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1406
1451
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1407
1452
|
}
|
|
1408
1453
|
}
|
|
@@ -1413,8 +1458,8 @@ var GraphExecutor = class {
|
|
|
1413
1458
|
checkpointCount
|
|
1414
1459
|
});
|
|
1415
1460
|
const cp = this.sanitize(state);
|
|
1416
|
-
await this.checkpointer.save(
|
|
1417
|
-
this.ephemeralLocals.delete(
|
|
1461
|
+
await this.checkpointer.save(checkpointKey, cp);
|
|
1462
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1418
1463
|
return { events: allEvents, checkpoint: cp, stepCount };
|
|
1419
1464
|
}
|
|
1420
1465
|
};
|
|
@@ -1577,15 +1622,15 @@ function splitConcatenatedJsonObjects(input) {
|
|
|
1577
1622
|
}
|
|
1578
1623
|
|
|
1579
1624
|
// src/runtime-kernel/graph-engine/tick-pipeline/helpers.ts
|
|
1580
|
-
function
|
|
1625
|
+
function readNonEmptyString2(value) {
|
|
1581
1626
|
if (typeof value !== "string") return void 0;
|
|
1582
1627
|
const trimmed = value.trim();
|
|
1583
1628
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
1584
1629
|
}
|
|
1585
1630
|
function resolveConversationIdForRuntimeEvents(toolContext) {
|
|
1586
|
-
const fromCamel =
|
|
1631
|
+
const fromCamel = readNonEmptyString2(toolContext?.conversationId);
|
|
1587
1632
|
if (fromCamel) return fromCamel;
|
|
1588
|
-
const fromSnake = toolContext ?
|
|
1633
|
+
const fromSnake = toolContext ? readNonEmptyString2(toolContext["conversation_id"]) : void 0;
|
|
1589
1634
|
if (fromSnake) return fromSnake;
|
|
1590
1635
|
return generateMessageId();
|
|
1591
1636
|
}
|
|
@@ -1942,7 +1987,7 @@ var runModelLockMiddleware = async (ctx, stage, next) => {
|
|
|
1942
1987
|
if (stage.id !== "execute_llm") {
|
|
1943
1988
|
return;
|
|
1944
1989
|
}
|
|
1945
|
-
const normalized =
|
|
1990
|
+
const normalized = readNonEmptyString2(ctx.cloudQuotaFallbackAppliedModelId);
|
|
1946
1991
|
if (!normalized) {
|
|
1947
1992
|
return;
|
|
1948
1993
|
}
|
|
@@ -2530,7 +2575,7 @@ function createExecuteLlmStage(dependencies) {
|
|
|
2530
2575
|
streamEventHandler,
|
|
2531
2576
|
ctx.signal,
|
|
2532
2577
|
(fallbackModelId) => {
|
|
2533
|
-
ctx.cloudQuotaFallbackAppliedModelId =
|
|
2578
|
+
ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString2(fallbackModelId);
|
|
2534
2579
|
},
|
|
2535
2580
|
(info) => {
|
|
2536
2581
|
ctx.modelFallbackAudit = info;
|
|
@@ -2574,7 +2619,7 @@ function createPrepareCallStage(dependencies) {
|
|
|
2574
2619
|
return {
|
|
2575
2620
|
id: "prepare_call",
|
|
2576
2621
|
async run(ctx) {
|
|
2577
|
-
const lockedRunModelId =
|
|
2622
|
+
const lockedRunModelId = readNonEmptyString2(ctx.executorLocal?.runLockedModelId);
|
|
2578
2623
|
const requestedModelId = lockedRunModelId ?? ctx.request.model_id;
|
|
2579
2624
|
ctx.modelId = dependencies.modelResolver.resolveModelId(requestedModelId);
|
|
2580
2625
|
await emitAuditEnvelope(ctx.audit, {
|
|
@@ -2646,7 +2691,7 @@ var GraphAgentExecutor = class {
|
|
|
2646
2691
|
this.llmCaller = dependencies.llmCaller;
|
|
2647
2692
|
this.toolRuntime = dependencies.toolRuntime;
|
|
2648
2693
|
this.contextBuilder = dependencies.contextBuilder;
|
|
2649
|
-
this.cloudQuotaFallbackModelId =
|
|
2694
|
+
this.cloudQuotaFallbackModelId = readNonEmptyString2(dependencies.cloudQuotaFallbackModelId);
|
|
2650
2695
|
this.modelCatalog = dependencies.modelCatalog ?? createEmptyModelCatalog();
|
|
2651
2696
|
this.modelResolver = dependencies.modelResolver ?? new ModelResolver({
|
|
2652
2697
|
modelCatalog: this.modelCatalog
|
|
@@ -2694,7 +2739,7 @@ var GraphAgentExecutor = class {
|
|
|
2694
2739
|
llmMessages: [],
|
|
2695
2740
|
mode: input.request.mode === "chat" ? "chat" : "agent",
|
|
2696
2741
|
conversationId: resolveConversationIdForRuntimeEvents(input.toolContext),
|
|
2697
|
-
turnId:
|
|
2742
|
+
turnId: readNonEmptyString2(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
|
|
2698
2743
|
telemetry: this.telemetryPort,
|
|
2699
2744
|
audit: this.auditPort
|
|
2700
2745
|
};
|
|
@@ -2744,18 +2789,18 @@ function isSummarizationCallbacks(value) {
|
|
|
2744
2789
|
function isGraphSseSink(value) {
|
|
2745
2790
|
return typeof value === "function";
|
|
2746
2791
|
}
|
|
2747
|
-
function
|
|
2792
|
+
function readNonEmptyString3(value) {
|
|
2748
2793
|
if (typeof value !== "string") return void 0;
|
|
2749
2794
|
const trimmed = value.trim();
|
|
2750
2795
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
2751
2796
|
}
|
|
2752
2797
|
function readGraphAgentLocal(local) {
|
|
2753
2798
|
const source = local ?? {};
|
|
2754
|
-
const answerId =
|
|
2799
|
+
const answerId = readNonEmptyString3(source.answerId);
|
|
2755
2800
|
const chunkSeq = Number.isInteger(source.chunkSeq) ? Number(source.chunkSeq) : 0;
|
|
2756
2801
|
return {
|
|
2757
|
-
conversationId:
|
|
2758
|
-
turnId:
|
|
2802
|
+
conversationId: readNonEmptyString3(source.conversationId) ?? "",
|
|
2803
|
+
turnId: readNonEmptyString3(source.turnId),
|
|
2759
2804
|
request: isAgentInvocationRequest(source.request) ? source.request : void 0,
|
|
2760
2805
|
toolContext: isToolExecutionContext(source.toolContext) ? source.toolContext : void 0,
|
|
2761
2806
|
history: isRuntimeEventArray(source.history) ? source.history : [],
|
|
@@ -3520,7 +3565,7 @@ var LlmNode = class {
|
|
|
3520
3565
|
function isRecord8(value) {
|
|
3521
3566
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3522
3567
|
}
|
|
3523
|
-
function
|
|
3568
|
+
function readNonEmptyString4(value) {
|
|
3524
3569
|
if (typeof value !== "string") {
|
|
3525
3570
|
return void 0;
|
|
3526
3571
|
}
|
|
@@ -3542,7 +3587,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3542
3587
|
return void 0;
|
|
3543
3588
|
}
|
|
3544
3589
|
if (toolName === "write_report") {
|
|
3545
|
-
const report =
|
|
3590
|
+
const report = readNonEmptyString4(data.report);
|
|
3546
3591
|
if (!report) {
|
|
3547
3592
|
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");
|
|
3548
3593
|
}
|
|
@@ -3552,7 +3597,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3552
3597
|
if (data.success !== true) {
|
|
3553
3598
|
return void 0;
|
|
3554
3599
|
}
|
|
3555
|
-
const finalAnswer =
|
|
3600
|
+
const finalAnswer = readNonEmptyString4(data.final_answer);
|
|
3556
3601
|
if (!finalAnswer) {
|
|
3557
3602
|
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");
|
|
3558
3603
|
}
|
|
@@ -4448,6 +4493,22 @@ var ToolNode = class {
|
|
|
4448
4493
|
});
|
|
4449
4494
|
}
|
|
4450
4495
|
async run(state) {
|
|
4496
|
+
const events = [];
|
|
4497
|
+
while (true) {
|
|
4498
|
+
const result = await this.runNextPendingToolCall(state);
|
|
4499
|
+
if (Array.isArray(result.events) && result.events.length > 0) {
|
|
4500
|
+
events.push(...result.events);
|
|
4501
|
+
}
|
|
4502
|
+
if (result.kind === "route" && result.nextNodeId === "tool") {
|
|
4503
|
+
continue;
|
|
4504
|
+
}
|
|
4505
|
+
return {
|
|
4506
|
+
...result,
|
|
4507
|
+
events
|
|
4508
|
+
};
|
|
4509
|
+
}
|
|
4510
|
+
}
|
|
4511
|
+
async runNextPendingToolCall(state) {
|
|
4451
4512
|
const calls = state.local?.pendingToolCalls ?? [];
|
|
4452
4513
|
const signalRaw = state.local?.signal;
|
|
4453
4514
|
if (isAbortSignal(signalRaw) && signalRaw.aborted) {
|
|
@@ -4655,18 +4716,25 @@ var ToolNode = class {
|
|
|
4655
4716
|
rawArguments: context.call.function?.arguments,
|
|
4656
4717
|
parsedArguments: context.toolArgs
|
|
4657
4718
|
});
|
|
4719
|
+
const remainingCalls = context.calls.slice(1);
|
|
4658
4720
|
context.state.local = buildErrorLocalState({
|
|
4659
4721
|
local: context.local,
|
|
4660
|
-
remainingCalls
|
|
4722
|
+
remainingCalls,
|
|
4661
4723
|
conversationId: context.conversationId,
|
|
4662
4724
|
turnId: context.turnId,
|
|
4663
4725
|
runtimeEvents: context.bridge.getRuntimeEvents(),
|
|
4664
4726
|
nextProtocolErrorCount: fuse.nextCount
|
|
4665
4727
|
});
|
|
4666
|
-
if (fuse.shouldFuse) {
|
|
4728
|
+
if (fuse.shouldFuse && remainingCalls.length === 0) {
|
|
4667
4729
|
throw createToolProtocolFuseError(fuse.nextCount, context.exec.error);
|
|
4668
4730
|
}
|
|
4669
|
-
return {
|
|
4731
|
+
return {
|
|
4732
|
+
kind: "route",
|
|
4733
|
+
// 同一个 assistant.tool_calls batch 必须为每个 call 产出 tool_output。
|
|
4734
|
+
// 出错时也继续消费剩余 call,ToolNode.run 会在本节点内 drain 完 batch 再回 LLM。
|
|
4735
|
+
nextNodeId: remainingCalls.length > 0 ? "tool" : "llm",
|
|
4736
|
+
events: context.bridge.getRuntimeEvents()
|
|
4737
|
+
};
|
|
4670
4738
|
}
|
|
4671
4739
|
};
|
|
4672
4740
|
|
|
@@ -4863,12 +4931,12 @@ function asRecord(value) {
|
|
|
4863
4931
|
}
|
|
4864
4932
|
return value;
|
|
4865
4933
|
}
|
|
4866
|
-
function summarizeCheckpoint(
|
|
4934
|
+
function summarizeCheckpoint(checkpointKey, state, savedAt) {
|
|
4867
4935
|
const local = asRecord(state.local);
|
|
4868
4936
|
const executorLocal = asRecord(local?.executorLocal);
|
|
4869
4937
|
const pendingToolCalls = local?.pendingToolCalls;
|
|
4870
4938
|
return {
|
|
4871
|
-
|
|
4939
|
+
checkpointKey,
|
|
4872
4940
|
schemaVersion: state.schemaVersion ?? 1,
|
|
4873
4941
|
savedAt,
|
|
4874
4942
|
currentNode: state.nodeId,
|
|
@@ -4887,25 +4955,25 @@ var MemoryCheckpointer = class {
|
|
|
4887
4955
|
local: state.local && typeof state.local === "object" && !Array.isArray(state.local) ? { ...state.local } : state.local
|
|
4888
4956
|
};
|
|
4889
4957
|
}
|
|
4890
|
-
async load(
|
|
4891
|
-
const entry = this.store.get(
|
|
4958
|
+
async load(checkpointKey) {
|
|
4959
|
+
const entry = this.store.get(checkpointKey);
|
|
4892
4960
|
return entry ? this.cloneState(entry.state) : null;
|
|
4893
4961
|
}
|
|
4894
|
-
async save(
|
|
4895
|
-
this.store.set(
|
|
4962
|
+
async save(checkpointKey, state) {
|
|
4963
|
+
this.store.set(checkpointKey, {
|
|
4896
4964
|
state: this.cloneState(state),
|
|
4897
4965
|
savedAt: Date.now()
|
|
4898
4966
|
});
|
|
4899
4967
|
}
|
|
4900
|
-
async clear(
|
|
4901
|
-
this.store.delete(
|
|
4968
|
+
async clear(checkpointKey) {
|
|
4969
|
+
this.store.delete(checkpointKey);
|
|
4902
4970
|
}
|
|
4903
|
-
async peekMeta(
|
|
4904
|
-
const entry = this.store.get(
|
|
4905
|
-
return entry ? summarizeCheckpoint(
|
|
4971
|
+
async peekMeta(checkpointKey) {
|
|
4972
|
+
const entry = this.store.get(checkpointKey);
|
|
4973
|
+
return entry ? summarizeCheckpoint(checkpointKey, entry.state, entry.savedAt) : null;
|
|
4906
4974
|
}
|
|
4907
4975
|
async list(filter = {}) {
|
|
4908
|
-
const summaries = Array.from(this.store.entries()).map(([
|
|
4976
|
+
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);
|
|
4909
4977
|
if (filter.limit === void 0) {
|
|
4910
4978
|
return summaries;
|
|
4911
4979
|
}
|
|
@@ -5162,18 +5230,18 @@ function createClassification(category, reason, suggestedDelay, extras) {
|
|
|
5162
5230
|
}
|
|
5163
5231
|
var ErrorClassifier = class {
|
|
5164
5232
|
static classify(error, context) {
|
|
5165
|
-
const
|
|
5233
|
+
const isRecord23 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
5166
5234
|
const baseMsg = (error.message || "").toLowerCase();
|
|
5167
5235
|
const causeMsg = (() => {
|
|
5168
5236
|
const cause = error.cause;
|
|
5169
5237
|
if (typeof cause === "string") return cause.toLowerCase();
|
|
5170
5238
|
if (cause instanceof Error) return (cause.message || "").toLowerCase();
|
|
5171
|
-
if (
|
|
5239
|
+
if (isRecord23(cause) && typeof cause["message"] === "string") return String(cause["message"]).toLowerCase();
|
|
5172
5240
|
return "";
|
|
5173
5241
|
})();
|
|
5174
5242
|
const causeCode = (() => {
|
|
5175
5243
|
const cause = error.cause;
|
|
5176
|
-
if (
|
|
5244
|
+
if (isRecord23(cause) && typeof cause["code"] === "string") return String(cause["code"]);
|
|
5177
5245
|
return "";
|
|
5178
5246
|
})();
|
|
5179
5247
|
const errorMessage = `${baseMsg} ${causeMsg}`.trim();
|
|
@@ -5849,6 +5917,67 @@ function assertToolCallsHaveValidJsonArguments(toolCalls) {
|
|
|
5849
5917
|
}
|
|
5850
5918
|
}
|
|
5851
5919
|
|
|
5920
|
+
// src/runtime-kernel/llm/reasoning-details.ts
|
|
5921
|
+
var mergeableTextFields = ["reasoning_content"];
|
|
5922
|
+
function isRecord18(value) {
|
|
5923
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
5924
|
+
}
|
|
5925
|
+
function findMergeableTextField(detail) {
|
|
5926
|
+
if (!isRecord18(detail)) return void 0;
|
|
5927
|
+
if (typeof detail.provider !== "string") return void 0;
|
|
5928
|
+
if (typeof detail.type !== "string") return void 0;
|
|
5929
|
+
for (const field of mergeableTextFields) {
|
|
5930
|
+
if (typeof detail[field] === "string") {
|
|
5931
|
+
return field;
|
|
5932
|
+
}
|
|
5933
|
+
}
|
|
5934
|
+
return void 0;
|
|
5935
|
+
}
|
|
5936
|
+
function hasOnlyStableTextDetailFields(detail, textField) {
|
|
5937
|
+
const allowedKeys = /* @__PURE__ */ new Set(["provider", "type", textField]);
|
|
5938
|
+
return Object.keys(detail).every((key) => allowedKeys.has(key));
|
|
5939
|
+
}
|
|
5940
|
+
function canMergeTextDetails(previous, incoming) {
|
|
5941
|
+
if (!isRecord18(previous) || !isRecord18(incoming)) return false;
|
|
5942
|
+
const previousField = findMergeableTextField(previous);
|
|
5943
|
+
const incomingField = findMergeableTextField(incoming);
|
|
5944
|
+
if (!previousField || previousField !== incomingField) return false;
|
|
5945
|
+
return previous.provider === incoming.provider && previous.type === incoming.type && hasOnlyStableTextDetailFields(previous, previousField) && hasOnlyStableTextDetailFields(incoming, incomingField);
|
|
5946
|
+
}
|
|
5947
|
+
function mergeStreamingText(previous, incoming) {
|
|
5948
|
+
if (!previous) return incoming;
|
|
5949
|
+
if (!incoming) return previous;
|
|
5950
|
+
if (incoming.startsWith(previous)) {
|
|
5951
|
+
return incoming;
|
|
5952
|
+
}
|
|
5953
|
+
if (previous.endsWith(incoming)) {
|
|
5954
|
+
return previous;
|
|
5955
|
+
}
|
|
5956
|
+
return `${previous}${incoming}`;
|
|
5957
|
+
}
|
|
5958
|
+
function appendStreamingProviderReasoningDetails(existing, incoming) {
|
|
5959
|
+
const next = [...existing];
|
|
5960
|
+
for (const detail of incoming) {
|
|
5961
|
+
const previous = next[next.length - 1];
|
|
5962
|
+
if (canMergeTextDetails(previous, detail)) {
|
|
5963
|
+
const textField = findMergeableTextField(previous);
|
|
5964
|
+
if (textField && isRecord18(detail)) {
|
|
5965
|
+
const mergedText = mergeStreamingText(String(previous[textField]), String(detail[textField]));
|
|
5966
|
+
if (mergedText === previous[textField]) {
|
|
5967
|
+
continue;
|
|
5968
|
+
}
|
|
5969
|
+
next[next.length - 1] = {
|
|
5970
|
+
...previous,
|
|
5971
|
+
[textField]: mergedText
|
|
5972
|
+
};
|
|
5973
|
+
continue;
|
|
5974
|
+
}
|
|
5975
|
+
}
|
|
5976
|
+
next.push(detail);
|
|
5977
|
+
}
|
|
5978
|
+
return next;
|
|
5979
|
+
}
|
|
5980
|
+
|
|
5852
5981
|
// src/runtime-kernel/llm/streaming-adapter.ts
|
|
5853
5982
|
async function callLlmStream(params) {
|
|
5854
5983
|
const {
|
|
@@ -5861,7 +5990,7 @@ async function callLlmStream(params) {
|
|
|
5861
5990
|
} = params;
|
|
5862
5991
|
let fullResponse = "";
|
|
5863
5992
|
let streamError = null;
|
|
5864
|
-
|
|
5993
|
+
let reasoningDetails = [];
|
|
5865
5994
|
const streamAnswerId = generateMessageId();
|
|
5866
5995
|
let streamChunkSeq = 0;
|
|
5867
5996
|
let capturedUsage = void 0;
|
|
@@ -5931,13 +6060,21 @@ async function callLlmStream(params) {
|
|
|
5931
6060
|
const reasoning = isRecord17(chunk) ? chunk["reasoning_details"] : void 0;
|
|
5932
6061
|
if (reasoning !== void 0) {
|
|
5933
6062
|
const newReasoningDetails = Array.isArray(reasoning) ? reasoning : [reasoning];
|
|
5934
|
-
reasoningDetails
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
6063
|
+
const previousReasoningDetails = reasoningDetails;
|
|
6064
|
+
const previousLength = previousReasoningDetails.length;
|
|
6065
|
+
const compactedReasoningDetails = appendStreamingProviderReasoningDetails(reasoningDetails, newReasoningDetails);
|
|
6066
|
+
reasoningDetails = compactedReasoningDetails;
|
|
6067
|
+
const previousLastChanged = previousLength > 0 && compactedReasoningDetails[previousLength - 1] !== previousReasoningDetails[previousLength - 1];
|
|
6068
|
+
const emitFromIndex = previousLastChanged ? previousLength - 1 : previousLength;
|
|
6069
|
+
const emittedReasoningDetails = compactedReasoningDetails.slice(Math.max(0, emitFromIndex));
|
|
6070
|
+
if (emittedReasoningDetails.length > 0) {
|
|
6071
|
+
eventHandler({
|
|
6072
|
+
type: "provider_sidecar",
|
|
6073
|
+
id: generateMessageId(),
|
|
6074
|
+
timestamp: Date.now(),
|
|
6075
|
+
reasoning_details: emittedReasoningDetails
|
|
6076
|
+
});
|
|
6077
|
+
}
|
|
5941
6078
|
}
|
|
5942
6079
|
if (chunk.tool_calls) {
|
|
5943
6080
|
emitThoughtComplete(thoughtSegmenter.onBoundary());
|
|
@@ -6376,7 +6513,7 @@ function cloneRunRecord(record) {
|
|
|
6376
6513
|
...record,
|
|
6377
6514
|
iterationBudget: record.iterationBudget ? { ...record.iterationBudget } : void 0,
|
|
6378
6515
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0,
|
|
6379
|
-
metadata: record.metadata ?
|
|
6516
|
+
metadata: record.metadata ? structuredClone(record.metadata) : void 0
|
|
6380
6517
|
};
|
|
6381
6518
|
}
|
|
6382
6519
|
function matchesStatus(candidate, filter) {
|
|
@@ -6508,7 +6645,7 @@ function runRecordToMeta(record) {
|
|
|
6508
6645
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0
|
|
6509
6646
|
};
|
|
6510
6647
|
}
|
|
6511
|
-
function
|
|
6648
|
+
function isRecord19(value) {
|
|
6512
6649
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6513
6650
|
}
|
|
6514
6651
|
function readStringField(record, key) {
|
|
@@ -6529,7 +6666,7 @@ function getRunIdFromMetadata(event) {
|
|
|
6529
6666
|
return snakeCaseRunId;
|
|
6530
6667
|
}
|
|
6531
6668
|
const runContext = metadata["run_context"];
|
|
6532
|
-
if (
|
|
6669
|
+
if (isRecord19(runContext)) {
|
|
6533
6670
|
return readStringField(runContext, "runId") ?? readStringField(runContext, "run_id");
|
|
6534
6671
|
}
|
|
6535
6672
|
return void 0;
|
|
@@ -6747,7 +6884,7 @@ function runMetaFromRecord(record) {
|
|
|
6747
6884
|
}
|
|
6748
6885
|
|
|
6749
6886
|
// src/runtime-kernel/run-supervisor/runSupervisor.ts
|
|
6750
|
-
function
|
|
6887
|
+
function isRecord20(value) {
|
|
6751
6888
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6752
6889
|
}
|
|
6753
6890
|
function readStringField2(record, key) {
|
|
@@ -6764,7 +6901,7 @@ function readRunIdFromRuntimeEvent(event) {
|
|
|
6764
6901
|
return directRunId;
|
|
6765
6902
|
}
|
|
6766
6903
|
const runContext = metadata["run_context"];
|
|
6767
|
-
if (!
|
|
6904
|
+
if (!isRecord20(runContext)) {
|
|
6768
6905
|
return void 0;
|
|
6769
6906
|
}
|
|
6770
6907
|
return readStringField2(runContext, "runId") ?? readStringField2(runContext, "run_id");
|
|
@@ -6776,7 +6913,7 @@ function readAwaitingUserReason(event) {
|
|
|
6776
6913
|
if (typeof event.prompt === "string" && event.prompt.trim().length > 0) {
|
|
6777
6914
|
return event.prompt;
|
|
6778
6915
|
}
|
|
6779
|
-
if (
|
|
6916
|
+
if (isRecord20(event.form)) {
|
|
6780
6917
|
const prompt = readStringField2(event.form, "prompt");
|
|
6781
6918
|
if (prompt && prompt.trim().length > 0) {
|
|
6782
6919
|
return prompt;
|
|
@@ -6788,7 +6925,7 @@ function isTerminalStatus(status) {
|
|
|
6788
6925
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
6789
6926
|
}
|
|
6790
6927
|
function cloneMetadata(metadata) {
|
|
6791
|
-
return metadata ?
|
|
6928
|
+
return metadata ? structuredClone(metadata) : void 0;
|
|
6792
6929
|
}
|
|
6793
6930
|
function recordToSnapshot(record) {
|
|
6794
6931
|
return {
|
|
@@ -6875,7 +7012,7 @@ var DefaultRunSupervisor = class {
|
|
|
6875
7012
|
startedAt,
|
|
6876
7013
|
updatedAt: startedAt,
|
|
6877
7014
|
iterationBudget: spec.iterationBudget ? { ...spec.iterationBudget } : void 0,
|
|
6878
|
-
metadata: spec.metadata
|
|
7015
|
+
metadata: cloneMetadata(spec.metadata)
|
|
6879
7016
|
};
|
|
6880
7017
|
await this.registryStore.save(record);
|
|
6881
7018
|
const handle = new DefaultRunHandle({
|
|
@@ -7049,12 +7186,13 @@ var DefaultRunSupervisor = class {
|
|
|
7049
7186
|
}
|
|
7050
7187
|
try {
|
|
7051
7188
|
await handle.markRunning({ currentNode: "detached" });
|
|
7189
|
+
const registeredRecord = await this.registryStore.load(handle.runId);
|
|
7052
7190
|
const executorOutcome = await this.executor.execute({
|
|
7053
7191
|
runId: handle.runId,
|
|
7054
|
-
parentRunId:
|
|
7055
|
-
conversationId: spec.conversationId,
|
|
7056
|
-
agentSpec: spec
|
|
7057
|
-
request:
|
|
7192
|
+
parentRunId: handle.parentRunId,
|
|
7193
|
+
conversationId: registeredRecord?.conversationId ?? spec.conversationId,
|
|
7194
|
+
agentSpec: await handle.spec(),
|
|
7195
|
+
request: await handle.request(),
|
|
7058
7196
|
signal: handle.signal,
|
|
7059
7197
|
eventBus: spec.eventBus,
|
|
7060
7198
|
eventStore: spec.eventStore,
|
|
@@ -7063,7 +7201,7 @@ var DefaultRunSupervisor = class {
|
|
|
7063
7201
|
contextFences: spec.contextFences,
|
|
7064
7202
|
wakeSource: spec.wakeSource,
|
|
7065
7203
|
ephemeral: spec.ephemeral,
|
|
7066
|
-
metadata: spec.metadata
|
|
7204
|
+
metadata: cloneMetadata(registeredRecord?.metadata ?? spec.metadata)
|
|
7067
7205
|
});
|
|
7068
7206
|
const outcome = await this.persistExecutorOutcome(handle, executorOutcome);
|
|
7069
7207
|
this.notifyTerminalWaiters(outcome);
|
|
@@ -7127,10 +7265,14 @@ var DefaultRunSupervisor = class {
|
|
|
7127
7265
|
await this.registryStore.save(record);
|
|
7128
7266
|
}
|
|
7129
7267
|
const completedAt = executorOutcome?.completedAt ?? this.now();
|
|
7268
|
+
const fallbackMeta = record ? void 0 : await handle.meta();
|
|
7130
7269
|
const outcome = recordToTerminalOutcome(record ?? {
|
|
7131
7270
|
runId: handle.runId,
|
|
7132
7271
|
parentRunId: handle.parentRunId,
|
|
7133
|
-
|
|
7272
|
+
conversationId: fallbackMeta?.conversationId ?? "",
|
|
7273
|
+
agentSpecId: fallbackMeta?.agentSpecId,
|
|
7274
|
+
status: executorOutcome?.status ?? "completed",
|
|
7275
|
+
startedAt: fallbackMeta?.startedAt ?? completedAt}, completedAt);
|
|
7134
7276
|
const nextOutcome = {
|
|
7135
7277
|
...outcome,
|
|
7136
7278
|
metadata: {
|
|
@@ -7386,7 +7528,7 @@ function createQuickstartTelemetryPort(collector) {
|
|
|
7386
7528
|
}
|
|
7387
7529
|
|
|
7388
7530
|
// src/quickstart/runAgent.ts
|
|
7389
|
-
function
|
|
7531
|
+
function isRecord21(value) {
|
|
7390
7532
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7391
7533
|
}
|
|
7392
7534
|
function readString4(value) {
|
|
@@ -7400,7 +7542,7 @@ function resolveModelId(agent, options) {
|
|
|
7400
7542
|
return modelId;
|
|
7401
7543
|
}
|
|
7402
7544
|
function isQuickstartStreamChunkEvent(value) {
|
|
7403
|
-
return
|
|
7545
|
+
return isRecord21(value) && value.type === "stream_chunk" && typeof value.content === "string";
|
|
7404
7546
|
}
|
|
7405
7547
|
function createNoopObservationPreview() {
|
|
7406
7548
|
return {
|
|
@@ -7440,7 +7582,7 @@ function readFinalAnswer(events, checkpointLocal) {
|
|
|
7440
7582
|
if (chunks.length > 0) {
|
|
7441
7583
|
return chunks.join("");
|
|
7442
7584
|
}
|
|
7443
|
-
if (
|
|
7585
|
+
if (isRecord21(checkpointLocal)) {
|
|
7444
7586
|
const finalAnswer = checkpointLocal["finalAnswer"];
|
|
7445
7587
|
if (typeof finalAnswer === "string") {
|
|
7446
7588
|
return finalAnswer;
|
|
@@ -7449,7 +7591,7 @@ function readFinalAnswer(events, checkpointLocal) {
|
|
|
7449
7591
|
return "";
|
|
7450
7592
|
}
|
|
7451
7593
|
function readContextTrace(checkpointLocal) {
|
|
7452
|
-
if (!
|
|
7594
|
+
if (!isRecord21(checkpointLocal)) return void 0;
|
|
7453
7595
|
return checkpointLocal["contextTrace"];
|
|
7454
7596
|
}
|
|
7455
7597
|
async function emitRunEvent(event, sink) {
|
|
@@ -7458,6 +7600,7 @@ async function emitRunEvent(event, sink) {
|
|
|
7458
7600
|
async function runAgent(agent, options) {
|
|
7459
7601
|
const modelId = resolveModelId(agent, options);
|
|
7460
7602
|
const conversationId = options.conversationId ?? `conv_${Date.now()}`;
|
|
7603
|
+
const checkpointKey = conversationId;
|
|
7461
7604
|
const runId = options.runId ?? generateRunId();
|
|
7462
7605
|
const turnId = runId;
|
|
7463
7606
|
const costCollector = new QuickstartRunCostCollector();
|
|
@@ -7512,7 +7655,7 @@ async function runAgent(agent, options) {
|
|
|
7512
7655
|
};
|
|
7513
7656
|
await handle.markRunning({ currentNode: "user" });
|
|
7514
7657
|
try {
|
|
7515
|
-
await executor.prime(
|
|
7658
|
+
await executor.prime(checkpointKey, {
|
|
7516
7659
|
conversationId,
|
|
7517
7660
|
turnId,
|
|
7518
7661
|
request: {
|
|
@@ -7537,7 +7680,7 @@ async function runAgent(agent, options) {
|
|
|
7537
7680
|
return void 0;
|
|
7538
7681
|
}
|
|
7539
7682
|
});
|
|
7540
|
-
const result = await executor.runUntilYield(
|
|
7683
|
+
const result = await executor.runUntilYield(checkpointKey);
|
|
7541
7684
|
runtimeEvents.push(...result.events);
|
|
7542
7685
|
for (const event of result.events) {
|
|
7543
7686
|
if (event.type === "final_answer_chunk") continue;
|
|
@@ -7573,11 +7716,11 @@ async function runAgent(agent, options) {
|
|
|
7573
7716
|
}
|
|
7574
7717
|
|
|
7575
7718
|
// src/cli/configLoader.ts
|
|
7576
|
-
function
|
|
7719
|
+
function isRecord22(value) {
|
|
7577
7720
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7578
7721
|
}
|
|
7579
7722
|
function readDefaultExport(moduleValue) {
|
|
7580
|
-
if (
|
|
7723
|
+
if (isRecord22(moduleValue) && "default" in moduleValue) {
|
|
7581
7724
|
return moduleValue.default;
|
|
7582
7725
|
}
|
|
7583
7726
|
return moduleValue;
|
|
@@ -7588,7 +7731,7 @@ async function loadConfig(configPath, cwd) {
|
|
|
7588
7731
|
moduleUrl.searchParams.set("t", String(Date.now()));
|
|
7589
7732
|
const loaded = await import(moduleUrl.href);
|
|
7590
7733
|
const config = readDefaultExport(loaded);
|
|
7591
|
-
if (!
|
|
7734
|
+
if (!isRecord22(config)) {
|
|
7592
7735
|
throw new Error(`[linnkit] config must export an object: ${absolutePath}`);
|
|
7593
7736
|
}
|
|
7594
7737
|
return defineConfig(config);
|
|
@@ -7700,7 +7843,7 @@ function createQuickstartTemplateFiles(projectName) {
|
|
|
7700
7843
|
start: 'linnkit run hello --input "\u4F60\u597D\uFF0C\u4ECB\u7ECD\u4E00\u4E0B\u4F60\u81EA\u5DF1"'
|
|
7701
7844
|
},
|
|
7702
7845
|
dependencies: {
|
|
7703
|
-
"@linnlabs/linnkit": "^0.
|
|
7846
|
+
"@linnlabs/linnkit": "^0.10.0",
|
|
7704
7847
|
zod: "^3.22.0"
|
|
7705
7848
|
},
|
|
7706
7849
|
devDependencies: {}
|