@rowan-agent/agent 0.35.0 → 0.35.2
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/dist/runtime.js +47 -20
- package/package.json +1 -1
package/dist/runtime.js
CHANGED
|
@@ -1767,6 +1767,17 @@ function resolveCoreToolPath(context, path = ".") {
|
|
|
1767
1767
|
function toolResult(input) {
|
|
1768
1768
|
return input.ok ? { ok: true, content: input.content } : { ok: false, content: input.content, error: input.error ?? "Tool execution failed" };
|
|
1769
1769
|
}
|
|
1770
|
+
function isSchemaParseError(error) {
|
|
1771
|
+
return !(error instanceof Error) && Array.isArray(error?.errors);
|
|
1772
|
+
}
|
|
1773
|
+
function toolErrorMessage(error) {
|
|
1774
|
+
if (error instanceof Error) return error.message;
|
|
1775
|
+
if (isSchemaParseError(error) && error.errors.length > 0) {
|
|
1776
|
+
const { errors } = error;
|
|
1777
|
+
return `Invalid arguments: ${errors.map((item) => `${item.instancePath || "/"} ${item.message ?? "is invalid"}`).join("; ")}`;
|
|
1778
|
+
}
|
|
1779
|
+
return String(error);
|
|
1780
|
+
}
|
|
1770
1781
|
async function executeRuntimeToolCall(input) {
|
|
1771
1782
|
const tool = input.tools.find((candidate) => candidate.name === input.toolCall.name);
|
|
1772
1783
|
if (!tool) {
|
|
@@ -1780,13 +1791,19 @@ async function executeRuntimeToolCall(input) {
|
|
|
1780
1791
|
}
|
|
1781
1792
|
let args;
|
|
1782
1793
|
try {
|
|
1783
|
-
|
|
1794
|
+
let rawArgs = input.toolCall.arguments;
|
|
1795
|
+
if (typeof rawArgs === "string") {
|
|
1796
|
+
try {
|
|
1797
|
+
rawArgs = JSON.parse(rawArgs);
|
|
1798
|
+
} catch {
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1784
1801
|
args = validatorFor(tool.parameters).Parse(rawArgs);
|
|
1785
1802
|
} catch (error) {
|
|
1786
1803
|
const result = toolResult({
|
|
1787
1804
|
ok: false,
|
|
1788
1805
|
content: null,
|
|
1789
|
-
error:
|
|
1806
|
+
error: toolErrorMessage(error)
|
|
1790
1807
|
});
|
|
1791
1808
|
await input.observe?.({ type: "tool_end", toolName: tool.name, result });
|
|
1792
1809
|
return result;
|
|
@@ -1963,7 +1980,7 @@ function createReadTool(context) {
|
|
|
1963
1980
|
return toolResult({
|
|
1964
1981
|
ok: false,
|
|
1965
1982
|
content: null,
|
|
1966
|
-
error:
|
|
1983
|
+
error: toolErrorMessage(error)
|
|
1967
1984
|
});
|
|
1968
1985
|
}
|
|
1969
1986
|
if (!fileStat.isFile()) {
|
|
@@ -1980,7 +1997,7 @@ function createReadTool(context) {
|
|
|
1980
1997
|
return toolResult({
|
|
1981
1998
|
ok: false,
|
|
1982
1999
|
content: null,
|
|
1983
|
-
error:
|
|
2000
|
+
error: toolErrorMessage(error)
|
|
1984
2001
|
});
|
|
1985
2002
|
}
|
|
1986
2003
|
const source = new TextDecoder().decode(bytes);
|
|
@@ -2095,7 +2112,7 @@ function createEditTool(context) {
|
|
|
2095
2112
|
return toolResult({
|
|
2096
2113
|
ok: false,
|
|
2097
2114
|
content: null,
|
|
2098
|
-
error:
|
|
2115
|
+
error: toolErrorMessage(error)
|
|
2099
2116
|
});
|
|
2100
2117
|
}
|
|
2101
2118
|
await writeFile(resolved.absolutePath, next, "utf8");
|
|
@@ -2632,9 +2649,6 @@ function createRouteToolResultContent(toolCall, error, executionContext) {
|
|
|
2632
2649
|
];
|
|
2633
2650
|
}
|
|
2634
2651
|
async function executePhaseWithModel(ctx) {
|
|
2635
|
-
const executableToolNames = new Set(
|
|
2636
|
-
ctx.context.tools.filter((tool) => tool.name !== PhaseRouteTool).map((tool) => tool.name)
|
|
2637
|
-
);
|
|
2638
2652
|
let output = {
|
|
2639
2653
|
message: "",
|
|
2640
2654
|
phase: ctx.phase.name,
|
|
@@ -2652,7 +2666,10 @@ async function executePhaseWithModel(ctx) {
|
|
|
2652
2666
|
if (checkpoint && typeof checkpoint === "object" && checkpoint.kind === "tool_call_suspension") {
|
|
2653
2667
|
const toolSuspension = checkpoint;
|
|
2654
2668
|
executableToolCalls = toolSuspension.toolCalls.filter(
|
|
2655
|
-
(toolCall) =>
|
|
2669
|
+
(toolCall) => (
|
|
2670
|
+
// An unknown name still runs, so the model gets "not available" back instead of a silent end of turn.
|
|
2671
|
+
toolCall.name !== PhaseRouteTool
|
|
2672
|
+
)
|
|
2656
2673
|
);
|
|
2657
2674
|
output = {
|
|
2658
2675
|
message: "",
|
|
@@ -2686,7 +2703,10 @@ async function executePhaseWithModel(ctx) {
|
|
|
2686
2703
|
await ctx.messageManager.end(messageId);
|
|
2687
2704
|
}
|
|
2688
2705
|
executableToolCalls = collected.toolCalls.filter(
|
|
2689
|
-
(toolCall) =>
|
|
2706
|
+
(toolCall) => (
|
|
2707
|
+
// An unknown name still runs, so the model gets "not available" back instead of a silent end of turn.
|
|
2708
|
+
toolCall.name !== PhaseRouteTool
|
|
2709
|
+
)
|
|
2690
2710
|
);
|
|
2691
2711
|
roundContentBlocks = collected.contentBlocks;
|
|
2692
2712
|
if (executableToolCalls.length === 0) {
|
|
@@ -5325,7 +5345,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
5325
5345
|
interruptOwner(ownerEpoch, message = "The previous Runtime owner expired or closed.") {
|
|
5326
5346
|
this.ownerEpoch = Math.max(this.ownerEpoch, ownerEpoch);
|
|
5327
5347
|
for (const run of this.runs.values()) {
|
|
5328
|
-
if (run.state !== "running" || run.execution
|
|
5348
|
+
if (run.state !== "running" || !run.execution || run.execution.ownerEpoch > ownerEpoch) continue;
|
|
5329
5349
|
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"));
|
|
5330
5350
|
const indeterminateToolCallIds = [];
|
|
5331
5351
|
for (const toolCall of activeToolCalls) {
|
|
@@ -10668,12 +10688,12 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
10668
10688
|
expectedRevision: revision,
|
|
10669
10689
|
toolCallId,
|
|
10670
10690
|
state: "failed",
|
|
10671
|
-
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available.` },
|
|
10691
|
+
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available. Available tools: ${input.toolConfig.tools.map(({ name }) => name).join(", ")}.` },
|
|
10672
10692
|
title: toolCall.name,
|
|
10673
10693
|
kind: "other"
|
|
10674
10694
|
});
|
|
10675
10695
|
setRevision(failed.run.revision);
|
|
10676
|
-
results2.push(protocolFailure(`Tool ${toolCall.name} is not available.`));
|
|
10696
|
+
results2.push(protocolFailure(`Tool ${toolCall.name} is not available. Available tools: ${input.toolConfig.tools.map(({ name }) => name).join(", ")}.`));
|
|
10677
10697
|
continue;
|
|
10678
10698
|
}
|
|
10679
10699
|
const decision = preDecisions[i] ?? { allow: true };
|
|
@@ -10791,12 +10811,12 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
10791
10811
|
expectedRevision: revision,
|
|
10792
10812
|
toolCallId,
|
|
10793
10813
|
state: "failed",
|
|
10794
|
-
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available.` },
|
|
10814
|
+
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available. Available tools: ${input.toolConfig.tools.map(({ name }) => name).join(", ")}.` },
|
|
10795
10815
|
title: toolCall.name,
|
|
10796
10816
|
kind: "other"
|
|
10797
10817
|
});
|
|
10798
10818
|
setRevision(failed.run.revision);
|
|
10799
|
-
results.push(protocolFailure(`Tool ${toolCall.name} is not available.`));
|
|
10819
|
+
results.push(protocolFailure(`Tool ${toolCall.name} is not available. Available tools: ${input.toolConfig.tools.map(({ name }) => name).join(", ")}.`));
|
|
10800
10820
|
continue;
|
|
10801
10821
|
}
|
|
10802
10822
|
const pendingPres = await presentToolPending(durableTool, toolCallArgs(toolCall));
|
|
@@ -11167,7 +11187,11 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
11167
11187
|
throw error;
|
|
11168
11188
|
}
|
|
11169
11189
|
let result = await withAbort(
|
|
11170
|
-
|
|
11190
|
+
// Invalid arguments are the model's to fix: a result it can read, not an indeterminate outcome.
|
|
11191
|
+
Promise.resolve(input.durableTool.execute(toolCallArgs(input.toolCall), context, effectiveSignal)).catch((error) => {
|
|
11192
|
+
if (isSchemaParseError(error)) return { ok: false, content: null, error: toolErrorMessage(error) };
|
|
11193
|
+
throw error;
|
|
11194
|
+
}),
|
|
11171
11195
|
input.options?.signal
|
|
11172
11196
|
);
|
|
11173
11197
|
if (!("ok" in result)) {
|
|
@@ -11606,6 +11630,12 @@ function toJsonValue(value) {
|
|
|
11606
11630
|
return value;
|
|
11607
11631
|
}
|
|
11608
11632
|
function toolCallArgs(toolCall) {
|
|
11633
|
+
if (typeof toolCall.arguments === "string") {
|
|
11634
|
+
try {
|
|
11635
|
+
return toJsonValue(JSON.parse(toolCall.arguments));
|
|
11636
|
+
} catch {
|
|
11637
|
+
}
|
|
11638
|
+
}
|
|
11609
11639
|
return toJsonValue(toolCall.arguments);
|
|
11610
11640
|
}
|
|
11611
11641
|
function createMergedToolCall(toolCallId, status, current, fallbackTitle, fallbackKind = "other") {
|
|
@@ -11896,10 +11926,6 @@ var SqliteStore = class {
|
|
|
11896
11926
|
}
|
|
11897
11927
|
const state = this.readState();
|
|
11898
11928
|
const memory = InMemoryStore.fromState(state);
|
|
11899
|
-
if (row.owner_id && row.owner_token && row.epoch > 0) {
|
|
11900
|
-
memory.attachOwner(ownerLease(row));
|
|
11901
|
-
memory.interruptOwner(row.epoch);
|
|
11902
|
-
}
|
|
11903
11929
|
const epoch = row.epoch + 1;
|
|
11904
11930
|
const token = `${state.incarnation}:${epoch}:${input.ownerId}`;
|
|
11905
11931
|
const next = {
|
|
@@ -11921,6 +11947,7 @@ var SqliteStore = class {
|
|
|
11921
11947
|
const tracker = new ChangeTracker();
|
|
11922
11948
|
memory.setChangeRecorder(tracker);
|
|
11923
11949
|
try {
|
|
11950
|
+
if (row.epoch > 0) memory.interruptOwner(row.epoch);
|
|
11924
11951
|
memory.dropSettledClaimReceipts();
|
|
11925
11952
|
memory.compactTerminalReceipts();
|
|
11926
11953
|
} finally {
|