@linnlabs/linnkit 0.9.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 +13 -0
- 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 +118 -65
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +118 -65
- package/dist/cli.js.map +1 -1
- package/dist/context-manager.cjs +234 -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 +234 -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-BanRABEt.d.cts → index-BAaUP9yU.d.cts} +26 -14
- package/dist/{index-Z8NXKNwI.d.ts → index-BaVpVNi2.d.ts} +26 -14
- 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 +186 -85
- 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 +186 -85
- 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 +119 -65
- 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 +119 -65
- 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 +181 -82
- 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 +181 -83
- package/dist/runtime-kernel.js.map +1 -1
- package/dist/testkit.cjs +181 -82
- 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 +181 -82
- 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 +4 -3
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(),
|
|
@@ -1084,6 +1085,7 @@ var Logger = class {
|
|
|
1084
1085
|
constructor(moduleName) {
|
|
1085
1086
|
this.moduleName = moduleName;
|
|
1086
1087
|
}
|
|
1088
|
+
moduleName;
|
|
1087
1089
|
debug(message, data) {
|
|
1088
1090
|
this.log(0 /* DEBUG */, "debug", message, data);
|
|
1089
1091
|
}
|
|
@@ -1156,6 +1158,17 @@ var logger = new Logger("GraphExecutor");
|
|
|
1156
1158
|
function asLocalRecord(local) {
|
|
1157
1159
|
return local && typeof local === "object" ? { ...local } : {};
|
|
1158
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
|
+
}
|
|
1159
1172
|
var GraphExecutor = class {
|
|
1160
1173
|
constructor(checkpointer, config = {}) {
|
|
1161
1174
|
this.checkpointer = checkpointer;
|
|
@@ -1165,6 +1178,7 @@ var GraphExecutor = class {
|
|
|
1165
1178
|
};
|
|
1166
1179
|
this.telemetryPort = config.telemetryPort ?? noopTelemetry;
|
|
1167
1180
|
}
|
|
1181
|
+
checkpointer;
|
|
1168
1182
|
nodes = /* @__PURE__ */ new Map();
|
|
1169
1183
|
ephemeralLocals = /* @__PURE__ */ new Map();
|
|
1170
1184
|
config;
|
|
@@ -1172,8 +1186,8 @@ var GraphExecutor = class {
|
|
|
1172
1186
|
registerNode(node) {
|
|
1173
1187
|
this.nodes.set(node.id, node);
|
|
1174
1188
|
}
|
|
1175
|
-
async peekCheckpoint(
|
|
1176
|
-
return await this.checkpointer.load(
|
|
1189
|
+
async peekCheckpoint(checkpointKey) {
|
|
1190
|
+
return await this.checkpointer.load(checkpointKey);
|
|
1177
1191
|
}
|
|
1178
1192
|
sanitize(state) {
|
|
1179
1193
|
const local = asLocalRecord(state.local);
|
|
@@ -1185,8 +1199,8 @@ var GraphExecutor = class {
|
|
|
1185
1199
|
local
|
|
1186
1200
|
};
|
|
1187
1201
|
}
|
|
1188
|
-
async prime(
|
|
1189
|
-
this.ephemeralLocals.set(
|
|
1202
|
+
async prime(checkpointKey, local, nodeId = "user") {
|
|
1203
|
+
this.ephemeralLocals.set(checkpointKey, { ...local || {} });
|
|
1190
1204
|
const localSansMemory = { ...local || {} };
|
|
1191
1205
|
if ("memory" in localSansMemory) delete localSansMemory.memory;
|
|
1192
1206
|
const state = {
|
|
@@ -1194,10 +1208,10 @@ var GraphExecutor = class {
|
|
|
1194
1208
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1195
1209
|
local: localSansMemory
|
|
1196
1210
|
};
|
|
1197
|
-
await this.checkpointer.save(
|
|
1211
|
+
await this.checkpointer.save(checkpointKey, state);
|
|
1198
1212
|
}
|
|
1199
|
-
async setNode(
|
|
1200
|
-
const current = await this.checkpointer.load(
|
|
1213
|
+
async setNode(checkpointKey, nodeId, localPatch) {
|
|
1214
|
+
const current = await this.checkpointer.load(checkpointKey) || {
|
|
1201
1215
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1202
1216
|
local: {}
|
|
1203
1217
|
};
|
|
@@ -1208,19 +1222,46 @@ var GraphExecutor = class {
|
|
|
1208
1222
|
schemaVersion: current.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
1209
1223
|
local: mergedLocal
|
|
1210
1224
|
};
|
|
1211
|
-
await this.checkpointer.save(
|
|
1225
|
+
await this.checkpointer.save(checkpointKey, next);
|
|
1212
1226
|
}
|
|
1213
|
-
async runUntilYield(
|
|
1227
|
+
async runUntilYield(checkpointKey) {
|
|
1214
1228
|
const runId = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1215
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);
|
|
1216
1251
|
this.telemetryPort.emit({
|
|
1217
1252
|
kind: "run_lifecycle",
|
|
1218
1253
|
runId,
|
|
1219
1254
|
phase: "spawned",
|
|
1220
|
-
scope: {
|
|
1255
|
+
scope: {
|
|
1256
|
+
conversationId: lifecycleConversationId,
|
|
1257
|
+
turnId: lifecycleTurnId
|
|
1258
|
+
}
|
|
1221
1259
|
});
|
|
1222
1260
|
try {
|
|
1223
|
-
|
|
1261
|
+
const result = await this.runUntilYieldInternal(checkpointKey, initialState);
|
|
1262
|
+
lifecycleConversationId = readRuntimeConversationId(result.checkpoint);
|
|
1263
|
+
lifecycleTurnId = readRuntimeTurnId(result.checkpoint);
|
|
1264
|
+
return result;
|
|
1224
1265
|
} catch (err) {
|
|
1225
1266
|
lifecyclePhase = err?.name === "AbortError" ? "cancelled" : "failed";
|
|
1226
1267
|
throw err;
|
|
@@ -1229,17 +1270,23 @@ var GraphExecutor = class {
|
|
|
1229
1270
|
kind: "run_lifecycle",
|
|
1230
1271
|
runId,
|
|
1231
1272
|
phase: lifecyclePhase,
|
|
1232
|
-
scope: {
|
|
1273
|
+
scope: {
|
|
1274
|
+
conversationId: lifecycleConversationId,
|
|
1275
|
+
turnId: lifecycleTurnId
|
|
1276
|
+
}
|
|
1233
1277
|
});
|
|
1234
1278
|
}
|
|
1235
1279
|
}
|
|
1236
|
-
async
|
|
1237
|
-
|
|
1280
|
+
async loadInitialState(checkpointKey) {
|
|
1281
|
+
return await this.checkpointer.load(checkpointKey) || {
|
|
1238
1282
|
nodeId: "user",
|
|
1239
1283
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1240
1284
|
local: {}
|
|
1241
1285
|
};
|
|
1242
|
-
|
|
1286
|
+
}
|
|
1287
|
+
async runUntilYieldInternal(checkpointKey, initialState) {
|
|
1288
|
+
let state = initialState;
|
|
1289
|
+
const ephemeral = this.ephemeralLocals.get(checkpointKey) || {};
|
|
1243
1290
|
state = {
|
|
1244
1291
|
...state,
|
|
1245
1292
|
schemaVersion: state.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
@@ -1268,7 +1315,7 @@ var GraphExecutor = class {
|
|
|
1268
1315
|
const signalRaw = state.local?.signal;
|
|
1269
1316
|
if (isAbortSignal2(signalRaw) && signalRaw.aborted) {
|
|
1270
1317
|
logger.warn("[GraphExecutor] \u6536\u5230 AbortSignal\uFF0C\u7ACB\u5373\u505C\u6B62\u63A8\u7406\u5FAA\u73AF");
|
|
1271
|
-
this.ephemeralLocals.delete(
|
|
1318
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1272
1319
|
throwAbortError();
|
|
1273
1320
|
}
|
|
1274
1321
|
const isLastStep = cycleStepCount >= this.config.maxSteps;
|
|
@@ -1316,8 +1363,8 @@ var GraphExecutor = class {
|
|
|
1316
1363
|
checkpointCount
|
|
1317
1364
|
});
|
|
1318
1365
|
const cp2 = this.sanitize(state);
|
|
1319
|
-
await this.checkpointer.save(
|
|
1320
|
-
this.ephemeralLocals.delete(
|
|
1366
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1367
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1321
1368
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1322
1369
|
}
|
|
1323
1370
|
logger.info("[GraphExecutor] \u8282\u70B9\u5207\u6362", {
|
|
@@ -1328,18 +1375,18 @@ var GraphExecutor = class {
|
|
|
1328
1375
|
});
|
|
1329
1376
|
const nodeRunStartedAt = Date.now();
|
|
1330
1377
|
const nodeIdForTelemetry = state.nodeId;
|
|
1378
|
+
const conversationIdForTelemetry = readRuntimeConversationId(state);
|
|
1331
1379
|
let result;
|
|
1332
1380
|
try {
|
|
1333
1381
|
result = await node.run(state);
|
|
1334
1382
|
} finally {
|
|
1335
|
-
const turnIdForTelemetry = typeof state.local?.turnId === "string" ? state.local.turnId : void 0;
|
|
1336
1383
|
this.telemetryPort.emit({
|
|
1337
1384
|
kind: "graph_node",
|
|
1338
1385
|
nodeId: nodeIdForTelemetry,
|
|
1339
1386
|
durationMs: Date.now() - nodeRunStartedAt,
|
|
1340
1387
|
scope: {
|
|
1341
|
-
conversationId:
|
|
1342
|
-
turnId:
|
|
1388
|
+
conversationId: conversationIdForTelemetry,
|
|
1389
|
+
turnId: readRuntimeTurnId(state)
|
|
1343
1390
|
}
|
|
1344
1391
|
});
|
|
1345
1392
|
}
|
|
@@ -1378,7 +1425,7 @@ var GraphExecutor = class {
|
|
|
1378
1425
|
});
|
|
1379
1426
|
state = { ...state, nodeId: nextNodeId };
|
|
1380
1427
|
const cp2 = this.sanitize(state);
|
|
1381
|
-
await this.checkpointer.save(
|
|
1428
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1382
1429
|
continue;
|
|
1383
1430
|
}
|
|
1384
1431
|
if (result.kind === "yield") {
|
|
@@ -1389,7 +1436,7 @@ var GraphExecutor = class {
|
|
|
1389
1436
|
checkpointCount
|
|
1390
1437
|
});
|
|
1391
1438
|
const cp2 = this.sanitize(state);
|
|
1392
|
-
await this.checkpointer.save(
|
|
1439
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1393
1440
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1394
1441
|
}
|
|
1395
1442
|
if (result.kind === "pause") {
|
|
@@ -1400,7 +1447,7 @@ var GraphExecutor = class {
|
|
|
1400
1447
|
checkpointCount
|
|
1401
1448
|
});
|
|
1402
1449
|
const cp2 = this.sanitize(state);
|
|
1403
|
-
await this.checkpointer.save(
|
|
1450
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1404
1451
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1405
1452
|
}
|
|
1406
1453
|
}
|
|
@@ -1411,8 +1458,8 @@ var GraphExecutor = class {
|
|
|
1411
1458
|
checkpointCount
|
|
1412
1459
|
});
|
|
1413
1460
|
const cp = this.sanitize(state);
|
|
1414
|
-
await this.checkpointer.save(
|
|
1415
|
-
this.ephemeralLocals.delete(
|
|
1461
|
+
await this.checkpointer.save(checkpointKey, cp);
|
|
1462
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1416
1463
|
return { events: allEvents, checkpoint: cp, stepCount };
|
|
1417
1464
|
}
|
|
1418
1465
|
};
|
|
@@ -1575,15 +1622,15 @@ function splitConcatenatedJsonObjects(input) {
|
|
|
1575
1622
|
}
|
|
1576
1623
|
|
|
1577
1624
|
// src/runtime-kernel/graph-engine/tick-pipeline/helpers.ts
|
|
1578
|
-
function
|
|
1625
|
+
function readNonEmptyString2(value) {
|
|
1579
1626
|
if (typeof value !== "string") return void 0;
|
|
1580
1627
|
const trimmed = value.trim();
|
|
1581
1628
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
1582
1629
|
}
|
|
1583
1630
|
function resolveConversationIdForRuntimeEvents(toolContext) {
|
|
1584
|
-
const fromCamel =
|
|
1631
|
+
const fromCamel = readNonEmptyString2(toolContext?.conversationId);
|
|
1585
1632
|
if (fromCamel) return fromCamel;
|
|
1586
|
-
const fromSnake = toolContext ?
|
|
1633
|
+
const fromSnake = toolContext ? readNonEmptyString2(toolContext["conversation_id"]) : void 0;
|
|
1587
1634
|
if (fromSnake) return fromSnake;
|
|
1588
1635
|
return generateMessageId();
|
|
1589
1636
|
}
|
|
@@ -1940,7 +1987,7 @@ var runModelLockMiddleware = async (ctx, stage, next) => {
|
|
|
1940
1987
|
if (stage.id !== "execute_llm") {
|
|
1941
1988
|
return;
|
|
1942
1989
|
}
|
|
1943
|
-
const normalized =
|
|
1990
|
+
const normalized = readNonEmptyString2(ctx.cloudQuotaFallbackAppliedModelId);
|
|
1944
1991
|
if (!normalized) {
|
|
1945
1992
|
return;
|
|
1946
1993
|
}
|
|
@@ -2528,7 +2575,7 @@ function createExecuteLlmStage(dependencies) {
|
|
|
2528
2575
|
streamEventHandler,
|
|
2529
2576
|
ctx.signal,
|
|
2530
2577
|
(fallbackModelId) => {
|
|
2531
|
-
ctx.cloudQuotaFallbackAppliedModelId =
|
|
2578
|
+
ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString2(fallbackModelId);
|
|
2532
2579
|
},
|
|
2533
2580
|
(info) => {
|
|
2534
2581
|
ctx.modelFallbackAudit = info;
|
|
@@ -2572,7 +2619,7 @@ function createPrepareCallStage(dependencies) {
|
|
|
2572
2619
|
return {
|
|
2573
2620
|
id: "prepare_call",
|
|
2574
2621
|
async run(ctx) {
|
|
2575
|
-
const lockedRunModelId =
|
|
2622
|
+
const lockedRunModelId = readNonEmptyString2(ctx.executorLocal?.runLockedModelId);
|
|
2576
2623
|
const requestedModelId = lockedRunModelId ?? ctx.request.model_id;
|
|
2577
2624
|
ctx.modelId = dependencies.modelResolver.resolveModelId(requestedModelId);
|
|
2578
2625
|
await emitAuditEnvelope(ctx.audit, {
|
|
@@ -2644,7 +2691,7 @@ var GraphAgentExecutor = class {
|
|
|
2644
2691
|
this.llmCaller = dependencies.llmCaller;
|
|
2645
2692
|
this.toolRuntime = dependencies.toolRuntime;
|
|
2646
2693
|
this.contextBuilder = dependencies.contextBuilder;
|
|
2647
|
-
this.cloudQuotaFallbackModelId =
|
|
2694
|
+
this.cloudQuotaFallbackModelId = readNonEmptyString2(dependencies.cloudQuotaFallbackModelId);
|
|
2648
2695
|
this.modelCatalog = dependencies.modelCatalog ?? createEmptyModelCatalog();
|
|
2649
2696
|
this.modelResolver = dependencies.modelResolver ?? new ModelResolver({
|
|
2650
2697
|
modelCatalog: this.modelCatalog
|
|
@@ -2692,7 +2739,7 @@ var GraphAgentExecutor = class {
|
|
|
2692
2739
|
llmMessages: [],
|
|
2693
2740
|
mode: input.request.mode === "chat" ? "chat" : "agent",
|
|
2694
2741
|
conversationId: resolveConversationIdForRuntimeEvents(input.toolContext),
|
|
2695
|
-
turnId:
|
|
2742
|
+
turnId: readNonEmptyString2(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
|
|
2696
2743
|
telemetry: this.telemetryPort,
|
|
2697
2744
|
audit: this.auditPort
|
|
2698
2745
|
};
|
|
@@ -2742,18 +2789,18 @@ function isSummarizationCallbacks(value) {
|
|
|
2742
2789
|
function isGraphSseSink(value) {
|
|
2743
2790
|
return typeof value === "function";
|
|
2744
2791
|
}
|
|
2745
|
-
function
|
|
2792
|
+
function readNonEmptyString3(value) {
|
|
2746
2793
|
if (typeof value !== "string") return void 0;
|
|
2747
2794
|
const trimmed = value.trim();
|
|
2748
2795
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
2749
2796
|
}
|
|
2750
2797
|
function readGraphAgentLocal(local) {
|
|
2751
2798
|
const source = local ?? {};
|
|
2752
|
-
const answerId =
|
|
2799
|
+
const answerId = readNonEmptyString3(source.answerId);
|
|
2753
2800
|
const chunkSeq = Number.isInteger(source.chunkSeq) ? Number(source.chunkSeq) : 0;
|
|
2754
2801
|
return {
|
|
2755
|
-
conversationId:
|
|
2756
|
-
turnId:
|
|
2802
|
+
conversationId: readNonEmptyString3(source.conversationId) ?? "",
|
|
2803
|
+
turnId: readNonEmptyString3(source.turnId),
|
|
2757
2804
|
request: isAgentInvocationRequest(source.request) ? source.request : void 0,
|
|
2758
2805
|
toolContext: isToolExecutionContext(source.toolContext) ? source.toolContext : void 0,
|
|
2759
2806
|
history: isRuntimeEventArray(source.history) ? source.history : [],
|
|
@@ -3518,7 +3565,7 @@ var LlmNode = class {
|
|
|
3518
3565
|
function isRecord8(value) {
|
|
3519
3566
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3520
3567
|
}
|
|
3521
|
-
function
|
|
3568
|
+
function readNonEmptyString4(value) {
|
|
3522
3569
|
if (typeof value !== "string") {
|
|
3523
3570
|
return void 0;
|
|
3524
3571
|
}
|
|
@@ -3540,7 +3587,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3540
3587
|
return void 0;
|
|
3541
3588
|
}
|
|
3542
3589
|
if (toolName === "write_report") {
|
|
3543
|
-
const report =
|
|
3590
|
+
const report = readNonEmptyString4(data.report);
|
|
3544
3591
|
if (!report) {
|
|
3545
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");
|
|
3546
3593
|
}
|
|
@@ -3550,7 +3597,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3550
3597
|
if (data.success !== true) {
|
|
3551
3598
|
return void 0;
|
|
3552
3599
|
}
|
|
3553
|
-
const finalAnswer =
|
|
3600
|
+
const finalAnswer = readNonEmptyString4(data.final_answer);
|
|
3554
3601
|
if (!finalAnswer) {
|
|
3555
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");
|
|
3556
3603
|
}
|
|
@@ -4884,12 +4931,12 @@ function asRecord(value) {
|
|
|
4884
4931
|
}
|
|
4885
4932
|
return value;
|
|
4886
4933
|
}
|
|
4887
|
-
function summarizeCheckpoint(
|
|
4934
|
+
function summarizeCheckpoint(checkpointKey, state, savedAt) {
|
|
4888
4935
|
const local = asRecord(state.local);
|
|
4889
4936
|
const executorLocal = asRecord(local?.executorLocal);
|
|
4890
4937
|
const pendingToolCalls = local?.pendingToolCalls;
|
|
4891
4938
|
return {
|
|
4892
|
-
|
|
4939
|
+
checkpointKey,
|
|
4893
4940
|
schemaVersion: state.schemaVersion ?? 1,
|
|
4894
4941
|
savedAt,
|
|
4895
4942
|
currentNode: state.nodeId,
|
|
@@ -4908,25 +4955,25 @@ var MemoryCheckpointer = class {
|
|
|
4908
4955
|
local: state.local && typeof state.local === "object" && !Array.isArray(state.local) ? { ...state.local } : state.local
|
|
4909
4956
|
};
|
|
4910
4957
|
}
|
|
4911
|
-
async load(
|
|
4912
|
-
const entry = this.store.get(
|
|
4958
|
+
async load(checkpointKey) {
|
|
4959
|
+
const entry = this.store.get(checkpointKey);
|
|
4913
4960
|
return entry ? this.cloneState(entry.state) : null;
|
|
4914
4961
|
}
|
|
4915
|
-
async save(
|
|
4916
|
-
this.store.set(
|
|
4962
|
+
async save(checkpointKey, state) {
|
|
4963
|
+
this.store.set(checkpointKey, {
|
|
4917
4964
|
state: this.cloneState(state),
|
|
4918
4965
|
savedAt: Date.now()
|
|
4919
4966
|
});
|
|
4920
4967
|
}
|
|
4921
|
-
async clear(
|
|
4922
|
-
this.store.delete(
|
|
4968
|
+
async clear(checkpointKey) {
|
|
4969
|
+
this.store.delete(checkpointKey);
|
|
4923
4970
|
}
|
|
4924
|
-
async peekMeta(
|
|
4925
|
-
const entry = this.store.get(
|
|
4926
|
-
return entry ? summarizeCheckpoint(
|
|
4971
|
+
async peekMeta(checkpointKey) {
|
|
4972
|
+
const entry = this.store.get(checkpointKey);
|
|
4973
|
+
return entry ? summarizeCheckpoint(checkpointKey, entry.state, entry.savedAt) : null;
|
|
4927
4974
|
}
|
|
4928
4975
|
async list(filter = {}) {
|
|
4929
|
-
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);
|
|
4930
4977
|
if (filter.limit === void 0) {
|
|
4931
4978
|
return summaries;
|
|
4932
4979
|
}
|
|
@@ -6466,7 +6513,7 @@ function cloneRunRecord(record) {
|
|
|
6466
6513
|
...record,
|
|
6467
6514
|
iterationBudget: record.iterationBudget ? { ...record.iterationBudget } : void 0,
|
|
6468
6515
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0,
|
|
6469
|
-
metadata: record.metadata ?
|
|
6516
|
+
metadata: record.metadata ? structuredClone(record.metadata) : void 0
|
|
6470
6517
|
};
|
|
6471
6518
|
}
|
|
6472
6519
|
function matchesStatus(candidate, filter) {
|
|
@@ -6878,7 +6925,7 @@ function isTerminalStatus(status) {
|
|
|
6878
6925
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
6879
6926
|
}
|
|
6880
6927
|
function cloneMetadata(metadata) {
|
|
6881
|
-
return metadata ?
|
|
6928
|
+
return metadata ? structuredClone(metadata) : void 0;
|
|
6882
6929
|
}
|
|
6883
6930
|
function recordToSnapshot(record) {
|
|
6884
6931
|
return {
|
|
@@ -6965,7 +7012,7 @@ var DefaultRunSupervisor = class {
|
|
|
6965
7012
|
startedAt,
|
|
6966
7013
|
updatedAt: startedAt,
|
|
6967
7014
|
iterationBudget: spec.iterationBudget ? { ...spec.iterationBudget } : void 0,
|
|
6968
|
-
metadata: spec.metadata
|
|
7015
|
+
metadata: cloneMetadata(spec.metadata)
|
|
6969
7016
|
};
|
|
6970
7017
|
await this.registryStore.save(record);
|
|
6971
7018
|
const handle = new DefaultRunHandle({
|
|
@@ -7139,12 +7186,13 @@ var DefaultRunSupervisor = class {
|
|
|
7139
7186
|
}
|
|
7140
7187
|
try {
|
|
7141
7188
|
await handle.markRunning({ currentNode: "detached" });
|
|
7189
|
+
const registeredRecord = await this.registryStore.load(handle.runId);
|
|
7142
7190
|
const executorOutcome = await this.executor.execute({
|
|
7143
7191
|
runId: handle.runId,
|
|
7144
|
-
parentRunId:
|
|
7145
|
-
conversationId: spec.conversationId,
|
|
7146
|
-
agentSpec: spec
|
|
7147
|
-
request:
|
|
7192
|
+
parentRunId: handle.parentRunId,
|
|
7193
|
+
conversationId: registeredRecord?.conversationId ?? spec.conversationId,
|
|
7194
|
+
agentSpec: await handle.spec(),
|
|
7195
|
+
request: await handle.request(),
|
|
7148
7196
|
signal: handle.signal,
|
|
7149
7197
|
eventBus: spec.eventBus,
|
|
7150
7198
|
eventStore: spec.eventStore,
|
|
@@ -7153,7 +7201,7 @@ var DefaultRunSupervisor = class {
|
|
|
7153
7201
|
contextFences: spec.contextFences,
|
|
7154
7202
|
wakeSource: spec.wakeSource,
|
|
7155
7203
|
ephemeral: spec.ephemeral,
|
|
7156
|
-
metadata: spec.metadata
|
|
7204
|
+
metadata: cloneMetadata(registeredRecord?.metadata ?? spec.metadata)
|
|
7157
7205
|
});
|
|
7158
7206
|
const outcome = await this.persistExecutorOutcome(handle, executorOutcome);
|
|
7159
7207
|
this.notifyTerminalWaiters(outcome);
|
|
@@ -7217,10 +7265,14 @@ var DefaultRunSupervisor = class {
|
|
|
7217
7265
|
await this.registryStore.save(record);
|
|
7218
7266
|
}
|
|
7219
7267
|
const completedAt = executorOutcome?.completedAt ?? this.now();
|
|
7268
|
+
const fallbackMeta = record ? void 0 : await handle.meta();
|
|
7220
7269
|
const outcome = recordToTerminalOutcome(record ?? {
|
|
7221
7270
|
runId: handle.runId,
|
|
7222
7271
|
parentRunId: handle.parentRunId,
|
|
7223
|
-
|
|
7272
|
+
conversationId: fallbackMeta?.conversationId ?? "",
|
|
7273
|
+
agentSpecId: fallbackMeta?.agentSpecId,
|
|
7274
|
+
status: executorOutcome?.status ?? "completed",
|
|
7275
|
+
startedAt: fallbackMeta?.startedAt ?? completedAt}, completedAt);
|
|
7224
7276
|
const nextOutcome = {
|
|
7225
7277
|
...outcome,
|
|
7226
7278
|
metadata: {
|
|
@@ -7548,6 +7600,7 @@ async function emitRunEvent(event, sink) {
|
|
|
7548
7600
|
async function runAgent(agent, options) {
|
|
7549
7601
|
const modelId = resolveModelId(agent, options);
|
|
7550
7602
|
const conversationId = options.conversationId ?? `conv_${Date.now()}`;
|
|
7603
|
+
const checkpointKey = conversationId;
|
|
7551
7604
|
const runId = options.runId ?? generateRunId();
|
|
7552
7605
|
const turnId = runId;
|
|
7553
7606
|
const costCollector = new QuickstartRunCostCollector();
|
|
@@ -7602,7 +7655,7 @@ async function runAgent(agent, options) {
|
|
|
7602
7655
|
};
|
|
7603
7656
|
await handle.markRunning({ currentNode: "user" });
|
|
7604
7657
|
try {
|
|
7605
|
-
await executor.prime(
|
|
7658
|
+
await executor.prime(checkpointKey, {
|
|
7606
7659
|
conversationId,
|
|
7607
7660
|
turnId,
|
|
7608
7661
|
request: {
|
|
@@ -7627,7 +7680,7 @@ async function runAgent(agent, options) {
|
|
|
7627
7680
|
return void 0;
|
|
7628
7681
|
}
|
|
7629
7682
|
});
|
|
7630
|
-
const result = await executor.runUntilYield(
|
|
7683
|
+
const result = await executor.runUntilYield(checkpointKey);
|
|
7631
7684
|
runtimeEvents.push(...result.events);
|
|
7632
7685
|
for (const event of result.events) {
|
|
7633
7686
|
if (event.type === "final_answer_chunk") continue;
|
|
@@ -7790,7 +7843,7 @@ function createQuickstartTemplateFiles(projectName) {
|
|
|
7790
7843
|
start: 'linnkit run hello --input "\u4F60\u597D\uFF0C\u4ECB\u7ECD\u4E00\u4E0B\u4F60\u81EA\u5DF1"'
|
|
7791
7844
|
},
|
|
7792
7845
|
dependencies: {
|
|
7793
|
-
"@linnlabs/linnkit": "^0.
|
|
7846
|
+
"@linnlabs/linnkit": "^0.10.0",
|
|
7794
7847
|
zod: "^3.22.0"
|
|
7795
7848
|
},
|
|
7796
7849
|
devDependencies: {}
|