diff --git a/CHANGELOG.md b/CHANGELOG.md index 469c33c2213..996dd8f9b3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Docs: https://docs.openclaw.ai - Gateway/assistant media: require `operator.read` scope for assistant-media file and metadata requests on identity-bearing HTTP auth paths so callers without a read scope can no longer access assistant media. (#68175) Thanks @eleqtrizit. - Exec approvals/display: escape raw control characters (including newline and carriage return) in the shared and macOS approval-prompt command sanitizers, so trailing command payloads no longer render on hidden extra lines in the approval UI. (#68198) - OpenAI Codex/OAuth + Pi: keep imported Codex CLI OAuth bootstrap, Pi auth export, and runtime overlay handling aligned so Codex sessions survive refresh and health checks without leaking transient CLI state into saved auth files. Thanks @vincentkoc. +- Agents/TTS: report failed speech synthesis as a real tool error so unconfigured providers no longer feed successful TTS failure output back into agent loops. (#67980) Thanks @lawrence3699. ## 2026.4.15 diff --git a/src/agents/tools/tts-tool.test.ts b/src/agents/tools/tts-tool.test.ts index f559166d7bb..7faa0790950 100644 --- a/src/agents/tools/tts-tool.test.ts +++ b/src/agents/tools/tts-tool.test.ts @@ -41,4 +41,17 @@ describe("createTtsTool", () => { }); expect(JSON.stringify(result.content)).not.toContain("MEDIA:"); }); + + it("throws when synthesis fails so the agent records a tool error", async () => { + textToSpeechSpy.mockResolvedValue({ + success: false, + error: "TTS conversion failed: openai: not configured", + }); + + const tool = createTtsTool(); + + await expect(tool.execute("call-1", { text: "hello" })).rejects.toThrow( + "TTS conversion failed: openai: not configured", + ); + }); }); diff --git a/src/agents/tools/tts-tool.ts b/src/agents/tools/tts-tool.ts index 38ac7b4e65f..ba37c73e0c4 100644 --- a/src/agents/tools/tts-tool.ts +++ b/src/agents/tools/tts-tool.ts @@ -49,15 +49,7 @@ export function createTtsTool(opts?: { }; } - return { - content: [ - { - type: "text", - text: result.error ?? "TTS conversion failed", - }, - ], - details: { error: result.error }, - }; + throw new Error(result.error ?? "TTS conversion failed"); }, }; }