fix: show tool error fallback for tool-only replies
This commit is contained in:
@@ -23,6 +23,8 @@ Docs: https://docs.clawd.bot
|
|||||||
### Fixes
|
### Fixes
|
||||||
- Gateway: compare Linux process start time to avoid PID recycling lock loops; keep locks unless stale. (#1572) Thanks @steipete.
|
- Gateway: compare Linux process start time to avoid PID recycling lock loops; keep locks unless stale. (#1572) Thanks @steipete.
|
||||||
- Skills: gate bird Homebrew install to macOS. (#1569) Thanks @bradleypriest.
|
- Skills: gate bird Homebrew install to macOS. (#1569) Thanks @bradleypriest.
|
||||||
|
- Slack: honor open groupPolicy for unlisted channels in message + slash gating. (#1563) Thanks @itsjaydesu.
|
||||||
|
- Agents: show tool error fallback when the last assistant turn only invoked tools (prevents silent stops).
|
||||||
- Agents: ignore IDENTITY.md template placeholders when parsing identity to avoid placeholder replies. (#1556)
|
- Agents: ignore IDENTITY.md template placeholders when parsing identity to avoid placeholder replies. (#1556)
|
||||||
- Agents: drop orphaned OpenAI Responses reasoning blocks on model switches. (#1562) Thanks @roshanasingh4.
|
- Agents: drop orphaned OpenAI Responses reasoning blocks on model switches. (#1562) Thanks @roshanasingh4.
|
||||||
- Docker: update gateway command in docker-compose and Hetzner guide. (#1514)
|
- Docker: update gateway command in docker-compose and Hetzner guide. (#1514)
|
||||||
|
|||||||
@@ -148,6 +148,35 @@ describe("buildEmbeddedRunPayloads", () => {
|
|||||||
expect(payloads[0]?.text).toBe("All good");
|
expect(payloads[0]?.text).toBe("All good");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("adds tool error fallback when the assistant only invoked tools", () => {
|
||||||
|
const payloads = buildEmbeddedRunPayloads({
|
||||||
|
assistantTexts: [],
|
||||||
|
toolMetas: [],
|
||||||
|
lastAssistant: {
|
||||||
|
stopReason: "toolUse",
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "toolCall",
|
||||||
|
id: "toolu_01",
|
||||||
|
name: "exec",
|
||||||
|
arguments: { command: "echo hi" },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} as AssistantMessage,
|
||||||
|
lastToolError: { toolName: "exec", error: "Command exited with code 1" },
|
||||||
|
sessionKey: "session:telegram",
|
||||||
|
inlineToolResultsAllowed: false,
|
||||||
|
verboseLevel: "off",
|
||||||
|
reasoningLevel: "off",
|
||||||
|
toolResultFormat: "plain",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(payloads).toHaveLength(1);
|
||||||
|
expect(payloads[0]?.isError).toBe(true);
|
||||||
|
expect(payloads[0]?.text).toContain("Exec");
|
||||||
|
expect(payloads[0]?.text).toContain("code 1");
|
||||||
|
});
|
||||||
|
|
||||||
it("suppresses recoverable tool errors containing 'required'", () => {
|
it("suppresses recoverable tool errors containing 'required'", () => {
|
||||||
const payloads = buildEmbeddedRunPayloads({
|
const payloads = buildEmbeddedRunPayloads({
|
||||||
assistantTexts: [],
|
assistantTexts: [],
|
||||||
|
|||||||
@@ -169,7 +169,16 @@ export function buildEmbeddedRunPayloads(params: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (params.lastToolError) {
|
if (params.lastToolError) {
|
||||||
const hasUserFacingReply = replyItems.length > 0;
|
const lastAssistantHasToolCalls =
|
||||||
|
Array.isArray(params.lastAssistant?.content) &&
|
||||||
|
params.lastAssistant?.content.some((block) =>
|
||||||
|
block && typeof block === "object"
|
||||||
|
? (block as { type?: unknown }).type === "toolCall"
|
||||||
|
: false,
|
||||||
|
);
|
||||||
|
const lastAssistantWasToolUse = params.lastAssistant?.stopReason === "toolUse";
|
||||||
|
const hasUserFacingReply =
|
||||||
|
replyItems.length > 0 && !lastAssistantHasToolCalls && !lastAssistantWasToolUse;
|
||||||
// Check if this is a recoverable/internal tool error that shouldn't be shown to users
|
// Check if this is a recoverable/internal tool error that shouldn't be shown to users
|
||||||
// when there's already a user-facing reply (the model should have retried).
|
// when there's already a user-facing reply (the model should have retried).
|
||||||
const errorLower = (params.lastToolError.error ?? "").toLowerCase();
|
const errorLower = (params.lastToolError.error ?? "").toLowerCase();
|
||||||
|
|||||||
Reference in New Issue
Block a user