@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.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(),
|
|
@@ -1081,6 +1082,7 @@ var Logger = class {
|
|
|
1081
1082
|
constructor(moduleName) {
|
|
1082
1083
|
this.moduleName = moduleName;
|
|
1083
1084
|
}
|
|
1085
|
+
moduleName;
|
|
1084
1086
|
debug(message, data) {
|
|
1085
1087
|
this.log(0 /* DEBUG */, "debug", message, data);
|
|
1086
1088
|
}
|
|
@@ -1153,6 +1155,17 @@ var logger = new Logger("GraphExecutor");
|
|
|
1153
1155
|
function asLocalRecord(local) {
|
|
1154
1156
|
return local && typeof local === "object" ? { ...local } : {};
|
|
1155
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
|
+
}
|
|
1156
1169
|
var GraphExecutor = class {
|
|
1157
1170
|
constructor(checkpointer, config = {}) {
|
|
1158
1171
|
this.checkpointer = checkpointer;
|
|
@@ -1162,6 +1175,7 @@ var GraphExecutor = class {
|
|
|
1162
1175
|
};
|
|
1163
1176
|
this.telemetryPort = config.telemetryPort ?? noopTelemetry;
|
|
1164
1177
|
}
|
|
1178
|
+
checkpointer;
|
|
1165
1179
|
nodes = /* @__PURE__ */ new Map();
|
|
1166
1180
|
ephemeralLocals = /* @__PURE__ */ new Map();
|
|
1167
1181
|
config;
|
|
@@ -1169,8 +1183,8 @@ var GraphExecutor = class {
|
|
|
1169
1183
|
registerNode(node) {
|
|
1170
1184
|
this.nodes.set(node.id, node);
|
|
1171
1185
|
}
|
|
1172
|
-
async peekCheckpoint(
|
|
1173
|
-
return await this.checkpointer.load(
|
|
1186
|
+
async peekCheckpoint(checkpointKey) {
|
|
1187
|
+
return await this.checkpointer.load(checkpointKey);
|
|
1174
1188
|
}
|
|
1175
1189
|
sanitize(state) {
|
|
1176
1190
|
const local = asLocalRecord(state.local);
|
|
@@ -1182,8 +1196,8 @@ var GraphExecutor = class {
|
|
|
1182
1196
|
local
|
|
1183
1197
|
};
|
|
1184
1198
|
}
|
|
1185
|
-
async prime(
|
|
1186
|
-
this.ephemeralLocals.set(
|
|
1199
|
+
async prime(checkpointKey, local, nodeId = "user") {
|
|
1200
|
+
this.ephemeralLocals.set(checkpointKey, { ...local || {} });
|
|
1187
1201
|
const localSansMemory = { ...local || {} };
|
|
1188
1202
|
if ("memory" in localSansMemory) delete localSansMemory.memory;
|
|
1189
1203
|
const state = {
|
|
@@ -1191,10 +1205,10 @@ var GraphExecutor = class {
|
|
|
1191
1205
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1192
1206
|
local: localSansMemory
|
|
1193
1207
|
};
|
|
1194
|
-
await this.checkpointer.save(
|
|
1208
|
+
await this.checkpointer.save(checkpointKey, state);
|
|
1195
1209
|
}
|
|
1196
|
-
async setNode(
|
|
1197
|
-
const current = await this.checkpointer.load(
|
|
1210
|
+
async setNode(checkpointKey, nodeId, localPatch) {
|
|
1211
|
+
const current = await this.checkpointer.load(checkpointKey) || {
|
|
1198
1212
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1199
1213
|
local: {}
|
|
1200
1214
|
};
|
|
@@ -1205,19 +1219,46 @@ var GraphExecutor = class {
|
|
|
1205
1219
|
schemaVersion: current.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
1206
1220
|
local: mergedLocal
|
|
1207
1221
|
};
|
|
1208
|
-
await this.checkpointer.save(
|
|
1222
|
+
await this.checkpointer.save(checkpointKey, next);
|
|
1209
1223
|
}
|
|
1210
|
-
async runUntilYield(
|
|
1224
|
+
async runUntilYield(checkpointKey) {
|
|
1211
1225
|
const runId = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1212
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);
|
|
1213
1248
|
this.telemetryPort.emit({
|
|
1214
1249
|
kind: "run_lifecycle",
|
|
1215
1250
|
runId,
|
|
1216
1251
|
phase: "spawned",
|
|
1217
|
-
scope: {
|
|
1252
|
+
scope: {
|
|
1253
|
+
conversationId: lifecycleConversationId,
|
|
1254
|
+
turnId: lifecycleTurnId
|
|
1255
|
+
}
|
|
1218
1256
|
});
|
|
1219
1257
|
try {
|
|
1220
|
-
|
|
1258
|
+
const result = await this.runUntilYieldInternal(checkpointKey, initialState);
|
|
1259
|
+
lifecycleConversationId = readRuntimeConversationId(result.checkpoint);
|
|
1260
|
+
lifecycleTurnId = readRuntimeTurnId(result.checkpoint);
|
|
1261
|
+
return result;
|
|
1221
1262
|
} catch (err) {
|
|
1222
1263
|
lifecyclePhase = err?.name === "AbortError" ? "cancelled" : "failed";
|
|
1223
1264
|
throw err;
|
|
@@ -1226,17 +1267,23 @@ var GraphExecutor = class {
|
|
|
1226
1267
|
kind: "run_lifecycle",
|
|
1227
1268
|
runId,
|
|
1228
1269
|
phase: lifecyclePhase,
|
|
1229
|
-
scope: {
|
|
1270
|
+
scope: {
|
|
1271
|
+
conversationId: lifecycleConversationId,
|
|
1272
|
+
turnId: lifecycleTurnId
|
|
1273
|
+
}
|
|
1230
1274
|
});
|
|
1231
1275
|
}
|
|
1232
1276
|
}
|
|
1233
|
-
async
|
|
1234
|
-
|
|
1277
|
+
async loadInitialState(checkpointKey) {
|
|
1278
|
+
return await this.checkpointer.load(checkpointKey) || {
|
|
1235
1279
|
nodeId: "user",
|
|
1236
1280
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1237
1281
|
local: {}
|
|
1238
1282
|
};
|
|
1239
|
-
|
|
1283
|
+
}
|
|
1284
|
+
async runUntilYieldInternal(checkpointKey, initialState) {
|
|
1285
|
+
let state = initialState;
|
|
1286
|
+
const ephemeral = this.ephemeralLocals.get(checkpointKey) || {};
|
|
1240
1287
|
state = {
|
|
1241
1288
|
...state,
|
|
1242
1289
|
schemaVersion: state.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
@@ -1265,7 +1312,7 @@ var GraphExecutor = class {
|
|
|
1265
1312
|
const signalRaw = state.local?.signal;
|
|
1266
1313
|
if (isAbortSignal2(signalRaw) && signalRaw.aborted) {
|
|
1267
1314
|
logger.warn("[GraphExecutor] \u6536\u5230 AbortSignal\uFF0C\u7ACB\u5373\u505C\u6B62\u63A8\u7406\u5FAA\u73AF");
|
|
1268
|
-
this.ephemeralLocals.delete(
|
|
1315
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1269
1316
|
throwAbortError();
|
|
1270
1317
|
}
|
|
1271
1318
|
const isLastStep = cycleStepCount >= this.config.maxSteps;
|
|
@@ -1313,8 +1360,8 @@ var GraphExecutor = class {
|
|
|
1313
1360
|
checkpointCount
|
|
1314
1361
|
});
|
|
1315
1362
|
const cp2 = this.sanitize(state);
|
|
1316
|
-
await this.checkpointer.save(
|
|
1317
|
-
this.ephemeralLocals.delete(
|
|
1363
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1364
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1318
1365
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1319
1366
|
}
|
|
1320
1367
|
logger.info("[GraphExecutor] \u8282\u70B9\u5207\u6362", {
|
|
@@ -1325,18 +1372,18 @@ var GraphExecutor = class {
|
|
|
1325
1372
|
});
|
|
1326
1373
|
const nodeRunStartedAt = Date.now();
|
|
1327
1374
|
const nodeIdForTelemetry = state.nodeId;
|
|
1375
|
+
const conversationIdForTelemetry = readRuntimeConversationId(state);
|
|
1328
1376
|
let result;
|
|
1329
1377
|
try {
|
|
1330
1378
|
result = await node.run(state);
|
|
1331
1379
|
} finally {
|
|
1332
|
-
const turnIdForTelemetry = typeof state.local?.turnId === "string" ? state.local.turnId : void 0;
|
|
1333
1380
|
this.telemetryPort.emit({
|
|
1334
1381
|
kind: "graph_node",
|
|
1335
1382
|
nodeId: nodeIdForTelemetry,
|
|
1336
1383
|
durationMs: Date.now() - nodeRunStartedAt,
|
|
1337
1384
|
scope: {
|
|
1338
|
-
conversationId:
|
|
1339
|
-
turnId:
|
|
1385
|
+
conversationId: conversationIdForTelemetry,
|
|
1386
|
+
turnId: readRuntimeTurnId(state)
|
|
1340
1387
|
}
|
|
1341
1388
|
});
|
|
1342
1389
|
}
|
|
@@ -1375,7 +1422,7 @@ var GraphExecutor = class {
|
|
|
1375
1422
|
});
|
|
1376
1423
|
state = { ...state, nodeId: nextNodeId };
|
|
1377
1424
|
const cp2 = this.sanitize(state);
|
|
1378
|
-
await this.checkpointer.save(
|
|
1425
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1379
1426
|
continue;
|
|
1380
1427
|
}
|
|
1381
1428
|
if (result.kind === "yield") {
|
|
@@ -1386,7 +1433,7 @@ var GraphExecutor = class {
|
|
|
1386
1433
|
checkpointCount
|
|
1387
1434
|
});
|
|
1388
1435
|
const cp2 = this.sanitize(state);
|
|
1389
|
-
await this.checkpointer.save(
|
|
1436
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1390
1437
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1391
1438
|
}
|
|
1392
1439
|
if (result.kind === "pause") {
|
|
@@ -1397,7 +1444,7 @@ var GraphExecutor = class {
|
|
|
1397
1444
|
checkpointCount
|
|
1398
1445
|
});
|
|
1399
1446
|
const cp2 = this.sanitize(state);
|
|
1400
|
-
await this.checkpointer.save(
|
|
1447
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1401
1448
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1402
1449
|
}
|
|
1403
1450
|
}
|
|
@@ -1408,8 +1455,8 @@ var GraphExecutor = class {
|
|
|
1408
1455
|
checkpointCount
|
|
1409
1456
|
});
|
|
1410
1457
|
const cp = this.sanitize(state);
|
|
1411
|
-
await this.checkpointer.save(
|
|
1412
|
-
this.ephemeralLocals.delete(
|
|
1458
|
+
await this.checkpointer.save(checkpointKey, cp);
|
|
1459
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1413
1460
|
return { events: allEvents, checkpoint: cp, stepCount };
|
|
1414
1461
|
}
|
|
1415
1462
|
};
|
|
@@ -1572,15 +1619,15 @@ function splitConcatenatedJsonObjects(input) {
|
|
|
1572
1619
|
}
|
|
1573
1620
|
|
|
1574
1621
|
// src/runtime-kernel/graph-engine/tick-pipeline/helpers.ts
|
|
1575
|
-
function
|
|
1622
|
+
function readNonEmptyString2(value) {
|
|
1576
1623
|
if (typeof value !== "string") return void 0;
|
|
1577
1624
|
const trimmed = value.trim();
|
|
1578
1625
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
1579
1626
|
}
|
|
1580
1627
|
function resolveConversationIdForRuntimeEvents(toolContext) {
|
|
1581
|
-
const fromCamel =
|
|
1628
|
+
const fromCamel = readNonEmptyString2(toolContext?.conversationId);
|
|
1582
1629
|
if (fromCamel) return fromCamel;
|
|
1583
|
-
const fromSnake = toolContext ?
|
|
1630
|
+
const fromSnake = toolContext ? readNonEmptyString2(toolContext["conversation_id"]) : void 0;
|
|
1584
1631
|
if (fromSnake) return fromSnake;
|
|
1585
1632
|
return generateMessageId();
|
|
1586
1633
|
}
|
|
@@ -1937,7 +1984,7 @@ var runModelLockMiddleware = async (ctx, stage, next) => {
|
|
|
1937
1984
|
if (stage.id !== "execute_llm") {
|
|
1938
1985
|
return;
|
|
1939
1986
|
}
|
|
1940
|
-
const normalized =
|
|
1987
|
+
const normalized = readNonEmptyString2(ctx.cloudQuotaFallbackAppliedModelId);
|
|
1941
1988
|
if (!normalized) {
|
|
1942
1989
|
return;
|
|
1943
1990
|
}
|
|
@@ -2525,7 +2572,7 @@ function createExecuteLlmStage(dependencies) {
|
|
|
2525
2572
|
streamEventHandler,
|
|
2526
2573
|
ctx.signal,
|
|
2527
2574
|
(fallbackModelId) => {
|
|
2528
|
-
ctx.cloudQuotaFallbackAppliedModelId =
|
|
2575
|
+
ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString2(fallbackModelId);
|
|
2529
2576
|
},
|
|
2530
2577
|
(info) => {
|
|
2531
2578
|
ctx.modelFallbackAudit = info;
|
|
@@ -2569,7 +2616,7 @@ function createPrepareCallStage(dependencies) {
|
|
|
2569
2616
|
return {
|
|
2570
2617
|
id: "prepare_call",
|
|
2571
2618
|
async run(ctx) {
|
|
2572
|
-
const lockedRunModelId =
|
|
2619
|
+
const lockedRunModelId = readNonEmptyString2(ctx.executorLocal?.runLockedModelId);
|
|
2573
2620
|
const requestedModelId = lockedRunModelId ?? ctx.request.model_id;
|
|
2574
2621
|
ctx.modelId = dependencies.modelResolver.resolveModelId(requestedModelId);
|
|
2575
2622
|
await emitAuditEnvelope(ctx.audit, {
|
|
@@ -2641,7 +2688,7 @@ var GraphAgentExecutor = class {
|
|
|
2641
2688
|
this.llmCaller = dependencies.llmCaller;
|
|
2642
2689
|
this.toolRuntime = dependencies.toolRuntime;
|
|
2643
2690
|
this.contextBuilder = dependencies.contextBuilder;
|
|
2644
|
-
this.cloudQuotaFallbackModelId =
|
|
2691
|
+
this.cloudQuotaFallbackModelId = readNonEmptyString2(dependencies.cloudQuotaFallbackModelId);
|
|
2645
2692
|
this.modelCatalog = dependencies.modelCatalog ?? createEmptyModelCatalog();
|
|
2646
2693
|
this.modelResolver = dependencies.modelResolver ?? new ModelResolver({
|
|
2647
2694
|
modelCatalog: this.modelCatalog
|
|
@@ -2689,7 +2736,7 @@ var GraphAgentExecutor = class {
|
|
|
2689
2736
|
llmMessages: [],
|
|
2690
2737
|
mode: input.request.mode === "chat" ? "chat" : "agent",
|
|
2691
2738
|
conversationId: resolveConversationIdForRuntimeEvents(input.toolContext),
|
|
2692
|
-
turnId:
|
|
2739
|
+
turnId: readNonEmptyString2(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
|
|
2693
2740
|
telemetry: this.telemetryPort,
|
|
2694
2741
|
audit: this.auditPort
|
|
2695
2742
|
};
|
|
@@ -2739,18 +2786,18 @@ function isSummarizationCallbacks(value) {
|
|
|
2739
2786
|
function isGraphSseSink(value) {
|
|
2740
2787
|
return typeof value === "function";
|
|
2741
2788
|
}
|
|
2742
|
-
function
|
|
2789
|
+
function readNonEmptyString3(value) {
|
|
2743
2790
|
if (typeof value !== "string") return void 0;
|
|
2744
2791
|
const trimmed = value.trim();
|
|
2745
2792
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
2746
2793
|
}
|
|
2747
2794
|
function readGraphAgentLocal(local) {
|
|
2748
2795
|
const source = local ?? {};
|
|
2749
|
-
const answerId =
|
|
2796
|
+
const answerId = readNonEmptyString3(source.answerId);
|
|
2750
2797
|
const chunkSeq = Number.isInteger(source.chunkSeq) ? Number(source.chunkSeq) : 0;
|
|
2751
2798
|
return {
|
|
2752
|
-
conversationId:
|
|
2753
|
-
turnId:
|
|
2799
|
+
conversationId: readNonEmptyString3(source.conversationId) ?? "",
|
|
2800
|
+
turnId: readNonEmptyString3(source.turnId),
|
|
2754
2801
|
request: isAgentInvocationRequest(source.request) ? source.request : void 0,
|
|
2755
2802
|
toolContext: isToolExecutionContext(source.toolContext) ? source.toolContext : void 0,
|
|
2756
2803
|
history: isRuntimeEventArray(source.history) ? source.history : [],
|
|
@@ -3515,7 +3562,7 @@ var LlmNode = class {
|
|
|
3515
3562
|
function isRecord8(value) {
|
|
3516
3563
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3517
3564
|
}
|
|
3518
|
-
function
|
|
3565
|
+
function readNonEmptyString4(value) {
|
|
3519
3566
|
if (typeof value !== "string") {
|
|
3520
3567
|
return void 0;
|
|
3521
3568
|
}
|
|
@@ -3537,7 +3584,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3537
3584
|
return void 0;
|
|
3538
3585
|
}
|
|
3539
3586
|
if (toolName === "write_report") {
|
|
3540
|
-
const report =
|
|
3587
|
+
const report = readNonEmptyString4(data.report);
|
|
3541
3588
|
if (!report) {
|
|
3542
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");
|
|
3543
3590
|
}
|
|
@@ -3547,7 +3594,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3547
3594
|
if (data.success !== true) {
|
|
3548
3595
|
return void 0;
|
|
3549
3596
|
}
|
|
3550
|
-
const finalAnswer =
|
|
3597
|
+
const finalAnswer = readNonEmptyString4(data.final_answer);
|
|
3551
3598
|
if (!finalAnswer) {
|
|
3552
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");
|
|
3553
3600
|
}
|
|
@@ -4881,12 +4928,12 @@ function asRecord(value) {
|
|
|
4881
4928
|
}
|
|
4882
4929
|
return value;
|
|
4883
4930
|
}
|
|
4884
|
-
function summarizeCheckpoint(
|
|
4931
|
+
function summarizeCheckpoint(checkpointKey, state, savedAt) {
|
|
4885
4932
|
const local = asRecord(state.local);
|
|
4886
4933
|
const executorLocal = asRecord(local?.executorLocal);
|
|
4887
4934
|
const pendingToolCalls = local?.pendingToolCalls;
|
|
4888
4935
|
return {
|
|
4889
|
-
|
|
4936
|
+
checkpointKey,
|
|
4890
4937
|
schemaVersion: state.schemaVersion ?? 1,
|
|
4891
4938
|
savedAt,
|
|
4892
4939
|
currentNode: state.nodeId,
|
|
@@ -4905,25 +4952,25 @@ var MemoryCheckpointer = class {
|
|
|
4905
4952
|
local: state.local && typeof state.local === "object" && !Array.isArray(state.local) ? { ...state.local } : state.local
|
|
4906
4953
|
};
|
|
4907
4954
|
}
|
|
4908
|
-
async load(
|
|
4909
|
-
const entry = this.store.get(
|
|
4955
|
+
async load(checkpointKey) {
|
|
4956
|
+
const entry = this.store.get(checkpointKey);
|
|
4910
4957
|
return entry ? this.cloneState(entry.state) : null;
|
|
4911
4958
|
}
|
|
4912
|
-
async save(
|
|
4913
|
-
this.store.set(
|
|
4959
|
+
async save(checkpointKey, state) {
|
|
4960
|
+
this.store.set(checkpointKey, {
|
|
4914
4961
|
state: this.cloneState(state),
|
|
4915
4962
|
savedAt: Date.now()
|
|
4916
4963
|
});
|
|
4917
4964
|
}
|
|
4918
|
-
async clear(
|
|
4919
|
-
this.store.delete(
|
|
4965
|
+
async clear(checkpointKey) {
|
|
4966
|
+
this.store.delete(checkpointKey);
|
|
4920
4967
|
}
|
|
4921
|
-
async peekMeta(
|
|
4922
|
-
const entry = this.store.get(
|
|
4923
|
-
return entry ? summarizeCheckpoint(
|
|
4968
|
+
async peekMeta(checkpointKey) {
|
|
4969
|
+
const entry = this.store.get(checkpointKey);
|
|
4970
|
+
return entry ? summarizeCheckpoint(checkpointKey, entry.state, entry.savedAt) : null;
|
|
4924
4971
|
}
|
|
4925
4972
|
async list(filter = {}) {
|
|
4926
|
-
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);
|
|
4927
4974
|
if (filter.limit === void 0) {
|
|
4928
4975
|
return summaries;
|
|
4929
4976
|
}
|
|
@@ -6463,7 +6510,7 @@ function cloneRunRecord(record) {
|
|
|
6463
6510
|
...record,
|
|
6464
6511
|
iterationBudget: record.iterationBudget ? { ...record.iterationBudget } : void 0,
|
|
6465
6512
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0,
|
|
6466
|
-
metadata: record.metadata ?
|
|
6513
|
+
metadata: record.metadata ? structuredClone(record.metadata) : void 0
|
|
6467
6514
|
};
|
|
6468
6515
|
}
|
|
6469
6516
|
function matchesStatus(candidate, filter) {
|
|
@@ -6875,7 +6922,7 @@ function isTerminalStatus(status) {
|
|
|
6875
6922
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
6876
6923
|
}
|
|
6877
6924
|
function cloneMetadata(metadata) {
|
|
6878
|
-
return metadata ?
|
|
6925
|
+
return metadata ? structuredClone(metadata) : void 0;
|
|
6879
6926
|
}
|
|
6880
6927
|
function recordToSnapshot(record) {
|
|
6881
6928
|
return {
|
|
@@ -6962,7 +7009,7 @@ var DefaultRunSupervisor = class {
|
|
|
6962
7009
|
startedAt,
|
|
6963
7010
|
updatedAt: startedAt,
|
|
6964
7011
|
iterationBudget: spec.iterationBudget ? { ...spec.iterationBudget } : void 0,
|
|
6965
|
-
metadata: spec.metadata
|
|
7012
|
+
metadata: cloneMetadata(spec.metadata)
|
|
6966
7013
|
};
|
|
6967
7014
|
await this.registryStore.save(record);
|
|
6968
7015
|
const handle = new DefaultRunHandle({
|
|
@@ -7136,12 +7183,13 @@ var DefaultRunSupervisor = class {
|
|
|
7136
7183
|
}
|
|
7137
7184
|
try {
|
|
7138
7185
|
await handle.markRunning({ currentNode: "detached" });
|
|
7186
|
+
const registeredRecord = await this.registryStore.load(handle.runId);
|
|
7139
7187
|
const executorOutcome = await this.executor.execute({
|
|
7140
7188
|
runId: handle.runId,
|
|
7141
|
-
parentRunId:
|
|
7142
|
-
conversationId: spec.conversationId,
|
|
7143
|
-
agentSpec: spec
|
|
7144
|
-
request:
|
|
7189
|
+
parentRunId: handle.parentRunId,
|
|
7190
|
+
conversationId: registeredRecord?.conversationId ?? spec.conversationId,
|
|
7191
|
+
agentSpec: await handle.spec(),
|
|
7192
|
+
request: await handle.request(),
|
|
7145
7193
|
signal: handle.signal,
|
|
7146
7194
|
eventBus: spec.eventBus,
|
|
7147
7195
|
eventStore: spec.eventStore,
|
|
@@ -7150,7 +7198,7 @@ var DefaultRunSupervisor = class {
|
|
|
7150
7198
|
contextFences: spec.contextFences,
|
|
7151
7199
|
wakeSource: spec.wakeSource,
|
|
7152
7200
|
ephemeral: spec.ephemeral,
|
|
7153
|
-
metadata: spec.metadata
|
|
7201
|
+
metadata: cloneMetadata(registeredRecord?.metadata ?? spec.metadata)
|
|
7154
7202
|
});
|
|
7155
7203
|
const outcome = await this.persistExecutorOutcome(handle, executorOutcome);
|
|
7156
7204
|
this.notifyTerminalWaiters(outcome);
|
|
@@ -7214,10 +7262,14 @@ var DefaultRunSupervisor = class {
|
|
|
7214
7262
|
await this.registryStore.save(record);
|
|
7215
7263
|
}
|
|
7216
7264
|
const completedAt = executorOutcome?.completedAt ?? this.now();
|
|
7265
|
+
const fallbackMeta = record ? void 0 : await handle.meta();
|
|
7217
7266
|
const outcome = recordToTerminalOutcome(record ?? {
|
|
7218
7267
|
runId: handle.runId,
|
|
7219
7268
|
parentRunId: handle.parentRunId,
|
|
7220
|
-
|
|
7269
|
+
conversationId: fallbackMeta?.conversationId ?? "",
|
|
7270
|
+
agentSpecId: fallbackMeta?.agentSpecId,
|
|
7271
|
+
status: executorOutcome?.status ?? "completed",
|
|
7272
|
+
startedAt: fallbackMeta?.startedAt ?? completedAt}, completedAt);
|
|
7221
7273
|
const nextOutcome = {
|
|
7222
7274
|
...outcome,
|
|
7223
7275
|
metadata: {
|
|
@@ -7545,6 +7597,7 @@ async function emitRunEvent(event, sink) {
|
|
|
7545
7597
|
async function runAgent(agent, options) {
|
|
7546
7598
|
const modelId = resolveModelId(agent, options);
|
|
7547
7599
|
const conversationId = options.conversationId ?? `conv_${Date.now()}`;
|
|
7600
|
+
const checkpointKey = conversationId;
|
|
7548
7601
|
const runId = options.runId ?? generateRunId();
|
|
7549
7602
|
const turnId = runId;
|
|
7550
7603
|
const costCollector = new QuickstartRunCostCollector();
|
|
@@ -7599,7 +7652,7 @@ async function runAgent(agent, options) {
|
|
|
7599
7652
|
};
|
|
7600
7653
|
await handle.markRunning({ currentNode: "user" });
|
|
7601
7654
|
try {
|
|
7602
|
-
await executor.prime(
|
|
7655
|
+
await executor.prime(checkpointKey, {
|
|
7603
7656
|
conversationId,
|
|
7604
7657
|
turnId,
|
|
7605
7658
|
request: {
|
|
@@ -7624,7 +7677,7 @@ async function runAgent(agent, options) {
|
|
|
7624
7677
|
return void 0;
|
|
7625
7678
|
}
|
|
7626
7679
|
});
|
|
7627
|
-
const result = await executor.runUntilYield(
|
|
7680
|
+
const result = await executor.runUntilYield(checkpointKey);
|
|
7628
7681
|
runtimeEvents.push(...result.events);
|
|
7629
7682
|
for (const event of result.events) {
|
|
7630
7683
|
if (event.type === "final_answer_chunk") continue;
|
|
@@ -7787,7 +7840,7 @@ function createQuickstartTemplateFiles(projectName) {
|
|
|
7787
7840
|
start: 'linnkit run hello --input "\u4F60\u597D\uFF0C\u4ECB\u7ECD\u4E00\u4E0B\u4F60\u81EA\u5DF1"'
|
|
7788
7841
|
},
|
|
7789
7842
|
dependencies: {
|
|
7790
|
-
"@linnlabs/linnkit": "^0.
|
|
7843
|
+
"@linnlabs/linnkit": "^0.10.0",
|
|
7791
7844
|
zod: "^3.22.0"
|
|
7792
7845
|
},
|
|
7793
7846
|
devDependencies: {}
|