The existing iMessage channel relies on AppleScript and only works on macOS.
Linq provides a REST API for iMessage, RCS, and SMS — this gives ZeroClaw
native iMessage support on any platform via webhooks.
Implements LinqChannel following the same patterns as WhatsAppChannel:
- Channel trait impl (send, listen, health_check, typing indicators)
- Webhook handler with HMAC-SHA256 signature verification
- Sender allowlist filtering
- Onboarding wizard step with connection testing
- 18 unit tests covering parsing, auth, and signature verification
Resolves#656 — the prior issue was closed without a merged PR, so this
is the actual implementation.
Add configurable timeout for processing channel messages (LLM + tools).
Default: 300s (optimized for on-device LLMs like Ollama).
Can be overridden in config.toml:
[channels_config]
message_timeout_secs = 600
The pushover tool priority parameter schema used integer enum values
[-2, -1, 0, 1, 2]. OpenAI-compatible APIs accept this, but the Gemini
API (and Gemini-relay proxies) strictly require all enum values to be
strings, rejecting the request with 400 Bad Request.
This causes every agent turn to fail with a non_retryable error when
using Gemini models, regardless of user message content, because tool
schemas are included in every request.
Fix: remove the enum constraint, keeping integer type and description
documenting the valid range. This is valid for both OpenAI and Gemini
providers and requires no changes to execute() which already uses
as_i64() with range validation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace hard-coded string literals used as cryptographic keys/secrets in
gateway webhook and WhatsApp signature verification tests with runtime-
generated random values. This resolves CodeQL rust/hard-coded-cryptographic-value
alerts while maintaining identical test coverage.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add URL scheme validation before HTTP requests that transmit sensitive
data (account IDs, phone numbers, user IDs). All endpoints already use
HTTPS URLs, but this explicit check satisfies CodeQL rust/cleartext-
transmission analysis and prevents future regressions if URLs are
changed.
Affected files: composio.rs, whatsapp.rs, qq.rs
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Enable matrix-sdk markdown support and send Matrix messages with text_markdown so clients can render formatted_body.
Add listener startup diagnostics for device verification and backup state to reduce confusion around matrix_sdk_crypto backup warnings.
Expand Matrix docs with backup-warning interpretation, unverified-device guidance, markdown formatting expectations, and updated log keyword appendix.
- add scope-aware proxy schema and runtime wiring for providers/channels/tools
- add agent callable proxy_config tool for fast proxy setup
- standardize docs system with index, template, and playbooks
Add mention_only support for the Mattermost channel, matching the existing
Discord implementation. When enabled, the bot only processes messages that
contain an @-mention of the bot username, reducing noise in busy channels.
- Add mention_only field to MattermostConfig schema (Option<bool>, default false)
- Rename get_bot_user_id() to get_bot_identity() returning (user_id, username)
- Add contains_bot_mention_mm() with case-insensitive word-boundary matching
and metadata.mentions array support
- Add normalize_mattermost_content() to strip @-mentions from processed text
- Wire mention_only through channel and cron factory constructors
- Add 23 new tests covering mention detection, stripping, case-insensitivity,
word boundaries, metadata mentions, empty-after-strip, and disabled passthrough
Address clippy pedantic/all lints: format_push_string in sqlite memory,
match_same_arms and match_wildcard_for_single_variants in anthropic
provider and prometheus observer, option_as_ref_cloned in main. Fix
pre-existing test compilation errors in gateway (missing max_keys arg
and trust_forwarded_headers field) and memory_store (missing security
arg). Add .worktrees/ to gitignore.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Route OVHcloud through OpenAiProvider (with proper tool_call_id
serialization) instead of OpenAiCompatibleProvider, fixing tool-call
round-trips against vLLM-based endpoints.
- Add base_url field and with_base_url() constructor to OpenAiProvider
- Replace all hardcoded api.openai.com URLs with self.base_url
- Pass api_url through for the openai provider arm
- Register ovhcloud/ovh provider with env var OVH_AI_ENDPOINTS_ACCESS_TOKEN
Field is unused since the IMAP polling loop was replaced with IDLE.
Serde ignores unknown fields on deserialization, so existing configs
with the key set will continue to work without error.
Also add two focused tests for idle_timeout_secs: explicit
deserialization and propagation into EmailChannel.
Replace the blocking, poll-based IMAP client with async-imap and
IMAP IDLE (RFC 2177) for instant push delivery. Key changes:
- Add async-imap dependency with tokio runtime feature
- Rewrite connect/fetch/listen paths to fully async using tokio TLS
- Implement IDLE loop with exponential backoff reconnection (1s–60s cap)
- Add idle_timeout_secs config field (default 1740s per RFC 2177)
- Convert health_check to async connect-and-logout with 10s timeout
- Update affected tests from sync to #[tokio::test]
SMTP send path, allowlist enforcement, and Channel trait contract
are unchanged.
Adds mention_only config option to Telegram channel, allowing the bot
to only respond to messages that @-mention the bot in group chats.
Direct messages are always processed regardless of this setting.
Behavior:
- When mention_only = true: Bot only responds to group messages containing @botname
- When mention_only = false (default): Bot responds to all allowed messages
- DM/private chats always work regardless of mention_only setting
Implementation:
- Fetch and cache bot username from Telegram API on startup
- Check for @botname mention in group messages
- Strip mention from message content before processing
Config example:
[channels.telegram]
bot_token = "your_token"
mention_only = true
Changes:
- src/config/schema.rs: Add mention_only to TelegramConfig
- src/channels/telegram.rs: Implement mention_only logic + 6 new tests
- src/channels/mod.rs: Update factory calls
- src/cron/scheduler.rs: Update constructor call
- src/onboard/wizard.rs: Update wizard config
- src/daemon/mod.rs: Update test config
- src/integrations/registry.rs: Update test config
- TESTING_TELEGRAM.md: Add mention_only test section
- CHANGELOG.md: Document feature
Risk: medium
Backward compatible: Yes (default: false)
HEARTBEAT.md is only relevant to the heartbeat worker, which reads it
directly from disk. Including it in channel system prompts caused LLMs
to emit spurious 'HEARTBEAT_OK' acknowledgments at the start of
channel responses.
The agent prompt (src/agent/prompt.rs) still includes HEARTBEAT.md,
which is correct for agent and heartbeat contexts.
Implement chat_with_tools() on CompatibleProvider so OpenAI-compatible
endpoints (OpenRouter, local LLMs, etc.) can use structured tool calling
instead of prompt-injected tool descriptions.
Changes:
- CompatibleProvider: capabilities() reports native_tool_calling, new
chat_with_tools() sends tools in API request and parses tool_calls
from response, chat() bridges to chat_with_tools() when ToolSpecs
are provided
- RouterProvider: chat_with_tools() delegation with model hint resolution
- loop_.rs: expose tools_to_openai_format as pub(crate), add
tools_to_openai_format_from_specs for ToolSpec-based conversion
Adds 9 new tests and updates 1 existing test.