@rowan-agent/agent 0.35.1 → 0.35.3
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 +48 -15
- 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) {
|
|
@@ -2706,6 +2726,7 @@ async function executePhaseWithModel(ctx) {
|
|
|
2706
2726
|
});
|
|
2707
2727
|
await ctx.messageManager.end(messageId);
|
|
2708
2728
|
}
|
|
2729
|
+
ctx.progressed = true;
|
|
2709
2730
|
}
|
|
2710
2731
|
}
|
|
2711
2732
|
async function runTurn(fn) {
|
|
@@ -2729,6 +2750,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2729
2750
|
if (resumingSuspendedRun) {
|
|
2730
2751
|
state.status = "running";
|
|
2731
2752
|
delete state.entryPhases;
|
|
2753
|
+
state.attempt = 0;
|
|
2732
2754
|
}
|
|
2733
2755
|
let previousPayload = resumingSuspendedRun ? state.continuation && Object.hasOwn(state.continuation, "previousPayload") ? state.continuation.previousPayload : state.initialPhasePayload : state.initialPhasePayload;
|
|
2734
2756
|
let previousPhaseMsgId = resumingSuspendedRun ? state.continuation?.previousPhaseMessageId : void 0;
|
|
@@ -2973,6 +2995,7 @@ async function runPhaseLoop(config, state, registry) {
|
|
|
2973
2995
|
}
|
|
2974
2996
|
const runtime = { phase, config, state, execution, messageManager, registry, context: phaseContext, completedPhases };
|
|
2975
2997
|
let output = await executePhase(runtime);
|
|
2998
|
+
if (runtime.progressed) state.attempt = 0;
|
|
2976
2999
|
delete state.initialPhasePayload;
|
|
2977
3000
|
delete state.entryPhases;
|
|
2978
3001
|
let modelRouteDecision = resolveModelRouteDecision(output.toolCalls, registry, state);
|
|
@@ -10668,12 +10691,12 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
10668
10691
|
expectedRevision: revision,
|
|
10669
10692
|
toolCallId,
|
|
10670
10693
|
state: "failed",
|
|
10671
|
-
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available.` },
|
|
10694
|
+
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available. Available tools: ${input.toolConfig.tools.map(({ name }) => name).join(", ")}.` },
|
|
10672
10695
|
title: toolCall.name,
|
|
10673
10696
|
kind: "other"
|
|
10674
10697
|
});
|
|
10675
10698
|
setRevision(failed.run.revision);
|
|
10676
|
-
results2.push(protocolFailure(`Tool ${toolCall.name} is not available.`));
|
|
10699
|
+
results2.push(protocolFailure(`Tool ${toolCall.name} is not available. Available tools: ${input.toolConfig.tools.map(({ name }) => name).join(", ")}.`));
|
|
10677
10700
|
continue;
|
|
10678
10701
|
}
|
|
10679
10702
|
const decision = preDecisions[i] ?? { allow: true };
|
|
@@ -10791,12 +10814,12 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
10791
10814
|
expectedRevision: revision,
|
|
10792
10815
|
toolCallId,
|
|
10793
10816
|
state: "failed",
|
|
10794
|
-
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available.` },
|
|
10817
|
+
result: { ok: false, content: null, error: `Tool ${toolCall.name} is not available. Available tools: ${input.toolConfig.tools.map(({ name }) => name).join(", ")}.` },
|
|
10795
10818
|
title: toolCall.name,
|
|
10796
10819
|
kind: "other"
|
|
10797
10820
|
});
|
|
10798
10821
|
setRevision(failed.run.revision);
|
|
10799
|
-
results.push(protocolFailure(`Tool ${toolCall.name} is not available.`));
|
|
10822
|
+
results.push(protocolFailure(`Tool ${toolCall.name} is not available. Available tools: ${input.toolConfig.tools.map(({ name }) => name).join(", ")}.`));
|
|
10800
10823
|
continue;
|
|
10801
10824
|
}
|
|
10802
10825
|
const pendingPres = await presentToolPending(durableTool, toolCallArgs(toolCall));
|
|
@@ -11167,7 +11190,11 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
11167
11190
|
throw error;
|
|
11168
11191
|
}
|
|
11169
11192
|
let result = await withAbort(
|
|
11170
|
-
|
|
11193
|
+
// Invalid arguments are the model's to fix: a result it can read, not an indeterminate outcome.
|
|
11194
|
+
Promise.resolve(input.durableTool.execute(toolCallArgs(input.toolCall), context, effectiveSignal)).catch((error) => {
|
|
11195
|
+
if (isSchemaParseError(error)) return { ok: false, content: null, error: toolErrorMessage(error) };
|
|
11196
|
+
throw error;
|
|
11197
|
+
}),
|
|
11171
11198
|
input.options?.signal
|
|
11172
11199
|
);
|
|
11173
11200
|
if (!("ok" in result)) {
|
|
@@ -11606,6 +11633,12 @@ function toJsonValue(value) {
|
|
|
11606
11633
|
return value;
|
|
11607
11634
|
}
|
|
11608
11635
|
function toolCallArgs(toolCall) {
|
|
11636
|
+
if (typeof toolCall.arguments === "string") {
|
|
11637
|
+
try {
|
|
11638
|
+
return toJsonValue(JSON.parse(toolCall.arguments));
|
|
11639
|
+
} catch {
|
|
11640
|
+
}
|
|
11641
|
+
}
|
|
11609
11642
|
return toJsonValue(toolCall.arguments);
|
|
11610
11643
|
}
|
|
11611
11644
|
function createMergedToolCall(toolCallId, status, current, fallbackTitle, fallbackKind = "other") {
|