@rowan-agent/agent 0.17.0 → 0.19.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/README.md +12 -3
- package/dist/index.d.ts +326 -210
- package/dist/index.js +1368 -461
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -945,7 +945,7 @@ function createRuntimeCoreTools(input = {}) {
|
|
|
945
945
|
import { mkdir as mkdir2, chmod as chmod2, writeFile as writeFile2 } from "fs/promises";
|
|
946
946
|
import { randomUUID } from "crypto";
|
|
947
947
|
import { join as join5 } from "path";
|
|
948
|
-
import { createModelStream } from "@rowan-agent/models";
|
|
948
|
+
import { createModelStream, isValidToolProgress } from "@rowan-agent/models";
|
|
949
949
|
|
|
950
950
|
// src/utils.ts
|
|
951
951
|
function createId(prefix) {
|
|
@@ -961,6 +961,49 @@ function createTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
|
961
961
|
const mm = String(abs % 60).padStart(2, "0");
|
|
962
962
|
return `${iso}${sign}${hh}:${mm}`;
|
|
963
963
|
}
|
|
964
|
+
function combineSignals(signalA, signalB) {
|
|
965
|
+
if (!signalA && !signalB) return new AbortController().signal;
|
|
966
|
+
if (!signalA) return signalB;
|
|
967
|
+
if (!signalB) return signalA;
|
|
968
|
+
if (typeof AbortSignal.any === "function") {
|
|
969
|
+
return AbortSignal.any([signalA, signalB]);
|
|
970
|
+
}
|
|
971
|
+
if (signalA.aborted) return signalA;
|
|
972
|
+
if (signalB.aborted) return signalB;
|
|
973
|
+
const controller = new AbortController();
|
|
974
|
+
const onAbort = (ev) => {
|
|
975
|
+
const target = ev.target;
|
|
976
|
+
controller.abort(target.reason);
|
|
977
|
+
};
|
|
978
|
+
signalA.addEventListener("abort", onAbort, { once: true });
|
|
979
|
+
signalB.addEventListener("abort", onAbort, { once: true });
|
|
980
|
+
return controller.signal;
|
|
981
|
+
}
|
|
982
|
+
function withAbort(promise, signal) {
|
|
983
|
+
if (!signal) return promise;
|
|
984
|
+
if (signal.aborted) {
|
|
985
|
+
const error = signal.reason instanceof Error ? signal.reason : new DOMException(typeof signal.reason === "string" ? signal.reason : "Tool execution aborted.", "AbortError");
|
|
986
|
+
return Promise.reject(error);
|
|
987
|
+
}
|
|
988
|
+
return new Promise((resolve9, reject) => {
|
|
989
|
+
const onAbort = () => {
|
|
990
|
+
signal.removeEventListener("abort", onAbort);
|
|
991
|
+
const error = signal.reason instanceof Error ? signal.reason : new DOMException(typeof signal.reason === "string" ? signal.reason : "Tool execution aborted.", "AbortError");
|
|
992
|
+
reject(error);
|
|
993
|
+
};
|
|
994
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
995
|
+
promise.then(
|
|
996
|
+
(val) => {
|
|
997
|
+
signal.removeEventListener("abort", onAbort);
|
|
998
|
+
resolve9(val);
|
|
999
|
+
},
|
|
1000
|
+
(err) => {
|
|
1001
|
+
signal.removeEventListener("abort", onAbort);
|
|
1002
|
+
reject(err);
|
|
1003
|
+
}
|
|
1004
|
+
);
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
964
1007
|
|
|
965
1008
|
// src/loop/state.ts
|
|
966
1009
|
function snapshotMessage(message) {
|
|
@@ -991,12 +1034,18 @@ function contentBlocksToMessageContent(blocks) {
|
|
|
991
1034
|
if (block.type === "thinking") {
|
|
992
1035
|
return { type: "thinking", thinking: block.thinking, ...block.signature ? { signature: block.signature } : {} };
|
|
993
1036
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1037
|
+
if (block.type === "image") {
|
|
1038
|
+
return { type: "image", data: block.data, mimeType: block.mimeType };
|
|
1039
|
+
}
|
|
1040
|
+
if (block.type === "tool_call") {
|
|
1041
|
+
let input = block.args;
|
|
1042
|
+
try {
|
|
1043
|
+
input = JSON.parse(block.args);
|
|
1044
|
+
} catch {
|
|
1045
|
+
}
|
|
1046
|
+
return { type: "tool_use", id: block.id, name: block.name, input };
|
|
998
1047
|
}
|
|
999
|
-
return { type: "
|
|
1048
|
+
return { type: "text", text: JSON.stringify(block) };
|
|
1000
1049
|
});
|
|
1001
1050
|
}
|
|
1002
1051
|
|
|
@@ -1329,7 +1378,42 @@ var LoopGuard = {
|
|
|
1329
1378
|
// src/loop/stream-collector.ts
|
|
1330
1379
|
var MAX_STREAMED_OUTPUT_CHARACTERS = 1024 * 1024;
|
|
1331
1380
|
async function invokeModel(input) {
|
|
1332
|
-
const
|
|
1381
|
+
const callContext = input.callContext ?? {
|
|
1382
|
+
signal: input.config.signal ?? new AbortController().signal,
|
|
1383
|
+
run: {
|
|
1384
|
+
id: input.config.execution.runId,
|
|
1385
|
+
agentId: input.config.execution.agentId,
|
|
1386
|
+
scope: input.config.execution.scope ?? [],
|
|
1387
|
+
cwd: input.config.execution.cwd ?? input.config.context.cwd ?? ""
|
|
1388
|
+
},
|
|
1389
|
+
interact: async (request) => {
|
|
1390
|
+
const handler = input.config.runtime?.interact ?? input.config.interact;
|
|
1391
|
+
if (!handler) {
|
|
1392
|
+
throw new Error("Run interactions are not supported in this runtime.");
|
|
1393
|
+
}
|
|
1394
|
+
return handler(request);
|
|
1395
|
+
},
|
|
1396
|
+
tools: {
|
|
1397
|
+
list: () => {
|
|
1398
|
+
return input.config.context.tools.map((t) => ({
|
|
1399
|
+
name: t.name,
|
|
1400
|
+
description: t.description,
|
|
1401
|
+
parameters: t.parameters,
|
|
1402
|
+
...t._meta !== void 0 ? { _meta: t._meta } : {}
|
|
1403
|
+
}));
|
|
1404
|
+
},
|
|
1405
|
+
call: async (_name, _args, _options) => {
|
|
1406
|
+
throw new Error("Tool calling is not available in standalone stream collector without callContext.");
|
|
1407
|
+
},
|
|
1408
|
+
report: (update) => {
|
|
1409
|
+
input.config.onToolReport?.({
|
|
1410
|
+
runId: input.config.execution.runId,
|
|
1411
|
+
update
|
|
1412
|
+
});
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
};
|
|
1416
|
+
const events = input.config.stream(input.request, callContext);
|
|
1333
1417
|
const result = await collectStreamResult({
|
|
1334
1418
|
config: input.config,
|
|
1335
1419
|
message: input.message,
|
|
@@ -1552,16 +1636,17 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1552
1636
|
let outputPayload = phaseIn?.state?.payload;
|
|
1553
1637
|
let nextPhase;
|
|
1554
1638
|
let outputMessage;
|
|
1555
|
-
let settingsProvider;
|
|
1556
1639
|
return {
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1640
|
+
hooks: {
|
|
1641
|
+
on: (eventType, handler) => {
|
|
1642
|
+
assertActive();
|
|
1643
|
+
hooks?.on(eventType, handler);
|
|
1644
|
+
trackCleanup?.(() => hooks?.off(eventType, handler));
|
|
1645
|
+
},
|
|
1646
|
+
off: (eventType, handler) => {
|
|
1647
|
+
assertActive();
|
|
1648
|
+
hooks?.off(eventType, handler);
|
|
1649
|
+
}
|
|
1565
1650
|
},
|
|
1566
1651
|
config: {
|
|
1567
1652
|
get: async (scope) => {
|
|
@@ -1611,9 +1696,28 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1611
1696
|
return store?.delete(key);
|
|
1612
1697
|
}
|
|
1613
1698
|
};
|
|
1699
|
+
},
|
|
1700
|
+
global: () => {
|
|
1701
|
+
assertActive();
|
|
1702
|
+
const store = options?.state?.global();
|
|
1703
|
+
return {
|
|
1704
|
+
get: async (key) => {
|
|
1705
|
+
assertActive();
|
|
1706
|
+
return store?.get(key);
|
|
1707
|
+
},
|
|
1708
|
+
set: async (key, value) => {
|
|
1709
|
+
assertActive();
|
|
1710
|
+
assertJsonValue(value);
|
|
1711
|
+
return store?.set(key, value);
|
|
1712
|
+
},
|
|
1713
|
+
delete: async (key) => {
|
|
1714
|
+
assertActive();
|
|
1715
|
+
return store?.delete(key);
|
|
1716
|
+
}
|
|
1717
|
+
};
|
|
1614
1718
|
}
|
|
1615
1719
|
},
|
|
1616
|
-
|
|
1720
|
+
tools: {
|
|
1617
1721
|
register: (tool) => {
|
|
1618
1722
|
assertActive();
|
|
1619
1723
|
options?.registerTool?.(tool);
|
|
@@ -1642,14 +1746,16 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1642
1746
|
};
|
|
1643
1747
|
}
|
|
1644
1748
|
},
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1749
|
+
providers: {
|
|
1750
|
+
register: (config) => {
|
|
1751
|
+
assertActive();
|
|
1752
|
+
options?.registerProvider?.(config);
|
|
1753
|
+
trackCleanup?.(() => options?.unregisterProvider?.(config.id));
|
|
1754
|
+
},
|
|
1755
|
+
unregister: (id) => {
|
|
1756
|
+
assertActive();
|
|
1757
|
+
options?.unregisterProvider?.(id);
|
|
1758
|
+
}
|
|
1653
1759
|
},
|
|
1654
1760
|
manifest: options?.manifest,
|
|
1655
1761
|
utils: {
|
|
@@ -1671,7 +1777,7 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1671
1777
|
}, off: () => {
|
|
1672
1778
|
}, emit: () => {
|
|
1673
1779
|
}, has: () => false, count: () => 0 },
|
|
1674
|
-
|
|
1780
|
+
phases: {
|
|
1675
1781
|
register: async (registration) => {
|
|
1676
1782
|
assertActive();
|
|
1677
1783
|
await options?.registerPhase?.(registration);
|
|
@@ -1692,19 +1798,25 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1692
1798
|
nextPhase = id;
|
|
1693
1799
|
},
|
|
1694
1800
|
getNextPhase: () => nextPhase,
|
|
1695
|
-
getMessage: () => outputMessage
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
settingsProvider = provider;
|
|
1706
|
-
options?.registerSettings?.(provider);
|
|
1801
|
+
getMessage: () => outputMessage
|
|
1802
|
+
},
|
|
1803
|
+
host: {
|
|
1804
|
+
contribute: (contribution) => {
|
|
1805
|
+
assertActive();
|
|
1806
|
+
if (!contribution || typeof contribution !== "object" || Array.isArray(contribution)) {
|
|
1807
|
+
throw new TypeError("Host contribution must be an object.");
|
|
1808
|
+
}
|
|
1809
|
+
if (typeof contribution.kind !== "string" || contribution.kind.trim() === "") {
|
|
1810
|
+
throw new TypeError("Host contribution requires a non-empty kind.");
|
|
1707
1811
|
}
|
|
1812
|
+
if (typeof contribution.id !== "string" || contribution.id.trim() === "") {
|
|
1813
|
+
throw new TypeError("Host contribution requires a non-empty id.");
|
|
1814
|
+
}
|
|
1815
|
+
assertJsonValue(contribution, "Host contribution");
|
|
1816
|
+
const dispose = options?.contributeToHost ? options.contributeToHost(contribution) : () => {
|
|
1817
|
+
};
|
|
1818
|
+
trackCleanup?.(dispose);
|
|
1819
|
+
return dispose;
|
|
1708
1820
|
}
|
|
1709
1821
|
}
|
|
1710
1822
|
};
|
|
@@ -1713,8 +1825,8 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1713
1825
|
// src/harness/phases/interactions.ts
|
|
1714
1826
|
var RunInteractionCancelledError = class extends Error {
|
|
1715
1827
|
code = "run_interaction_cancelled";
|
|
1716
|
-
constructor() {
|
|
1717
|
-
super(
|
|
1828
|
+
constructor(message = "Run interaction work was cancelled.") {
|
|
1829
|
+
super(message);
|
|
1718
1830
|
this.name = "RunInteractionCancelledError";
|
|
1719
1831
|
}
|
|
1720
1832
|
};
|
|
@@ -2185,17 +2297,6 @@ async function loadPhase(targetPath) {
|
|
|
2185
2297
|
}
|
|
2186
2298
|
return phase;
|
|
2187
2299
|
}
|
|
2188
|
-
async function loadPhaseSettings(phase, context) {
|
|
2189
|
-
if (!phase.factory) return void 0;
|
|
2190
|
-
let provider;
|
|
2191
|
-
const api = createExtensionAPI(void 0, {
|
|
2192
|
-
registerSettings: (candidate) => {
|
|
2193
|
-
provider = candidate;
|
|
2194
|
-
}
|
|
2195
|
-
});
|
|
2196
|
-
await phase.factory(api);
|
|
2197
|
-
return provider ? provider(context) : void 0;
|
|
2198
|
-
}
|
|
2199
2300
|
async function loadPhaseSkills(baseDir) {
|
|
2200
2301
|
const entries = await readdir2(baseDir, { withFileTypes: true });
|
|
2201
2302
|
const skills = [];
|
|
@@ -2637,9 +2738,11 @@ function extractToolResults(transcript) {
|
|
|
2637
2738
|
}
|
|
2638
2739
|
for (const part of msg.content) {
|
|
2639
2740
|
if (part.type !== "tool_result") continue;
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2741
|
+
if (typeof part.content === "string") {
|
|
2742
|
+
const result = parseToolResult(part.content);
|
|
2743
|
+
if (result) {
|
|
2744
|
+
results.push(result);
|
|
2745
|
+
}
|
|
2643
2746
|
}
|
|
2644
2747
|
}
|
|
2645
2748
|
}
|
|
@@ -3488,10 +3591,10 @@ async function executePhase(ctx) {
|
|
|
3488
3591
|
});
|
|
3489
3592
|
await phase.factory(api);
|
|
3490
3593
|
return {
|
|
3491
|
-
message: api.
|
|
3492
|
-
route: api.
|
|
3594
|
+
message: api.phases.getMessage() ?? `${phase.name} phase completed.`,
|
|
3595
|
+
route: api.phases.getNextPhase() || "stop",
|
|
3493
3596
|
phase: phase.name,
|
|
3494
|
-
payload: api.
|
|
3597
|
+
payload: api.phases.getPayload()
|
|
3495
3598
|
};
|
|
3496
3599
|
}
|
|
3497
3600
|
return executePhaseWithModel(ctx);
|
|
@@ -3503,7 +3606,8 @@ async function executeToolCall(input) {
|
|
|
3503
3606
|
config: input.config,
|
|
3504
3607
|
toolCall: input.toolCall,
|
|
3505
3608
|
contentBlocks: input.contentBlocks,
|
|
3506
|
-
driver: input.driver
|
|
3609
|
+
driver: input.driver,
|
|
3610
|
+
options: input.options
|
|
3507
3611
|
});
|
|
3508
3612
|
} else {
|
|
3509
3613
|
const toolContext = {
|
|
@@ -3516,7 +3620,7 @@ async function executeToolCall(input) {
|
|
|
3516
3620
|
toolContext,
|
|
3517
3621
|
beforeToolCall: input.config.beforeToolCall,
|
|
3518
3622
|
afterToolCall: input.config.afterToolCall,
|
|
3519
|
-
signal: input.config.signal
|
|
3623
|
+
signal: combineSignals(input.config.signal, input.options?.signal)
|
|
3520
3624
|
});
|
|
3521
3625
|
}
|
|
3522
3626
|
return {
|
|
@@ -3548,6 +3652,28 @@ async function executeToolCalls(input) {
|
|
|
3548
3652
|
}
|
|
3549
3653
|
function createPhaseExecution(config, state, phase, messageManager, toolExecutionManager, registry) {
|
|
3550
3654
|
const interaction = createRunInteractionDriver(state, phase.name, config.signal);
|
|
3655
|
+
const executePhaseTool = async (phaseContext, toolCall, options) => {
|
|
3656
|
+
return runTurn(async () => {
|
|
3657
|
+
await toolExecutionManager.start(toolCall.id, toolCall.name, toolCall.args);
|
|
3658
|
+
const tools = phaseContext.tools.filter((tool) => tool.name !== PhaseRouteTool);
|
|
3659
|
+
const result = await executeToolCall({
|
|
3660
|
+
config: {
|
|
3661
|
+
...config,
|
|
3662
|
+
context: {
|
|
3663
|
+
...config.context,
|
|
3664
|
+
tools,
|
|
3665
|
+
skills: phaseContext.skills
|
|
3666
|
+
}
|
|
3667
|
+
},
|
|
3668
|
+
tools,
|
|
3669
|
+
toolCall,
|
|
3670
|
+
driver: interaction,
|
|
3671
|
+
options
|
|
3672
|
+
});
|
|
3673
|
+
await toolExecutionManager.end(result.toolCallId, result.toolName, result, !result.ok);
|
|
3674
|
+
return result;
|
|
3675
|
+
});
|
|
3676
|
+
};
|
|
3551
3677
|
return {
|
|
3552
3678
|
interaction,
|
|
3553
3679
|
messages: messageManager,
|
|
@@ -3591,6 +3717,51 @@ function createPhaseExecution(config, state, phase, messageManager, toolExecutio
|
|
|
3591
3717
|
}));
|
|
3592
3718
|
}
|
|
3593
3719
|
}
|
|
3720
|
+
const scope = config.execution.scope ?? [];
|
|
3721
|
+
const cwd = config.execution.cwd ?? config.context.cwd ?? "";
|
|
3722
|
+
const callContext = {
|
|
3723
|
+
signal: config.signal ?? new AbortController().signal,
|
|
3724
|
+
run: {
|
|
3725
|
+
id: config.execution.runId,
|
|
3726
|
+
agentId: config.execution.agentId,
|
|
3727
|
+
scope,
|
|
3728
|
+
cwd
|
|
3729
|
+
},
|
|
3730
|
+
interact: async (interactionReq) => {
|
|
3731
|
+
const handler = config.runtime?.interact ?? config.interact;
|
|
3732
|
+
if (!handler) {
|
|
3733
|
+
throw new Error("Run interactions are not supported in this runtime.");
|
|
3734
|
+
}
|
|
3735
|
+
return handler(interactionReq);
|
|
3736
|
+
},
|
|
3737
|
+
tools: {
|
|
3738
|
+
list: () => {
|
|
3739
|
+
const tools = phaseContext.tools.filter((tool) => tool.name !== PhaseRouteTool);
|
|
3740
|
+
return tools.map((t) => ({
|
|
3741
|
+
name: t.name,
|
|
3742
|
+
description: t.description,
|
|
3743
|
+
parameters: t.parameters,
|
|
3744
|
+
...t._meta !== void 0 ? { _meta: t._meta } : {}
|
|
3745
|
+
}));
|
|
3746
|
+
},
|
|
3747
|
+
call: async (name, args, options2) => {
|
|
3748
|
+
const toolCallId = createId("call");
|
|
3749
|
+
const toolCall = {
|
|
3750
|
+
id: toolCallId,
|
|
3751
|
+
name,
|
|
3752
|
+
args
|
|
3753
|
+
};
|
|
3754
|
+
const res = await executePhaseTool(phaseContext, toolCall, options2);
|
|
3755
|
+
return res.ok ? { ok: true, content: res.content } : { ok: false, error: res.error ?? "Tool execution failed", ...res.content !== void 0 ? { content: res.content } : {} };
|
|
3756
|
+
},
|
|
3757
|
+
report: (update) => {
|
|
3758
|
+
config.onToolReport?.({
|
|
3759
|
+
runId: config.execution.runId,
|
|
3760
|
+
update
|
|
3761
|
+
});
|
|
3762
|
+
}
|
|
3763
|
+
}
|
|
3764
|
+
};
|
|
3594
3765
|
const result = await runTurn(
|
|
3595
3766
|
() => withRetry(
|
|
3596
3767
|
() => invokeModel({
|
|
@@ -3600,7 +3771,8 @@ function createPhaseExecution(config, state, phase, messageManager, toolExecutio
|
|
|
3600
3771
|
phaseId: phase.name,
|
|
3601
3772
|
output: options.output,
|
|
3602
3773
|
onThinkingDelta: config.onThinkingDelta,
|
|
3603
|
-
onToolCallDelta: config.onToolCallDelta
|
|
3774
|
+
onToolCallDelta: config.onToolCallDelta,
|
|
3775
|
+
callContext
|
|
3604
3776
|
}),
|
|
3605
3777
|
{
|
|
3606
3778
|
signal: config.signal,
|
|
@@ -3623,27 +3795,7 @@ function createPhaseExecution(config, state, phase, messageManager, toolExecutio
|
|
|
3623
3795
|
async reportStatus(status) {
|
|
3624
3796
|
await config.onPhaseStatus?.(phase.name, status);
|
|
3625
3797
|
},
|
|
3626
|
-
|
|
3627
|
-
return runTurn(async () => {
|
|
3628
|
-
await toolExecutionManager.start(toolCall.id, toolCall.name, toolCall.args);
|
|
3629
|
-
const tools = phaseContext.tools.filter((tool) => tool.name !== PhaseRouteTool);
|
|
3630
|
-
const result = await executeToolCall({
|
|
3631
|
-
config: {
|
|
3632
|
-
...config,
|
|
3633
|
-
context: {
|
|
3634
|
-
...config.context,
|
|
3635
|
-
tools,
|
|
3636
|
-
skills: phaseContext.skills
|
|
3637
|
-
}
|
|
3638
|
-
},
|
|
3639
|
-
tools,
|
|
3640
|
-
toolCall,
|
|
3641
|
-
driver: interaction
|
|
3642
|
-
});
|
|
3643
|
-
await toolExecutionManager.end(result.toolCallId, result.toolName, result, !result.ok);
|
|
3644
|
-
return result;
|
|
3645
|
-
});
|
|
3646
|
-
},
|
|
3798
|
+
executeTool: executePhaseTool,
|
|
3647
3799
|
async executeTools(phaseContext, toolCalls, contentBlocks) {
|
|
3648
3800
|
return runTurn(async () => {
|
|
3649
3801
|
const tools = phaseContext.tools.filter((tool) => tool.name !== PhaseRouteTool);
|
|
@@ -3913,6 +4065,7 @@ async function executeOnce(input) {
|
|
|
3913
4065
|
onModelTranscript: input.onModelTranscript,
|
|
3914
4066
|
onPhaseEntered: input.onPhaseEntered,
|
|
3915
4067
|
onPhaseStatus: input.onPhaseStatus,
|
|
4068
|
+
onToolReport: input.onToolReport,
|
|
3916
4069
|
runtime: input.runtime,
|
|
3917
4070
|
waitForInput: async (nextState, request) => {
|
|
3918
4071
|
if (!nextState || !request) throw new Error("Input boundary did not include execution state.");
|
|
@@ -4003,6 +4156,46 @@ function isContinuation(value) {
|
|
|
4003
4156
|
return value.previousResults.every((result) => isRecord2(result) && typeof result.name === "string" && (result.output === void 0 || isJsonValue(result.output))) && (value.pendingInstruction === void 0 || typeof value.pendingInstruction === "string") && (value.previousPhaseMessageId === void 0 || typeof value.previousPhaseMessageId === "string");
|
|
4004
4157
|
}
|
|
4005
4158
|
|
|
4159
|
+
// src/runtime/tool-call-merge.ts
|
|
4160
|
+
function isValidPresentationOutput(output) {
|
|
4161
|
+
if (typeof output !== "object" || output === null || Array.isArray(output)) return false;
|
|
4162
|
+
const o = output;
|
|
4163
|
+
if (o.title !== void 0 && typeof o.title !== "string") return false;
|
|
4164
|
+
if (o.locations !== void 0) {
|
|
4165
|
+
if (!Array.isArray(o.locations)) return false;
|
|
4166
|
+
for (const loc of o.locations) {
|
|
4167
|
+
if (typeof loc !== "object" || loc === null || typeof loc.path !== "string") return false;
|
|
4168
|
+
if (loc.line !== void 0 && typeof loc.line !== "number") return false;
|
|
4169
|
+
}
|
|
4170
|
+
}
|
|
4171
|
+
if (o.content !== void 0) {
|
|
4172
|
+
if (!Array.isArray(o.content)) return false;
|
|
4173
|
+
for (const c of o.content) {
|
|
4174
|
+
if (typeof c !== "object" || c === null || typeof c.type !== "string") return false;
|
|
4175
|
+
}
|
|
4176
|
+
}
|
|
4177
|
+
if (o._meta !== void 0) {
|
|
4178
|
+
if (typeof o._meta !== "object" || o._meta === null || Array.isArray(o._meta)) return false;
|
|
4179
|
+
}
|
|
4180
|
+
return true;
|
|
4181
|
+
}
|
|
4182
|
+
function mergeToolCall(target, patch) {
|
|
4183
|
+
if (patch.title !== void 0) target.title = patch.title;
|
|
4184
|
+
if (patch.kind !== void 0) target.kind = patch.kind;
|
|
4185
|
+
if (patch.status !== void 0) target.status = patch.status;
|
|
4186
|
+
if (patch.locations !== void 0) target.locations = structuredClone(patch.locations);
|
|
4187
|
+
if (patch.content !== void 0) target.content = structuredClone(patch.content);
|
|
4188
|
+
if (patch.rawInput !== void 0) target.rawInput = structuredClone(patch.rawInput);
|
|
4189
|
+
if (patch.rawOutput !== void 0) target.rawOutput = structuredClone(patch.rawOutput);
|
|
4190
|
+
if (patch._meta !== void 0) {
|
|
4191
|
+
target._meta = {
|
|
4192
|
+
...target._meta ?? {},
|
|
4193
|
+
...structuredClone(patch._meta)
|
|
4194
|
+
};
|
|
4195
|
+
}
|
|
4196
|
+
return target;
|
|
4197
|
+
}
|
|
4198
|
+
|
|
4006
4199
|
// src/runtime/contracts.ts
|
|
4007
4200
|
var THINKING_LEVELS = [
|
|
4008
4201
|
"off",
|
|
@@ -4013,23 +4206,8 @@ var THINKING_LEVELS = [
|
|
|
4013
4206
|
"xhigh",
|
|
4014
4207
|
"max"
|
|
4015
4208
|
];
|
|
4016
|
-
function
|
|
4017
|
-
|
|
4018
|
-
const mori = record?.mori;
|
|
4019
|
-
if (!isRecord3(mori)) return void 0;
|
|
4020
|
-
const level = mori.thinkingLevel;
|
|
4021
|
-
return typeof level === "string" && THINKING_LEVELS.includes(level) ? level : void 0;
|
|
4022
|
-
}
|
|
4023
|
-
function thinkingLevelFromMessages(messages) {
|
|
4024
|
-
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
4025
|
-
const message = messages[index];
|
|
4026
|
-
if (message?.role !== "user") continue;
|
|
4027
|
-
const metadata = message.metadata;
|
|
4028
|
-
const kind = isRecord3(metadata) && typeof metadata.kind === "string" ? metadata.kind : void 0;
|
|
4029
|
-
if (kind === "phase_prompt" || kind === "phase_input") continue;
|
|
4030
|
-
return thinkingLevelFromMetadata(metadata);
|
|
4031
|
-
}
|
|
4032
|
-
return void 0;
|
|
4209
|
+
function thinkingLevelFromUserInput(input) {
|
|
4210
|
+
return typeof input === "string" ? void 0 : input.thinkingLevel;
|
|
4033
4211
|
}
|
|
4034
4212
|
var METADATA_LIMIT = 64 * 1024;
|
|
4035
4213
|
var IDENTITY_LIMIT = 256;
|
|
@@ -4085,8 +4263,13 @@ function isAssistantContent(value) {
|
|
|
4085
4263
|
}
|
|
4086
4264
|
function normalizeUserInput(input) {
|
|
4087
4265
|
const normalized = typeof input === "string" ? { content: input } : input;
|
|
4088
|
-
if (!isRecord3(normalized) || !hasOnlyKeys(normalized, ["content", "metadata"]) || !isUserContent(normalized.content))
|
|
4266
|
+
if (!isRecord3(normalized) || !hasOnlyKeys(normalized, ["content", "metadata", "thinkingLevel"]) || !isUserContent(normalized.content)) {
|
|
4267
|
+
throw new TypeError("input must contain only valid UserContent");
|
|
4268
|
+
}
|
|
4089
4269
|
if (normalized.metadata !== void 0) assertMetadata(normalized.metadata, "input.metadata");
|
|
4270
|
+
if (normalized.thinkingLevel !== void 0 && !THINKING_LEVELS.includes(normalized.thinkingLevel)) {
|
|
4271
|
+
throw new TypeError("input.thinkingLevel must be a valid ThinkingLevel");
|
|
4272
|
+
}
|
|
4090
4273
|
assertJsonValue(normalized, "input");
|
|
4091
4274
|
return normalized;
|
|
4092
4275
|
}
|
|
@@ -4094,9 +4277,16 @@ function isAssistantMessage(value) {
|
|
|
4094
4277
|
return isRecord3(value) && hasOnlyKeys(value, ["id", "agentId", "runId", "messageRevision", "role", "content", "metadata", "sequenceWithinRun", "createdAt", "interrupted"]) && typeof value.id === "string" && typeof value.agentId === "string" && typeof value.runId === "string" && value.role === "assistant" && (value.messageRevision === void 0 || Number.isInteger(value.messageRevision) && value.messageRevision >= 0) && Number.isInteger(value.sequenceWithinRun) && value.sequenceWithinRun >= 0 && typeof value.createdAt === "string" && isAssistantContent(value.content) && (value.metadata === void 0 || isMetadata(value.metadata)) && (value.interrupted === void 0 || typeof value.interrupted === "boolean");
|
|
4095
4278
|
}
|
|
4096
4279
|
function isToolResult(value) {
|
|
4097
|
-
if (!isRecord3(value)
|
|
4280
|
+
if (!isRecord3(value)) return false;
|
|
4281
|
+
if (value.structuredContent !== void 0 && !isJsonValue(value.structuredContent)) return false;
|
|
4282
|
+
if (Array.isArray(value.content)) {
|
|
4283
|
+
if (value.isError !== void 0 && typeof value.isError !== "boolean") return false;
|
|
4284
|
+
return true;
|
|
4285
|
+
}
|
|
4286
|
+
if (!isJsonValue(value.content) || typeof value.ok !== "boolean") return false;
|
|
4287
|
+
const keys = Object.keys(value).filter((k) => k !== "structuredContent").sort();
|
|
4098
4288
|
const expected = value.ok ? ["content", "ok"] : ["content", "error", "ok"];
|
|
4099
|
-
if (JSON.stringify(
|
|
4289
|
+
if (JSON.stringify(keys) !== JSON.stringify(expected)) return false;
|
|
4100
4290
|
return value.ok || typeof value.error === "string";
|
|
4101
4291
|
}
|
|
4102
4292
|
function assertAgentConfiguration(config) {
|
|
@@ -4269,17 +4459,20 @@ function encodeIdempotencyScope(storeIncarnation, scope) {
|
|
|
4269
4459
|
if (typeof storeIncarnation !== "string" || storeIncarnation.length === 0) throw new TypeError("storeIncarnation must be non-empty");
|
|
4270
4460
|
return canonicalJson([storeIncarnation, ...scope]);
|
|
4271
4461
|
}
|
|
4272
|
-
function canonicalStartRunRequest(input, metadata, phasePayload, pinnedConfigToken, entryPhases) {
|
|
4462
|
+
function canonicalStartRunRequest(input, metadata, phasePayload, pinnedConfigToken, entryPhases, scope, cwd) {
|
|
4273
4463
|
const normalized = normalizeUserInput(input);
|
|
4274
4464
|
if (metadata !== void 0) assertUtf8ByteLimit(canonicalJson(metadata), METADATA_JSON_BYTES, "run.metadata");
|
|
4275
4465
|
if (phasePayload !== void 0) assertUtf8ByteLimit(canonicalJson(phasePayload), MESSAGE_CONTENT_JSON_BYTES, "run.phasePayload");
|
|
4276
4466
|
if (entryPhases !== void 0) assertUtf8ByteLimit(canonicalJson(entryPhases), MESSAGE_CONTENT_JSON_BYTES, "run.entryPhases");
|
|
4467
|
+
if (cwd !== void 0 && typeof cwd !== "string") throw new TypeError("run.cwd must be a string");
|
|
4277
4468
|
return canonicalJson({
|
|
4278
4469
|
input: normalized,
|
|
4279
4470
|
...metadata === void 0 ? {} : { metadata },
|
|
4280
4471
|
...phasePayload === void 0 ? {} : { phasePayload },
|
|
4281
4472
|
...entryPhases === void 0 ? {} : { entryPhases },
|
|
4282
|
-
...pinnedConfigToken === void 0 ? {} : { pinnedConfigToken }
|
|
4473
|
+
...pinnedConfigToken === void 0 ? {} : { pinnedConfigToken },
|
|
4474
|
+
...scope === void 0 ? {} : { scope },
|
|
4475
|
+
...cwd === void 0 ? {} : { cwd }
|
|
4283
4476
|
});
|
|
4284
4477
|
}
|
|
4285
4478
|
|
|
@@ -4821,7 +5014,8 @@ function projectToolMessage(message, toolInteractionTexts) {
|
|
|
4821
5014
|
id: message.id,
|
|
4822
5015
|
role: message.role,
|
|
4823
5016
|
content: message.content.map((part) => {
|
|
4824
|
-
const
|
|
5017
|
+
const isError = "isError" in part.result ? Boolean(part.result.isError) : !part.result.ok;
|
|
5018
|
+
const rawResult = Array.isArray(part.result.content) ? part.result.content.map((block) => block?.type === "text" ? block.text : JSON.stringify(block)).join("\n\n") : jsonText(part.result.content);
|
|
4825
5019
|
const interactionTexts = toolInteractionTexts.get(String(part.toolCallId));
|
|
4826
5020
|
let content = rawResult;
|
|
4827
5021
|
if (interactionTexts && interactionTexts.length > 0) {
|
|
@@ -4834,7 +5028,7 @@ ${rawResult}`;
|
|
|
4834
5028
|
type: "tool_result",
|
|
4835
5029
|
toolUseId: part.providerToolCallId ?? String(part.toolCallId),
|
|
4836
5030
|
content,
|
|
4837
|
-
...
|
|
5031
|
+
...isError ? { isError: true } : {}
|
|
4838
5032
|
};
|
|
4839
5033
|
}),
|
|
4840
5034
|
createdAt: message.createdAt,
|
|
@@ -4866,12 +5060,16 @@ function projectAssistantContent(content) {
|
|
|
4866
5060
|
});
|
|
4867
5061
|
}
|
|
4868
5062
|
function projectToolContent(content) {
|
|
4869
|
-
return content.map((part) =>
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
5063
|
+
return content.map((part) => {
|
|
5064
|
+
const isError = "isError" in part.result ? Boolean(part.result.isError) : !part.result.ok;
|
|
5065
|
+
const textContent = Array.isArray(part.result.content) ? part.result.content.map((block) => block?.type === "text" ? block.text : JSON.stringify(block)).join("\n\n") : jsonText(part.result.content);
|
|
5066
|
+
return {
|
|
5067
|
+
type: "tool_result",
|
|
5068
|
+
toolUseId: part.providerToolCallId ?? part.toolCallId,
|
|
5069
|
+
content: textContent,
|
|
5070
|
+
...isError ? { isError: true } : {}
|
|
5071
|
+
};
|
|
5072
|
+
});
|
|
4875
5073
|
}
|
|
4876
5074
|
function inertRunInteraction(signal) {
|
|
4877
5075
|
const controller = signal ? void 0 : new AbortController();
|
|
@@ -4900,6 +5098,7 @@ function projectTool(tool, agentId, runId) {
|
|
|
4900
5098
|
parameters: tool.parameters,
|
|
4901
5099
|
...tool.promptSnippet ? { promptSnippet: tool.promptSnippet } : {},
|
|
4902
5100
|
...tool.promptGuidelines ? { promptGuidelines: [...tool.promptGuidelines] } : {},
|
|
5101
|
+
...tool._meta !== void 0 ? { _meta: tool._meta } : {},
|
|
4903
5102
|
execute: async (args, context, signal) => {
|
|
4904
5103
|
const result = await tool.execute(args, {
|
|
4905
5104
|
agentId,
|
|
@@ -4909,7 +5108,8 @@ function projectTool(tool, agentId, runId) {
|
|
|
4909
5108
|
reportProgress: () => void 0,
|
|
4910
5109
|
interaction: context.interaction ?? inertRunInteraction(signal)
|
|
4911
5110
|
}, signal ?? new AbortController().signal);
|
|
4912
|
-
|
|
5111
|
+
const ok = "ok" in result && typeof result.ok === "boolean" ? result.ok : !result.isError;
|
|
5112
|
+
return { toolCallId: context.toolCallId, toolName: tool.name, ok, ...result };
|
|
4913
5113
|
}
|
|
4914
5114
|
};
|
|
4915
5115
|
}
|
|
@@ -5004,20 +5204,38 @@ function resolveDefinitionContext(snapshot, assembled) {
|
|
|
5004
5204
|
systemPrompt: [snapshot.definition.prompt, buildContextDescription(contexts)].filter((section) => section.length > 0).join("\n\n"),
|
|
5005
5205
|
tools,
|
|
5006
5206
|
skills,
|
|
5007
|
-
phases: { phases, entryPhaseId }
|
|
5207
|
+
phases: { phases, entryPhaseId },
|
|
5208
|
+
...snapshot.cwd ? { cwd: snapshot.cwd } : {}
|
|
5008
5209
|
};
|
|
5009
5210
|
}
|
|
5010
5211
|
function toLoopResult(result, toolCallId, toolName) {
|
|
5212
|
+
const ok = "ok" in result && typeof result.ok === "boolean" ? result.ok : !result.isError;
|
|
5213
|
+
const error = "error" in result && typeof result.error === "string" ? result.error : void 0;
|
|
5011
5214
|
return {
|
|
5012
5215
|
toolCallId,
|
|
5013
5216
|
toolName,
|
|
5014
|
-
ok
|
|
5217
|
+
ok,
|
|
5015
5218
|
content: result.content,
|
|
5016
|
-
...!
|
|
5219
|
+
...!ok && error ? { error } : {},
|
|
5220
|
+
...result.structuredContent !== void 0 ? { structuredContent: result.structuredContent } : {},
|
|
5221
|
+
...result.isError !== void 0 ? { isError: result.isError } : {}
|
|
5017
5222
|
};
|
|
5018
5223
|
}
|
|
5019
5224
|
function fromLoopResult(result) {
|
|
5020
|
-
|
|
5225
|
+
if (Array.isArray(result.content)) {
|
|
5226
|
+
return {
|
|
5227
|
+
content: result.content,
|
|
5228
|
+
...result.ok !== void 0 ? { ok: result.ok } : {},
|
|
5229
|
+
...result.structuredContent !== void 0 ? { structuredContent: result.structuredContent } : {},
|
|
5230
|
+
...result.isError !== void 0 ? { isError: result.isError } : !result.ok ? { isError: true } : {},
|
|
5231
|
+
...result.error !== void 0 ? { error: result.error } : {}
|
|
5232
|
+
};
|
|
5233
|
+
}
|
|
5234
|
+
return {
|
|
5235
|
+
...result.ok ? { ok: true } : { ok: false, error: result.error ?? "Extension hook rejected the Tool result." },
|
|
5236
|
+
content: result.content,
|
|
5237
|
+
...result.structuredContent !== void 0 ? { structuredContent: result.structuredContent } : {}
|
|
5238
|
+
};
|
|
5021
5239
|
}
|
|
5022
5240
|
|
|
5023
5241
|
// src/runtime/transient-run-events.ts
|
|
@@ -5053,6 +5271,29 @@ var TransientRunEventSubscription = class {
|
|
|
5053
5271
|
previous?.kind === "tool_call_delta" && event.kind === "tool_call_delta" && previous.executionId === event.executionId && previous.providerToolCallId === event.providerToolCallId
|
|
5054
5272
|
) {
|
|
5055
5273
|
this.queue[this.queue.length - 1] = event;
|
|
5274
|
+
} else if (event.kind === "tool_state_changed") {
|
|
5275
|
+
const toolCallId = event.toolCall.toolCallId;
|
|
5276
|
+
let index = -1;
|
|
5277
|
+
for (let i = this.queue.length - 1; i >= 0; i -= 1) {
|
|
5278
|
+
const existing = this.queue[i];
|
|
5279
|
+
if (existing && existing.kind === "tool_state_changed" && existing.runId === event.runId && existing.toolCall.toolCallId === toolCallId) {
|
|
5280
|
+
index = i;
|
|
5281
|
+
break;
|
|
5282
|
+
}
|
|
5283
|
+
}
|
|
5284
|
+
if (index !== -1) {
|
|
5285
|
+
const existing = this.queue[index];
|
|
5286
|
+
const mergedCall = { ...existing.toolCall };
|
|
5287
|
+
mergeToolCall(mergedCall, event.toolCall);
|
|
5288
|
+
this.queue[index] = {
|
|
5289
|
+
...existing,
|
|
5290
|
+
transition: { from: existing.transition.from, to: event.transition.to },
|
|
5291
|
+
toolCall: mergedCall
|
|
5292
|
+
};
|
|
5293
|
+
} else {
|
|
5294
|
+
if (this.queue.length >= MAX_BUFFERED_EVENTS) this.queue.shift();
|
|
5295
|
+
this.queue.push(event);
|
|
5296
|
+
}
|
|
5056
5297
|
} else {
|
|
5057
5298
|
if (this.queue.length >= MAX_BUFFERED_EVENTS) this.queue.shift();
|
|
5058
5299
|
this.queue.push(event);
|
|
@@ -5068,7 +5309,7 @@ var TransientRunEventSubscription = class {
|
|
|
5068
5309
|
else {
|
|
5069
5310
|
for (let index = this.queue.length - 1; index >= 0; index -= 1) {
|
|
5070
5311
|
const event = this.queue[index];
|
|
5071
|
-
if (event
|
|
5312
|
+
if (event && "executionId" in event && event.executionId === executionId && !(preserveCompletedPhaseStatus && event.kind === "phase_status" && event.status.state === "completed")) {
|
|
5072
5313
|
this.queue.splice(index, 1);
|
|
5073
5314
|
}
|
|
5074
5315
|
}
|
|
@@ -5085,7 +5326,7 @@ var TransientRunEventSubscription = class {
|
|
|
5085
5326
|
clearTool(toolCallId) {
|
|
5086
5327
|
for (let index = this.queue.length - 1; index >= 0; index -= 1) {
|
|
5087
5328
|
const event = this.queue[index];
|
|
5088
|
-
if (event?.kind === "
|
|
5329
|
+
if (event?.kind === "tool_state_changed" && event.toolCall.toolCallId === toolCallId) this.queue.splice(index, 1);
|
|
5089
5330
|
}
|
|
5090
5331
|
this.notify();
|
|
5091
5332
|
}
|
|
@@ -5229,6 +5470,7 @@ var HooksManager = class {
|
|
|
5229
5470
|
var InMemoryExtensionHost = class {
|
|
5230
5471
|
configs = /* @__PURE__ */ new Map();
|
|
5231
5472
|
agentState = /* @__PURE__ */ new Map();
|
|
5473
|
+
globalState = /* @__PURE__ */ new Map();
|
|
5232
5474
|
listeners = /* @__PURE__ */ new Set();
|
|
5233
5475
|
constructor(options = {}) {
|
|
5234
5476
|
if (options.configs) {
|
|
@@ -5255,8 +5497,18 @@ var InMemoryExtensionHost = class {
|
|
|
5255
5497
|
this.agentState.set(agentId, agentMap);
|
|
5256
5498
|
}
|
|
5257
5499
|
}
|
|
5500
|
+
if (options.globalState) {
|
|
5501
|
+
for (const [extId, stateMap] of Object.entries(options.globalState)) {
|
|
5502
|
+
const map = /* @__PURE__ */ new Map();
|
|
5503
|
+
for (const [key, val] of Object.entries(stateMap)) {
|
|
5504
|
+
assertJsonValue(val);
|
|
5505
|
+
map.set(key, structuredClone(val));
|
|
5506
|
+
}
|
|
5507
|
+
this.globalState.set(extId, map);
|
|
5508
|
+
}
|
|
5509
|
+
}
|
|
5258
5510
|
}
|
|
5259
|
-
setConfig(extensionId, config, scope =
|
|
5511
|
+
setConfig(extensionId, config, scope = []) {
|
|
5260
5512
|
const scopeKey = scopeToKey(scope);
|
|
5261
5513
|
if (!this.configs.has(scopeKey)) {
|
|
5262
5514
|
this.configs.set(scopeKey, /* @__PURE__ */ new Map());
|
|
@@ -5270,19 +5522,18 @@ var InMemoryExtensionHost = class {
|
|
|
5270
5522
|
}
|
|
5271
5523
|
this.notifyConfigChanged(extensionId, scope);
|
|
5272
5524
|
}
|
|
5273
|
-
getConfig(extensionId, scope =
|
|
5525
|
+
getConfig(extensionId, scope = []) {
|
|
5526
|
+
let merged = null;
|
|
5274
5527
|
const globalConfig = this.configs.get("global")?.get(extensionId);
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
const teamConfig = this.configs.get(`team:${scope.teamId}`)?.get(extensionId);
|
|
5278
|
-
if (teamConfig) {
|
|
5279
|
-
merged = { ...merged ?? {}, ...teamConfig };
|
|
5280
|
-
}
|
|
5528
|
+
if (globalConfig) {
|
|
5529
|
+
merged = { ...globalConfig };
|
|
5281
5530
|
}
|
|
5282
|
-
|
|
5283
|
-
const
|
|
5284
|
-
|
|
5285
|
-
|
|
5531
|
+
for (let i = 1; i <= scope.length; i++) {
|
|
5532
|
+
const subScope = scope.slice(0, i);
|
|
5533
|
+
const key = scopeToKey(subScope);
|
|
5534
|
+
const layerConfig = this.configs.get(key)?.get(extensionId);
|
|
5535
|
+
if (layerConfig) {
|
|
5536
|
+
merged = { ...merged ?? {}, ...layerConfig };
|
|
5286
5537
|
}
|
|
5287
5538
|
}
|
|
5288
5539
|
return merged ? structuredClone(merged) : null;
|
|
@@ -5291,7 +5542,7 @@ var InMemoryExtensionHost = class {
|
|
|
5291
5542
|
this.listeners.add(listener);
|
|
5292
5543
|
return () => this.listeners.delete(listener);
|
|
5293
5544
|
}
|
|
5294
|
-
notifyConfigChanged(extensionId, scope =
|
|
5545
|
+
notifyConfigChanged(extensionId, scope = []) {
|
|
5295
5546
|
for (const listener of this.listeners) {
|
|
5296
5547
|
try {
|
|
5297
5548
|
listener(extensionId, scope);
|
|
@@ -5320,29 +5571,26 @@ var InMemoryExtensionHost = class {
|
|
|
5320
5571
|
deleteAgentState(extensionId, agentId, key) {
|
|
5321
5572
|
this.agentState.get(agentId)?.get(extensionId)?.delete(key);
|
|
5322
5573
|
}
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
case "global":
|
|
5327
|
-
return "global";
|
|
5328
|
-
case "team":
|
|
5329
|
-
return `team:${scope.teamId}`;
|
|
5330
|
-
case "project":
|
|
5331
|
-
return `project:${scope.teamId}:${scope.projectId}`;
|
|
5574
|
+
getGlobalState(extensionId, key) {
|
|
5575
|
+
const val = this.globalState.get(extensionId)?.get(key);
|
|
5576
|
+
return val !== void 0 ? structuredClone(val) : void 0;
|
|
5332
5577
|
}
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
return { kind: "project", teamId, projectId };
|
|
5340
|
-
}
|
|
5341
|
-
if (teamId) {
|
|
5342
|
-
return { kind: "team", teamId };
|
|
5578
|
+
setGlobalState(extensionId, key, value) {
|
|
5579
|
+
assertJsonValue(value);
|
|
5580
|
+
let extMap = this.globalState.get(extensionId);
|
|
5581
|
+
if (!extMap) {
|
|
5582
|
+
extMap = /* @__PURE__ */ new Map();
|
|
5583
|
+
this.globalState.set(extensionId, extMap);
|
|
5343
5584
|
}
|
|
5585
|
+
extMap.set(key, structuredClone(value));
|
|
5586
|
+
}
|
|
5587
|
+
deleteGlobalState(extensionId, key) {
|
|
5588
|
+
this.globalState.get(extensionId)?.delete(key);
|
|
5344
5589
|
}
|
|
5345
|
-
|
|
5590
|
+
};
|
|
5591
|
+
function scopeToKey(scope) {
|
|
5592
|
+
if (scope.length === 0) return "global";
|
|
5593
|
+
return scope.map((layer) => `${layer.kind}:${layer.id}`).join("/");
|
|
5346
5594
|
}
|
|
5347
5595
|
|
|
5348
5596
|
// src/extensions/runner.ts
|
|
@@ -5456,8 +5704,9 @@ async function execCommand(command, args, cwd, options) {
|
|
|
5456
5704
|
});
|
|
5457
5705
|
}
|
|
5458
5706
|
function applyProviderRegistration(config) {
|
|
5459
|
-
|
|
5460
|
-
|
|
5707
|
+
unregisterProviderModels(config.id);
|
|
5708
|
+
if (config.stream) {
|
|
5709
|
+
registerApiProvider({ protocol: config.protocol, stream: config.stream });
|
|
5461
5710
|
}
|
|
5462
5711
|
for (const modelConfig of config.models) {
|
|
5463
5712
|
registerModel({
|
|
@@ -5467,12 +5716,13 @@ function applyProviderRegistration(config) {
|
|
|
5467
5716
|
provider: config.id,
|
|
5468
5717
|
baseUrl: config.baseUrl,
|
|
5469
5718
|
apiKey: config.apiKey,
|
|
5470
|
-
reasoning: modelConfig.reasoning,
|
|
5719
|
+
reasoning: modelConfig.reasoning ?? false,
|
|
5471
5720
|
...modelConfig.thinkingLevel !== void 0 ? { thinkingLevel: modelConfig.thinkingLevel } : {},
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5721
|
+
...modelConfig.thinkingLevels !== void 0 ? { thinkingLevels: modelConfig.thinkingLevels } : {},
|
|
5722
|
+
input: modelConfig.input ?? ["text"],
|
|
5723
|
+
cost: modelConfig.cost ?? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
5724
|
+
contextWindow: modelConfig.contextWindow ?? 128e3,
|
|
5725
|
+
maxTokens: modelConfig.maxTokens ?? 4096,
|
|
5476
5726
|
...config.headers || modelConfig.headers ? { headers: { ...config.headers, ...modelConfig.headers } } : {},
|
|
5477
5727
|
...config.timeoutMs !== void 0 ? { timeoutMs: config.timeoutMs } : {},
|
|
5478
5728
|
...config.maxRetries !== void 0 ? { maxRetries: config.maxRetries } : {},
|
|
@@ -5508,6 +5758,8 @@ var ExtensionRunner = class {
|
|
|
5508
5758
|
errorListeners = /* @__PURE__ */ new Set();
|
|
5509
5759
|
// Capability change listeners
|
|
5510
5760
|
capabilityListeners = /* @__PURE__ */ new Set();
|
|
5761
|
+
// Host contribution change listeners
|
|
5762
|
+
hostContributionListeners = /* @__PURE__ */ new Set();
|
|
5511
5763
|
/** Current agent context — set by the agent before each phase */
|
|
5512
5764
|
currentContext;
|
|
5513
5765
|
constructor(options) {
|
|
@@ -5611,6 +5863,7 @@ var ExtensionRunner = class {
|
|
|
5611
5863
|
tools: /* @__PURE__ */ new Map(),
|
|
5612
5864
|
phases: /* @__PURE__ */ new Set(),
|
|
5613
5865
|
capabilities: /* @__PURE__ */ new Map(),
|
|
5866
|
+
hostContributions: /* @__PURE__ */ new Map(),
|
|
5614
5867
|
cleanup: [],
|
|
5615
5868
|
runtime: createExtensionRuntime()
|
|
5616
5869
|
};
|
|
@@ -5623,6 +5876,9 @@ var ExtensionRunner = class {
|
|
|
5623
5876
|
if (extension.capabilities.size > 0) {
|
|
5624
5877
|
this.notifyCapabilitiesChanged();
|
|
5625
5878
|
}
|
|
5879
|
+
if (extension.hostContributions.size > 0) {
|
|
5880
|
+
this.notifyHostContributionsChanged();
|
|
5881
|
+
}
|
|
5626
5882
|
} catch (error) {
|
|
5627
5883
|
await this.rollbackExtension(extension);
|
|
5628
5884
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -5751,6 +6007,27 @@ var ExtensionRunner = class {
|
|
|
5751
6007
|
this.capabilityListeners.add(listener);
|
|
5752
6008
|
return () => this.capabilityListeners.delete(listener);
|
|
5753
6009
|
}
|
|
6010
|
+
/** Get all contributed host elements across all extensions. */
|
|
6011
|
+
getHostContributions() {
|
|
6012
|
+
const result = [];
|
|
6013
|
+
for (const ext of this.extensions) {
|
|
6014
|
+
for (const contrib of ext.hostContributions.values()) {
|
|
6015
|
+
result.push(contrib);
|
|
6016
|
+
}
|
|
6017
|
+
}
|
|
6018
|
+
return Object.freeze(result);
|
|
6019
|
+
}
|
|
6020
|
+
/**
|
|
6021
|
+
* Subscribe to host contribution changes (contributions added, removed, or extensions disposed).
|
|
6022
|
+
* Returns an unsubscribe function.
|
|
6023
|
+
*/
|
|
6024
|
+
onHostContributionsChanged(listener) {
|
|
6025
|
+
this.hostContributionListeners.add(listener);
|
|
6026
|
+
return () => this.hostContributionListeners.delete(listener);
|
|
6027
|
+
}
|
|
6028
|
+
triggerUiAction(event) {
|
|
6029
|
+
this.events.emit("ui.action", event);
|
|
6030
|
+
}
|
|
5754
6031
|
// ---------------------------------------------------------------------------
|
|
5755
6032
|
// Phase management
|
|
5756
6033
|
// ---------------------------------------------------------------------------
|
|
@@ -5868,7 +6145,7 @@ var ExtensionRunner = class {
|
|
|
5868
6145
|
}
|
|
5869
6146
|
}
|
|
5870
6147
|
async emitBeforeToolCall(tool, args, context) {
|
|
5871
|
-
const scope = context?.scope ??
|
|
6148
|
+
const scope = context?.scope ?? [];
|
|
5872
6149
|
const turn = context?.turn ?? {};
|
|
5873
6150
|
const result = await this.emitHook("before_tool_call", {
|
|
5874
6151
|
type: "before_tool_call",
|
|
@@ -5885,7 +6162,7 @@ var ExtensionRunner = class {
|
|
|
5885
6162
|
return result ?? { allow: true };
|
|
5886
6163
|
}
|
|
5887
6164
|
async emitAfterToolCall(tool, result, context) {
|
|
5888
|
-
const scope = context?.scope ??
|
|
6165
|
+
const scope = context?.scope ?? [];
|
|
5889
6166
|
const turn = context?.turn ?? {};
|
|
5890
6167
|
const hookResult = await this.emitHook("after_tool_call", {
|
|
5891
6168
|
type: "after_tool_call",
|
|
@@ -5965,12 +6242,13 @@ var ExtensionRunner = class {
|
|
|
5965
6242
|
registerTool: (tool) => this.registerTool(extension, tool),
|
|
5966
6243
|
unregisterTool: (toolName) => this.unregisterTool(extension, toolName),
|
|
5967
6244
|
contributeCapability: (contribution) => this.contributeCapability(extension, contribution),
|
|
6245
|
+
contributeToHost: (contribution) => this.contributeToHost(extension, contribution),
|
|
5968
6246
|
context: extContext,
|
|
5969
6247
|
manifest,
|
|
5970
6248
|
trackCleanup: (cleanup) => extension.cleanup.push(cleanup),
|
|
5971
6249
|
config: {
|
|
5972
6250
|
get: async (scope) => {
|
|
5973
|
-
const effectiveScope = scope ??
|
|
6251
|
+
const effectiveScope = scope ?? [];
|
|
5974
6252
|
const res = await runner.host.getConfig(extension.id, effectiveScope);
|
|
5975
6253
|
return res ?? null;
|
|
5976
6254
|
},
|
|
@@ -5999,6 +6277,11 @@ var ExtensionRunner = class {
|
|
|
5999
6277
|
get: async (key) => runner.host.getAgentState(extension.id, agentId, key),
|
|
6000
6278
|
set: async (key, value) => runner.host.setAgentState(extension.id, agentId, key, value),
|
|
6001
6279
|
delete: async (key) => runner.host.deleteAgentState(extension.id, agentId, key)
|
|
6280
|
+
}),
|
|
6281
|
+
global: () => ({
|
|
6282
|
+
get: async (key) => runner.host.getGlobalState(extension.id, key),
|
|
6283
|
+
set: async (key, value) => runner.host.setGlobalState(extension.id, key, value),
|
|
6284
|
+
delete: async (key) => runner.host.deleteGlobalState(extension.id, key)
|
|
6002
6285
|
})
|
|
6003
6286
|
}
|
|
6004
6287
|
}, extension.runtime, this.events);
|
|
@@ -6069,6 +6352,44 @@ var ExtensionRunner = class {
|
|
|
6069
6352
|
}
|
|
6070
6353
|
}
|
|
6071
6354
|
}
|
|
6355
|
+
contributeToHost(extension, contribution) {
|
|
6356
|
+
const key = `${contribution.kind}:${contribution.id}`;
|
|
6357
|
+
const entry = {
|
|
6358
|
+
...contribution
|
|
6359
|
+
};
|
|
6360
|
+
extension.hostContributions.set(key, entry);
|
|
6361
|
+
if (this.extensions.includes(extension)) {
|
|
6362
|
+
this.notifyHostContributionsChanged();
|
|
6363
|
+
}
|
|
6364
|
+
let disposed = false;
|
|
6365
|
+
const dispose = () => {
|
|
6366
|
+
if (disposed) return;
|
|
6367
|
+
disposed = true;
|
|
6368
|
+
if (extension.hostContributions.get(key) === entry) {
|
|
6369
|
+
extension.hostContributions.delete(key);
|
|
6370
|
+
if (this.extensions.includes(extension)) {
|
|
6371
|
+
this.notifyHostContributionsChanged();
|
|
6372
|
+
}
|
|
6373
|
+
}
|
|
6374
|
+
};
|
|
6375
|
+
extension.cleanup.push(dispose);
|
|
6376
|
+
return dispose;
|
|
6377
|
+
}
|
|
6378
|
+
notifyHostContributionsChanged() {
|
|
6379
|
+
const contributions = this.getHostContributions();
|
|
6380
|
+
for (const listener of this.hostContributionListeners) {
|
|
6381
|
+
try {
|
|
6382
|
+
listener(contributions);
|
|
6383
|
+
} catch (error) {
|
|
6384
|
+
this.emitError({
|
|
6385
|
+
extensionPath: "<runtime>",
|
|
6386
|
+
event: "host_contributions_changed",
|
|
6387
|
+
error: error instanceof Error ? error.message : String(error),
|
|
6388
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
6389
|
+
});
|
|
6390
|
+
}
|
|
6391
|
+
}
|
|
6392
|
+
}
|
|
6072
6393
|
async registerPhase(extension, registration) {
|
|
6073
6394
|
if (typeof registration === "string") {
|
|
6074
6395
|
if (registration.length === 0) {
|
|
@@ -6157,6 +6478,8 @@ var ExtensionRunner = class {
|
|
|
6157
6478
|
for (const name of extension.phases) this.phases.delete(name);
|
|
6158
6479
|
const hadCapabilities = extension.capabilities.size > 0;
|
|
6159
6480
|
extension.capabilities.clear();
|
|
6481
|
+
const hadHostContributions = extension.hostContributions.size > 0;
|
|
6482
|
+
extension.hostContributions.clear();
|
|
6160
6483
|
for (const cleanup of [...extension.cleanup].reverse()) {
|
|
6161
6484
|
await Promise.resolve().then(() => cleanup()).catch(() => void 0);
|
|
6162
6485
|
}
|
|
@@ -6167,6 +6490,9 @@ var ExtensionRunner = class {
|
|
|
6167
6490
|
if (hadCapabilities) {
|
|
6168
6491
|
this.notifyCapabilitiesChanged();
|
|
6169
6492
|
}
|
|
6493
|
+
if (hadHostContributions) {
|
|
6494
|
+
this.notifyHostContributionsChanged();
|
|
6495
|
+
}
|
|
6170
6496
|
}
|
|
6171
6497
|
};
|
|
6172
6498
|
function createExtensionRunner(options) {
|
|
@@ -6859,11 +7185,11 @@ function adaptExtensionTool(input) {
|
|
|
6859
7185
|
parameters: definition.parameters,
|
|
6860
7186
|
...definition.promptSnippet ? { promptSnippet: definition.promptSnippet } : {},
|
|
6861
7187
|
...definition.promptGuidelines ? { promptGuidelines: definition.promptGuidelines } : {},
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
7188
|
+
...definition.kind ? { kind: definition.kind } : {},
|
|
7189
|
+
...definition.annotations ? { annotations: definition.annotations } : {},
|
|
7190
|
+
...definition._meta !== void 0 ? { _meta: definition._meta } : {},
|
|
7191
|
+
...definition.present ? { present: definition.present } : {},
|
|
7192
|
+
execute: async (args, context, signal) => definition.execute(args, context, signal)
|
|
6867
7193
|
};
|
|
6868
7194
|
}
|
|
6869
7195
|
|
|
@@ -6931,12 +7257,53 @@ async function spillLargeToolResult(result, archiveDir, toolName) {
|
|
|
6931
7257
|
await writeFile2(path, serialized, { encoding: "utf8", mode: 384 });
|
|
6932
7258
|
await chmod2(path, 384).catch(() => void 0);
|
|
6933
7259
|
const preview = new TextDecoder().decode(bytes.subarray(0, MAX_INLINE_TOOL_RESULT_BYTES));
|
|
6934
|
-
|
|
6935
|
-
...result,
|
|
6936
|
-
content: `${preview}
|
|
7260
|
+
const truncatedText = `${preview}
|
|
6937
7261
|
[truncated]
|
|
6938
7262
|
|
|
6939
|
-
[Full result: ${path}, offset 0]
|
|
7263
|
+
[Full result: ${path}, offset 0]`;
|
|
7264
|
+
if (Array.isArray(result.content)) {
|
|
7265
|
+
return {
|
|
7266
|
+
...result,
|
|
7267
|
+
content: [{ type: "text", text: truncatedText }]
|
|
7268
|
+
};
|
|
7269
|
+
}
|
|
7270
|
+
if (result.ok) {
|
|
7271
|
+
return {
|
|
7272
|
+
ok: true,
|
|
7273
|
+
content: truncatedText,
|
|
7274
|
+
...result.structuredContent !== void 0 ? { structuredContent: result.structuredContent } : {}
|
|
7275
|
+
};
|
|
7276
|
+
}
|
|
7277
|
+
return {
|
|
7278
|
+
ok: false,
|
|
7279
|
+
content: truncatedText,
|
|
7280
|
+
error: result.error ?? "Tool execution failed.",
|
|
7281
|
+
...result.structuredContent !== void 0 ? { structuredContent: result.structuredContent } : {}
|
|
7282
|
+
};
|
|
7283
|
+
}
|
|
7284
|
+
async function presentToolCall(tool, call) {
|
|
7285
|
+
if (!tool.present) return void 0;
|
|
7286
|
+
try {
|
|
7287
|
+
const res = await tool.present(call);
|
|
7288
|
+
if (!res) return void 0;
|
|
7289
|
+
if (!isValidPresentationOutput(res)) {
|
|
7290
|
+
console.warn(`Tool "${tool.name}" present() returned invalid shape for status "${call.status}":`, res);
|
|
7291
|
+
return void 0;
|
|
7292
|
+
}
|
|
7293
|
+
return res;
|
|
7294
|
+
} catch (err) {
|
|
7295
|
+
console.warn(`Tool "${tool.name}" present() threw for status "${call.status}":`, err);
|
|
7296
|
+
return void 0;
|
|
7297
|
+
}
|
|
7298
|
+
}
|
|
7299
|
+
async function presentToolPending(tool, args) {
|
|
7300
|
+
const pres = await presentToolCall(tool, { status: "pending", args });
|
|
7301
|
+
return {
|
|
7302
|
+
title: pres?.title ?? tool.annotations?.title ?? tool.name,
|
|
7303
|
+
kind: tool.kind ?? "other",
|
|
7304
|
+
...pres?.locations !== void 0 ? { locations: pres.locations } : {},
|
|
7305
|
+
...pres?.content !== void 0 ? { content: pres.content } : {},
|
|
7306
|
+
...pres?._meta !== void 0 ? { _meta: pres._meta } : {}
|
|
6940
7307
|
};
|
|
6941
7308
|
}
|
|
6942
7309
|
var AgentRuntime = class _AgentRuntime {
|
|
@@ -6955,6 +7322,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6955
7322
|
host;
|
|
6956
7323
|
resources;
|
|
6957
7324
|
startedRuns = /* @__PURE__ */ new Set();
|
|
7325
|
+
liveInteractions = /* @__PURE__ */ new Map();
|
|
6958
7326
|
heartbeat;
|
|
6959
7327
|
pumping = false;
|
|
6960
7328
|
closed = false;
|
|
@@ -6990,6 +7358,13 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6990
7358
|
}
|
|
6991
7359
|
}
|
|
6992
7360
|
async handleRunEnd(runId, agentId, outcome) {
|
|
7361
|
+
const runLive = this.liveInteractions.get(runId);
|
|
7362
|
+
if (runLive) {
|
|
7363
|
+
for (const live of runLive.values()) {
|
|
7364
|
+
live.reject(new RunInteractionCancelledError("Run ended."));
|
|
7365
|
+
}
|
|
7366
|
+
this.liveInteractions.delete(runId);
|
|
7367
|
+
}
|
|
6993
7368
|
if (this.startedRuns.has(runId)) {
|
|
6994
7369
|
this.startedRuns.delete(runId);
|
|
6995
7370
|
try {
|
|
@@ -7133,6 +7508,8 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7133
7508
|
agentId,
|
|
7134
7509
|
input,
|
|
7135
7510
|
...options.metadata === void 0 ? {} : { metadata: options.metadata },
|
|
7511
|
+
...options.scope === void 0 ? {} : { scope: options.scope },
|
|
7512
|
+
...options.cwd === void 0 ? {} : { cwd: options.cwd },
|
|
7136
7513
|
...phasePayload === void 0 ? {} : { phasePayload },
|
|
7137
7514
|
...options.entryPhases === void 0 ? {} : { entryPhases: options.entryPhases },
|
|
7138
7515
|
...pinnedConfigToken === agent.currentConfigToken ? {} : { pinnedConfigToken },
|
|
@@ -7221,12 +7598,72 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7221
7598
|
this.assertOpen();
|
|
7222
7599
|
return this.resources.extensionRunner.onCapabilitiesChanged(listener);
|
|
7223
7600
|
}
|
|
7601
|
+
listHostContributions() {
|
|
7602
|
+
this.assertOpen();
|
|
7603
|
+
return this.resources.extensionRunner.getHostContributions();
|
|
7604
|
+
}
|
|
7605
|
+
onHostContributionsChanged(listener) {
|
|
7606
|
+
this.assertOpen();
|
|
7607
|
+
return this.resources.extensionRunner.onHostContributionsChanged(listener);
|
|
7608
|
+
}
|
|
7609
|
+
triggerUiAction(event) {
|
|
7610
|
+
this.assertOpen();
|
|
7611
|
+
this.resources.extensionRunner.triggerUiAction(event);
|
|
7612
|
+
}
|
|
7613
|
+
liveInteract(runId, request, signal) {
|
|
7614
|
+
if (signal.aborted) {
|
|
7615
|
+
return Promise.reject(signal.reason ?? new Error("Run aborted"));
|
|
7616
|
+
}
|
|
7617
|
+
const interactionId = request.id ?? createId("interaction");
|
|
7618
|
+
const interaction = {
|
|
7619
|
+
id: interactionId,
|
|
7620
|
+
phase: "default",
|
|
7621
|
+
kind: request.kind,
|
|
7622
|
+
prompt: request.prompt,
|
|
7623
|
+
payload: request.payload,
|
|
7624
|
+
toolCallId: request.toolCallId,
|
|
7625
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7626
|
+
status: "pending",
|
|
7627
|
+
result: request.result
|
|
7628
|
+
};
|
|
7629
|
+
let runLive = this.liveInteractions.get(runId);
|
|
7630
|
+
if (!runLive) {
|
|
7631
|
+
runLive = /* @__PURE__ */ new Map();
|
|
7632
|
+
this.liveInteractions.set(runId, runLive);
|
|
7633
|
+
}
|
|
7634
|
+
return new Promise((resolve9, reject) => {
|
|
7635
|
+
const onAbort = () => {
|
|
7636
|
+
runLive?.delete(interactionId);
|
|
7637
|
+
if (runLive && runLive.size === 0) this.liveInteractions.delete(runId);
|
|
7638
|
+
signal.removeEventListener("abort", onAbort);
|
|
7639
|
+
reject(signal.reason ?? new Error("Run aborted"));
|
|
7640
|
+
};
|
|
7641
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
7642
|
+
runLive.set(interactionId, {
|
|
7643
|
+
interaction,
|
|
7644
|
+
resolve: (val) => {
|
|
7645
|
+
signal.removeEventListener("abort", onAbort);
|
|
7646
|
+
resolve9(val);
|
|
7647
|
+
},
|
|
7648
|
+
reject: (err) => {
|
|
7649
|
+
signal.removeEventListener("abort", onAbort);
|
|
7650
|
+
reject(err);
|
|
7651
|
+
}
|
|
7652
|
+
});
|
|
7653
|
+
});
|
|
7654
|
+
}
|
|
7224
7655
|
async close() {
|
|
7225
7656
|
if (this.closed) return;
|
|
7226
7657
|
this.closed = true;
|
|
7227
7658
|
if (this.heartbeat) clearInterval(this.heartbeat);
|
|
7228
7659
|
for (const execution of this.executions.values()) execution.controller.abort();
|
|
7229
7660
|
this.executions.clear();
|
|
7661
|
+
for (const runLive of this.liveInteractions.values()) {
|
|
7662
|
+
for (const live of runLive.values()) {
|
|
7663
|
+
live.reject(new RunInteractionCancelledError("Runtime closed."));
|
|
7664
|
+
}
|
|
7665
|
+
}
|
|
7666
|
+
this.liveInteractions.clear();
|
|
7230
7667
|
this.transientEvents.close();
|
|
7231
7668
|
for (const subscription of this.consumers.values()) subscription.controller.abort();
|
|
7232
7669
|
await this.resources.closeExtensions();
|
|
@@ -7234,7 +7671,15 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7234
7671
|
}
|
|
7235
7672
|
async snapshot(runId) {
|
|
7236
7673
|
this.assertOpen();
|
|
7237
|
-
|
|
7674
|
+
const snap = await this.owned.snapshotRun(runId);
|
|
7675
|
+
const runLive = this.liveInteractions.get(runId);
|
|
7676
|
+
if (runLive && runLive.size > 0 && snap.state === "running") {
|
|
7677
|
+
return {
|
|
7678
|
+
...snap,
|
|
7679
|
+
interactions: [...runLive.values()].map((l) => l.interaction)
|
|
7680
|
+
};
|
|
7681
|
+
}
|
|
7682
|
+
return snap;
|
|
7238
7683
|
}
|
|
7239
7684
|
async history(agentId) {
|
|
7240
7685
|
this.assertOpen();
|
|
@@ -7242,6 +7687,20 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7242
7687
|
}
|
|
7243
7688
|
async respondInteraction(runId, input) {
|
|
7244
7689
|
this.assertOpen();
|
|
7690
|
+
const runLive = this.liveInteractions.get(runId);
|
|
7691
|
+
const live = runLive?.get(input.interactionId);
|
|
7692
|
+
if (live) {
|
|
7693
|
+
runLive.delete(input.interactionId);
|
|
7694
|
+
if (runLive.size === 0) this.liveInteractions.delete(runId);
|
|
7695
|
+
if (input.cancel) {
|
|
7696
|
+
live.reject(new RunInteractionCancelledError("Run interaction cancelled."));
|
|
7697
|
+
} else if (input.input !== void 0) {
|
|
7698
|
+
live.resolve(input.input);
|
|
7699
|
+
} else {
|
|
7700
|
+
live.reject(new TypeError("respondInteraction requires input or cancel: true"));
|
|
7701
|
+
}
|
|
7702
|
+
return;
|
|
7703
|
+
}
|
|
7245
7704
|
const snapshot = await this.owned.snapshotRun(runId);
|
|
7246
7705
|
if (snapshot.state !== "input_required" || !snapshot.interactions.some((interaction) => interaction.id === input.interactionId)) {
|
|
7247
7706
|
throw new RuntimeError("input_request_conflict", { runId, interactionId: input.interactionId, reason: "not_found" });
|
|
@@ -7251,6 +7710,13 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7251
7710
|
}
|
|
7252
7711
|
async cancel(runId, reason) {
|
|
7253
7712
|
this.assertOpen();
|
|
7713
|
+
const runLive = this.liveInteractions.get(runId);
|
|
7714
|
+
if (runLive) {
|
|
7715
|
+
for (const live of runLive.values()) {
|
|
7716
|
+
live.reject(new RunInteractionCancelledError(reason ?? "Agent run stopped."));
|
|
7717
|
+
}
|
|
7718
|
+
this.liveInteractions.delete(runId);
|
|
7719
|
+
}
|
|
7254
7720
|
const done = this.executionDone.get(runId);
|
|
7255
7721
|
if (done) {
|
|
7256
7722
|
this.cancellationRequested.add(runId);
|
|
@@ -7309,6 +7775,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7309
7775
|
async execute(run) {
|
|
7310
7776
|
let claim;
|
|
7311
7777
|
let executionRevision = run.revision;
|
|
7778
|
+
let toolQueue = Promise.resolve();
|
|
7312
7779
|
try {
|
|
7313
7780
|
const agent = await this.requireAgent(run.agentId);
|
|
7314
7781
|
let token = run.pinnedConfigToken ?? agent.currentConfigToken;
|
|
@@ -7396,7 +7863,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7396
7863
|
const assembly = assembleRegisteredExtensions(config, this.resources.extensionRunner, {
|
|
7397
7864
|
toolArchiveDir: this.archiveDirFor(run.agentId)
|
|
7398
7865
|
});
|
|
7399
|
-
|
|
7866
|
+
toolQueue = Promise.resolve();
|
|
7400
7867
|
const model = "stream" in config && config.stream ? config.model : { provider: config.model.provider, id: config.model.id };
|
|
7401
7868
|
const stream = "stream" in config && config.stream ? config.stream : createModelStream(config.model);
|
|
7402
7869
|
const phaseRegistry = normalizePhaseRegistry(assembly.context.phases);
|
|
@@ -7435,10 +7902,12 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7435
7902
|
executionId: claim.execution.executionId,
|
|
7436
7903
|
input: typeof run.input === "string" ? run.input : run.input.content,
|
|
7437
7904
|
...agent.metadata === void 0 ? {} : { agentMetadata: agent.metadata },
|
|
7438
|
-
...run.metadata === void 0 ? {} : { runMetadata: run.metadata }
|
|
7905
|
+
...run.metadata === void 0 ? {} : { runMetadata: run.metadata },
|
|
7906
|
+
...run.scope === void 0 ? {} : { scope: run.scope },
|
|
7907
|
+
...run.cwd === void 0 ? {} : { cwd: run.cwd }
|
|
7439
7908
|
},
|
|
7440
7909
|
model,
|
|
7441
|
-
thinkingLevel:
|
|
7910
|
+
thinkingLevel: thinkingLevelFromUserInput(run.input),
|
|
7442
7911
|
stream,
|
|
7443
7912
|
maxAttempts: config.maxAttempts,
|
|
7444
7913
|
checkpoint: claim.run.checkpoint,
|
|
@@ -7579,21 +8048,48 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7579
8048
|
error: event.error
|
|
7580
8049
|
});
|
|
7581
8050
|
},
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
8051
|
+
onToolReport: (event) => {
|
|
8052
|
+
const active = this.executions.get(run.id);
|
|
8053
|
+
if (this.closed || controller.signal.aborted || active?.executionId !== claim.execution.executionId) return;
|
|
8054
|
+
this.transientEvents.publish({
|
|
8055
|
+
kind: "tool_state_changed",
|
|
8056
|
+
durability: "transient",
|
|
8057
|
+
runId: event.runId,
|
|
8058
|
+
executionId: claim.execution.executionId,
|
|
8059
|
+
transition: { from: null, to: event.update.status ?? "in_progress" },
|
|
8060
|
+
toolCall: event.update,
|
|
8061
|
+
external: true
|
|
8062
|
+
});
|
|
8063
|
+
const task = toolQueue.then(async () => {
|
|
8064
|
+
const active2 = this.executions.get(run.id);
|
|
8065
|
+
if (this.closed || controller.signal.aborted || active2?.executionId !== claim.execution.executionId) return;
|
|
8066
|
+
const recorded = await this.owned.recordToolCall({
|
|
8067
|
+
runId: run.id,
|
|
8068
|
+
execution: claim.execution,
|
|
8069
|
+
update: event.update,
|
|
8070
|
+
external: true
|
|
8071
|
+
});
|
|
8072
|
+
executionRevision = recorded.runRevision;
|
|
8073
|
+
});
|
|
8074
|
+
toolQueue = task.then(() => void 0, () => void 0);
|
|
8075
|
+
},
|
|
8076
|
+
retryDelayMs: this.retryDelayMs,
|
|
8077
|
+
onContext: assembly.setContext,
|
|
8078
|
+
runtime: {
|
|
8079
|
+
interact: (request) => this.liveInteract(run.id, request, controller.signal),
|
|
8080
|
+
tools: ({ toolCall, contentBlocks, driver, options }) => {
|
|
8081
|
+
const task = toolQueue.then(async () => {
|
|
8082
|
+
const execution = await this.executeToolBatch({
|
|
8083
|
+
run,
|
|
8084
|
+
agentMetadata: agent.metadata,
|
|
8085
|
+
execution: claim.execution,
|
|
7591
8086
|
expectedRevision: executionRevision,
|
|
7592
8087
|
toolConfig: executionTools,
|
|
7593
8088
|
toolCalls: [toolCall],
|
|
7594
8089
|
contentBlocks,
|
|
7595
8090
|
signal: controller.signal,
|
|
7596
8091
|
driver,
|
|
8092
|
+
options,
|
|
7597
8093
|
onRevision: (rev) => {
|
|
7598
8094
|
executionRevision = rev;
|
|
7599
8095
|
}
|
|
@@ -7604,7 +8100,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7604
8100
|
toolQueue = task.then(() => void 0, () => void 0);
|
|
7605
8101
|
return task;
|
|
7606
8102
|
},
|
|
7607
|
-
toolsBatch: ({ toolCalls, contentBlocks, driver }) => {
|
|
8103
|
+
toolsBatch: ({ toolCalls, contentBlocks, driver, options }) => {
|
|
7608
8104
|
const task = toolQueue.then(async () => {
|
|
7609
8105
|
const execution = await this.executeToolBatch({
|
|
7610
8106
|
run,
|
|
@@ -7616,6 +8112,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7616
8112
|
contentBlocks,
|
|
7617
8113
|
signal: controller.signal,
|
|
7618
8114
|
driver,
|
|
8115
|
+
options,
|
|
7619
8116
|
onRevision: (rev) => {
|
|
7620
8117
|
executionRevision = rev;
|
|
7621
8118
|
}
|
|
@@ -7639,6 +8136,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7639
8136
|
result = await executeModel(executionContext);
|
|
7640
8137
|
}
|
|
7641
8138
|
}
|
|
8139
|
+
await toolQueue;
|
|
7642
8140
|
if (this.cancellationRequested.has(run.id) || controller.signal.aborted) {
|
|
7643
8141
|
const output2 = latestAssistant(run, result.messages, executionContext.messages.length, true);
|
|
7644
8142
|
const reason = this.cancellationReasons.get(run.id) ?? "Agent run stopped.";
|
|
@@ -7711,6 +8209,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7711
8209
|
} catch (error) {
|
|
7712
8210
|
if (!claim && error instanceof RuntimeError && ["run_state_conflict", "runtime_ownership_lost", "run_not_found"].includes(error.code)) return;
|
|
7713
8211
|
if (claim) {
|
|
8212
|
+
await toolQueue;
|
|
7714
8213
|
if (this.cancellationRequested.has(run.id)) {
|
|
7715
8214
|
const reason = this.cancellationReasons.get(run.id) ?? "Agent run stopped.";
|
|
7716
8215
|
await this.owned.cancelRun({
|
|
@@ -7766,7 +8265,8 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7766
8265
|
return { result: batch.results[0], revision: batch.revision };
|
|
7767
8266
|
}
|
|
7768
8267
|
async executeToolBatch(input) {
|
|
7769
|
-
const scope =
|
|
8268
|
+
const scope = input.run.scope ?? [];
|
|
8269
|
+
const cwd = input.run.cwd;
|
|
7770
8270
|
const turn = typeof input.run.input === "object" && input.run.input !== null && !Array.isArray(input.run.input) ? input.run.input : {};
|
|
7771
8271
|
const checkpoint = input.driver?.checkpoint();
|
|
7772
8272
|
const isSuspensionResume = checkpoint && typeof checkpoint === "object" && checkpoint.kind === "tool_call_suspension";
|
|
@@ -7796,6 +8296,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7796
8296
|
toolCallId,
|
|
7797
8297
|
providerToolCallId: toolCall.id,
|
|
7798
8298
|
scope,
|
|
8299
|
+
...cwd ? { cwd } : {},
|
|
7799
8300
|
turn,
|
|
7800
8301
|
interaction: createRunInteractionDriver({
|
|
7801
8302
|
currentPhase: "default",
|
|
@@ -7823,6 +8324,12 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7823
8324
|
}
|
|
7824
8325
|
}
|
|
7825
8326
|
if (!hasInteraction) {
|
|
8327
|
+
const startPresentations = await Promise.all(
|
|
8328
|
+
input.toolCalls.map(async (tc) => {
|
|
8329
|
+
const t = input.toolConfig.tools.find((c) => c.name === tc.name);
|
|
8330
|
+
return t ? presentToolPending(t, toJsonValue(tc.args)) : void 0;
|
|
8331
|
+
})
|
|
8332
|
+
);
|
|
7826
8333
|
const reserved = await this.owned.reserveToolCalls({
|
|
7827
8334
|
runId: input.run.id,
|
|
7828
8335
|
execution: input.execution,
|
|
@@ -7833,7 +8340,8 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7833
8340
|
toolCallId: toolCallIds[i],
|
|
7834
8341
|
providerToolCallId: tc.id,
|
|
7835
8342
|
name: tc.name,
|
|
7836
|
-
args: toJsonValue(tc.args)
|
|
8343
|
+
args: toJsonValue(tc.args),
|
|
8344
|
+
...startPresentations[i] ?? {}
|
|
7837
8345
|
}))
|
|
7838
8346
|
});
|
|
7839
8347
|
setRevision(reserved.run.revision);
|
|
@@ -7857,7 +8365,9 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7857
8365
|
expectedRevision: revision,
|
|
7858
8366
|
toolCallId,
|
|
7859
8367
|
state: "failed",
|
|
7860
|
-
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available.` }
|
|
8368
|
+
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available.` },
|
|
8369
|
+
title: toolCall.name,
|
|
8370
|
+
kind: "other"
|
|
7861
8371
|
});
|
|
7862
8372
|
setRevision(failed.run.revision);
|
|
7863
8373
|
results2.push(protocolFailure(`Tool ${toolCall.name} is not available.`));
|
|
@@ -7871,117 +8381,64 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7871
8381
|
expectedRevision: revision,
|
|
7872
8382
|
toolCallId,
|
|
7873
8383
|
state: "failed",
|
|
7874
|
-
result: { ok: false, content: null, error: decision.reason }
|
|
8384
|
+
result: { ok: false, content: null, error: decision.reason },
|
|
8385
|
+
title: durableTool.annotations?.title ?? durableTool.name,
|
|
8386
|
+
kind: durableTool.kind ?? "other"
|
|
7875
8387
|
});
|
|
7876
8388
|
setRevision(failed.run.revision);
|
|
7877
8389
|
results2.push(protocolFailure(decision.reason));
|
|
7878
8390
|
continue;
|
|
7879
8391
|
}
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
toolCallId,
|
|
7887
|
-
providerToolCallId,
|
|
7888
|
-
scope,
|
|
7889
|
-
turn,
|
|
7890
|
-
interaction: createToolInteractionDriver(input.driver, {
|
|
7891
|
-
toolCallId,
|
|
7892
|
-
toolCallIds,
|
|
7893
|
-
toolCalls: input.toolCalls,
|
|
7894
|
-
pendingIndex: i,
|
|
7895
|
-
completedResults: results2
|
|
7896
|
-
}),
|
|
7897
|
-
reportProgress: (progress) => {
|
|
7898
|
-
const active = this.executions.get(input.run.id);
|
|
7899
|
-
if (!progressActive || this.closed || input.signal.aborted || active?.executionId !== input.execution.executionId || !isJsonValue(progress)) return;
|
|
7900
|
-
let copy;
|
|
7901
|
-
try {
|
|
7902
|
-
if (JSON.stringify(progress).length > 64 * 1024) return;
|
|
7903
|
-
copy = structuredClone(progress);
|
|
7904
|
-
} catch {
|
|
7905
|
-
return;
|
|
7906
|
-
}
|
|
7907
|
-
this.transientEvents.publish({
|
|
7908
|
-
kind: "tool_progress",
|
|
7909
|
-
durability: "transient",
|
|
7910
|
-
runId: input.run.id,
|
|
7911
|
-
executionId: input.execution.executionId,
|
|
7912
|
-
toolCallId,
|
|
7913
|
-
progress: copy
|
|
7914
|
-
});
|
|
7915
|
-
}
|
|
8392
|
+
const currentToolState = {
|
|
8393
|
+
...startPresentations[i] ?? {
|
|
8394
|
+
title: durableTool.annotations?.title ?? durableTool.name,
|
|
8395
|
+
kind: durableTool.kind ?? "other"
|
|
8396
|
+
},
|
|
8397
|
+
rawInput: toJsonValue(toolCall.args)
|
|
7916
8398
|
};
|
|
8399
|
+
const inProgressPres = await presentToolCall(durableTool, {
|
|
8400
|
+
status: "in_progress",
|
|
8401
|
+
args: toJsonValue(toolCall.args)
|
|
8402
|
+
});
|
|
8403
|
+
if (inProgressPres) mergeToolCall(currentToolState, inProgressPres);
|
|
7917
8404
|
const started = await this.owned.startToolCall({
|
|
7918
8405
|
runId: input.run.id,
|
|
7919
8406
|
execution: input.execution,
|
|
7920
8407
|
expectedRevision: revision,
|
|
7921
|
-
toolCallId
|
|
8408
|
+
toolCallId,
|
|
8409
|
+
title: currentToolState.title ?? durableTool.annotations?.title ?? durableTool.name,
|
|
8410
|
+
kind: currentToolState.kind ?? durableTool.kind ?? "other",
|
|
8411
|
+
...currentToolState.locations !== void 0 ? { locations: currentToolState.locations } : {},
|
|
8412
|
+
...currentToolState.content !== void 0 ? { content: currentToolState.content } : {},
|
|
8413
|
+
...currentToolState._meta !== void 0 ? { _meta: currentToolState._meta } : {}
|
|
7922
8414
|
});
|
|
7923
8415
|
setRevision(started.run.revision);
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
setRevision(committed.run.revision);
|
|
7951
|
-
const projectedResult = await this.foldToolInteractionRecords(result, toolCallId, input.run.agentId);
|
|
7952
|
-
results2.push({
|
|
7953
|
-
toolCallId: providerToolCallId,
|
|
7954
|
-
toolName: toolCall.name,
|
|
7955
|
-
...projectedResult
|
|
7956
|
-
});
|
|
7957
|
-
} catch (error) {
|
|
7958
|
-
if (error instanceof RunInteractionBoundary) {
|
|
7959
|
-
const suspended = await this.owned.suspendToolCall({
|
|
7960
|
-
runId: input.run.id,
|
|
7961
|
-
execution: input.execution,
|
|
7962
|
-
expectedRevision: revision,
|
|
7963
|
-
toolCallId
|
|
7964
|
-
});
|
|
7965
|
-
setRevision(suspended.run.revision);
|
|
7966
|
-
throw error;
|
|
7967
|
-
}
|
|
7968
|
-
if (error instanceof RunInteractionCancelledError) throw error;
|
|
7969
|
-
const reason = error instanceof Error ? error.message : "Tool execution outcome is indeterminate.";
|
|
7970
|
-
const indeterminate = await this.owned.commitToolResult({
|
|
7971
|
-
runId: input.run.id,
|
|
7972
|
-
execution: input.execution,
|
|
7973
|
-
expectedRevision: revision,
|
|
7974
|
-
toolCallId,
|
|
7975
|
-
state: "indeterminate",
|
|
7976
|
-
reason,
|
|
7977
|
-
result: { ok: false, content: null, error: reason }
|
|
7978
|
-
});
|
|
7979
|
-
setRevision(indeterminate.run.revision);
|
|
7980
|
-
results2.push(protocolFailure(reason));
|
|
7981
|
-
} finally {
|
|
7982
|
-
progressActive = false;
|
|
7983
|
-
this.transientEvents.clearTool(input.run.id, toolCallId);
|
|
7984
|
-
}
|
|
8416
|
+
const toolResult2 = await this.executeAndCommitTool({
|
|
8417
|
+
runId: input.run.id,
|
|
8418
|
+
agentId: input.run.agentId,
|
|
8419
|
+
agentMetadata: input.agentMetadata,
|
|
8420
|
+
runMetadata: input.run.metadata,
|
|
8421
|
+
execution: input.execution,
|
|
8422
|
+
revision,
|
|
8423
|
+
setRevision,
|
|
8424
|
+
toolCall,
|
|
8425
|
+
durableTool,
|
|
8426
|
+
toolCallId,
|
|
8427
|
+
providerToolCallId,
|
|
8428
|
+
scope,
|
|
8429
|
+
cwd,
|
|
8430
|
+
turn,
|
|
8431
|
+
driver: input.driver,
|
|
8432
|
+
toolCalls: input.toolCalls,
|
|
8433
|
+
toolCallIds,
|
|
8434
|
+
pendingIndex: i,
|
|
8435
|
+
completedResults: results2,
|
|
8436
|
+
signal: input.signal,
|
|
8437
|
+
afterToolCall: input.toolConfig.afterToolCall,
|
|
8438
|
+
currentToolState,
|
|
8439
|
+
options: input.options
|
|
8440
|
+
});
|
|
8441
|
+
results2.push(toolResult2);
|
|
7985
8442
|
}
|
|
7986
8443
|
return { results: results2, revision };
|
|
7987
8444
|
}
|
|
@@ -8001,7 +8458,7 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
8001
8458
|
error
|
|
8002
8459
|
});
|
|
8003
8460
|
if (!durableTool) {
|
|
8004
|
-
const
|
|
8461
|
+
const reserved = await this.owned.reserveToolCalls({
|
|
8005
8462
|
runId: input.run.id,
|
|
8006
8463
|
execution: input.execution,
|
|
8007
8464
|
expectedRevision: revision,
|
|
@@ -8014,27 +8471,58 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
8014
8471
|
args: toJsonValue(toolCall.args)
|
|
8015
8472
|
}]
|
|
8016
8473
|
});
|
|
8017
|
-
setRevision(
|
|
8474
|
+
setRevision(reserved.run.revision);
|
|
8018
8475
|
const failed = await this.owned.commitToolResult({
|
|
8019
8476
|
runId: input.run.id,
|
|
8020
8477
|
execution: input.execution,
|
|
8021
8478
|
expectedRevision: revision,
|
|
8022
8479
|
toolCallId,
|
|
8023
8480
|
state: "failed",
|
|
8024
|
-
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available.` }
|
|
8481
|
+
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available.` },
|
|
8482
|
+
title: toolCall.name,
|
|
8483
|
+
kind: "other"
|
|
8025
8484
|
});
|
|
8026
8485
|
setRevision(failed.run.revision);
|
|
8027
8486
|
results.push(protocolFailure(`Tool ${toolCall.name} is not available.`));
|
|
8028
8487
|
continue;
|
|
8029
8488
|
}
|
|
8030
|
-
|
|
8031
|
-
const
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
|
|
8489
|
+
const pendingPres = await presentToolPending(durableTool, toJsonValue(toolCall.args));
|
|
8490
|
+
const currentToolState = {
|
|
8491
|
+
...pendingPres,
|
|
8492
|
+
rawInput: toJsonValue(toolCall.args)
|
|
8493
|
+
};
|
|
8494
|
+
const resumedStart = suspension && index === suspension.pendingIndex ? await (async () => {
|
|
8495
|
+
const inProgressPres = await presentToolCall(durableTool, {
|
|
8496
|
+
status: "in_progress",
|
|
8497
|
+
args: toJsonValue(toolCall.args)
|
|
8498
|
+
});
|
|
8499
|
+
if (inProgressPres) mergeToolCall(currentToolState, inProgressPres);
|
|
8500
|
+
return this.owned.startToolCall({
|
|
8501
|
+
runId: input.run.id,
|
|
8502
|
+
execution: input.execution,
|
|
8503
|
+
expectedRevision: revision,
|
|
8504
|
+
toolCallId,
|
|
8505
|
+
title: currentToolState.title ?? durableTool.annotations?.title ?? durableTool.name,
|
|
8506
|
+
kind: currentToolState.kind ?? durableTool.kind ?? "other",
|
|
8507
|
+
...currentToolState.locations !== void 0 ? { locations: currentToolState.locations } : {},
|
|
8508
|
+
...currentToolState.content !== void 0 ? { content: currentToolState.content } : {},
|
|
8509
|
+
...currentToolState._meta !== void 0 ? { _meta: currentToolState._meta } : {}
|
|
8510
|
+
});
|
|
8511
|
+
})() : void 0;
|
|
8037
8512
|
if (resumedStart) setRevision(resumedStart.run.revision);
|
|
8513
|
+
const baseDriver = input.driver ?? createRunInteractionDriver({
|
|
8514
|
+
currentPhase: "default",
|
|
8515
|
+
attempt: 0,
|
|
8516
|
+
status: "running",
|
|
8517
|
+
metrics: { iterations: 0, phaseTransitions: [], compactionCount: 0, retryCount: 0, startedAt: (/* @__PURE__ */ new Date()).toISOString(), startedAtMs: Date.now() }
|
|
8518
|
+
}, "default", input.signal);
|
|
8519
|
+
const interactionDriver = createToolInteractionDriver(baseDriver, {
|
|
8520
|
+
toolCallId,
|
|
8521
|
+
...suspension?.toolCallIds === void 0 ? {} : { toolCallIds: suspension.toolCallIds },
|
|
8522
|
+
toolCalls: input.toolCalls,
|
|
8523
|
+
pendingIndex: index,
|
|
8524
|
+
completedResults: results
|
|
8525
|
+
});
|
|
8038
8526
|
const context = {
|
|
8039
8527
|
agentId: input.run.agentId,
|
|
8040
8528
|
runId: input.run.id,
|
|
@@ -8043,32 +8531,10 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
8043
8531
|
toolCallId,
|
|
8044
8532
|
providerToolCallId,
|
|
8045
8533
|
scope,
|
|
8534
|
+
...cwd ? { cwd } : {},
|
|
8046
8535
|
turn,
|
|
8047
|
-
interaction:
|
|
8048
|
-
|
|
8049
|
-
...suspension?.toolCallIds === void 0 ? {} : { toolCallIds: suspension.toolCallIds },
|
|
8050
|
-
toolCalls: input.toolCalls,
|
|
8051
|
-
pendingIndex: index,
|
|
8052
|
-
completedResults: results
|
|
8053
|
-
}),
|
|
8054
|
-
reportProgress: (progress) => {
|
|
8055
|
-
const active = this.executions.get(input.run.id);
|
|
8056
|
-
if (!progressActive || this.closed || input.signal.aborted || active?.executionId !== input.execution.executionId || !isJsonValue(progress)) return;
|
|
8057
|
-
let copy;
|
|
8058
|
-
try {
|
|
8059
|
-
if (JSON.stringify(progress).length > 64 * 1024) return;
|
|
8060
|
-
copy = structuredClone(progress);
|
|
8061
|
-
} catch {
|
|
8062
|
-
return;
|
|
8063
|
-
}
|
|
8064
|
-
this.transientEvents.publish({
|
|
8065
|
-
kind: "tool_progress",
|
|
8066
|
-
durability: "transient",
|
|
8067
|
-
runId: input.run.id,
|
|
8068
|
-
executionId: input.execution.executionId,
|
|
8069
|
-
toolCallId,
|
|
8070
|
-
progress: copy
|
|
8071
|
-
});
|
|
8536
|
+
interaction: interactionDriver,
|
|
8537
|
+
reportProgress: () => {
|
|
8072
8538
|
}
|
|
8073
8539
|
};
|
|
8074
8540
|
const answer = suspension && index === suspension.pendingIndex ? suspension.interactionIds?.map((id) => input.driver?.answers().get(id)).find((value) => value !== void 0) : void 0;
|
|
@@ -8085,31 +8551,43 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
8085
8551
|
if (!input.driver) {
|
|
8086
8552
|
throw new Error("Tool call requested interaction but no interaction driver is active.");
|
|
8087
8553
|
}
|
|
8088
|
-
|
|
8089
|
-
if (!
|
|
8090
|
-
const
|
|
8554
|
+
interactionDriver.request(decision.interaction);
|
|
8555
|
+
if (!resumedStart) {
|
|
8556
|
+
const reserved = await this.owned.reserveToolCalls({
|
|
8091
8557
|
runId: input.run.id,
|
|
8092
8558
|
execution: input.execution,
|
|
8093
8559
|
expectedRevision: revision,
|
|
8094
8560
|
requestMessageId: createId("msg"),
|
|
8095
8561
|
contentBlocks: input.contentBlocks,
|
|
8096
|
-
calls: [{
|
|
8562
|
+
calls: [{
|
|
8563
|
+
toolCallId,
|
|
8564
|
+
providerToolCallId,
|
|
8565
|
+
name: toolCall.name,
|
|
8566
|
+
args: toJsonValue(toolCall.args),
|
|
8567
|
+
...pendingPres
|
|
8568
|
+
}]
|
|
8097
8569
|
});
|
|
8098
|
-
setRevision(
|
|
8570
|
+
setRevision(reserved.run.revision);
|
|
8099
8571
|
}
|
|
8100
|
-
|
|
8572
|
+
interactionDriver.suspend();
|
|
8101
8573
|
}
|
|
8102
8574
|
if ("allow" in decision && !decision.allow) {
|
|
8103
|
-
if (!
|
|
8104
|
-
const
|
|
8575
|
+
if (!resumedStart) {
|
|
8576
|
+
const reserved = await this.owned.reserveToolCalls({
|
|
8105
8577
|
runId: input.run.id,
|
|
8106
8578
|
execution: input.execution,
|
|
8107
8579
|
expectedRevision: revision,
|
|
8108
8580
|
requestMessageId: createId("msg"),
|
|
8109
8581
|
contentBlocks: input.contentBlocks,
|
|
8110
|
-
calls: [{
|
|
8582
|
+
calls: [{
|
|
8583
|
+
toolCallId,
|
|
8584
|
+
providerToolCallId,
|
|
8585
|
+
name: toolCall.name,
|
|
8586
|
+
args: toJsonValue(toolCall.args),
|
|
8587
|
+
...pendingPres
|
|
8588
|
+
}]
|
|
8111
8589
|
});
|
|
8112
|
-
setRevision(
|
|
8590
|
+
setRevision(reserved.run.revision);
|
|
8113
8591
|
}
|
|
8114
8592
|
const failed = await this.owned.commitToolResult({
|
|
8115
8593
|
runId: input.run.id,
|
|
@@ -8117,9 +8595,27 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
8117
8595
|
expectedRevision: revision,
|
|
8118
8596
|
toolCallId,
|
|
8119
8597
|
state: "failed",
|
|
8120
|
-
result: { ok: false, content: null, error: decision.reason }
|
|
8598
|
+
result: { ok: false, content: null, error: decision.reason },
|
|
8599
|
+
title: currentToolState.title ?? durableTool.annotations?.title ?? durableTool.name,
|
|
8600
|
+
kind: currentToolState.kind ?? durableTool.kind ?? "other",
|
|
8601
|
+
locations: currentToolState.locations,
|
|
8602
|
+
content: currentToolState.content,
|
|
8603
|
+
_meta: currentToolState._meta
|
|
8121
8604
|
});
|
|
8122
8605
|
setRevision(failed.run.revision);
|
|
8606
|
+
if (input.options?.onUpdate) {
|
|
8607
|
+
try {
|
|
8608
|
+
input.options.onUpdate(createMergedToolCall(
|
|
8609
|
+
toolCallId,
|
|
8610
|
+
"failed",
|
|
8611
|
+
currentToolState,
|
|
8612
|
+
durableTool.annotations?.title ?? durableTool.name,
|
|
8613
|
+
durableTool.kind ?? "other"
|
|
8614
|
+
));
|
|
8615
|
+
} catch (err) {
|
|
8616
|
+
console.warn(`Error in tool call onUpdate callback:`, err);
|
|
8617
|
+
}
|
|
8618
|
+
}
|
|
8123
8619
|
results.push(protocolFailure(decision.reason));
|
|
8124
8620
|
continue;
|
|
8125
8621
|
}
|
|
@@ -8129,16 +8625,22 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
8129
8625
|
throw error;
|
|
8130
8626
|
}
|
|
8131
8627
|
const reason = error instanceof Error ? error.message : "Tool policy rejected the call.";
|
|
8132
|
-
if (!
|
|
8133
|
-
const
|
|
8628
|
+
if (!resumedStart) {
|
|
8629
|
+
const reserved = await this.owned.reserveToolCalls({
|
|
8134
8630
|
runId: input.run.id,
|
|
8135
8631
|
execution: input.execution,
|
|
8136
8632
|
expectedRevision: revision,
|
|
8137
8633
|
requestMessageId: createId("msg"),
|
|
8138
8634
|
contentBlocks: input.contentBlocks,
|
|
8139
|
-
calls: [{
|
|
8635
|
+
calls: [{
|
|
8636
|
+
toolCallId,
|
|
8637
|
+
providerToolCallId,
|
|
8638
|
+
name: toolCall.name,
|
|
8639
|
+
args: toJsonValue(toolCall.args),
|
|
8640
|
+
...pendingPres
|
|
8641
|
+
}]
|
|
8140
8642
|
});
|
|
8141
|
-
setRevision(
|
|
8643
|
+
setRevision(reserved.run.revision);
|
|
8142
8644
|
}
|
|
8143
8645
|
const failed = await this.owned.commitToolResult({
|
|
8144
8646
|
runId: input.run.id,
|
|
@@ -8146,94 +8648,316 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
8146
8648
|
expectedRevision: revision,
|
|
8147
8649
|
toolCallId,
|
|
8148
8650
|
state: "failed",
|
|
8149
|
-
result: { ok: false, content: null, error: reason }
|
|
8651
|
+
result: { ok: false, content: null, error: reason },
|
|
8652
|
+
title: currentToolState.title ?? durableTool.annotations?.title ?? durableTool.name,
|
|
8653
|
+
kind: currentToolState.kind ?? durableTool.kind ?? "other",
|
|
8654
|
+
locations: currentToolState.locations,
|
|
8655
|
+
content: currentToolState.content,
|
|
8656
|
+
_meta: currentToolState._meta
|
|
8150
8657
|
});
|
|
8151
8658
|
setRevision(failed.run.revision);
|
|
8659
|
+
if (input.options?.onUpdate) {
|
|
8660
|
+
try {
|
|
8661
|
+
input.options.onUpdate(createMergedToolCall(
|
|
8662
|
+
toolCallId,
|
|
8663
|
+
"failed",
|
|
8664
|
+
currentToolState,
|
|
8665
|
+
durableTool.annotations?.title ?? durableTool.name,
|
|
8666
|
+
durableTool.kind ?? "other"
|
|
8667
|
+
));
|
|
8668
|
+
} catch (err) {
|
|
8669
|
+
console.warn(`Error in tool call onUpdate callback:`, err);
|
|
8670
|
+
}
|
|
8671
|
+
}
|
|
8152
8672
|
results.push(protocolFailure(reason));
|
|
8153
8673
|
continue;
|
|
8154
8674
|
}
|
|
8155
|
-
|
|
8156
|
-
const
|
|
8675
|
+
if (!resumedStart) {
|
|
8676
|
+
const reserved = await this.owned.reserveToolCalls({
|
|
8157
8677
|
runId: input.run.id,
|
|
8158
8678
|
execution: input.execution,
|
|
8159
8679
|
expectedRevision: revision,
|
|
8160
8680
|
requestMessageId: createId("msg"),
|
|
8161
8681
|
contentBlocks: input.contentBlocks,
|
|
8162
|
-
calls: [{
|
|
8682
|
+
calls: [{
|
|
8683
|
+
toolCallId,
|
|
8684
|
+
providerToolCallId,
|
|
8685
|
+
name: toolCall.name,
|
|
8686
|
+
args: toJsonValue(toolCall.args),
|
|
8687
|
+
...pendingPres
|
|
8688
|
+
}]
|
|
8163
8689
|
});
|
|
8164
|
-
setRevision(
|
|
8165
|
-
|
|
8166
|
-
|
|
8167
|
-
|
|
8168
|
-
expectedRevision: revision,
|
|
8169
|
-
toolCallId
|
|
8690
|
+
setRevision(reserved.run.revision);
|
|
8691
|
+
const inProgressPres = await presentToolCall(durableTool, {
|
|
8692
|
+
status: "in_progress",
|
|
8693
|
+
args: toJsonValue(toolCall.args)
|
|
8170
8694
|
});
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
progressActive = true;
|
|
8174
|
-
try {
|
|
8175
|
-
let result = await durableTool.execute(toJsonValue(toolCall.args), context, input.signal);
|
|
8176
|
-
assertToolExecutionResult(result);
|
|
8177
|
-
if (input.toolConfig.afterToolCall) {
|
|
8178
|
-
result = await input.toolConfig.afterToolCall({
|
|
8179
|
-
tool: durableTool,
|
|
8180
|
-
result,
|
|
8181
|
-
context,
|
|
8182
|
-
signal: input.signal
|
|
8183
|
-
});
|
|
8184
|
-
}
|
|
8185
|
-
assertToolExecutionResult(result);
|
|
8186
|
-
result = await spillLargeToolResult(
|
|
8187
|
-
result,
|
|
8188
|
-
this.archiveDirFor(input.run.agentId),
|
|
8189
|
-
toolCall.name
|
|
8190
|
-
);
|
|
8191
|
-
const committed = await this.owned.commitToolResult({
|
|
8695
|
+
if (inProgressPres) mergeToolCall(currentToolState, inProgressPres);
|
|
8696
|
+
const started = await this.owned.startToolCall({
|
|
8192
8697
|
runId: input.run.id,
|
|
8193
8698
|
execution: input.execution,
|
|
8194
8699
|
expectedRevision: revision,
|
|
8195
8700
|
toolCallId,
|
|
8196
|
-
|
|
8197
|
-
|
|
8701
|
+
title: currentToolState.title ?? durableTool.annotations?.title ?? durableTool.name,
|
|
8702
|
+
kind: currentToolState.kind ?? durableTool.kind ?? "other",
|
|
8703
|
+
...currentToolState.locations !== void 0 ? { locations: currentToolState.locations } : {},
|
|
8704
|
+
...currentToolState.content !== void 0 ? { content: currentToolState.content } : {},
|
|
8705
|
+
...currentToolState._meta !== void 0 ? { _meta: currentToolState._meta } : {}
|
|
8198
8706
|
});
|
|
8199
|
-
setRevision(
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8707
|
+
setRevision(started.run.revision);
|
|
8708
|
+
}
|
|
8709
|
+
const toolResult2 = await this.executeAndCommitTool({
|
|
8710
|
+
runId: input.run.id,
|
|
8711
|
+
agentId: input.run.agentId,
|
|
8712
|
+
agentMetadata: input.agentMetadata,
|
|
8713
|
+
runMetadata: input.run.metadata,
|
|
8714
|
+
execution: input.execution,
|
|
8715
|
+
revision,
|
|
8716
|
+
setRevision,
|
|
8717
|
+
toolCall,
|
|
8718
|
+
durableTool,
|
|
8719
|
+
toolCallId,
|
|
8720
|
+
providerToolCallId,
|
|
8721
|
+
scope,
|
|
8722
|
+
cwd,
|
|
8723
|
+
turn,
|
|
8724
|
+
driver: input.driver,
|
|
8725
|
+
toolCalls: input.toolCalls,
|
|
8726
|
+
toolCallIds: suspension?.toolCallIds,
|
|
8727
|
+
pendingIndex: index,
|
|
8728
|
+
completedResults: results,
|
|
8729
|
+
signal: input.signal,
|
|
8730
|
+
afterToolCall: input.toolConfig.afterToolCall,
|
|
8731
|
+
currentToolState,
|
|
8732
|
+
options: input.options
|
|
8733
|
+
});
|
|
8734
|
+
results.push(toolResult2);
|
|
8735
|
+
}
|
|
8736
|
+
input.driver?.clearCheckpoint();
|
|
8737
|
+
return { results, revision };
|
|
8738
|
+
}
|
|
8739
|
+
async executeAndCommitTool(input) {
|
|
8740
|
+
let progressActive = true;
|
|
8741
|
+
let progressQueue = Promise.resolve();
|
|
8742
|
+
const notifyUpdate = (toolCall, progress) => {
|
|
8743
|
+
if (input.options?.onUpdate) {
|
|
8744
|
+
try {
|
|
8745
|
+
input.options.onUpdate(toolCall, progress);
|
|
8746
|
+
} catch (err) {
|
|
8747
|
+
console.warn(`Error in tool call onUpdate callback:`, err);
|
|
8216
8748
|
}
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8749
|
+
}
|
|
8750
|
+
};
|
|
8751
|
+
const startToolCall = createMergedToolCall(
|
|
8752
|
+
input.toolCallId,
|
|
8753
|
+
"in_progress",
|
|
8754
|
+
input.currentToolState,
|
|
8755
|
+
input.durableTool.annotations?.title ?? input.durableTool.name,
|
|
8756
|
+
input.durableTool.kind ?? "other"
|
|
8757
|
+
);
|
|
8758
|
+
notifyUpdate(startToolCall);
|
|
8759
|
+
const effectiveSignal = combineSignals(input.signal, input.options?.signal);
|
|
8760
|
+
const baseDriver = input.driver ?? createRunInteractionDriver({
|
|
8761
|
+
currentPhase: "default",
|
|
8762
|
+
attempt: 0,
|
|
8763
|
+
status: "running",
|
|
8764
|
+
metrics: { iterations: 0, phaseTransitions: [], compactionCount: 0, retryCount: 0, startedAt: (/* @__PURE__ */ new Date()).toISOString(), startedAtMs: Date.now() }
|
|
8765
|
+
}, "default", effectiveSignal);
|
|
8766
|
+
const interactionDriver = createToolInteractionDriver(baseDriver, {
|
|
8767
|
+
toolCallId: input.toolCallId,
|
|
8768
|
+
...input.toolCallIds === void 0 ? {} : { toolCallIds: input.toolCallIds },
|
|
8769
|
+
toolCalls: input.toolCalls,
|
|
8770
|
+
pendingIndex: input.pendingIndex,
|
|
8771
|
+
completedResults: input.completedResults
|
|
8772
|
+
});
|
|
8773
|
+
const context = {
|
|
8774
|
+
agentId: input.agentId,
|
|
8775
|
+
runId: input.runId,
|
|
8776
|
+
...input.agentMetadata === void 0 ? {} : { agentMetadata: input.agentMetadata },
|
|
8777
|
+
...input.runMetadata === void 0 ? {} : { runMetadata: input.runMetadata },
|
|
8778
|
+
toolCallId: input.toolCallId,
|
|
8779
|
+
providerToolCallId: input.providerToolCallId,
|
|
8780
|
+
scope: input.scope,
|
|
8781
|
+
...input.cwd ? { cwd: input.cwd } : {},
|
|
8782
|
+
turn: input.turn,
|
|
8783
|
+
interaction: interactionDriver,
|
|
8784
|
+
reportProgress: (progress) => {
|
|
8785
|
+
const active = this.executions.get(input.runId);
|
|
8786
|
+
if (!progressActive || this.closed || effectiveSignal.aborted || active?.executionId !== input.execution.executionId) return;
|
|
8787
|
+
if (!isValidToolProgress(progress)) {
|
|
8788
|
+
console.warn(`Invalid progress report for tool "${input.durableTool.name}": expected valid ToolProgress shape with finite numbers.`);
|
|
8789
|
+
return;
|
|
8790
|
+
}
|
|
8791
|
+
let copy;
|
|
8792
|
+
try {
|
|
8793
|
+
if (JSON.stringify(progress).length > 64 * 1024) return;
|
|
8794
|
+
copy = structuredClone(progress);
|
|
8795
|
+
} catch {
|
|
8796
|
+
return;
|
|
8797
|
+
}
|
|
8798
|
+
progressQueue = progressQueue.then(async () => {
|
|
8799
|
+
if (!progressActive || this.closed || effectiveSignal.aborted) return;
|
|
8800
|
+
const pres = await presentToolCall(input.durableTool, {
|
|
8801
|
+
status: "in_progress",
|
|
8802
|
+
args: toJsonValue(input.toolCall.args),
|
|
8803
|
+
progress: copy
|
|
8804
|
+
});
|
|
8805
|
+
if (pres) {
|
|
8806
|
+
mergeToolCall(input.currentToolState, pres);
|
|
8807
|
+
const progressToolCall = createMergedToolCall(
|
|
8808
|
+
input.toolCallId,
|
|
8809
|
+
"in_progress",
|
|
8810
|
+
input.currentToolState,
|
|
8811
|
+
input.durableTool.annotations?.title ?? input.durableTool.name,
|
|
8812
|
+
input.durableTool.kind ?? "other"
|
|
8813
|
+
);
|
|
8814
|
+
this.transientEvents.publish({
|
|
8815
|
+
kind: "tool_state_changed",
|
|
8816
|
+
durability: "transient",
|
|
8817
|
+
runId: input.runId,
|
|
8818
|
+
executionId: input.execution.executionId,
|
|
8819
|
+
transition: { from: "in_progress", to: "in_progress" },
|
|
8820
|
+
toolCall: progressToolCall
|
|
8821
|
+
});
|
|
8822
|
+
notifyUpdate(progressToolCall, copy);
|
|
8823
|
+
}
|
|
8824
|
+
}).catch((err) => {
|
|
8825
|
+
console.warn(`Error handling progress report for tool "${input.durableTool.name}":`, err);
|
|
8826
|
+
});
|
|
8827
|
+
}
|
|
8828
|
+
};
|
|
8829
|
+
try {
|
|
8830
|
+
if (input.options?.signal?.aborted) {
|
|
8831
|
+
const error = input.options.signal.reason instanceof Error ? input.options.signal.reason : new DOMException(
|
|
8832
|
+
typeof input.options.signal.reason === "string" ? input.options.signal.reason : "Tool execution aborted.",
|
|
8833
|
+
"AbortError"
|
|
8834
|
+
);
|
|
8835
|
+
throw error;
|
|
8836
|
+
}
|
|
8837
|
+
let result = await withAbort(
|
|
8838
|
+
input.durableTool.execute(toJsonValue(input.toolCall.args), context, effectiveSignal),
|
|
8839
|
+
input.options?.signal
|
|
8840
|
+
);
|
|
8841
|
+
assertToolExecutionResult(result);
|
|
8842
|
+
if (input.afterToolCall) {
|
|
8843
|
+
result = await input.afterToolCall({
|
|
8844
|
+
tool: input.durableTool,
|
|
8845
|
+
result,
|
|
8846
|
+
context,
|
|
8847
|
+
signal: effectiveSignal
|
|
8848
|
+
});
|
|
8849
|
+
}
|
|
8850
|
+
assertToolExecutionResult(result);
|
|
8851
|
+
result = await spillLargeToolResult(
|
|
8852
|
+
result,
|
|
8853
|
+
this.archiveDirFor(input.agentId),
|
|
8854
|
+
input.toolCall.name
|
|
8855
|
+
);
|
|
8856
|
+
await progressQueue.catch(() => {
|
|
8857
|
+
});
|
|
8858
|
+
const finalState = result.ok ? "completed" : "failed";
|
|
8859
|
+
const completionPres = await presentToolCall(input.durableTool, {
|
|
8860
|
+
status: finalState,
|
|
8861
|
+
args: toJsonValue(input.toolCall.args),
|
|
8862
|
+
result
|
|
8863
|
+
});
|
|
8864
|
+
if (completionPres) {
|
|
8865
|
+
mergeToolCall(input.currentToolState, completionPres);
|
|
8866
|
+
}
|
|
8867
|
+
const rawOutput = "structuredContent" in result && result.structuredContent !== void 0 ? toJsonValue(result.structuredContent) : toJsonValue(result.content);
|
|
8868
|
+
if (input.currentToolState.rawOutput === void 0) {
|
|
8869
|
+
input.currentToolState.rawOutput = rawOutput;
|
|
8870
|
+
}
|
|
8871
|
+
const committed = await this.owned.commitToolResult({
|
|
8872
|
+
runId: input.runId,
|
|
8873
|
+
execution: input.execution,
|
|
8874
|
+
expectedRevision: input.revision,
|
|
8875
|
+
toolCallId: input.toolCallId,
|
|
8876
|
+
state: finalState,
|
|
8877
|
+
result,
|
|
8878
|
+
title: input.currentToolState.title ?? input.durableTool.annotations?.title ?? input.durableTool.name,
|
|
8879
|
+
kind: input.currentToolState.kind ?? input.durableTool.kind ?? "other",
|
|
8880
|
+
locations: input.currentToolState.locations,
|
|
8881
|
+
content: input.currentToolState.content,
|
|
8882
|
+
rawOutput: input.currentToolState.rawOutput,
|
|
8883
|
+
_meta: input.currentToolState._meta
|
|
8884
|
+
});
|
|
8885
|
+
input.setRevision(committed.run.revision);
|
|
8886
|
+
const finalToolCall = createMergedToolCall(
|
|
8887
|
+
input.toolCallId,
|
|
8888
|
+
finalState,
|
|
8889
|
+
input.currentToolState,
|
|
8890
|
+
input.durableTool.annotations?.title ?? input.durableTool.name,
|
|
8891
|
+
input.durableTool.kind ?? "other"
|
|
8892
|
+
);
|
|
8893
|
+
notifyUpdate(finalToolCall);
|
|
8894
|
+
const projectedResult = await this.foldToolInteractionRecords(result, input.toolCallId, input.agentId);
|
|
8895
|
+
const ok = "ok" in projectedResult && typeof projectedResult.ok === "boolean" ? projectedResult.ok : !projectedResult.isError;
|
|
8896
|
+
return {
|
|
8897
|
+
toolCallId: input.providerToolCallId,
|
|
8898
|
+
toolName: input.toolCall.name,
|
|
8899
|
+
...projectedResult,
|
|
8900
|
+
ok
|
|
8901
|
+
};
|
|
8902
|
+
} catch (error) {
|
|
8903
|
+
if (error instanceof RunInteractionBoundary) {
|
|
8904
|
+
const suspended = await this.owned.suspendToolCall({
|
|
8905
|
+
runId: input.runId,
|
|
8221
8906
|
execution: input.execution,
|
|
8222
|
-
expectedRevision: revision,
|
|
8223
|
-
toolCallId
|
|
8224
|
-
state: "indeterminate",
|
|
8225
|
-
reason,
|
|
8226
|
-
result: { ok: false, content: null, error: reason }
|
|
8907
|
+
expectedRevision: input.revision,
|
|
8908
|
+
toolCallId: input.toolCallId
|
|
8227
8909
|
});
|
|
8228
|
-
setRevision(
|
|
8229
|
-
|
|
8230
|
-
} finally {
|
|
8231
|
-
progressActive = false;
|
|
8232
|
-
this.transientEvents.clearTool(input.run.id, toolCallId);
|
|
8910
|
+
input.setRevision(suspended.run.revision);
|
|
8911
|
+
throw error;
|
|
8233
8912
|
}
|
|
8913
|
+
if (error instanceof RunInteractionCancelledError) throw error;
|
|
8914
|
+
const isPerCallAbort = Boolean(input.options?.signal?.aborted && !input.signal.aborted);
|
|
8915
|
+
const reason = error instanceof Error ? error.message : isPerCallAbort ? "Tool execution aborted." : "Tool execution outcome is indeterminate.";
|
|
8916
|
+
await progressQueue.catch(() => {
|
|
8917
|
+
});
|
|
8918
|
+
const failurePres = await presentToolCall(input.durableTool, {
|
|
8919
|
+
status: "failed",
|
|
8920
|
+
args: toJsonValue(input.toolCall.args),
|
|
8921
|
+
result: { ok: false, content: null, error: reason }
|
|
8922
|
+
});
|
|
8923
|
+
if (failurePres) {
|
|
8924
|
+
mergeToolCall(input.currentToolState, failurePres);
|
|
8925
|
+
}
|
|
8926
|
+
const commitState = isPerCallAbort ? "failed" : "indeterminate";
|
|
8927
|
+
const committed = await this.owned.commitToolResult({
|
|
8928
|
+
runId: input.runId,
|
|
8929
|
+
execution: input.execution,
|
|
8930
|
+
expectedRevision: input.revision,
|
|
8931
|
+
toolCallId: input.toolCallId,
|
|
8932
|
+
state: commitState,
|
|
8933
|
+
...isPerCallAbort ? {} : { reason },
|
|
8934
|
+
result: { ok: false, content: null, error: reason },
|
|
8935
|
+
title: input.currentToolState.title ?? input.durableTool.annotations?.title ?? input.durableTool.name,
|
|
8936
|
+
kind: input.currentToolState.kind ?? input.durableTool.kind ?? "other",
|
|
8937
|
+
locations: input.currentToolState.locations,
|
|
8938
|
+
content: input.currentToolState.content,
|
|
8939
|
+
_meta: input.currentToolState._meta
|
|
8940
|
+
});
|
|
8941
|
+
input.setRevision(committed.run.revision);
|
|
8942
|
+
const finalToolCall = createMergedToolCall(
|
|
8943
|
+
input.toolCallId,
|
|
8944
|
+
"failed",
|
|
8945
|
+
input.currentToolState,
|
|
8946
|
+
input.durableTool.annotations?.title ?? input.durableTool.name,
|
|
8947
|
+
input.durableTool.kind ?? "other"
|
|
8948
|
+
);
|
|
8949
|
+
notifyUpdate(finalToolCall);
|
|
8950
|
+
return {
|
|
8951
|
+
toolCallId: input.providerToolCallId,
|
|
8952
|
+
toolName: input.toolCall.name,
|
|
8953
|
+
ok: false,
|
|
8954
|
+
content: null,
|
|
8955
|
+
error: reason
|
|
8956
|
+
};
|
|
8957
|
+
} finally {
|
|
8958
|
+
progressActive = false;
|
|
8959
|
+
this.transientEvents.clearTool(input.runId, input.toolCallId);
|
|
8234
8960
|
}
|
|
8235
|
-
input.driver?.clearCheckpoint();
|
|
8236
|
-
return { results, revision };
|
|
8237
8961
|
}
|
|
8238
8962
|
async foldToolInteractionRecords(result, toolCallId, agentId) {
|
|
8239
8963
|
const interactionMessages = (await this.owned.history(agentId)).filter(
|
|
@@ -8242,11 +8966,27 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
8242
8966
|
if (interactionMessages.length === 0) return result;
|
|
8243
8967
|
const interactionText = interactionMessages.filter((message) => message.role === "interaction").map(renderInteractionText).join("\n\n");
|
|
8244
8968
|
const content = typeof result.content === "string" ? result.content : JSON.stringify(result.content) ?? "null";
|
|
8245
|
-
|
|
8246
|
-
...result,
|
|
8247
|
-
content: content === "null" || content.length === 0 ? interactionText : `${interactionText}
|
|
8969
|
+
const appendedText = content === "null" || content.length === 0 ? interactionText : `${interactionText}
|
|
8248
8970
|
|
|
8249
|
-
${content}
|
|
8971
|
+
${content}`;
|
|
8972
|
+
if (Array.isArray(result.content)) {
|
|
8973
|
+
return {
|
|
8974
|
+
...result,
|
|
8975
|
+
content: [{ type: "text", text: appendedText }]
|
|
8976
|
+
};
|
|
8977
|
+
}
|
|
8978
|
+
if (result.ok) {
|
|
8979
|
+
return {
|
|
8980
|
+
ok: true,
|
|
8981
|
+
content: appendedText,
|
|
8982
|
+
...result.structuredContent !== void 0 ? { structuredContent: result.structuredContent } : {}
|
|
8983
|
+
};
|
|
8984
|
+
}
|
|
8985
|
+
return {
|
|
8986
|
+
ok: false,
|
|
8987
|
+
content: appendedText,
|
|
8988
|
+
error: result.error ?? "Tool execution failed.",
|
|
8989
|
+
...result.structuredContent !== void 0 ? { structuredContent: result.structuredContent } : {}
|
|
8250
8990
|
};
|
|
8251
8991
|
}
|
|
8252
8992
|
async requireAgent(agentId) {
|
|
@@ -8334,8 +9074,8 @@ ${content}`
|
|
|
8334
9074
|
if (event.runId !== runId) continue;
|
|
8335
9075
|
if (event.kind === "message_committed") {
|
|
8336
9076
|
subscription.clearMessage(event.message.id);
|
|
8337
|
-
} else if (event.kind === "tool_state_changed" && ["completed", "failed"
|
|
8338
|
-
subscription.clearTool(event.toolCall.
|
|
9077
|
+
} else if (event.kind === "tool_state_changed" && ["completed", "failed"].includes(event.transition.to)) {
|
|
9078
|
+
subscription.clearTool(event.toolCall.toolCallId);
|
|
8339
9079
|
}
|
|
8340
9080
|
if (event.kind === "run_state_changed" && ["completed", "failed", "cancelled"].includes(event.to)) {
|
|
8341
9081
|
while (true) {
|
|
@@ -8533,6 +9273,19 @@ function toJsonValue(value) {
|
|
|
8533
9273
|
assertJsonValue(value, "tool arguments");
|
|
8534
9274
|
return value;
|
|
8535
9275
|
}
|
|
9276
|
+
function createMergedToolCall(toolCallId, status, current, fallbackTitle, fallbackKind = "other") {
|
|
9277
|
+
return {
|
|
9278
|
+
toolCallId,
|
|
9279
|
+
title: current.title ?? fallbackTitle,
|
|
9280
|
+
kind: current.kind ?? fallbackKind,
|
|
9281
|
+
status,
|
|
9282
|
+
...current.locations !== void 0 ? { locations: current.locations } : {},
|
|
9283
|
+
...current.content !== void 0 ? { content: current.content } : {},
|
|
9284
|
+
...current.rawInput !== void 0 ? { rawInput: current.rawInput } : {},
|
|
9285
|
+
...current.rawOutput !== void 0 ? { rawOutput: current.rawOutput } : {},
|
|
9286
|
+
...current._meta !== void 0 ? { _meta: current._meta } : {}
|
|
9287
|
+
};
|
|
9288
|
+
}
|
|
8536
9289
|
function deferred2() {
|
|
8537
9290
|
let resolve9;
|
|
8538
9291
|
let reject;
|
|
@@ -8545,6 +9298,24 @@ function deferred2() {
|
|
|
8545
9298
|
|
|
8546
9299
|
// src/runtime/durable-store.ts
|
|
8547
9300
|
import { createHash } from "crypto";
|
|
9301
|
+
function defaultToolCallContent(result) {
|
|
9302
|
+
if ("content" in result && Array.isArray(result.content)) {
|
|
9303
|
+
return result.content.map((block) => {
|
|
9304
|
+
if (typeof block === "object" && block !== null && "type" in block && (block.type === "content" || block.type === "diff" || block.type === "terminal")) {
|
|
9305
|
+
return block;
|
|
9306
|
+
}
|
|
9307
|
+
return {
|
|
9308
|
+
type: "content",
|
|
9309
|
+
content: block
|
|
9310
|
+
};
|
|
9311
|
+
});
|
|
9312
|
+
}
|
|
9313
|
+
const content = result.content;
|
|
9314
|
+
if (typeof content === "string") {
|
|
9315
|
+
return [{ type: "content", content: { type: "text", text: content } }];
|
|
9316
|
+
}
|
|
9317
|
+
return [{ type: "content", content: { type: "text", text: JSON.stringify(content ?? null) } }];
|
|
9318
|
+
}
|
|
8548
9319
|
var InMemoryStore = class _InMemoryStore {
|
|
8549
9320
|
incarnation;
|
|
8550
9321
|
agents = /* @__PURE__ */ new Map();
|
|
@@ -8663,7 +9434,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8663
9434
|
}
|
|
8664
9435
|
}
|
|
8665
9436
|
for (const message of state.messages) store.messages.set(message.id, clone(message));
|
|
8666
|
-
for (const toolCall of state.toolCalls ?? []) store.toolCalls.set(toolCall.id, clone(toolCall));
|
|
9437
|
+
for (const toolCall of state.toolCalls ?? []) store.toolCalls.set(toolCall.id ?? toolCall.toolCallId, clone(toolCall));
|
|
8667
9438
|
store.events.push(...clone(state.events));
|
|
8668
9439
|
for (const [key, receipt] of state.idempotency) store.idempotency.set(key, clone(receipt));
|
|
8669
9440
|
for (const [key, receipt] of state.operationReceipts) {
|
|
@@ -8728,10 +9499,10 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8728
9499
|
this.ownerEpoch = Math.max(this.ownerEpoch, ownerEpoch);
|
|
8729
9500
|
for (const run of this.runs.values()) {
|
|
8730
9501
|
if (run.state !== "running" || run.execution?.ownerEpoch !== ownerEpoch) continue;
|
|
8731
|
-
const activeToolCalls = [...this.toolCalls.values()].filter((toolCall) => toolCall.runId === run.id && toolCall.executionId === run.execution?.executionId && (toolCall.state === "pending" || toolCall.state === "
|
|
9502
|
+
const activeToolCalls = [...this.toolCalls.values()].filter((toolCall) => toolCall.runId === run.id && toolCall.executionId === run.execution?.executionId && (toolCall.status === "pending" || toolCall.status === "in_progress" || toolCall.state === "pending" || toolCall.state === "in_progress"));
|
|
8732
9503
|
const indeterminateToolCallIds = [];
|
|
8733
9504
|
for (const toolCall of activeToolCalls) {
|
|
8734
|
-
if (toolCall.state === "
|
|
9505
|
+
if (toolCall.status === "in_progress" || toolCall.state === "in_progress") indeterminateToolCallIds.push(toolCall.id);
|
|
8735
9506
|
this.interruptToolCall(run, toolCall, message);
|
|
8736
9507
|
}
|
|
8737
9508
|
const failure = indeterminateToolCallIds.length > 0 ? { code: "tool_indeterminate", message, toolCallIds: indeterminateToolCallIds } : { code: "runtime_interrupted", message, ownerEpoch };
|
|
@@ -8991,7 +9762,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8991
9762
|
run.invalidatedBy = { messageId: original.id, messageRevision: actualRevision + 1 };
|
|
8992
9763
|
if (run.state === "running" || run.state === "queued" || run.state === "input_required") {
|
|
8993
9764
|
if (run.state === "running") {
|
|
8994
|
-
const openToolCalls = [...this.toolCalls.values()].filter((toolCall) => toolCall.runId === run.id && toolCall.executionId === run.execution?.executionId && (toolCall.state === "pending" || toolCall.state === "
|
|
9765
|
+
const openToolCalls = [...this.toolCalls.values()].filter((toolCall) => toolCall.runId === run.id && toolCall.executionId === run.execution?.executionId && (toolCall.status === "pending" || toolCall.status === "in_progress" || toolCall.state === "pending" || toolCall.state === "in_progress"));
|
|
8995
9766
|
for (const toolCall of openToolCalls) this.interruptToolCall(run, toolCall, "Run superseded by Message revision.");
|
|
8996
9767
|
} else {
|
|
8997
9768
|
delete run.openInteractions;
|
|
@@ -9087,7 +9858,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9087
9858
|
if (input.phasePayload !== void 0) assertJsonValue(input.phasePayload, "run.phasePayload");
|
|
9088
9859
|
if (input.entryPhases !== void 0) assertEntryPhases(input.entryPhases, "run.entryPhases");
|
|
9089
9860
|
const scope = createIdempotencyScope("start_run", input.agentId, input.idempotencyKey);
|
|
9090
|
-
const payload = canonicalStartRunRequest(normalizedInput, input.metadata, input.phasePayload, input.pinnedConfigToken, input.entryPhases);
|
|
9861
|
+
const payload = canonicalStartRunRequest(normalizedInput, input.metadata, input.phasePayload, input.pinnedConfigToken, input.entryPhases, input.scope, input.cwd);
|
|
9091
9862
|
const replay = this.replay(scope, payload);
|
|
9092
9863
|
if (replay) return clone(replay);
|
|
9093
9864
|
const waitingRun = isControlMetadata(input.metadata) ? void 0 : [...this.runs.values()].find((candidate) => candidate.agentId === input.agentId && candidate.state === "input_required");
|
|
@@ -9143,6 +9914,8 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9143
9914
|
state: "queued",
|
|
9144
9915
|
input: clone(normalizedInput),
|
|
9145
9916
|
...input.metadata ? { metadata: clone(input.metadata) } : {},
|
|
9917
|
+
...input.scope !== void 0 ? { scope: clone(input.scope) } : {},
|
|
9918
|
+
...input.cwd !== void 0 ? { cwd: input.cwd } : {},
|
|
9146
9919
|
...input.phasePayload === void 0 ? {} : { phasePayload: clone(input.phasePayload) },
|
|
9147
9920
|
...input.entryPhases === void 0 ? {} : { entryPhases: clone(input.entryPhases) },
|
|
9148
9921
|
...input.pinnedConfigToken === void 0 ? {} : { pinnedConfigToken: input.pinnedConfigToken },
|
|
@@ -9418,19 +10191,30 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9418
10191
|
this.assertExecution(run, input.execution, input.expectedRevision);
|
|
9419
10192
|
if (this.messages.has(input.requestMessageId)) throw new RuntimeError("run_state_conflict", { runId: run.id, expected: ["running"], actual: run.state });
|
|
9420
10193
|
const timestamp = createTimestamp();
|
|
9421
|
-
const toolCalls = input.calls.map((call) =>
|
|
9422
|
-
|
|
9423
|
-
|
|
9424
|
-
|
|
9425
|
-
|
|
9426
|
-
|
|
9427
|
-
|
|
9428
|
-
|
|
9429
|
-
|
|
9430
|
-
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
|
|
10194
|
+
const toolCalls = input.calls.map((call) => {
|
|
10195
|
+
const toolCallId = call.providerToolCallId || (call.toolCallId ?? createId("tool"));
|
|
10196
|
+
return {
|
|
10197
|
+
id: call.toolCallId ?? createId("tool"),
|
|
10198
|
+
toolCallId,
|
|
10199
|
+
...call.providerToolCallId ? { providerToolCallId: call.providerToolCallId } : {},
|
|
10200
|
+
agentId: run.agentId,
|
|
10201
|
+
runId: run.id,
|
|
10202
|
+
executionId: input.execution.executionId,
|
|
10203
|
+
requestMessageId: input.requestMessageId,
|
|
10204
|
+
name: call.name,
|
|
10205
|
+
title: call.title ?? call.name,
|
|
10206
|
+
kind: call.kind ?? "other",
|
|
10207
|
+
status: "pending",
|
|
10208
|
+
state: "pending",
|
|
10209
|
+
...call.content ? { content: clone(call.content) } : {},
|
|
10210
|
+
...call.locations ? { locations: clone(call.locations) } : {},
|
|
10211
|
+
rawInput: clone(call.args),
|
|
10212
|
+
...call._meta ? { _meta: clone(call._meta) } : {},
|
|
10213
|
+
args: clone(call.args),
|
|
10214
|
+
createdAt: timestamp,
|
|
10215
|
+
updatedAt: timestamp
|
|
10216
|
+
};
|
|
10217
|
+
});
|
|
9434
10218
|
for (const toolCall of toolCalls) {
|
|
9435
10219
|
if (this.toolCalls.has(toolCall.id)) throw new RuntimeError("run_state_conflict", { runId: run.id, expected: ["running"], actual: run.state });
|
|
9436
10220
|
}
|
|
@@ -9466,15 +10250,27 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9466
10250
|
const run = this.requireRun(input.runId);
|
|
9467
10251
|
this.assertExecution(run, input.execution, input.expectedRevision);
|
|
9468
10252
|
const toolCall = this.requireToolCall(input.toolCallId, run);
|
|
9469
|
-
if (toolCall.state !== "pending") throw new RuntimeError("run_state_conflict", { runId: run.id, expected: ["running"], actual: run.state });
|
|
9470
|
-
toolCall.
|
|
10253
|
+
if (toolCall.status !== "pending" && toolCall.state !== "pending") throw new RuntimeError("run_state_conflict", { runId: run.id, expected: ["running"], actual: run.state });
|
|
10254
|
+
const from = toolCall.status ?? "pending";
|
|
10255
|
+
toolCall.status = "in_progress";
|
|
10256
|
+
toolCall.state = "in_progress";
|
|
9471
10257
|
toolCall.executionId = input.execution.executionId;
|
|
10258
|
+
if (input.title !== void 0) toolCall.title = input.title;
|
|
10259
|
+
if (input.kind !== void 0) toolCall.kind = input.kind;
|
|
10260
|
+
if (input.locations !== void 0) toolCall.locations = clone(input.locations);
|
|
10261
|
+
if (input.content !== void 0) toolCall.content = clone(input.content);
|
|
10262
|
+
if (input._meta !== void 0) {
|
|
10263
|
+
toolCall._meta = {
|
|
10264
|
+
...toolCall._meta ?? {},
|
|
10265
|
+
...clone(input._meta)
|
|
10266
|
+
};
|
|
10267
|
+
}
|
|
9472
10268
|
toolCall.updatedAt = createTimestamp();
|
|
9473
10269
|
this.storeToolCall(toolCall);
|
|
9474
10270
|
run.revision += 1;
|
|
9475
10271
|
run.updatedAt = toolCall.updatedAt;
|
|
9476
10272
|
this.touchRun(run);
|
|
9477
|
-
this.appendToolTransition(run, { from
|
|
10273
|
+
this.appendToolTransition(run, { from, to: "in_progress" }, toolCall);
|
|
9478
10274
|
const result = { run: clone(run), toolCall: clone(toolCall) };
|
|
9479
10275
|
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
9480
10276
|
return result;
|
|
@@ -9488,16 +10284,18 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9488
10284
|
const run = this.requireRun(input.runId);
|
|
9489
10285
|
this.assertExecution(run, input.execution, input.expectedRevision);
|
|
9490
10286
|
const toolCall = this.requireToolCall(input.toolCallId, run);
|
|
9491
|
-
if (toolCall.state !== "
|
|
10287
|
+
if (toolCall.status !== "in_progress" && toolCall.state !== "in_progress" || toolCall.executionId !== input.execution.executionId) {
|
|
9492
10288
|
throw new RuntimeError("run_state_conflict", { runId: run.id, expected: ["running"], actual: run.state });
|
|
9493
10289
|
}
|
|
10290
|
+
const from = toolCall.status ?? "in_progress";
|
|
10291
|
+
toolCall.status = "pending";
|
|
9494
10292
|
toolCall.state = "pending";
|
|
9495
10293
|
toolCall.updatedAt = createTimestamp();
|
|
9496
10294
|
this.storeToolCall(toolCall);
|
|
9497
10295
|
run.revision += 1;
|
|
9498
10296
|
run.updatedAt = toolCall.updatedAt;
|
|
9499
10297
|
this.touchRun(run);
|
|
9500
|
-
this.appendToolTransition(run, { from
|
|
10298
|
+
this.appendToolTransition(run, { from, to: "pending" }, toolCall);
|
|
9501
10299
|
const result = { run: clone(run), toolCall: clone(toolCall) };
|
|
9502
10300
|
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
9503
10301
|
return result;
|
|
@@ -9506,8 +10304,9 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9506
10304
|
this.assertOwner(lease);
|
|
9507
10305
|
assertToolExecutionResult(input.result);
|
|
9508
10306
|
assertToolValue(input.result, "tool.result");
|
|
9509
|
-
|
|
9510
|
-
if (input.state
|
|
10307
|
+
const isCompleted = "ok" in input.result ? input.result.ok : !input.result.isError;
|
|
10308
|
+
if (input.state === "completed" && !isCompleted) throw new TypeError("completed ToolCall requires a successful result");
|
|
10309
|
+
if (input.state !== "completed" && isCompleted) throw new TypeError(`${input.state} ToolCall requires a failed result`);
|
|
9511
10310
|
if (input.state === "indeterminate" && (!input.reason || input.reason.trim().length === 0)) throw new TypeError("indeterminate ToolCall requires a reason");
|
|
9512
10311
|
const operationKey = `tool_commit:${input.toolCallId}`;
|
|
9513
10312
|
const operationPayload = canonicalJson([input.runId, input.expectedRevision, input.execution.executionId, input.state, input.result, input.reason ?? null]);
|
|
@@ -9517,10 +10316,9 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9517
10316
|
this.assertExecution(run, input.execution, input.expectedRevision);
|
|
9518
10317
|
const toolCall = this.requireToolCall(input.toolCallId, run);
|
|
9519
10318
|
if (toolCall.executionId !== input.execution.executionId) throw new RuntimeError("runtime_ownership_lost", { reason: "epoch_advanced", expectedEpoch: input.execution.ownerEpoch, actualEpoch: this.ownerEpoch });
|
|
9520
|
-
const
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
const durableResult = { toolCallId: toolCall.id, toolName: toolCall.name, ...clone(input.result) };
|
|
10319
|
+
const fromStatus = toolCall.status ?? (toolCall.state === "in_progress" ? "in_progress" : toolCall.state);
|
|
10320
|
+
const toStatus = input.state === "completed" ? "completed" : "failed";
|
|
10321
|
+
const durableResult = { toolCallId: toolCall.id, toolName: toolCall.name ?? toolCall.title, ...clone(input.result) };
|
|
9524
10322
|
const resultMessageId = createId("msg");
|
|
9525
10323
|
const message = {
|
|
9526
10324
|
id: resultMessageId,
|
|
@@ -9532,7 +10330,21 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9532
10330
|
createdAt: createTimestamp()
|
|
9533
10331
|
};
|
|
9534
10332
|
this.storeMessage(message);
|
|
9535
|
-
toolCall.
|
|
10333
|
+
toolCall.status = toStatus;
|
|
10334
|
+
toolCall.state = toStatus;
|
|
10335
|
+
if (input.title !== void 0) toolCall.title = input.title;
|
|
10336
|
+
if (input.kind !== void 0) toolCall.kind = input.kind;
|
|
10337
|
+
if (input.locations !== void 0) toolCall.locations = clone(input.locations);
|
|
10338
|
+
if (input.content !== void 0) toolCall.content = clone(input.content);
|
|
10339
|
+
else if (toolCall.content === void 0) toolCall.content = defaultToolCallContent(input.result);
|
|
10340
|
+
if (input.rawOutput !== void 0) toolCall.rawOutput = clone(input.rawOutput);
|
|
10341
|
+
else if (toolCall.rawOutput === void 0) toolCall.rawOutput = "structuredContent" in input.result && input.result.structuredContent !== void 0 ? clone(input.result.structuredContent) : clone(input.result.content);
|
|
10342
|
+
if (input._meta !== void 0) {
|
|
10343
|
+
toolCall._meta = {
|
|
10344
|
+
...toolCall._meta ?? {},
|
|
10345
|
+
...clone(input._meta)
|
|
10346
|
+
};
|
|
10347
|
+
}
|
|
9536
10348
|
toolCall.result = durableResult;
|
|
9537
10349
|
toolCall.resultMessageId = resultMessageId;
|
|
9538
10350
|
if (input.state === "indeterminate") toolCall.reason = input.reason;
|
|
@@ -9542,13 +10354,13 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9542
10354
|
run.revision += 1;
|
|
9543
10355
|
run.updatedAt = message.createdAt;
|
|
9544
10356
|
this.touchRun(run);
|
|
9545
|
-
this.appendToolTransition(run, { from, to:
|
|
10357
|
+
this.appendToolTransition(run, { from: fromStatus, to: toStatus }, toolCall);
|
|
9546
10358
|
this.appendMessage(run, message);
|
|
9547
10359
|
if (input.state === "indeterminate") {
|
|
9548
|
-
const openToolCalls = [...this.toolCalls.values()].filter((candidate) => candidate.runId === run.id && candidate.executionId === input.execution.executionId && candidate.id !== toolCall.id && (candidate.state === "pending" || candidate.state === "
|
|
10360
|
+
const openToolCalls = [...this.toolCalls.values()].filter((candidate) => candidate.runId === run.id && candidate.executionId === input.execution.executionId && candidate.id !== toolCall.id && (candidate.status === "pending" || candidate.status === "in_progress" || candidate.state === "pending" || candidate.state === "in_progress"));
|
|
9549
10361
|
const indeterminateToolCallIds = [toolCall.id];
|
|
9550
10362
|
for (const candidate of openToolCalls) {
|
|
9551
|
-
if (candidate.state === "
|
|
10363
|
+
if (candidate.status === "in_progress" || candidate.state === "in_progress") indeterminateToolCallIds.push(candidate.id);
|
|
9552
10364
|
this.interruptToolCall(run, candidate, input.reason);
|
|
9553
10365
|
}
|
|
9554
10366
|
const failure = {
|
|
@@ -9627,14 +10439,14 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9627
10439
|
return result2;
|
|
9628
10440
|
}
|
|
9629
10441
|
const from = run.state;
|
|
9630
|
-
const activeToolCalls = run.execution ? [...this.toolCalls.values()].filter((toolCall) => toolCall.runId === run.id && toolCall.executionId === run.execution?.executionId && (toolCall.state === "pending" || toolCall.state === "
|
|
10442
|
+
const activeToolCalls = run.execution ? [...this.toolCalls.values()].filter((toolCall) => toolCall.runId === run.id && toolCall.executionId === run.execution?.executionId && (toolCall.status === "pending" || toolCall.status === "in_progress" || toolCall.state === "pending" || toolCall.state === "in_progress")) : run.state === "input_required" && run.checkpoint?.data && typeof run.checkpoint.data === "object" && !Array.isArray(run.checkpoint.data) ? (() => {
|
|
9631
10443
|
const interactionState = run.checkpoint.data.runInteractions;
|
|
9632
10444
|
const interactionCheckpoint = interactionState && typeof interactionState === "object" && !Array.isArray(interactionState) ? interactionState.checkpoint : void 0;
|
|
9633
10445
|
const ids = interactionCheckpoint && typeof interactionCheckpoint === "object" && !Array.isArray(interactionCheckpoint) ? interactionCheckpoint.toolCallIds : void 0;
|
|
9634
10446
|
const allowed = new Set(Array.isArray(ids) ? ids : []);
|
|
9635
|
-
return [...this.toolCalls.values()].filter((toolCall) => toolCall.runId === run.id && toolCall.state === "pending" && allowed.has(toolCall.id));
|
|
10447
|
+
return [...this.toolCalls.values()].filter((toolCall) => toolCall.runId === run.id && (toolCall.status === "pending" || toolCall.state === "pending") && allowed.has(toolCall.id));
|
|
9636
10448
|
})() : [];
|
|
9637
|
-
const indeterminateToolCallIds = activeToolCalls.filter((toolCall) => toolCall.state === "
|
|
10449
|
+
const indeterminateToolCallIds = activeToolCalls.filter((toolCall) => toolCall.status === "in_progress" || toolCall.state === "in_progress").map((toolCall) => toolCall.id);
|
|
9638
10450
|
for (const toolCall of activeToolCalls) this.interruptToolCall(run, toolCall, input.reason ?? "The Run was cancelled.");
|
|
9639
10451
|
if (input.output && (typeof input.output.content === "string" ? input.output.content.length > 0 : input.output.content.length > 0)) {
|
|
9640
10452
|
const output = { ...clone(input.output), sequenceWithinRun: this.nextMessageSequence(run.id) };
|
|
@@ -9681,6 +10493,74 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9681
10493
|
const result = clone(run);
|
|
9682
10494
|
return result;
|
|
9683
10495
|
}
|
|
10496
|
+
recordToolCall(lease, input) {
|
|
10497
|
+
this.assertOwner(lease);
|
|
10498
|
+
const run = this.requireRun(input.runId);
|
|
10499
|
+
if (input.execution) {
|
|
10500
|
+
if (run.state !== "running" || !run.execution || run.execution.executionId !== input.execution.executionId || run.execution.ownerEpoch !== input.execution.ownerEpoch) {
|
|
10501
|
+
throw new RuntimeError("runtime_ownership_lost", {
|
|
10502
|
+
reason: "epoch_advanced",
|
|
10503
|
+
expectedEpoch: input.execution.ownerEpoch,
|
|
10504
|
+
actualEpoch: this.ownerEpoch
|
|
10505
|
+
});
|
|
10506
|
+
}
|
|
10507
|
+
}
|
|
10508
|
+
const toolCallId = input.update.toolCallId;
|
|
10509
|
+
const existing = this.toolCalls.get(toolCallId);
|
|
10510
|
+
const fromStatus = existing ? existing.status : null;
|
|
10511
|
+
const toStatus = input.update.status ?? (existing ? existing.status : "in_progress");
|
|
10512
|
+
const timestamp = createTimestamp();
|
|
10513
|
+
let stored;
|
|
10514
|
+
if (existing) {
|
|
10515
|
+
mergeToolCall(existing, input.update);
|
|
10516
|
+
existing.status = toStatus;
|
|
10517
|
+
existing.state = toStatus;
|
|
10518
|
+
if (input.external !== void 0) existing.external = input.external;
|
|
10519
|
+
existing.updatedAt = timestamp;
|
|
10520
|
+
stored = existing;
|
|
10521
|
+
} else {
|
|
10522
|
+
stored = {
|
|
10523
|
+
id: toolCallId,
|
|
10524
|
+
toolCallId,
|
|
10525
|
+
providerToolCallId: toolCallId,
|
|
10526
|
+
agentId: run.agentId,
|
|
10527
|
+
runId: run.id,
|
|
10528
|
+
executionId: input.execution?.executionId,
|
|
10529
|
+
title: "title" in input.update && input.update.title ? input.update.title : "external_tool",
|
|
10530
|
+
kind: "kind" in input.update && input.update.kind ? input.update.kind : "other",
|
|
10531
|
+
status: toStatus,
|
|
10532
|
+
state: toStatus,
|
|
10533
|
+
external: input.external ?? false,
|
|
10534
|
+
createdAt: timestamp,
|
|
10535
|
+
updatedAt: timestamp
|
|
10536
|
+
};
|
|
10537
|
+
mergeToolCall(stored, input.update);
|
|
10538
|
+
this.toolCalls.set(stored.id, stored);
|
|
10539
|
+
}
|
|
10540
|
+
this.storeToolCall(stored);
|
|
10541
|
+
run.revision += 1;
|
|
10542
|
+
run.updatedAt = timestamp;
|
|
10543
|
+
this.touchRun(run);
|
|
10544
|
+
const acpToolCall = {
|
|
10545
|
+
toolCallId: stored.toolCallId,
|
|
10546
|
+
title: stored.title,
|
|
10547
|
+
kind: stored.kind,
|
|
10548
|
+
status: stored.status,
|
|
10549
|
+
...stored.content !== void 0 ? { content: clone(stored.content) } : {},
|
|
10550
|
+
...stored.locations !== void 0 ? { locations: clone(stored.locations) } : {},
|
|
10551
|
+
...stored.rawInput !== void 0 ? { rawInput: clone(stored.rawInput) } : {},
|
|
10552
|
+
...stored.rawOutput !== void 0 ? { rawOutput: clone(stored.rawOutput) } : {},
|
|
10553
|
+
...stored._meta !== void 0 ? { _meta: clone(stored._meta) } : {}
|
|
10554
|
+
};
|
|
10555
|
+
const event = this.baseEvent(run, {
|
|
10556
|
+
kind: "tool_state_changed",
|
|
10557
|
+
transition: { from: fromStatus, to: toStatus },
|
|
10558
|
+
toolCall: acpToolCall,
|
|
10559
|
+
...input.external ? { external: true } : {}
|
|
10560
|
+
});
|
|
10561
|
+
this.appendEvent(event);
|
|
10562
|
+
return event;
|
|
10563
|
+
}
|
|
9684
10564
|
snapshotRun(lease, runId) {
|
|
9685
10565
|
this.assertOwner(lease);
|
|
9686
10566
|
const run = this.requireRun(runId);
|
|
@@ -9691,6 +10571,8 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9691
10571
|
revision: run.revision,
|
|
9692
10572
|
input: clone(run.input),
|
|
9693
10573
|
...run.metadata ? { metadata: clone(run.metadata) } : {},
|
|
10574
|
+
...run.scope !== void 0 ? { scope: clone(run.scope) } : {},
|
|
10575
|
+
...run.cwd !== void 0 ? { cwd: run.cwd } : {},
|
|
9694
10576
|
...run.phasePayload === void 0 ? {} : { phasePayload: clone(run.phasePayload) },
|
|
9695
10577
|
...run.entryPhases === void 0 ? {} : { entryPhases: clone(run.entryPhases) },
|
|
9696
10578
|
messageCount: this.messagesForRun(run.id).length,
|
|
@@ -9777,7 +10659,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9777
10659
|
if (run.state === "running") blockedRunIds.add(run.id);
|
|
9778
10660
|
}
|
|
9779
10661
|
for (const tool of this.toolCalls.values()) {
|
|
9780
|
-
if (tool.
|
|
10662
|
+
if (tool.status === "pending" || tool.status === "in_progress" || tool.state === "pending" || tool.state === "in_progress") {
|
|
9781
10663
|
blockedRunIds.add(tool.runId);
|
|
9782
10664
|
}
|
|
9783
10665
|
}
|
|
@@ -9918,13 +10800,13 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9918
10800
|
}
|
|
9919
10801
|
assertNoOpenTools(run, allowedPendingToolCallIds = []) {
|
|
9920
10802
|
const allowed = new Set(allowedPendingToolCallIds);
|
|
9921
|
-
if ([...this.toolCalls.values()].some((toolCall) => toolCall.runId === run.id && (toolCall.state === "
|
|
10803
|
+
if ([...this.toolCalls.values()].some((toolCall) => toolCall.runId === run.id && (toolCall.status === "in_progress" || toolCall.state === "in_progress" || (toolCall.status === "pending" || toolCall.state === "pending") && !allowed.has(toolCall.id)))) {
|
|
9922
10804
|
throw new RuntimeError("run_state_conflict", { runId: run.id, expected: ["running"], actual: run.state });
|
|
9923
10805
|
}
|
|
9924
10806
|
}
|
|
9925
10807
|
interruptToolCall(run, toolCall, reason) {
|
|
9926
10808
|
const result = { ok: false, content: null, error: reason };
|
|
9927
|
-
const durableResult = { toolCallId: toolCall.id, toolName: toolCall.name, ...result };
|
|
10809
|
+
const durableResult = { toolCallId: toolCall.id, toolName: toolCall.name ?? toolCall.title, ...result };
|
|
9928
10810
|
const message = {
|
|
9929
10811
|
id: createId("msg"),
|
|
9930
10812
|
agentId: run.agentId,
|
|
@@ -9934,13 +10816,14 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
9934
10816
|
sequenceWithinRun: this.nextMessageSequence(run.id),
|
|
9935
10817
|
createdAt: createTimestamp()
|
|
9936
10818
|
};
|
|
9937
|
-
const from = toolCall.state;
|
|
9938
|
-
const to =
|
|
10819
|
+
const from = toolCall.status ?? toolCall.state ?? "in_progress";
|
|
10820
|
+
const to = "failed";
|
|
9939
10821
|
this.storeMessage(message);
|
|
9940
10822
|
toolCall.state = to;
|
|
10823
|
+
toolCall.status = to;
|
|
9941
10824
|
toolCall.result = durableResult;
|
|
9942
10825
|
toolCall.resultMessageId = message.id;
|
|
9943
|
-
|
|
10826
|
+
toolCall.reason = reason;
|
|
9944
10827
|
toolCall.updatedAt = message.createdAt;
|
|
9945
10828
|
this.storeToolCall(toolCall);
|
|
9946
10829
|
run.revision += 1;
|
|
@@ -10101,11 +10984,24 @@ ${record.summary}`,
|
|
|
10101
10984
|
this.appendEvent(transition);
|
|
10102
10985
|
}
|
|
10103
10986
|
appendToolTransition(run, transition, toolCall) {
|
|
10104
|
-
|
|
10987
|
+
const acpToolCall = {
|
|
10988
|
+
toolCallId: toolCall.toolCallId ?? toolCall.id,
|
|
10989
|
+
title: toolCall.title ?? toolCall.name ?? toolCall.toolCallId,
|
|
10990
|
+
kind: toolCall.kind ?? "other",
|
|
10991
|
+
status: toolCall.status ?? toolCall.state,
|
|
10992
|
+
...toolCall.content ? { content: clone(toolCall.content) } : {},
|
|
10993
|
+
...toolCall.locations ? { locations: clone(toolCall.locations) } : {},
|
|
10994
|
+
...toolCall.rawInput !== void 0 ? { rawInput: clone(toolCall.rawInput) } : {},
|
|
10995
|
+
...toolCall.rawOutput !== void 0 ? { rawOutput: clone(toolCall.rawOutput) } : {},
|
|
10996
|
+
...toolCall._meta ? { _meta: clone(toolCall._meta) } : {}
|
|
10997
|
+
};
|
|
10998
|
+
this.appendEvent({
|
|
10999
|
+
...this.baseEvent(run),
|
|
10105
11000
|
kind: "tool_state_changed",
|
|
10106
11001
|
transition,
|
|
10107
|
-
toolCall:
|
|
10108
|
-
|
|
11002
|
+
toolCall: acpToolCall,
|
|
11003
|
+
...toolCall.external ? { external: true } : {}
|
|
11004
|
+
});
|
|
10109
11005
|
}
|
|
10110
11006
|
baseEvent(run, extra) {
|
|
10111
11007
|
this.eventSequence += 1;
|
|
@@ -10207,6 +11103,9 @@ var MemoryOwnedStore = class {
|
|
|
10207
11103
|
async cancelRun(input) {
|
|
10208
11104
|
return this.store.cancelRun(this.lease, input);
|
|
10209
11105
|
}
|
|
11106
|
+
async recordToolCall(input) {
|
|
11107
|
+
return this.store.recordToolCall(this.lease, input);
|
|
11108
|
+
}
|
|
10210
11109
|
async snapshotRun(runId) {
|
|
10211
11110
|
return this.store.snapshotRun(this.lease, runId);
|
|
10212
11111
|
}
|
|
@@ -10350,19 +11249,19 @@ function requestMessageContent(toolCalls, contentBlocks) {
|
|
|
10350
11249
|
const toolUse = (toolCall) => ({
|
|
10351
11250
|
type: "tool_use",
|
|
10352
11251
|
toolCallId: toolCall.id,
|
|
10353
|
-
providerToolCallId: toolCall.providerToolCallId,
|
|
10354
|
-
name: toolCall.name,
|
|
10355
|
-
input: clone(toolCall.args)
|
|
11252
|
+
...toolCall.providerToolCallId !== void 0 ? { providerToolCallId: toolCall.providerToolCallId } : {},
|
|
11253
|
+
name: toolCall.name ?? toolCall.title ?? "tool",
|
|
11254
|
+
input: clone(toolCall.args !== void 0 ? toolCall.args : toolCall.rawInput !== void 0 ? toolCall.rawInput : {})
|
|
10356
11255
|
});
|
|
10357
11256
|
if (!contentBlocks) return toolCalls.map(toolUse);
|
|
10358
|
-
const reserved = new Map(toolCalls.map((toolCall) => [toolCall.providerToolCallId, toolCall]));
|
|
11257
|
+
const reserved = new Map(toolCalls.map((toolCall) => [toolCall.providerToolCallId ?? toolCall.id, toolCall]));
|
|
10359
11258
|
const parts = [];
|
|
10360
11259
|
for (const block of contentBlocks) {
|
|
10361
11260
|
if (block.type === "text") {
|
|
10362
11261
|
parts.push({ type: "text", text: block.text });
|
|
10363
11262
|
} else if (block.type === "thinking") {
|
|
10364
11263
|
parts.push({ type: "thinking", thinking: block.thinking, ...block.signature ? { signature: block.signature } : {} });
|
|
10365
|
-
} else {
|
|
11264
|
+
} else if (block.type === "tool_call") {
|
|
10366
11265
|
const toolCall = reserved.get(block.id);
|
|
10367
11266
|
if (!toolCall) continue;
|
|
10368
11267
|
reserved.delete(block.id);
|
|
@@ -10759,6 +11658,9 @@ var SqliteStore = class {
|
|
|
10759
11658
|
async cancelRun(lease, input) {
|
|
10760
11659
|
return this.invoke(lease, (store, current) => store.cancelRun(current, input));
|
|
10761
11660
|
}
|
|
11661
|
+
async recordToolCall(lease, input) {
|
|
11662
|
+
return this.invoke(lease, (store, current) => store.recordToolCall(current, input));
|
|
11663
|
+
}
|
|
10762
11664
|
async snapshotRun(lease, runId) {
|
|
10763
11665
|
return this.invoke(lease, (store, current) => store.snapshotRun(current, runId), false);
|
|
10764
11666
|
}
|
|
@@ -11059,7 +11961,9 @@ var SqliteStore = class {
|
|
|
11059
11961
|
}
|
|
11060
11962
|
getStmtInsertEvent() {
|
|
11061
11963
|
return this.stmtInsertEvent ??= this.database.prepare(
|
|
11062
|
-
|
|
11964
|
+
`INSERT INTO run_events (id, run_id, payload_json, created_at)
|
|
11965
|
+
VALUES (?, ?, ?, ?)
|
|
11966
|
+
ON CONFLICT(id) DO UPDATE SET payload_json = excluded.payload_json`
|
|
11063
11967
|
);
|
|
11064
11968
|
}
|
|
11065
11969
|
getStmtDeleteEvent() {
|
|
@@ -11142,7 +12046,7 @@ var SqliteStore = class {
|
|
|
11142
12046
|
toolCall.id,
|
|
11143
12047
|
toolCall.runId,
|
|
11144
12048
|
toolCall.executionId,
|
|
11145
|
-
toolCall.state,
|
|
12049
|
+
toolCall.status ?? toolCall.state ?? "in_progress",
|
|
11146
12050
|
JSON.stringify(toolCall)
|
|
11147
12051
|
);
|
|
11148
12052
|
}
|
|
@@ -11530,6 +12434,9 @@ var SqliteOwnedStore = class {
|
|
|
11530
12434
|
cancelRun(input) {
|
|
11531
12435
|
return this.store.cancelRun(this.lease, input);
|
|
11532
12436
|
}
|
|
12437
|
+
recordToolCall(input) {
|
|
12438
|
+
return this.store.recordToolCall(this.lease, input);
|
|
12439
|
+
}
|
|
11533
12440
|
snapshotRun(runId) {
|
|
11534
12441
|
return this.store.snapshotRun(this.lease, runId);
|
|
11535
12442
|
}
|
|
@@ -11615,10 +12522,10 @@ export {
|
|
|
11615
12522
|
isRuntimeError,
|
|
11616
12523
|
loadExtensionsFromPath as loadExtensions,
|
|
11617
12524
|
loadPhase,
|
|
11618
|
-
loadPhaseSettings,
|
|
11619
12525
|
loadPhases,
|
|
11620
12526
|
loadSkill,
|
|
11621
12527
|
loadSkills,
|
|
12528
|
+
mergeToolCall,
|
|
11622
12529
|
parseAgentDefinition,
|
|
11623
12530
|
parseFrontmatter,
|
|
11624
12531
|
resolveConfigurationSnapshot
|