Summary
Two related observations from production WhatsApp deployment on [email protected]:
-
Sanitizer regression — Anthropic-style XML tool-calling tags (<function_calls>…</function_calls>, <invoke>, <parameter>, <tool_call>) are bleeding through to user-visible WhatsApp messages on certain agent paths. Pre-2026.4.23 these were stripped reliably; current versions leak the literal tags into the final delivered text.
-
Missing per-channel error visibility knob — there is no way to suppress raw error text on WhatsApp without disabling all error reactions. telegram has silentErrorReplies and errorPolicy: silent; whatsapp channel schema has neither. An exposeErrorText: false (or analogous errorPolicy) at channels.whatsapp level would close the gap.
Reproduction (item 1)
- Deploy openclaw 2026.4.23 with WhatsApp channel + an agent whose model returns Anthropic-style tool XML on a fallback/embedded-harness path (observed with Claude Sonnet 4.6 fallback when primary
openai-codex/gpt-5.5 fails over).
- Send a group message that triggers tool use (e.g., bot replies in a group with web-search style follow-up).
- Observe in WhatsApp: outbound message contains literal
<function_calls>...<invoke name="...">...</invoke>...</function_calls> blocks.
The existing sanitizer regex (in dist as a precompiled token, recovered as):
/<\s*\/?\s*(?:tool_call|tool_result|function_calls?|function|tool_calls)\b/i
…seems to match but is no longer applied at the right point in the pipeline for WA outbound — possibly the sanitizer runs before merge of fallback-harness output, or a later coalescer concatenates raw assistant chunks that bypass it.
Reproduction (item 2)
- WA agent fails an inbound turn (provider 5xx, malformed tool result, etc.).
- User sees raw error text on WhatsApp — there's no per-channel toggle to suppress it.
Workarounds in place locally
(none of these are real fixes — please consider them documentation of the gap)
- Added explicit anti-XML rule to
agents.list[main].systemPromptOverride instructing the model never to emit <function_calls> etc. — works on cooperative models, useless when the leak happens post-model.
acp.stream.deliveryMode: final_only, coalesceIdleMs: 250, maxChunkChars: 4000, repeatSuppression: true to reduce streaming surface area.
messages.queue.debounceMsByChannel.whatsapp: 1200 to coalesce bursts.
Asks
- Re-validate that the XML-tag sanitizer is applied at every outbound projection step on WA (post-coalesce, post-fallback merge, pre-Baileys send).
- Add
exposeErrorText: boolean (or errorPolicy/silentErrorReplies) to the channels.whatsapp schema, parity with telegram.
- Optionally: extract the sanitizer regex into config (
channels.<channel>.outboundSanitizers) so operators can extend it without core patches — aligns with the "no core patches" principle some of us run with.
Environment
- openclaw
2026.4.23, Mac mini host, LaunchAgent gateway on 127.0.0.1:18789.
- Channels:
whatsapp via Baileys, telegram.
- Providers in play during repro:
openai-codex/gpt-5.5 (primary), anthropic/claude-sonnet-4-6, workers-ai/@cf/moonshotai/kimi-k2.6.
Happy to provide redacted log snippets privately if helpful.
Summary
Two related observations from production WhatsApp deployment on
[email protected]:Sanitizer regression — Anthropic-style XML tool-calling tags (
<function_calls>…</function_calls>,<invoke>,<parameter>,<tool_call>) are bleeding through to user-visible WhatsApp messages on certain agent paths. Pre-2026.4.23 these were stripped reliably; current versions leak the literal tags into the final delivered text.Missing per-channel error visibility knob — there is no way to suppress raw error text on WhatsApp without disabling all error reactions.
telegramhassilentErrorRepliesanderrorPolicy: silent;whatsappchannel schema has neither. AnexposeErrorText: false(or analogouserrorPolicy) atchannels.whatsapplevel would close the gap.Reproduction (item 1)
openai-codex/gpt-5.5fails over).<function_calls>...<invoke name="...">...</invoke>...</function_calls>blocks.The existing sanitizer regex (in dist as a precompiled token, recovered as):
…seems to match but is no longer applied at the right point in the pipeline for WA outbound — possibly the sanitizer runs before merge of fallback-harness output, or a later coalescer concatenates raw assistant chunks that bypass it.
Reproduction (item 2)
Workarounds in place locally
(none of these are real fixes — please consider them documentation of the gap)
agents.list[main].systemPromptOverrideinstructing the model never to emit<function_calls>etc. — works on cooperative models, useless when the leak happens post-model.acp.stream.deliveryMode: final_only,coalesceIdleMs: 250,maxChunkChars: 4000,repeatSuppression: trueto reduce streaming surface area.messages.queue.debounceMsByChannel.whatsapp: 1200to coalesce bursts.Asks
exposeErrorText: boolean(orerrorPolicy/silentErrorReplies) to thechannels.whatsappschema, parity withtelegram.channels.<channel>.outboundSanitizers) so operators can extend it without core patches — aligns with the "no core patches" principle some of us run with.Environment
2026.4.23, Mac mini host, LaunchAgent gateway on127.0.0.1:18789.whatsappvia Baileys,telegram.openai-codex/gpt-5.5(primary),anthropic/claude-sonnet-4-6,workers-ai/@cf/moonshotai/kimi-k2.6.Happy to provide redacted log snippets privately if helpful.