Follow-up to the previous commit on this branch. The agent message-tool
schema now describes forceDocument/asDocument as a cross-channel knob,
so the public CLI help and the user-facing CLI docs need to match, and
the regenerated prompt snapshot fixtures need to drop the stale
"Telegram only" string the schema no longer emits.
* src/cli/program/message/register.send.ts: rephrase the `--force-document`
CLI option help from "Send media as document to avoid Telegram
compression (Telegram only)" to "Send media as document to avoid
channel compression (Telegram, WhatsApp)" so `openclaw message send
--help` no longer claims Telegram exclusivity.
* docs/cli/message.md: change the per-flag entry under `send` from
"Telegram only: --force-document (...avoid Telegram compression)" to
"Telegram + WhatsApp: --force-document (...avoid channel compression)"
so the public docs match both the schema and the CLI help.
* test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/*:
regenerate via `pnpm prompt:snapshots:gen` so the captured tool
descriptions, dynamic-tools JSON, and rough-token counts reflect the
new schema strings. Six fixtures change in lockstep:
- discord-group-codex-message-tool.md
- telegram-direct-codex-message-tool.md
- telegram-heartbeat-codex-tool.md
- codex-dynamic-tools.discord-group.json
- codex-dynamic-tools.telegram-direct.json
- codex-dynamic-tools.heartbeat-turn.json
Verified locally:
* `pnpm prompt:snapshots:check` reports 7 files current.
* `pnpm exec oxfmt --check --threads=1` is clean for both touched ts
files plus docs/cli/message.md and CHANGELOG.md.
* `pnpm test extensions/whatsapp/src/send.test.ts
extensions/whatsapp/src/inbound/send-api.test.ts` keeps the 51-case
WhatsApp send/inbound suite green, including the three new
forceDocument/asDocument cases from the previous commit.
`ChannelOutboundContext.forceDocument` and the agent `message`-tool
`asDocument` alias were documented as cross-channel knobs to "send
image/GIF as document to avoid channel compression", but on the
WhatsApp side the flag was silently dropped between the outbound
context and the Baileys payload selector. Telegram honored the same
flag through its own outbound, so any agent that asked for an
uncompressed image hand-off worked on Telegram and got a compressed
JPEG on WhatsApp instead.
This change wires the flag through the existing layers without
introducing a new contract:
* extensions/whatsapp/src/outbound-base.ts: destructure forceDocument
from ChannelOutboundContext.sendMedia and forward it to send().
* extensions/whatsapp/src/send.ts: sendMessageWhatsApp options gain
forceDocument; documentFileName is set regardless of media.kind
when the flag is true; sendOptions exposes asDocument so the
inbound send-api layer can pick the document payload shape.
* extensions/whatsapp/src/inbound/types.ts: ActiveWebSendOptions
gains asDocument so the payload selector can short-circuit on
the flag instead of inferring intent from fileName alone.
* extensions/whatsapp/src/inbound/send-api.ts: payload-shape
selector guards `asDocument === true` ahead of MIME branches and
builds the document content with caller-supplied filename and
mimetype, falling back to "file" only when nothing is supplied.
* extensions/whatsapp/src/outbound-media-contract.ts: preserve
caller-supplied fileName on canonical media for non-document
kinds. Without this, an image+forceDocument hand-off lost the
filename inside normalizeWhatsAppLoadedMedia before send.ts
could promote it.
* src/channels/plugins/outbound.types.ts and
src/agents/tools/message-tool.ts: drop the now-misleading
"Telegram only" qualifier from the public JSDoc and the agent
schema descriptions for forceDocument and asDocument so the
surface stops lying about WhatsApp support.
Tests: extensions/whatsapp/src/send.test.ts gains
"forces document branch when forceDocument is true with image media"
and "falls back to a default filename when forceDocument media has
no fileName"; extensions/whatsapp/src/inbound/send-api.test.ts gains
"sends as document when sendOptions.asDocument is true regardless of
MIME". Existing 48 cases in those two files unchanged.
Changelog: single-line Channels/whatsapp Fixes entry under the
Unreleased section.
Include the checked credential source in missing API key errors so users can see which env var, profile, or config path to fix.
Fixes#82785.
Co-authored-by: gleb <116607327+loeclos@users.noreply.github.com>
Fix CLI web search/fetch command SecretRef resolution for provider-scoped plugin credentials.
- Carry command provider overrides through gateway and local secret resolution.
- Mark the selected web provider targets active and unrelated plugin refs inactive.
- Cover Tavily, DuckDuckGo, legacy Firecrawl fetch, protocol overrides, and runtime command-secret behavior.
- Add public plugin-sdk test mock exports needed by existing plugin tests after CI boundary enforcement.
Fixes#82621.
Replacement for #82699.
Co-authored-by: 吴杨帆 <39647285+leno23@users.noreply.github.com>
Fix diagnostics/session usage limit handling and voice-call numeric CLI validation.
- Treat explicit zero, negative, and non-finite diagnostics/session limits as empty results instead of falling back to defaults.
- Reject invalid, non-finite, and fractional voice-call numeric flags.
- Add focused tests and a live repro proof for the canonical edge cases.
Fixes#82646, #82650, #82651, #82653.
Co-authored-by: wuyangfan <1102042793@qq.com>