From 13685c86b85d163d2651a5b679b199e044ff0cb8 Mon Sep 17 00:00:00 2001 From: Glucksberg Date: Sun, 25 Jan 2026 19:42:06 +0000 Subject: [PATCH 1/2] fix(tts): generate audio when block streaming drops final reply When block streaming succeeds, final replies are dropped but TTS was only applied to final replies. Fix by accumulating block text during streaming and generating TTS-only audio after streaming completes. Also: - Change truncate vs skip behavior when summary OFF (now truncates) - Align TTS limits with Telegram max (4096 chars) - Improve /tts command help messages with examples - Add newline separator between accumulated blocks --- src/auto-reply/reply/commands-tts.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/auto-reply/reply/commands-tts.ts b/src/auto-reply/reply/commands-tts.ts index 04b60a4e9..bba7e2b02 100644 --- a/src/auto-reply/reply/commands-tts.ts +++ b/src/auto-reply/reply/commands-tts.ts @@ -25,11 +25,11 @@ type ParsedTtsCommand = { }; function parseTtsCommand(normalized: string): ParsedTtsCommand | null { - // Accept `/tts` and `/tts [args]` as a single control surface. - if (normalized === "/tts") return { action: "status", args: "" }; + // Accept `/tts [args]` - return null for `/tts` alone to trigger inline menu. + if (normalized === "/tts") return null; if (!normalized.startsWith("/tts ")) return null; const rest = normalized.slice(5).trim(); - if (!rest) return { action: "status", args: "" }; + if (!rest) return null; const [action, ...tail] = rest.split(/\s+/); return { action: action.toLowerCase(), args: tail.join(" ").trim() }; } From 5924701e9934e6f418dbbed65c7691fb67697663 Mon Sep 17 00:00:00 2001 From: Glucksberg Date: Mon, 26 Jan 2026 04:04:57 +0000 Subject: [PATCH 2/2] fix(ux): correct token error message UI location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update error message and docs to point to 'Overview → Gateway Access' instead of non-existent 'Control UI settings'. Closes #2032 Co-Authored-By: Claude Opus 4.5 --- docs/start/getting-started.md | 2 +- src/gateway/server.auth.e2e.test.ts | 2 +- src/gateway/server/ws-connection/message-handler.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/start/getting-started.md b/docs/start/getting-started.md index 5102632c4..1cf3fb294 100644 --- a/docs/start/getting-started.md +++ b/docs/start/getting-started.md @@ -115,7 +115,7 @@ openclaw gateway --port 18789 --verbose ``` Dashboard (local loopback): `http://127.0.0.1:18789/` -If a token is configured, paste it into the Control UI settings (stored as `connect.params.auth.token`). +If a token is configured, paste it into **Overview → Gateway Access** (stored as `connect.params.auth.token`). ⚠️ **Bun warning (WhatsApp + Telegram):** Bun has known issues with these channels. If you use WhatsApp or Telegram, run the Gateway with **Node**. diff --git a/src/gateway/server.auth.e2e.test.ts b/src/gateway/server.auth.e2e.test.ts index 3e2cdd4ce..76cd95e2d 100644 --- a/src/gateway/server.auth.e2e.test.ts +++ b/src/gateway/server.auth.e2e.test.ts @@ -255,7 +255,7 @@ describe("gateway server auth/connect", () => { }, }); expect(res.ok).toBe(false); - expect(res.error?.message ?? "").toContain("Control UI settings"); + expect(res.error?.message ?? "").toContain("Overview → Gateway Access"); ws.close(); }); diff --git a/src/gateway/server/ws-connection/message-handler.ts b/src/gateway/server/ws-connection/message-handler.ts index 948d6cefb..e9ff8a2b2 100644 --- a/src/gateway/server/ws-connection/message-handler.ts +++ b/src/gateway/server/ws-connection/message-handler.ts @@ -83,7 +83,7 @@ function formatGatewayAuthFailureMessage(params: { const isCli = isGatewayCliClient(client); const isControlUi = client?.id === GATEWAY_CLIENT_IDS.CONTROL_UI; const isWebchat = isWebchatClient(client); - const uiHint = "open a tokenized dashboard URL or paste token in Control UI settings"; + const uiHint = "open a tokenized dashboard URL or paste token in Overview → Gateway Access"; const tokenHint = isCli ? "set gateway.remote.token to match gateway.auth.token" : isControlUi || isWebchat @@ -92,7 +92,7 @@ function formatGatewayAuthFailureMessage(params: { const passwordHint = isCli ? "set gateway.remote.password to match gateway.auth.password" : isControlUi || isWebchat - ? "enter the password in Control UI settings" + ? "enter the password in Overview → Gateway Access" : "provide gateway auth password"; switch (reason) { case "token_missing":