@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/index.js
CHANGED
|
@@ -46,14 +46,18 @@ __export(runtime_kernel_exports, {
|
|
|
46
46
|
UserNode: () => UserNode,
|
|
47
47
|
WaitUserNode: () => WaitUserNode,
|
|
48
48
|
agentHasToolTrigger: () => agentHasToolTrigger,
|
|
49
|
+
appendStreamingProviderReasoningDetails: () => appendStreamingProviderReasoningDetails,
|
|
49
50
|
applySystemReminders: () => applySystemReminders,
|
|
50
51
|
audit: () => audit_exports,
|
|
51
52
|
budgetWarningTrigger: () => budgetWarningTrigger,
|
|
52
53
|
childRunTrace: () => child_run_trace_exports,
|
|
53
54
|
childRuns: () => child_runs_exports,
|
|
55
|
+
compactProviderReasoningDetails: () => compactProviderReasoningDetails,
|
|
56
|
+
compactReasoningDetailsInValue: () => compactReasoningDetailsInValue,
|
|
54
57
|
computeToolIdempotencyKey: () => computeToolIdempotencyKey,
|
|
55
58
|
consoleAudit: () => consoleAudit,
|
|
56
59
|
contextBudgetWarningTemplate: () => contextBudgetWarningTemplate,
|
|
60
|
+
copyToolContextRuntimeCapability: () => copyToolContextRuntimeCapability,
|
|
57
61
|
countToolCallsInCurrentRequest: () => countToolCallsInCurrentRequest,
|
|
58
62
|
createCompositeAudit: () => createCompositeAudit,
|
|
59
63
|
createConsoleAudit: () => createConsoleAudit,
|
|
@@ -559,6 +563,7 @@ var AgentSpecBudgetPolicy = z.object({
|
|
|
559
563
|
});
|
|
560
564
|
var AgentSpecToolHistoryPolicy = z.object({
|
|
561
565
|
strategy: z.enum(["per-pair", "per-run", "none"]).optional(),
|
|
566
|
+
retentionMode: z.enum(["drop", "compress"]).optional(),
|
|
562
567
|
keepLatestToolPairs: z.number().int().nonnegative().optional(),
|
|
563
568
|
keepLatestRuns: z.number().int().nonnegative().optional(),
|
|
564
569
|
maxInteractionGroups: z.number().int().nonnegative().optional(),
|
|
@@ -681,12 +686,13 @@ var AgentSpecContextPolicy = z.object({
|
|
|
681
686
|
var DEFAULT_CONTEXT_POLICY = {
|
|
682
687
|
profileId: "agent",
|
|
683
688
|
budget: {
|
|
684
|
-
maxTokens:
|
|
689
|
+
maxTokens: 232e3,
|
|
685
690
|
reservedForResponse: 2400,
|
|
686
691
|
workingMemoryBudgetPercentage: 0.7
|
|
687
692
|
},
|
|
688
693
|
toolHistory: {
|
|
689
694
|
strategy: "per-run",
|
|
695
|
+
retentionMode: "drop",
|
|
690
696
|
keepLatestToolPairs: 2,
|
|
691
697
|
keepLatestRuns: 1,
|
|
692
698
|
maxInteractionGroups: 12,
|
|
@@ -1538,6 +1544,17 @@ var logger = new Logger("GraphExecutor");
|
|
|
1538
1544
|
function asLocalRecord(local) {
|
|
1539
1545
|
return local && typeof local === "object" ? { ...local } : {};
|
|
1540
1546
|
}
|
|
1547
|
+
function readNonEmptyString(value) {
|
|
1548
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1549
|
+
}
|
|
1550
|
+
function readRuntimeConversationId(state) {
|
|
1551
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1552
|
+
return readNonEmptyString(local?.conversationId);
|
|
1553
|
+
}
|
|
1554
|
+
function readRuntimeTurnId(state) {
|
|
1555
|
+
const local = state?.local && typeof state.local === "object" ? state.local : void 0;
|
|
1556
|
+
return readNonEmptyString(local?.turnId);
|
|
1557
|
+
}
|
|
1541
1558
|
var GraphExecutor = class {
|
|
1542
1559
|
constructor(checkpointer, config = {}) {
|
|
1543
1560
|
this.checkpointer = checkpointer;
|
|
@@ -1555,8 +1572,8 @@ var GraphExecutor = class {
|
|
|
1555
1572
|
registerNode(node) {
|
|
1556
1573
|
this.nodes.set(node.id, node);
|
|
1557
1574
|
}
|
|
1558
|
-
async peekCheckpoint(
|
|
1559
|
-
return await this.checkpointer.load(
|
|
1575
|
+
async peekCheckpoint(checkpointKey) {
|
|
1576
|
+
return await this.checkpointer.load(checkpointKey);
|
|
1560
1577
|
}
|
|
1561
1578
|
sanitize(state) {
|
|
1562
1579
|
const local = asLocalRecord(state.local);
|
|
@@ -1568,8 +1585,8 @@ var GraphExecutor = class {
|
|
|
1568
1585
|
local
|
|
1569
1586
|
};
|
|
1570
1587
|
}
|
|
1571
|
-
async prime(
|
|
1572
|
-
this.ephemeralLocals.set(
|
|
1588
|
+
async prime(checkpointKey, local, nodeId = "user") {
|
|
1589
|
+
this.ephemeralLocals.set(checkpointKey, { ...local || {} });
|
|
1573
1590
|
const localSansMemory = { ...local || {} };
|
|
1574
1591
|
if ("memory" in localSansMemory) delete localSansMemory.memory;
|
|
1575
1592
|
const state = {
|
|
@@ -1577,10 +1594,10 @@ var GraphExecutor = class {
|
|
|
1577
1594
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1578
1595
|
local: localSansMemory
|
|
1579
1596
|
};
|
|
1580
|
-
await this.checkpointer.save(
|
|
1597
|
+
await this.checkpointer.save(checkpointKey, state);
|
|
1581
1598
|
}
|
|
1582
|
-
async setNode(
|
|
1583
|
-
const current = await this.checkpointer.load(
|
|
1599
|
+
async setNode(checkpointKey, nodeId, localPatch) {
|
|
1600
|
+
const current = await this.checkpointer.load(checkpointKey) || {
|
|
1584
1601
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1585
1602
|
local: {}
|
|
1586
1603
|
};
|
|
@@ -1591,19 +1608,46 @@ var GraphExecutor = class {
|
|
|
1591
1608
|
schemaVersion: current.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
1592
1609
|
local: mergedLocal
|
|
1593
1610
|
};
|
|
1594
|
-
await this.checkpointer.save(
|
|
1611
|
+
await this.checkpointer.save(checkpointKey, next);
|
|
1595
1612
|
}
|
|
1596
|
-
async runUntilYield(
|
|
1613
|
+
async runUntilYield(checkpointKey) {
|
|
1597
1614
|
const runId = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1598
1615
|
let lifecyclePhase = "completed";
|
|
1616
|
+
let initialState = null;
|
|
1617
|
+
try {
|
|
1618
|
+
initialState = await this.loadInitialState(checkpointKey);
|
|
1619
|
+
} catch (err) {
|
|
1620
|
+
lifecyclePhase = "failed";
|
|
1621
|
+
this.telemetryPort.emit({
|
|
1622
|
+
kind: "run_lifecycle",
|
|
1623
|
+
runId,
|
|
1624
|
+
phase: "spawned",
|
|
1625
|
+
scope: {}
|
|
1626
|
+
});
|
|
1627
|
+
this.telemetryPort.emit({
|
|
1628
|
+
kind: "run_lifecycle",
|
|
1629
|
+
runId,
|
|
1630
|
+
phase: lifecyclePhase,
|
|
1631
|
+
scope: {}
|
|
1632
|
+
});
|
|
1633
|
+
throw err;
|
|
1634
|
+
}
|
|
1635
|
+
let lifecycleConversationId = readRuntimeConversationId(initialState);
|
|
1636
|
+
let lifecycleTurnId = readRuntimeTurnId(initialState);
|
|
1599
1637
|
this.telemetryPort.emit({
|
|
1600
1638
|
kind: "run_lifecycle",
|
|
1601
1639
|
runId,
|
|
1602
1640
|
phase: "spawned",
|
|
1603
|
-
scope: {
|
|
1641
|
+
scope: {
|
|
1642
|
+
conversationId: lifecycleConversationId,
|
|
1643
|
+
turnId: lifecycleTurnId
|
|
1644
|
+
}
|
|
1604
1645
|
});
|
|
1605
1646
|
try {
|
|
1606
|
-
|
|
1647
|
+
const result = await this.runUntilYieldInternal(checkpointKey, initialState);
|
|
1648
|
+
lifecycleConversationId = readRuntimeConversationId(result.checkpoint);
|
|
1649
|
+
lifecycleTurnId = readRuntimeTurnId(result.checkpoint);
|
|
1650
|
+
return result;
|
|
1607
1651
|
} catch (err) {
|
|
1608
1652
|
lifecyclePhase = err?.name === "AbortError" ? "cancelled" : "failed";
|
|
1609
1653
|
throw err;
|
|
@@ -1612,17 +1656,23 @@ var GraphExecutor = class {
|
|
|
1612
1656
|
kind: "run_lifecycle",
|
|
1613
1657
|
runId,
|
|
1614
1658
|
phase: lifecyclePhase,
|
|
1615
|
-
scope: {
|
|
1659
|
+
scope: {
|
|
1660
|
+
conversationId: lifecycleConversationId,
|
|
1661
|
+
turnId: lifecycleTurnId
|
|
1662
|
+
}
|
|
1616
1663
|
});
|
|
1617
1664
|
}
|
|
1618
1665
|
}
|
|
1619
|
-
async
|
|
1620
|
-
|
|
1666
|
+
async loadInitialState(checkpointKey) {
|
|
1667
|
+
return await this.checkpointer.load(checkpointKey) || {
|
|
1621
1668
|
nodeId: "user",
|
|
1622
1669
|
schemaVersion: ENGINE_STATE_SCHEMA_VERSION,
|
|
1623
1670
|
local: {}
|
|
1624
1671
|
};
|
|
1625
|
-
|
|
1672
|
+
}
|
|
1673
|
+
async runUntilYieldInternal(checkpointKey, initialState) {
|
|
1674
|
+
let state = initialState;
|
|
1675
|
+
const ephemeral = this.ephemeralLocals.get(checkpointKey) || {};
|
|
1626
1676
|
state = {
|
|
1627
1677
|
...state,
|
|
1628
1678
|
schemaVersion: state.schemaVersion ?? ENGINE_STATE_SCHEMA_VERSION,
|
|
@@ -1651,7 +1701,7 @@ var GraphExecutor = class {
|
|
|
1651
1701
|
const signalRaw = state.local?.signal;
|
|
1652
1702
|
if (isAbortSignal2(signalRaw) && signalRaw.aborted) {
|
|
1653
1703
|
logger.warn("[GraphExecutor] \u6536\u5230 AbortSignal\uFF0C\u7ACB\u5373\u505C\u6B62\u63A8\u7406\u5FAA\u73AF");
|
|
1654
|
-
this.ephemeralLocals.delete(
|
|
1704
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1655
1705
|
throwAbortError();
|
|
1656
1706
|
}
|
|
1657
1707
|
const isLastStep = cycleStepCount >= this.config.maxSteps;
|
|
@@ -1699,8 +1749,8 @@ var GraphExecutor = class {
|
|
|
1699
1749
|
checkpointCount
|
|
1700
1750
|
});
|
|
1701
1751
|
const cp2 = this.sanitize(state);
|
|
1702
|
-
await this.checkpointer.save(
|
|
1703
|
-
this.ephemeralLocals.delete(
|
|
1752
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1753
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1704
1754
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1705
1755
|
}
|
|
1706
1756
|
logger.info("[GraphExecutor] \u8282\u70B9\u5207\u6362", {
|
|
@@ -1711,18 +1761,18 @@ var GraphExecutor = class {
|
|
|
1711
1761
|
});
|
|
1712
1762
|
const nodeRunStartedAt = Date.now();
|
|
1713
1763
|
const nodeIdForTelemetry = state.nodeId;
|
|
1764
|
+
const conversationIdForTelemetry = readRuntimeConversationId(state);
|
|
1714
1765
|
let result;
|
|
1715
1766
|
try {
|
|
1716
1767
|
result = await node.run(state);
|
|
1717
1768
|
} finally {
|
|
1718
|
-
const turnIdForTelemetry = typeof state.local?.turnId === "string" ? state.local.turnId : void 0;
|
|
1719
1769
|
this.telemetryPort.emit({
|
|
1720
1770
|
kind: "graph_node",
|
|
1721
1771
|
nodeId: nodeIdForTelemetry,
|
|
1722
1772
|
durationMs: Date.now() - nodeRunStartedAt,
|
|
1723
1773
|
scope: {
|
|
1724
|
-
conversationId:
|
|
1725
|
-
turnId:
|
|
1774
|
+
conversationId: conversationIdForTelemetry,
|
|
1775
|
+
turnId: readRuntimeTurnId(state)
|
|
1726
1776
|
}
|
|
1727
1777
|
});
|
|
1728
1778
|
}
|
|
@@ -1761,7 +1811,7 @@ var GraphExecutor = class {
|
|
|
1761
1811
|
});
|
|
1762
1812
|
state = { ...state, nodeId: nextNodeId };
|
|
1763
1813
|
const cp2 = this.sanitize(state);
|
|
1764
|
-
await this.checkpointer.save(
|
|
1814
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1765
1815
|
continue;
|
|
1766
1816
|
}
|
|
1767
1817
|
if (result.kind === "yield") {
|
|
@@ -1772,7 +1822,7 @@ var GraphExecutor = class {
|
|
|
1772
1822
|
checkpointCount
|
|
1773
1823
|
});
|
|
1774
1824
|
const cp2 = this.sanitize(state);
|
|
1775
|
-
await this.checkpointer.save(
|
|
1825
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1776
1826
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1777
1827
|
}
|
|
1778
1828
|
if (result.kind === "pause") {
|
|
@@ -1783,7 +1833,7 @@ var GraphExecutor = class {
|
|
|
1783
1833
|
checkpointCount
|
|
1784
1834
|
});
|
|
1785
1835
|
const cp2 = this.sanitize(state);
|
|
1786
|
-
await this.checkpointer.save(
|
|
1836
|
+
await this.checkpointer.save(checkpointKey, cp2);
|
|
1787
1837
|
return { events: allEvents, checkpoint: cp2, stepCount };
|
|
1788
1838
|
}
|
|
1789
1839
|
}
|
|
@@ -1794,8 +1844,8 @@ var GraphExecutor = class {
|
|
|
1794
1844
|
checkpointCount
|
|
1795
1845
|
});
|
|
1796
1846
|
const cp = this.sanitize(state);
|
|
1797
|
-
await this.checkpointer.save(
|
|
1798
|
-
this.ephemeralLocals.delete(
|
|
1847
|
+
await this.checkpointer.save(checkpointKey, cp);
|
|
1848
|
+
this.ephemeralLocals.delete(checkpointKey);
|
|
1799
1849
|
return { events: allEvents, checkpoint: cp, stepCount };
|
|
1800
1850
|
}
|
|
1801
1851
|
};
|
|
@@ -1992,15 +2042,15 @@ function splitConcatenatedJsonObjects(input) {
|
|
|
1992
2042
|
}
|
|
1993
2043
|
|
|
1994
2044
|
// src/runtime-kernel/graph-engine/tick-pipeline/helpers.ts
|
|
1995
|
-
function
|
|
2045
|
+
function readNonEmptyString2(value) {
|
|
1996
2046
|
if (typeof value !== "string") return void 0;
|
|
1997
2047
|
const trimmed = value.trim();
|
|
1998
2048
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
1999
2049
|
}
|
|
2000
2050
|
function resolveConversationIdForRuntimeEvents(toolContext) {
|
|
2001
|
-
const fromCamel =
|
|
2051
|
+
const fromCamel = readNonEmptyString2(toolContext?.conversationId);
|
|
2002
2052
|
if (fromCamel) return fromCamel;
|
|
2003
|
-
const fromSnake = toolContext ?
|
|
2053
|
+
const fromSnake = toolContext ? readNonEmptyString2(toolContext["conversation_id"]) : void 0;
|
|
2004
2054
|
if (fromSnake) return fromSnake;
|
|
2005
2055
|
return generateMessageId();
|
|
2006
2056
|
}
|
|
@@ -2382,7 +2432,7 @@ var runModelLockMiddleware = async (ctx, stage, next) => {
|
|
|
2382
2432
|
if (stage.id !== "execute_llm") {
|
|
2383
2433
|
return;
|
|
2384
2434
|
}
|
|
2385
|
-
const normalized =
|
|
2435
|
+
const normalized = readNonEmptyString2(ctx.cloudQuotaFallbackAppliedModelId);
|
|
2386
2436
|
if (!normalized) {
|
|
2387
2437
|
return;
|
|
2388
2438
|
}
|
|
@@ -2983,7 +3033,7 @@ function createExecuteLlmStage(dependencies) {
|
|
|
2983
3033
|
streamEventHandler,
|
|
2984
3034
|
ctx.signal,
|
|
2985
3035
|
(fallbackModelId) => {
|
|
2986
|
-
ctx.cloudQuotaFallbackAppliedModelId =
|
|
3036
|
+
ctx.cloudQuotaFallbackAppliedModelId = readNonEmptyString2(fallbackModelId);
|
|
2987
3037
|
},
|
|
2988
3038
|
(info) => {
|
|
2989
3039
|
ctx.modelFallbackAudit = info;
|
|
@@ -3027,7 +3077,7 @@ function createPrepareCallStage(dependencies) {
|
|
|
3027
3077
|
return {
|
|
3028
3078
|
id: "prepare_call",
|
|
3029
3079
|
async run(ctx) {
|
|
3030
|
-
const lockedRunModelId =
|
|
3080
|
+
const lockedRunModelId = readNonEmptyString2(ctx.executorLocal?.runLockedModelId);
|
|
3031
3081
|
const requestedModelId = lockedRunModelId ?? ctx.request.model_id;
|
|
3032
3082
|
ctx.modelId = dependencies.modelResolver.resolveModelId(requestedModelId);
|
|
3033
3083
|
await emitAuditEnvelope(ctx.audit, {
|
|
@@ -3099,7 +3149,7 @@ var GraphAgentExecutor = class {
|
|
|
3099
3149
|
this.llmCaller = dependencies.llmCaller;
|
|
3100
3150
|
this.toolRuntime = dependencies.toolRuntime;
|
|
3101
3151
|
this.contextBuilder = dependencies.contextBuilder;
|
|
3102
|
-
this.cloudQuotaFallbackModelId =
|
|
3152
|
+
this.cloudQuotaFallbackModelId = readNonEmptyString2(dependencies.cloudQuotaFallbackModelId);
|
|
3103
3153
|
this.modelCatalog = dependencies.modelCatalog ?? createEmptyModelCatalog();
|
|
3104
3154
|
this.modelResolver = dependencies.modelResolver ?? new ModelResolver({
|
|
3105
3155
|
modelCatalog: this.modelCatalog
|
|
@@ -3147,7 +3197,7 @@ var GraphAgentExecutor = class {
|
|
|
3147
3197
|
llmMessages: [],
|
|
3148
3198
|
mode: input.request.mode === "chat" ? "chat" : "agent",
|
|
3149
3199
|
conversationId: resolveConversationIdForRuntimeEvents(input.toolContext),
|
|
3150
|
-
turnId:
|
|
3200
|
+
turnId: readNonEmptyString2(input.toolContext?.turnId) ?? `turn_${Date.now()}`,
|
|
3151
3201
|
telemetry: this.telemetryPort,
|
|
3152
3202
|
audit: this.auditPort
|
|
3153
3203
|
};
|
|
@@ -3197,18 +3247,18 @@ function isSummarizationCallbacks(value) {
|
|
|
3197
3247
|
function isGraphSseSink(value) {
|
|
3198
3248
|
return typeof value === "function";
|
|
3199
3249
|
}
|
|
3200
|
-
function
|
|
3250
|
+
function readNonEmptyString3(value) {
|
|
3201
3251
|
if (typeof value !== "string") return void 0;
|
|
3202
3252
|
const trimmed = value.trim();
|
|
3203
3253
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
3204
3254
|
}
|
|
3205
3255
|
function readGraphAgentLocal(local) {
|
|
3206
3256
|
const source = local ?? {};
|
|
3207
|
-
const answerId =
|
|
3257
|
+
const answerId = readNonEmptyString3(source.answerId);
|
|
3208
3258
|
const chunkSeq = Number.isInteger(source.chunkSeq) ? Number(source.chunkSeq) : 0;
|
|
3209
3259
|
return {
|
|
3210
|
-
conversationId:
|
|
3211
|
-
turnId:
|
|
3260
|
+
conversationId: readNonEmptyString3(source.conversationId) ?? "",
|
|
3261
|
+
turnId: readNonEmptyString3(source.turnId),
|
|
3212
3262
|
request: isAgentInvocationRequest(source.request) ? source.request : void 0,
|
|
3213
3263
|
toolContext: isToolExecutionContext(source.toolContext) ? source.toolContext : void 0,
|
|
3214
3264
|
history: isRuntimeEventArray(source.history) ? source.history : [],
|
|
@@ -3973,7 +4023,7 @@ var LlmNode = class {
|
|
|
3973
4023
|
function isRecord8(value) {
|
|
3974
4024
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3975
4025
|
}
|
|
3976
|
-
function
|
|
4026
|
+
function readNonEmptyString4(value) {
|
|
3977
4027
|
if (typeof value !== "string") {
|
|
3978
4028
|
return void 0;
|
|
3979
4029
|
}
|
|
@@ -3995,7 +4045,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
3995
4045
|
return void 0;
|
|
3996
4046
|
}
|
|
3997
4047
|
if (toolName === "write_report") {
|
|
3998
|
-
const report =
|
|
4048
|
+
const report = readNonEmptyString4(data.report);
|
|
3999
4049
|
if (!report) {
|
|
4000
4050
|
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");
|
|
4001
4051
|
}
|
|
@@ -4005,7 +4055,7 @@ function resolveFinalAnswerFromToolResult(toolName, parsedResult) {
|
|
|
4005
4055
|
if (data.success !== true) {
|
|
4006
4056
|
return void 0;
|
|
4007
4057
|
}
|
|
4008
|
-
const finalAnswer =
|
|
4058
|
+
const finalAnswer = readNonEmptyString4(data.final_answer);
|
|
4009
4059
|
if (!finalAnswer) {
|
|
4010
4060
|
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");
|
|
4011
4061
|
}
|
|
@@ -4555,6 +4605,31 @@ function ensureToolContextRuntimeCapability(params) {
|
|
|
4555
4605
|
function getToolContextRuntimeBinding(context) {
|
|
4556
4606
|
return readBinding(context);
|
|
4557
4607
|
}
|
|
4608
|
+
function copyToolContextRuntimeCapability(source, target) {
|
|
4609
|
+
const sourceBinding = readBinding(source);
|
|
4610
|
+
if (!sourceBinding) {
|
|
4611
|
+
return void 0;
|
|
4612
|
+
}
|
|
4613
|
+
const existingTargetBinding = readBinding(target);
|
|
4614
|
+
if (existingTargetBinding) {
|
|
4615
|
+
exposeCompatibilitySurface(target, existingTargetBinding);
|
|
4616
|
+
return existingTargetBinding;
|
|
4617
|
+
}
|
|
4618
|
+
const targetBinding = createRuntimeBinding({
|
|
4619
|
+
context: target,
|
|
4620
|
+
persistedHistory: () => sourceBinding.getPersistedHistoryEvents(),
|
|
4621
|
+
workingHistory: () => sourceBinding.getWorkingHistoryEvents(),
|
|
4622
|
+
executionMeta: sourceBinding.readExecutionMeta()
|
|
4623
|
+
});
|
|
4624
|
+
Object.defineProperty(target, TOOL_CONTEXT_RUNTIME_BINDING_KEY, {
|
|
4625
|
+
value: targetBinding,
|
|
4626
|
+
enumerable: false,
|
|
4627
|
+
configurable: true,
|
|
4628
|
+
writable: false
|
|
4629
|
+
});
|
|
4630
|
+
exposeCompatibilitySurface(target, targetBinding);
|
|
4631
|
+
return targetBinding;
|
|
4632
|
+
}
|
|
4558
4633
|
function readToolContextWorkingHistory(context) {
|
|
4559
4634
|
if (context.conversationView) {
|
|
4560
4635
|
return context.conversationView.getWorkingHistoryEvents();
|
|
@@ -4968,6 +5043,22 @@ var ToolNode = class {
|
|
|
4968
5043
|
});
|
|
4969
5044
|
}
|
|
4970
5045
|
async run(state) {
|
|
5046
|
+
const events = [];
|
|
5047
|
+
while (true) {
|
|
5048
|
+
const result = await this.runNextPendingToolCall(state);
|
|
5049
|
+
if (Array.isArray(result.events) && result.events.length > 0) {
|
|
5050
|
+
events.push(...result.events);
|
|
5051
|
+
}
|
|
5052
|
+
if (result.kind === "route" && result.nextNodeId === "tool") {
|
|
5053
|
+
continue;
|
|
5054
|
+
}
|
|
5055
|
+
return {
|
|
5056
|
+
...result,
|
|
5057
|
+
events
|
|
5058
|
+
};
|
|
5059
|
+
}
|
|
5060
|
+
}
|
|
5061
|
+
async runNextPendingToolCall(state) {
|
|
4971
5062
|
const calls = state.local?.pendingToolCalls ?? [];
|
|
4972
5063
|
const signalRaw = state.local?.signal;
|
|
4973
5064
|
if (isAbortSignal(signalRaw) && signalRaw.aborted) {
|
|
@@ -5175,18 +5266,25 @@ var ToolNode = class {
|
|
|
5175
5266
|
rawArguments: context.call.function?.arguments,
|
|
5176
5267
|
parsedArguments: context.toolArgs
|
|
5177
5268
|
});
|
|
5269
|
+
const remainingCalls = context.calls.slice(1);
|
|
5178
5270
|
context.state.local = buildErrorLocalState({
|
|
5179
5271
|
local: context.local,
|
|
5180
|
-
remainingCalls
|
|
5272
|
+
remainingCalls,
|
|
5181
5273
|
conversationId: context.conversationId,
|
|
5182
5274
|
turnId: context.turnId,
|
|
5183
5275
|
runtimeEvents: context.bridge.getRuntimeEvents(),
|
|
5184
5276
|
nextProtocolErrorCount: fuse.nextCount
|
|
5185
5277
|
});
|
|
5186
|
-
if (fuse.shouldFuse) {
|
|
5278
|
+
if (fuse.shouldFuse && remainingCalls.length === 0) {
|
|
5187
5279
|
throw createToolProtocolFuseError(fuse.nextCount, context.exec.error);
|
|
5188
5280
|
}
|
|
5189
|
-
return {
|
|
5281
|
+
return {
|
|
5282
|
+
kind: "route",
|
|
5283
|
+
// 同一个 assistant.tool_calls batch 必须为每个 call 产出 tool_output。
|
|
5284
|
+
// 出错时也继续消费剩余 call,ToolNode.run 会在本节点内 drain 完 batch 再回 LLM。
|
|
5285
|
+
nextNodeId: remainingCalls.length > 0 ? "tool" : "llm",
|
|
5286
|
+
events: context.bridge.getRuntimeEvents()
|
|
5287
|
+
};
|
|
5190
5288
|
}
|
|
5191
5289
|
};
|
|
5192
5290
|
|
|
@@ -5383,12 +5481,12 @@ function asRecord(value) {
|
|
|
5383
5481
|
}
|
|
5384
5482
|
return value;
|
|
5385
5483
|
}
|
|
5386
|
-
function summarizeCheckpoint(
|
|
5484
|
+
function summarizeCheckpoint(checkpointKey, state, savedAt) {
|
|
5387
5485
|
const local = asRecord(state.local);
|
|
5388
5486
|
const executorLocal = asRecord(local?.executorLocal);
|
|
5389
5487
|
const pendingToolCalls = local?.pendingToolCalls;
|
|
5390
5488
|
return {
|
|
5391
|
-
|
|
5489
|
+
checkpointKey,
|
|
5392
5490
|
schemaVersion: state.schemaVersion ?? 1,
|
|
5393
5491
|
savedAt,
|
|
5394
5492
|
currentNode: state.nodeId,
|
|
@@ -5407,25 +5505,25 @@ var MemoryCheckpointer = class {
|
|
|
5407
5505
|
local: state.local && typeof state.local === "object" && !Array.isArray(state.local) ? { ...state.local } : state.local
|
|
5408
5506
|
};
|
|
5409
5507
|
}
|
|
5410
|
-
async load(
|
|
5411
|
-
const entry = this.store.get(
|
|
5508
|
+
async load(checkpointKey) {
|
|
5509
|
+
const entry = this.store.get(checkpointKey);
|
|
5412
5510
|
return entry ? this.cloneState(entry.state) : null;
|
|
5413
5511
|
}
|
|
5414
|
-
async save(
|
|
5415
|
-
this.store.set(
|
|
5512
|
+
async save(checkpointKey, state) {
|
|
5513
|
+
this.store.set(checkpointKey, {
|
|
5416
5514
|
state: this.cloneState(state),
|
|
5417
5515
|
savedAt: Date.now()
|
|
5418
5516
|
});
|
|
5419
5517
|
}
|
|
5420
|
-
async clear(
|
|
5421
|
-
this.store.delete(
|
|
5518
|
+
async clear(checkpointKey) {
|
|
5519
|
+
this.store.delete(checkpointKey);
|
|
5422
5520
|
}
|
|
5423
|
-
async peekMeta(
|
|
5424
|
-
const entry = this.store.get(
|
|
5425
|
-
return entry ? summarizeCheckpoint(
|
|
5521
|
+
async peekMeta(checkpointKey) {
|
|
5522
|
+
const entry = this.store.get(checkpointKey);
|
|
5523
|
+
return entry ? summarizeCheckpoint(checkpointKey, entry.state, entry.savedAt) : null;
|
|
5426
5524
|
}
|
|
5427
5525
|
async list(filter = {}) {
|
|
5428
|
-
const summaries = Array.from(this.store.entries()).map(([
|
|
5526
|
+
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);
|
|
5429
5527
|
if (filter.limit === void 0) {
|
|
5430
5528
|
return summaries;
|
|
5431
5529
|
}
|
|
@@ -5497,6 +5595,7 @@ __export(tools_exports, {
|
|
|
5497
5595
|
CommonParameterTypes: () => CommonParameterTypes,
|
|
5498
5596
|
ContextCheckpointTool: () => ContextCheckpointTool,
|
|
5499
5597
|
computeToolIdempotencyKey: () => computeToolIdempotencyKey,
|
|
5598
|
+
copyToolContextRuntimeCapability: () => copyToolContextRuntimeCapability,
|
|
5500
5599
|
createContextCheckpointTool: () => createContextCheckpointTool,
|
|
5501
5600
|
ensureToolContextRuntimeCapability: () => ensureToolContextRuntimeCapability,
|
|
5502
5601
|
findCachedToolOutputByIdempotencyKey: () => findCachedToolOutputByIdempotencyKey,
|
|
@@ -5690,7 +5789,7 @@ function createContextCheckpointTool(options) {
|
|
|
5690
5789
|
function isRecord15(value) {
|
|
5691
5790
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
5692
5791
|
}
|
|
5693
|
-
function
|
|
5792
|
+
function readNonEmptyString5(value) {
|
|
5694
5793
|
if (typeof value !== "string") {
|
|
5695
5794
|
return void 0;
|
|
5696
5795
|
}
|
|
@@ -5710,13 +5809,13 @@ function readToolContextUserQuery(context) {
|
|
|
5710
5809
|
if (!context) {
|
|
5711
5810
|
return void 0;
|
|
5712
5811
|
}
|
|
5713
|
-
return
|
|
5812
|
+
return readNonEmptyString5(context["user_query"]);
|
|
5714
5813
|
}
|
|
5715
5814
|
function readToolContextModelId(context) {
|
|
5716
5815
|
if (!context) {
|
|
5717
5816
|
return void 0;
|
|
5718
5817
|
}
|
|
5719
|
-
return
|
|
5818
|
+
return readNonEmptyString5(context["modelId"]);
|
|
5720
5819
|
}
|
|
5721
5820
|
function readToolContextRunContext(context) {
|
|
5722
5821
|
if (!context) {
|
|
@@ -5923,18 +6022,18 @@ function createClassification(category, reason, suggestedDelay, extras) {
|
|
|
5923
6022
|
}
|
|
5924
6023
|
var ErrorClassifier = class {
|
|
5925
6024
|
static classify(error, context) {
|
|
5926
|
-
const
|
|
6025
|
+
const isRecord25 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
5927
6026
|
const baseMsg = (error.message || "").toLowerCase();
|
|
5928
6027
|
const causeMsg = (() => {
|
|
5929
6028
|
const cause = error.cause;
|
|
5930
6029
|
if (typeof cause === "string") return cause.toLowerCase();
|
|
5931
6030
|
if (cause instanceof Error) return (cause.message || "").toLowerCase();
|
|
5932
|
-
if (
|
|
6031
|
+
if (isRecord25(cause) && typeof cause["message"] === "string") return String(cause["message"]).toLowerCase();
|
|
5933
6032
|
return "";
|
|
5934
6033
|
})();
|
|
5935
6034
|
const causeCode = (() => {
|
|
5936
6035
|
const cause = error.cause;
|
|
5937
|
-
if (
|
|
6036
|
+
if (isRecord25(cause) && typeof cause["code"] === "string") return String(cause["code"]);
|
|
5938
6037
|
return "";
|
|
5939
6038
|
})();
|
|
5940
6039
|
const errorMessage = `${baseMsg} ${causeMsg}`.trim();
|
|
@@ -6426,6 +6525,9 @@ __export(llm_exports, {
|
|
|
6426
6525
|
LLMPolicyEngine: () => LLMPolicyEngine,
|
|
6427
6526
|
LlmCaller: () => LlmCaller,
|
|
6428
6527
|
ModelResolver: () => ModelResolver,
|
|
6528
|
+
appendStreamingProviderReasoningDetails: () => appendStreamingProviderReasoningDetails,
|
|
6529
|
+
compactProviderReasoningDetails: () => compactProviderReasoningDetails,
|
|
6530
|
+
compactReasoningDetailsInValue: () => compactReasoningDetailsInValue,
|
|
6429
6531
|
createDefaultTokenizerPort: () => createDefaultTokenizerPort,
|
|
6430
6532
|
defaultPolicyEngine: () => defaultPolicyEngine
|
|
6431
6533
|
});
|
|
@@ -6815,6 +6917,90 @@ function assertToolCallsHaveValidJsonArguments(toolCalls) {
|
|
|
6815
6917
|
}
|
|
6816
6918
|
}
|
|
6817
6919
|
|
|
6920
|
+
// src/runtime-kernel/llm/reasoning-details.ts
|
|
6921
|
+
var mergeableTextFields = ["reasoning_content"];
|
|
6922
|
+
function isRecord20(value) {
|
|
6923
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
6924
|
+
}
|
|
6925
|
+
function findMergeableTextField(detail) {
|
|
6926
|
+
if (!isRecord20(detail)) return void 0;
|
|
6927
|
+
if (typeof detail.provider !== "string") return void 0;
|
|
6928
|
+
if (typeof detail.type !== "string") return void 0;
|
|
6929
|
+
for (const field of mergeableTextFields) {
|
|
6930
|
+
if (typeof detail[field] === "string") {
|
|
6931
|
+
return field;
|
|
6932
|
+
}
|
|
6933
|
+
}
|
|
6934
|
+
return void 0;
|
|
6935
|
+
}
|
|
6936
|
+
function hasOnlyStableTextDetailFields(detail, textField) {
|
|
6937
|
+
const allowedKeys = /* @__PURE__ */ new Set(["provider", "type", textField]);
|
|
6938
|
+
return Object.keys(detail).every((key) => allowedKeys.has(key));
|
|
6939
|
+
}
|
|
6940
|
+
function canMergeTextDetails(previous, incoming) {
|
|
6941
|
+
if (!isRecord20(previous) || !isRecord20(incoming)) return false;
|
|
6942
|
+
const previousField = findMergeableTextField(previous);
|
|
6943
|
+
const incomingField = findMergeableTextField(incoming);
|
|
6944
|
+
if (!previousField || previousField !== incomingField) return false;
|
|
6945
|
+
return previous.provider === incoming.provider && previous.type === incoming.type && hasOnlyStableTextDetailFields(previous, previousField) && hasOnlyStableTextDetailFields(incoming, incomingField);
|
|
6946
|
+
}
|
|
6947
|
+
function mergeStreamingText(previous, incoming) {
|
|
6948
|
+
if (!previous) return incoming;
|
|
6949
|
+
if (!incoming) return previous;
|
|
6950
|
+
if (incoming.startsWith(previous)) {
|
|
6951
|
+
return incoming;
|
|
6952
|
+
}
|
|
6953
|
+
if (previous.endsWith(incoming)) {
|
|
6954
|
+
return previous;
|
|
6955
|
+
}
|
|
6956
|
+
return `${previous}${incoming}`;
|
|
6957
|
+
}
|
|
6958
|
+
function appendStreamingProviderReasoningDetails(existing, incoming) {
|
|
6959
|
+
const next = [...existing];
|
|
6960
|
+
for (const detail of incoming) {
|
|
6961
|
+
const previous = next[next.length - 1];
|
|
6962
|
+
if (canMergeTextDetails(previous, detail)) {
|
|
6963
|
+
const textField = findMergeableTextField(previous);
|
|
6964
|
+
if (textField && isRecord20(detail)) {
|
|
6965
|
+
const mergedText = mergeStreamingText(String(previous[textField]), String(detail[textField]));
|
|
6966
|
+
if (mergedText === previous[textField]) {
|
|
6967
|
+
continue;
|
|
6968
|
+
}
|
|
6969
|
+
next[next.length - 1] = {
|
|
6970
|
+
...previous,
|
|
6971
|
+
[textField]: mergedText
|
|
6972
|
+
};
|
|
6973
|
+
continue;
|
|
6974
|
+
}
|
|
6975
|
+
}
|
|
6976
|
+
next.push(detail);
|
|
6977
|
+
}
|
|
6978
|
+
return next;
|
|
6979
|
+
}
|
|
6980
|
+
function compactProviderReasoningDetails(reasoningDetails) {
|
|
6981
|
+
return appendStreamingProviderReasoningDetails([], reasoningDetails);
|
|
6982
|
+
}
|
|
6983
|
+
function compactReasoningDetailsInValue(value) {
|
|
6984
|
+
return compactValue(value);
|
|
6985
|
+
}
|
|
6986
|
+
function compactValue(value) {
|
|
6987
|
+
if (Array.isArray(value)) {
|
|
6988
|
+
return value.map((item) => compactValue(item));
|
|
6989
|
+
}
|
|
6990
|
+
if (!isRecord20(value)) {
|
|
6991
|
+
return value;
|
|
6992
|
+
}
|
|
6993
|
+
const compacted = {};
|
|
6994
|
+
for (const [key, childValue] of Object.entries(value)) {
|
|
6995
|
+
if (key === "reasoning_details" && Array.isArray(childValue)) {
|
|
6996
|
+
compacted[key] = compactProviderReasoningDetails(childValue);
|
|
6997
|
+
continue;
|
|
6998
|
+
}
|
|
6999
|
+
compacted[key] = compactValue(childValue);
|
|
7000
|
+
}
|
|
7001
|
+
return compacted;
|
|
7002
|
+
}
|
|
7003
|
+
|
|
6818
7004
|
// src/runtime-kernel/llm/streaming-adapter.ts
|
|
6819
7005
|
async function callLlmStream(params) {
|
|
6820
7006
|
const {
|
|
@@ -6827,7 +7013,7 @@ async function callLlmStream(params) {
|
|
|
6827
7013
|
} = params;
|
|
6828
7014
|
let fullResponse = "";
|
|
6829
7015
|
let streamError = null;
|
|
6830
|
-
|
|
7016
|
+
let reasoningDetails = [];
|
|
6831
7017
|
const streamAnswerId = generateMessageId();
|
|
6832
7018
|
let streamChunkSeq = 0;
|
|
6833
7019
|
let capturedUsage = void 0;
|
|
@@ -6897,13 +7083,21 @@ async function callLlmStream(params) {
|
|
|
6897
7083
|
const reasoning = isRecord19(chunk) ? chunk["reasoning_details"] : void 0;
|
|
6898
7084
|
if (reasoning !== void 0) {
|
|
6899
7085
|
const newReasoningDetails = Array.isArray(reasoning) ? reasoning : [reasoning];
|
|
6900
|
-
reasoningDetails
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
7086
|
+
const previousReasoningDetails = reasoningDetails;
|
|
7087
|
+
const previousLength = previousReasoningDetails.length;
|
|
7088
|
+
const compactedReasoningDetails = appendStreamingProviderReasoningDetails(reasoningDetails, newReasoningDetails);
|
|
7089
|
+
reasoningDetails = compactedReasoningDetails;
|
|
7090
|
+
const previousLastChanged = previousLength > 0 && compactedReasoningDetails[previousLength - 1] !== previousReasoningDetails[previousLength - 1];
|
|
7091
|
+
const emitFromIndex = previousLastChanged ? previousLength - 1 : previousLength;
|
|
7092
|
+
const emittedReasoningDetails = compactedReasoningDetails.slice(Math.max(0, emitFromIndex));
|
|
7093
|
+
if (emittedReasoningDetails.length > 0) {
|
|
7094
|
+
eventHandler({
|
|
7095
|
+
type: "provider_sidecar",
|
|
7096
|
+
id: generateMessageId(),
|
|
7097
|
+
timestamp: Date.now(),
|
|
7098
|
+
reasoning_details: emittedReasoningDetails
|
|
7099
|
+
});
|
|
7100
|
+
}
|
|
6907
7101
|
}
|
|
6908
7102
|
if (chunk.tool_calls) {
|
|
6909
7103
|
emitThoughtComplete(thoughtSegmenter.onBoundary());
|
|
@@ -7357,7 +7551,6 @@ __export(child_runs_exports, {
|
|
|
7357
7551
|
|
|
7358
7552
|
// src/runtime-kernel/child-runs/childToolContext.ts
|
|
7359
7553
|
function createChildRunToolContext(params) {
|
|
7360
|
-
const inheritedConversationId = typeof params.parentToolContext.conversationId === "string" && params.parentToolContext.conversationId.trim().length > 0 ? params.parentToolContext.conversationId.trim() : void 0;
|
|
7361
7554
|
const inheritedContext = stripRuntimeReservedToolContextPatch(params.parentToolContext);
|
|
7362
7555
|
const childToolContext = {
|
|
7363
7556
|
...inheritedContext,
|
|
@@ -7369,7 +7562,7 @@ function createChildRunToolContext(params) {
|
|
|
7369
7562
|
persistedHistory: params.seedHistory,
|
|
7370
7563
|
workingHistory: params.seedHistory,
|
|
7371
7564
|
executionMeta: {
|
|
7372
|
-
conversationId:
|
|
7565
|
+
conversationId: params.conversationId,
|
|
7373
7566
|
turnId: params.turnId,
|
|
7374
7567
|
runId: params.runId,
|
|
7375
7568
|
parentRunId: params.parentRunId
|
|
@@ -7520,7 +7713,7 @@ var FinalAnswerCollector = class {
|
|
|
7520
7713
|
};
|
|
7521
7714
|
|
|
7522
7715
|
// src/runtime-kernel/child-runs/childRunTraceSink.ts
|
|
7523
|
-
function
|
|
7716
|
+
function isRecord21(v) {
|
|
7524
7717
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
7525
7718
|
}
|
|
7526
7719
|
function getString2(obj, key) {
|
|
@@ -7553,7 +7746,7 @@ function createChildRunTraceSink(params) {
|
|
|
7553
7746
|
const { publisher, conversationId, turnId } = params;
|
|
7554
7747
|
const finalAnswerCollector = new FinalAnswerCollector(conversationId, turnId);
|
|
7555
7748
|
const sink = (evt) => {
|
|
7556
|
-
if (!
|
|
7749
|
+
if (!isRecord21(evt)) {
|
|
7557
7750
|
return [];
|
|
7558
7751
|
}
|
|
7559
7752
|
const type = getString2(evt, "type");
|
|
@@ -7689,7 +7882,7 @@ function readCheckpointHistory(checkpoint) {
|
|
|
7689
7882
|
});
|
|
7690
7883
|
}
|
|
7691
7884
|
async function recoverChildRunEventsFromCheckpoint(params) {
|
|
7692
|
-
const checkpoint = await params.checkpointer.load(params.
|
|
7885
|
+
const checkpoint = await params.checkpointer.load(params.checkpointKey);
|
|
7693
7886
|
const history = readCheckpointHistory(checkpoint);
|
|
7694
7887
|
if (history.length === 0) {
|
|
7695
7888
|
return [];
|
|
@@ -7697,7 +7890,7 @@ async function recoverChildRunEventsFromCheckpoint(params) {
|
|
|
7697
7890
|
if (hasSeedHistoryPrefix(history, params.seedHistory)) {
|
|
7698
7891
|
return history.slice(params.seedHistory.length);
|
|
7699
7892
|
}
|
|
7700
|
-
return history.filter((event) => event.conversation_id === params.
|
|
7893
|
+
return history.filter((event) => event.conversation_id === params.childConversationId);
|
|
7701
7894
|
}
|
|
7702
7895
|
|
|
7703
7896
|
// src/runtime-kernel/child-runs/childRunInvoker.ts
|
|
@@ -7726,6 +7919,7 @@ var ChildRunInvoker = class {
|
|
|
7726
7919
|
agentConfig,
|
|
7727
7920
|
userMessage,
|
|
7728
7921
|
parentToolContext,
|
|
7922
|
+
conversationId,
|
|
7729
7923
|
runId,
|
|
7730
7924
|
parentRunId,
|
|
7731
7925
|
subrunTracePublisher,
|
|
@@ -7734,12 +7928,18 @@ var ChildRunInvoker = class {
|
|
|
7734
7928
|
modelId,
|
|
7735
7929
|
abortSignal
|
|
7736
7930
|
} = config;
|
|
7737
|
-
const
|
|
7931
|
+
const internalCheckpointKey = `internal_${generateMessageId()}`;
|
|
7932
|
+
const runtimeConversationId = resolveChildRunConversationId({
|
|
7933
|
+
explicitConversationId: conversationId,
|
|
7934
|
+
parentToolContext,
|
|
7935
|
+
fallbackConversationId: internalCheckpointKey
|
|
7936
|
+
});
|
|
7738
7937
|
const turnId = `turn_${Date.now()}`;
|
|
7739
|
-
const childRunId = typeof runId === "string" && runId.trim().length > 0 ? runId.trim() :
|
|
7938
|
+
const childRunId = typeof runId === "string" && runId.trim().length > 0 ? runId.trim() : internalCheckpointKey;
|
|
7740
7939
|
const resolvedParentRunId = typeof parentRunId === "string" && parentRunId.trim().length > 0 ? parentRunId.trim() : typeof parentToolContext.runId === "string" && parentToolContext.runId.trim().length > 0 ? parentToolContext.runId.trim() : void 0;
|
|
7741
7940
|
logger13.info(`\u542F\u52A8 child-run: ${agentConfig.id}`, {
|
|
7742
|
-
conversationId:
|
|
7941
|
+
conversationId: runtimeConversationId,
|
|
7942
|
+
checkpointKey: internalCheckpointKey,
|
|
7743
7943
|
maxSteps,
|
|
7744
7944
|
userMessage: userMessage.slice(0, 100) + (userMessage.length > 100 ? "..." : "")
|
|
7745
7945
|
});
|
|
@@ -7800,7 +8000,7 @@ var ChildRunInvoker = class {
|
|
|
7800
8000
|
const seedHistory = Array.isArray(seedHistoryEvents) ? seedHistoryEvents : [];
|
|
7801
8001
|
const childToolContext = createChildRunToolContext({
|
|
7802
8002
|
parentToolContext,
|
|
7803
|
-
|
|
8003
|
+
conversationId: runtimeConversationId,
|
|
7804
8004
|
turnId,
|
|
7805
8005
|
runId: childRunId,
|
|
7806
8006
|
parentRunId: resolvedParentRunId,
|
|
@@ -7809,13 +8009,13 @@ var ChildRunInvoker = class {
|
|
|
7809
8009
|
});
|
|
7810
8010
|
const subrunSseSink = subrunTracePublisher ? createChildRunTraceSink({
|
|
7811
8011
|
publisher: subrunTracePublisher,
|
|
7812
|
-
conversationId:
|
|
8012
|
+
conversationId: runtimeConversationId,
|
|
7813
8013
|
turnId
|
|
7814
8014
|
}) : void 0;
|
|
7815
8015
|
const initialLocal = {
|
|
7816
8016
|
request,
|
|
7817
8017
|
history: seedHistory,
|
|
7818
|
-
conversationId:
|
|
8018
|
+
conversationId: runtimeConversationId,
|
|
7819
8019
|
turnId,
|
|
7820
8020
|
toolContext: childToolContext,
|
|
7821
8021
|
...abortSignal ? { signal: abortSignal } : {},
|
|
@@ -7823,7 +8023,7 @@ var ChildRunInvoker = class {
|
|
|
7823
8023
|
...subrunSseSink ? { sseSink: subrunSseSink } : {},
|
|
7824
8024
|
systemPrompt
|
|
7825
8025
|
};
|
|
7826
|
-
await graphExecutor.prime(
|
|
8026
|
+
await graphExecutor.prime(internalCheckpointKey, initialLocal, "llm");
|
|
7827
8027
|
const allEvents = [];
|
|
7828
8028
|
let stepCount = 0;
|
|
7829
8029
|
let finalAnswer;
|
|
@@ -7835,7 +8035,7 @@ var ChildRunInvoker = class {
|
|
|
7835
8035
|
err.name = "AbortError";
|
|
7836
8036
|
throw err;
|
|
7837
8037
|
}
|
|
7838
|
-
const result = await graphExecutor.runUntilYield(
|
|
8038
|
+
const result = await graphExecutor.runUntilYield(internalCheckpointKey);
|
|
7839
8039
|
appendUniqueEvents(allEvents, result.events);
|
|
7840
8040
|
stepCount = result.stepCount;
|
|
7841
8041
|
if (subrunSseSink && typeof subrunSseSink.finalize === "function") {
|
|
@@ -7869,8 +8069,8 @@ var ChildRunInvoker = class {
|
|
|
7869
8069
|
}
|
|
7870
8070
|
const recoveredEvents = await recoverChildRunEventsFromCheckpoint({
|
|
7871
8071
|
checkpointer,
|
|
7872
|
-
|
|
7873
|
-
|
|
8072
|
+
checkpointKey: internalCheckpointKey,
|
|
8073
|
+
childConversationId: runtimeConversationId,
|
|
7874
8074
|
seedHistory
|
|
7875
8075
|
});
|
|
7876
8076
|
appendUniqueEvents(allEvents, recoveredEvents);
|
|
@@ -7887,7 +8087,7 @@ var ChildRunInvoker = class {
|
|
|
7887
8087
|
stack: err.stack
|
|
7888
8088
|
} : { error: String(err) });
|
|
7889
8089
|
}
|
|
7890
|
-
await checkpointer.clear(
|
|
8090
|
+
await checkpointer.clear(internalCheckpointKey);
|
|
7891
8091
|
return {
|
|
7892
8092
|
success: !error,
|
|
7893
8093
|
runId: childRunId,
|
|
@@ -7900,6 +8100,16 @@ var ChildRunInvoker = class {
|
|
|
7900
8100
|
};
|
|
7901
8101
|
}
|
|
7902
8102
|
};
|
|
8103
|
+
function readNonEmptyString6(value) {
|
|
8104
|
+
if (typeof value !== "string") {
|
|
8105
|
+
return void 0;
|
|
8106
|
+
}
|
|
8107
|
+
const trimmed = value.trim();
|
|
8108
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
8109
|
+
}
|
|
8110
|
+
function resolveChildRunConversationId(params) {
|
|
8111
|
+
return readNonEmptyString6(params.explicitConversationId) ?? readNonEmptyString6(params.parentToolContext.conversationId) ?? params.fallbackConversationId;
|
|
8112
|
+
}
|
|
7903
8113
|
function resolveChildRunSystemReminderPolicy(agentConfig) {
|
|
7904
8114
|
const configured = agentConfig.systemReminderPolicy ?? agentConfig.contextPolicy?.systemReminder;
|
|
7905
8115
|
const threshold = agentConfig.stepPolicy?.lastStepsHintThreshold;
|
|
@@ -8090,7 +8300,7 @@ function cloneRunRecord(record) {
|
|
|
8090
8300
|
...record,
|
|
8091
8301
|
iterationBudget: record.iterationBudget ? { ...record.iterationBudget } : void 0,
|
|
8092
8302
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0,
|
|
8093
|
-
metadata: record.metadata ?
|
|
8303
|
+
metadata: record.metadata ? structuredClone(record.metadata) : void 0
|
|
8094
8304
|
};
|
|
8095
8305
|
}
|
|
8096
8306
|
function matchesStatus(candidate, filter) {
|
|
@@ -8222,7 +8432,7 @@ function runRecordToMeta(record) {
|
|
|
8222
8432
|
errorIfAny: record.errorIfAny ? { ...record.errorIfAny } : void 0
|
|
8223
8433
|
};
|
|
8224
8434
|
}
|
|
8225
|
-
function
|
|
8435
|
+
function isRecord22(value) {
|
|
8226
8436
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8227
8437
|
}
|
|
8228
8438
|
function readStringField(record, key) {
|
|
@@ -8243,7 +8453,7 @@ function getRunIdFromMetadata(event) {
|
|
|
8243
8453
|
return snakeCaseRunId;
|
|
8244
8454
|
}
|
|
8245
8455
|
const runContext = metadata["run_context"];
|
|
8246
|
-
if (
|
|
8456
|
+
if (isRecord22(runContext)) {
|
|
8247
8457
|
return readStringField(runContext, "runId") ?? readStringField(runContext, "run_id");
|
|
8248
8458
|
}
|
|
8249
8459
|
return void 0;
|
|
@@ -8461,7 +8671,7 @@ function runMetaFromRecord(record) {
|
|
|
8461
8671
|
}
|
|
8462
8672
|
|
|
8463
8673
|
// src/runtime-kernel/run-supervisor/runSupervisor.ts
|
|
8464
|
-
function
|
|
8674
|
+
function isRecord23(value) {
|
|
8465
8675
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8466
8676
|
}
|
|
8467
8677
|
function readStringField2(record, key) {
|
|
@@ -8478,7 +8688,7 @@ function readRunIdFromRuntimeEvent(event) {
|
|
|
8478
8688
|
return directRunId;
|
|
8479
8689
|
}
|
|
8480
8690
|
const runContext = metadata["run_context"];
|
|
8481
|
-
if (!
|
|
8691
|
+
if (!isRecord23(runContext)) {
|
|
8482
8692
|
return void 0;
|
|
8483
8693
|
}
|
|
8484
8694
|
return readStringField2(runContext, "runId") ?? readStringField2(runContext, "run_id");
|
|
@@ -8490,7 +8700,7 @@ function readAwaitingUserReason(event) {
|
|
|
8490
8700
|
if (typeof event.prompt === "string" && event.prompt.trim().length > 0) {
|
|
8491
8701
|
return event.prompt;
|
|
8492
8702
|
}
|
|
8493
|
-
if (
|
|
8703
|
+
if (isRecord23(event.form)) {
|
|
8494
8704
|
const prompt = readStringField2(event.form, "prompt");
|
|
8495
8705
|
if (prompt && prompt.trim().length > 0) {
|
|
8496
8706
|
return prompt;
|
|
@@ -8502,7 +8712,7 @@ function isTerminalStatus(status) {
|
|
|
8502
8712
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
8503
8713
|
}
|
|
8504
8714
|
function cloneMetadata(metadata) {
|
|
8505
|
-
return metadata ?
|
|
8715
|
+
return metadata ? structuredClone(metadata) : void 0;
|
|
8506
8716
|
}
|
|
8507
8717
|
function recordToSnapshot(record) {
|
|
8508
8718
|
return {
|
|
@@ -8589,7 +8799,7 @@ var DefaultRunSupervisor = class {
|
|
|
8589
8799
|
startedAt,
|
|
8590
8800
|
updatedAt: startedAt,
|
|
8591
8801
|
iterationBudget: spec.iterationBudget ? { ...spec.iterationBudget } : void 0,
|
|
8592
|
-
metadata: spec.metadata
|
|
8802
|
+
metadata: cloneMetadata(spec.metadata)
|
|
8593
8803
|
};
|
|
8594
8804
|
await this.registryStore.save(record);
|
|
8595
8805
|
const handle = new DefaultRunHandle({
|
|
@@ -8763,12 +8973,13 @@ var DefaultRunSupervisor = class {
|
|
|
8763
8973
|
}
|
|
8764
8974
|
try {
|
|
8765
8975
|
await handle.markRunning({ currentNode: "detached" });
|
|
8976
|
+
const registeredRecord = await this.registryStore.load(handle.runId);
|
|
8766
8977
|
const executorOutcome = await this.executor.execute({
|
|
8767
8978
|
runId: handle.runId,
|
|
8768
|
-
parentRunId:
|
|
8769
|
-
conversationId: spec.conversationId,
|
|
8770
|
-
agentSpec: spec
|
|
8771
|
-
request:
|
|
8979
|
+
parentRunId: handle.parentRunId,
|
|
8980
|
+
conversationId: registeredRecord?.conversationId ?? spec.conversationId,
|
|
8981
|
+
agentSpec: await handle.spec(),
|
|
8982
|
+
request: await handle.request(),
|
|
8772
8983
|
signal: handle.signal,
|
|
8773
8984
|
eventBus: spec.eventBus,
|
|
8774
8985
|
eventStore: spec.eventStore,
|
|
@@ -8777,7 +8988,7 @@ var DefaultRunSupervisor = class {
|
|
|
8777
8988
|
contextFences: spec.contextFences,
|
|
8778
8989
|
wakeSource: spec.wakeSource,
|
|
8779
8990
|
ephemeral: spec.ephemeral,
|
|
8780
|
-
metadata: spec.metadata
|
|
8991
|
+
metadata: cloneMetadata(registeredRecord?.metadata ?? spec.metadata)
|
|
8781
8992
|
});
|
|
8782
8993
|
const outcome = await this.persistExecutorOutcome(handle, executorOutcome);
|
|
8783
8994
|
this.notifyTerminalWaiters(outcome);
|
|
@@ -8841,10 +9052,14 @@ var DefaultRunSupervisor = class {
|
|
|
8841
9052
|
await this.registryStore.save(record);
|
|
8842
9053
|
}
|
|
8843
9054
|
const completedAt = executorOutcome?.completedAt ?? this.now();
|
|
9055
|
+
const fallbackMeta = record ? void 0 : await handle.meta();
|
|
8844
9056
|
const outcome = recordToTerminalOutcome(record ?? {
|
|
8845
9057
|
runId: handle.runId,
|
|
8846
9058
|
parentRunId: handle.parentRunId,
|
|
8847
|
-
|
|
9059
|
+
conversationId: fallbackMeta?.conversationId ?? "",
|
|
9060
|
+
agentSpecId: fallbackMeta?.agentSpecId,
|
|
9061
|
+
status: executorOutcome?.status ?? "completed",
|
|
9062
|
+
startedAt: fallbackMeta?.startedAt ?? completedAt}, completedAt);
|
|
8848
9063
|
const nextOutcome = {
|
|
8849
9064
|
...outcome,
|
|
8850
9065
|
metadata: {
|
|
@@ -9072,6 +9287,7 @@ function createGraphLoopHarness(options) {
|
|
|
9072
9287
|
};
|
|
9073
9288
|
return {
|
|
9074
9289
|
async run() {
|
|
9290
|
+
const checkpointKey = options.conversationId;
|
|
9075
9291
|
const executor = createDefaultGraphExecutor({
|
|
9076
9292
|
llmNode: options.createLlmNode({
|
|
9077
9293
|
llmCaller: options.llmCaller,
|
|
@@ -9100,8 +9316,8 @@ function createGraphLoopHarness(options) {
|
|
|
9100
9316
|
signal: options.signal ?? options.toolContext.abortSignal,
|
|
9101
9317
|
executorLocal
|
|
9102
9318
|
};
|
|
9103
|
-
await executor.prime(
|
|
9104
|
-
const result = await executor.runUntilYield(
|
|
9319
|
+
await executor.prime(checkpointKey, local, "user");
|
|
9320
|
+
const result = await executor.runUntilYield(checkpointKey);
|
|
9105
9321
|
return {
|
|
9106
9322
|
checkpointNodeId: result.checkpoint.nodeId,
|
|
9107
9323
|
stepCount: result.stepCount
|
|
@@ -9372,7 +9588,7 @@ function createQuickstartTelemetryPort(collector) {
|
|
|
9372
9588
|
}
|
|
9373
9589
|
|
|
9374
9590
|
// src/quickstart/runAgent.ts
|
|
9375
|
-
function
|
|
9591
|
+
function isRecord24(value) {
|
|
9376
9592
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9377
9593
|
}
|
|
9378
9594
|
function readString4(value) {
|
|
@@ -9386,7 +9602,7 @@ function resolveModelId(agent, options) {
|
|
|
9386
9602
|
return modelId;
|
|
9387
9603
|
}
|
|
9388
9604
|
function isQuickstartStreamChunkEvent(value) {
|
|
9389
|
-
return
|
|
9605
|
+
return isRecord24(value) && value.type === "stream_chunk" && typeof value.content === "string";
|
|
9390
9606
|
}
|
|
9391
9607
|
function createNoopObservationPreview() {
|
|
9392
9608
|
return {
|
|
@@ -9426,7 +9642,7 @@ function readFinalAnswer(events, checkpointLocal) {
|
|
|
9426
9642
|
if (chunks.length > 0) {
|
|
9427
9643
|
return chunks.join("");
|
|
9428
9644
|
}
|
|
9429
|
-
if (
|
|
9645
|
+
if (isRecord24(checkpointLocal)) {
|
|
9430
9646
|
const finalAnswer = checkpointLocal["finalAnswer"];
|
|
9431
9647
|
if (typeof finalAnswer === "string") {
|
|
9432
9648
|
return finalAnswer;
|
|
@@ -9435,7 +9651,7 @@ function readFinalAnswer(events, checkpointLocal) {
|
|
|
9435
9651
|
return "";
|
|
9436
9652
|
}
|
|
9437
9653
|
function readContextTrace(checkpointLocal) {
|
|
9438
|
-
if (!
|
|
9654
|
+
if (!isRecord24(checkpointLocal)) return void 0;
|
|
9439
9655
|
return checkpointLocal["contextTrace"];
|
|
9440
9656
|
}
|
|
9441
9657
|
async function emitRunEvent(event, sink) {
|
|
@@ -9444,6 +9660,7 @@ async function emitRunEvent(event, sink) {
|
|
|
9444
9660
|
async function runAgent(agent, options) {
|
|
9445
9661
|
const modelId = resolveModelId(agent, options);
|
|
9446
9662
|
const conversationId = options.conversationId ?? `conv_${Date.now()}`;
|
|
9663
|
+
const checkpointKey = conversationId;
|
|
9447
9664
|
const runId = options.runId ?? generateRunId();
|
|
9448
9665
|
const turnId = runId;
|
|
9449
9666
|
const costCollector = new QuickstartRunCostCollector();
|
|
@@ -9498,7 +9715,7 @@ async function runAgent(agent, options) {
|
|
|
9498
9715
|
};
|
|
9499
9716
|
await handle.markRunning({ currentNode: "user" });
|
|
9500
9717
|
try {
|
|
9501
|
-
await executor.prime(
|
|
9718
|
+
await executor.prime(checkpointKey, {
|
|
9502
9719
|
conversationId,
|
|
9503
9720
|
turnId,
|
|
9504
9721
|
request: {
|
|
@@ -9523,7 +9740,7 @@ async function runAgent(agent, options) {
|
|
|
9523
9740
|
return void 0;
|
|
9524
9741
|
}
|
|
9525
9742
|
});
|
|
9526
|
-
const result = await executor.runUntilYield(
|
|
9743
|
+
const result = await executor.runUntilYield(checkpointKey);
|
|
9527
9744
|
runtimeEvents.push(...result.events);
|
|
9528
9745
|
for (const event of result.events) {
|
|
9529
9746
|
if (event.type === "final_answer_chunk") continue;
|