mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-16 14:23:15 +02:00
fix: suppress commentary fallback payloads
This commit is contained in:
@@ -13,6 +13,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Doctor: warn when on-disk agent directories still exist under `~/.openclaw/agents/<id>/agent` but the matching `agents.list[]` entries are missing from config. (#65113) Thanks @neeravmakwana.
|
||||
- Telegram: route approval button callback queries onto a separate sequentializer lane so plugin approval clicks can resolve immediately instead of deadlocking behind the blocked agent turn. (#64979) Thanks @nk3750.
|
||||
- Agents/Anthropic replay: preserve immutable signed-thinking replay safety across stored and live reruns, keep non-thinking embedded `tool_result` user blocks intact, and drop conflicting preserved tool IDs before validation so retries stop degrading into omitted tool calls. (#65126) Thanks @shakkernerd.
|
||||
- Telegram/direct sessions: keep commentary-only assistant fallback payloads out of visible direct delivery, so Codex planning chatter cannot leak into Telegram DMs when a run has no `final_answer` text. (#65112) Thanks @vincentkoc.
|
||||
|
||||
## 2026.4.11
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import type { AssistantMessage } from "@mariozechner/pi-ai";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildPayloads, expectSingleToolErrorPayload } from "./payloads.test-helpers.js";
|
||||
import {
|
||||
buildPayloads,
|
||||
expectSinglePayloadText,
|
||||
expectSingleToolErrorPayload,
|
||||
} from "./payloads.test-helpers.js";
|
||||
|
||||
describe("buildEmbeddedRunPayloads tool-error warnings", () => {
|
||||
function expectNoPayloads(params: Parameters<typeof buildPayloads>[0]) {
|
||||
@@ -7,6 +12,59 @@ describe("buildEmbeddedRunPayloads tool-error warnings", () => {
|
||||
expect(payloads).toHaveLength(0);
|
||||
}
|
||||
|
||||
it("does not fall back to commentary-only assistant text when streamed text was suppressed", () => {
|
||||
const payloads = buildPayloads({
|
||||
lastAssistant: {
|
||||
role: "assistant",
|
||||
stopReason: "toolUse",
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "Need update cron messages to use finalBrief/briefPath.",
|
||||
textSignature: JSON.stringify({
|
||||
v: 1,
|
||||
id: "item_commentary",
|
||||
phase: "commentary",
|
||||
}),
|
||||
},
|
||||
],
|
||||
} as AssistantMessage,
|
||||
});
|
||||
|
||||
expect(payloads).toEqual([]);
|
||||
});
|
||||
|
||||
it("falls back to final-answer assistant text when streamed text is unavailable", () => {
|
||||
const payloads = buildPayloads({
|
||||
lastAssistant: {
|
||||
role: "assistant",
|
||||
stopReason: "stop",
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "Need inspect.",
|
||||
textSignature: JSON.stringify({
|
||||
v: 1,
|
||||
id: "item_commentary",
|
||||
phase: "commentary",
|
||||
}),
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
text: "Done.",
|
||||
textSignature: JSON.stringify({
|
||||
v: 1,
|
||||
id: "item_final",
|
||||
phase: "final_answer",
|
||||
}),
|
||||
},
|
||||
],
|
||||
} as AssistantMessage,
|
||||
});
|
||||
|
||||
expectSinglePayloadText(payloads, "Done.");
|
||||
});
|
||||
|
||||
it("suppresses exec tool errors when verbose mode is off", () => {
|
||||
expectNoPayloads({
|
||||
lastToolError: { toolName: "exec", error: "command failed" },
|
||||
|
||||
@@ -20,8 +20,8 @@ import {
|
||||
} from "../../pi-embedded-helpers.js";
|
||||
import type { ToolResultFormat } from "../../pi-embedded-subscribe.shared-types.js";
|
||||
import {
|
||||
extractAssistantText,
|
||||
extractAssistantThinking,
|
||||
extractAssistantVisibleText,
|
||||
formatReasoningMessage,
|
||||
} from "../../pi-embedded-utils.js";
|
||||
import { isExecLikeToolName, type ToolErrorSummary } from "../../tool-error-summary.js";
|
||||
@@ -217,7 +217,9 @@ export function buildEmbeddedRunPayloads(params: {
|
||||
replyItems.push({ text: reasoningText, isReasoning: true });
|
||||
}
|
||||
|
||||
const fallbackAnswerText = params.lastAssistant ? extractAssistantText(params.lastAssistant) : "";
|
||||
const fallbackAnswerText = params.lastAssistant
|
||||
? extractAssistantVisibleText(params.lastAssistant)
|
||||
: "";
|
||||
const shouldSuppressRawErrorText = (text: string) => {
|
||||
if (!lastAssistantErrored) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user