Commit Graph

298 Commits

Author SHA1 Message Date
zhzy0077
aba3a146c1
fix(channels): expand lark ack reactions with valid emoji_type ids
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-24 16:02:59 +08:00
zhzy0077
5e4bbd39a5
fix(channels): use valid Feishu emoji_type for lark ack
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-24 16:02:59 +08:00
Chummy
ef8f2fed70
fix(discord): send attachment markers as files/urls 2026-02-24 16:02:59 +08:00
Chummy
c6eb44438b
fix(channels): render WhatsApp Web pairing QR in terminal 2026-02-24 16:02:59 +08:00
Chummy
123be02653
fix(slack): bootstrap poll cursor to avoid replay 2026-02-24 16:02:59 +08:00
Ken Yeung
ecc8865cb7
feat: add WATI WhatsApp Business API channel (#1472)
Add a new WATI channel for WhatsApp Business API integration via the
WATI managed platform. WATI simplifies WhatsApp integration with its
own REST API and webhook system.

- New WatiChannel implementation (webhook mode, REST send)
- WatiConfig with api_token, api_url, tenant_id, allowed_numbers
- Gateway routes: GET/POST /wati for webhook verification and messages
- Flexible webhook parsing handles WATI's variable field names
- 15 unit tests covering parsing, allowlist, timestamps, phone normalization
2026-02-23 08:02:00 -05:00
agorevski
8331c65bcc fix(telegram): prevent non-image files from getting [IMAGE:] markers
Add file extension validation before generating [IMAGE:] markers for
incoming Telegram attachments. Non-image files (e.g. .md, .txt, .pdf)
now always use [Document:] format regardless of how Telegram classifies
them, preventing false vision capability errors.

Extract format_attachment_content() and is_image_extension() helpers
to centralize the logic and make it testable.

Fixes #1274

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-22 17:29:53 +08:00
Chummy
8db161a8e0 feat(channel): split lark and feishu providers 2026-02-22 14:10:34 +08:00
Chummy
1b8370f74b feat(channels): add immediate ack reactions for telegram discord and lark 2026-02-21 22:47:54 +08:00
Chummy
cb62135887 fix(channel/qq): preserve image attachments in inbound messages 2026-02-21 22:06:27 +08:00
InuDial
92e6c6e5ae Implement ChannelConfig for ClawdTalk 2026-02-21 19:38:19 +08:00
InuDial
b658e76bfd fix format 2026-02-21 19:38:19 +08:00
InuDial
9f844173b8 Use channels(&self) and channels_except_webhook(&self)
to reduce repeat
2026-02-21 19:38:19 +08:00
InuDial
052e9b8e85 add ChannelConfig implement for EmailConfig 2026-02-21 19:38:19 +08:00
Chummy
2aacdfeed3 fix(channels): rollback failed vision turns from sender history 2026-02-21 19:26:03 +08:00
Chummy
39997c7f37 Fix telegram channel prompt/test context regressions 2026-02-21 17:38:27 +08:00
Chummy
78196e027d Fix flaky regressions after main rebase 2026-02-21 17:38:27 +08:00
Chummy
1682bd9b23 fix(clawdtalk): finalize rebase compatibility updates 2026-02-21 17:38:27 +08:00
Abhishek
20cd26fead feat: add Telnyx AI inference provider and ClawdTalk voice channel 2026-02-21 17:38:27 +08:00
chumyin
0fd2c693a5 fix(tests): remove duplicate non_cli_excluded_tools init 2026-02-21 17:32:18 +08:00
Allen Huang
7c4dc0982d feat(agent): add draft progress streaming for tool call execution
Port the progress streaming code from the fork's 75fdeb0 commit.
The upstream run_tool_call_loop only uses on_delta for final response
streaming, missing real-time feedback during tool execution.

Added progress sends at 4 points in the tool loop:
- "Thinking..." / "Thinking (round N)..." before each LLM call
- "Got N tool call(s) (Xs)" after LLM responds with tool calls
- Tool start: " tool_name: hint..." before each tool execution
- Tool complete: " tool_name (Xs)" or " tool_name (Xs)" after

Also added DRAFT_CLEAR_SENTINEL handling in the channel draft updater
so progress lines are cleared before the final answer streams in.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-21 17:22:32 +08:00
Chummy
520bcdac4b fix(matrix): persist e2ee sdk store under zeroclaw state dir 2026-02-21 17:07:53 +08:00
chumyin
ef9c12abf9 fix(telegram): preserve fenced code blocks and restore delivery instruction phrase 2026-02-21 17:00:38 +08:00
Chummy
61f98a8fd3 feat(observability): add runtime trace diagnostics and trace doctor query 2026-02-21 17:00:38 +08:00
chumyin0912@gmail.com
f3beba1f24 test(channels): include new runtime excluded-tools field in fixture 2026-02-21 16:14:01 +08:00
Chummy
580cc52a0a
Merge pull request #1127 from ecschoye/fix/non-cli-tool-exclusion
feat(security): add non_cli_excluded_tools config for channel tool filtering
2026-02-21 15:33:16 +08:00
chumyin
67942318c9 Merge origin/main into fix/non-cli-tool-exclusion 2026-02-21 15:28:53 +08:00
chumyin0912@gmail.com
81b05deb64 fix(test): include hooks field after rebase 2026-02-21 15:12:27 +08:00
chumyin
782bb0b483 fix: resolve multi-issue provider/channel/tool regressions 2026-02-21 15:12:27 +08:00
Chummy
2a291aec24 fix(slack): allow listening without explicit channel_id 2026-02-21 15:07:13 +08:00
chumyin0912@gmail.com
ae84112a22 chore(fmt): align formatting after main rebase 2026-02-21 14:54:19 +08:00
Kevin Syong
3822778f40 fix(channels): include date and time in system prompt datetime section
- Fix 'Current Date & Time' section only emitting timezone string (e.g. 'Timezone: +08:00'), omitting actual date and time values.
- Caused AI to hallucinate incorrect dates when asked about current time.
- Emit full datetime in format 'YYYY-MM-DD HH:MM:SS (TZ)' instead.
2026-02-21 14:49:11 +08:00
Allen Huang
de85d53c73 fix(channel): close orphan user turn on error and timeout
When a channel message triggers an LLM error or idle timeout, the user
turn was already appended to conversation history (line 1517) but no
assistant turn was recorded. This orphan user turn caused the LLM to
treat the failed request as unfinished context on subsequent messages,
leading to unrelated replies (e.g., re-executing a timed-out GitHub
search when the user asked about WAL checkpoints).

Append a short assistant marker ("[Task failed — not continuing this
request]" or "[Task timed out — ...]") in the error and timeout
branches so the conversation history stays properly alternating and the
LLM sees the prior request as closed.

The cancel and context-overflow paths are intentionally left unchanged:
cancel is superseded by a newer message, and context-overflow prompts
the user to resend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-21 14:33:33 +08:00
chumyin
f74fd478b1 fix(telegram): harden html rendering and scope allowlist change 2026-02-21 14:32:02 +08:00
Shawn Zhang
7fed5cf56b feat(telegram): convert Markdown to Telegram HTML for proper formatting
- Add markdown_to_telegram_html() to TelegramChannel: converts **bold**,
  *italic*, `code`, ```blocks```, [text](url) links, and ## headers
  to Telegram HTML tags (<b>, <i>, <code>, <pre>, <a href>)
- Switch send_text_chunks() and finalize_draft() from parse_mode=Markdown
  to parse_mode=HTML — more reliable and supports richer formatting
- Update channel_delivery_instructions() for Telegram: guide model to use
  bold, emoji, and concise style (mirrors OpenClaw SOUL.md approach)
- Add wildcard support to http_request allowlist: allowed_domains=["*"]
  now bypasses domain filtering entirely
- Expand system prompt URL fetching guidance: jina.ai reader-mode proxy
  as fallback for paywalled/403 content
2026-02-21 14:32:02 +08:00
agorevski
00a7510e91 fix(tests): update test structs for new usage and hooks fields
Add missing `usage: None` to ChatResponse literals in benchmarks,
agent loop tests, and file_read tests. Add missing `hooks: None` to
channel context structs in channel tests. Remove obsolete
`.map(|(m, _)| m)` calls in telegram tests to match updated
parse_update_message return type.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-20 22:30:23 -08:00
Alex Gorevski
bd31f77e8f
Merge pull request #1182 from zeroclaw-labs/fix/cleartext-logging-alerts
fix(security): remove sensitive fields from Debug impls
2026-02-20 22:14:04 -08:00
agorevski
52f72692ba fix(security): remove sensitive fields from Debug impls
Resolve 18 CodeQL cleartext-logging/cleartext-transmission alerts by
removing sensitive data from Debug output entirely rather than redacting.

Changes:
- memory/mod.rs: omit api_key from ResolvedEmbeddingConfig Debug
- tools/browser.rs: omit api_key from ComputerUseConfig Debug
- providers/mod.rs: omit access_token/refresh_token from
  QwenOauthCredentials Debug, credential from QwenOauthProviderContext
- memory/traits.rs: custom Debug for MemoryEntry omitting session_id
- auth/profiles.rs: custom Debug for AuthProfile omitting token,
  token_set, account_id
- channels/matrix.rs: add Debug impl for MatrixChannel omitting
  access_token
- channels/qq.rs: sanitize user_id before URL interpolation
- channels/whatsapp_storage.rs: document false-positive analysis

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-20 22:06:21 -08:00
chumyin0912@gmail.com
29aa400160 fix(hooks): harden dispatch and outbound message guardrails 2026-02-21 13:34:09 +08:00
xj
eb60d0fb81 fix(hooks): address code review findings
- C1: Use real tool success boolean instead of starts_with("Error")
  heuristic in after_tool_call hook
- C2: Wire HookRunner from config into ChannelRuntimeContext so hooks
  actually fire in daemon/channel mode (was hardcoded to None)
- I1: Suppress unused_imports warning on HookHandler public API re-export
- I3: Remove session_memory and boot_script config fields that had no
  backing implementation (YAGNI); keep only command_logger which is wired

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:34:09 +08:00
xj
6d4dca9a07 chore(hooks): fix formatting and clippy warnings
Apply cargo fmt and replace sort_by with sort_by_key per clippy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:34:09 +08:00
xj
0638266b63 feat(hooks): integrate HookRunner into agent loop, channels, and gateway
Thread Option<&HookRunner> into run_tool_call_loop with hook fire points
for LLM input, before/after tool calls. Add hooks field to
ChannelRuntimeContext for message received/sending interception.
Build HookRunner from config in run_gateway and fire gateway_start.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:34:09 +08:00
chumyin0912@gmail.com
6cee99c8ad fix(channel): keep nostr wiring compatible with channel collectors 2026-02-21 13:16:20 +08:00
Kieran
11edda3ed6 feat(channel): add Nostr channel with NIP-04 and NIP-17 support
Adds a full NostrChannel implementation enabling ZeroClaw to send and
receive private messages over the Nostr protocol via user-configured
relay WebSocket connections.

Key design decisions:
- Implements the Channel trait in src/channels/nostr.rs; registered via
  the existing factory in channels/mod.rs
- Supports both NIP-04 (legacy encrypted DMs) and NIP-17 (gift-wrapped
  private messages); replies automatically mirror the sender's protocol
- Deny-by-default allowlist (allowed_pubkeys = [] denies all)
- Private key encrypted at rest via SecretStore (ChaCha20-Poly1305 AEAD)
  when secrets.encrypt = true (the default)
- nostr-sdk added with default-features = false and only nip04 + nip59
  features to minimise binary size impact
- health_check() returns true if any relay reports is_connected()

Wiring:
- New NostrConfig struct and optional field in ChannelsConfig
- has_supervised_channels() in daemon updated to include nostr
- Onboarding wizard extended with a dedicated Nostr step (key
  validation, relay selection, allowlist configuration)

Docs compliance:
- channels-reference.md: channel matrix, delivery modes table, allowlist
  field names, numbered config section (4.12), log keyword table (7.2),
  and log filter command all updated
- config-reference.md: [channels_config.nostr] sub-section with key
  table and security notes added
- network-deployment.md and README.md updated
- .github/pull_request_template.md: resolved stale conflict markers from
  chore/labeler-spacing-trusted-tier
2026-02-21 13:16:20 +08:00
xero7689
9aaa305f66 feat(channel): inline text attachments from Discord messages
Extract d.attachments from MESSAGE_CREATE payloads and fetch text/*
content from Discord CDN URLs, appending it to ChannelMessage.content
before the agent loop receives the message.

- Add process_attachments() async helper: fetches text/* attachments,
  skips all other MIME types with debug log, warns on fetch errors
- Reuse existing build_runtime_proxy_client HTTP client (no new deps)
- Format inlined content as [filename]\n<content>, joined by ---
- Add unit tests: empty list, unsupported MIME type skip

Closes #1169
2026-02-21 13:00:28 +08:00
Edvard
1e8961ca17 fix(channel): strip tool_call XML tags from Discord outgoing messages
Move strip_tool_call_tags to channels/mod.rs as shared utility and
call it in Discord's send method. Telegram already stripped these tags
but Discord sent raw LLM output including <tool_call>...</tool_call>
XML, which leaked internal protocol to end users.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:57:40 +08:00
Aleksandr Prilipko
930158b02f fix(channel): remove reply context truncation to preserve full context
Remove the 200-char truncation of quoted reply text in Telegram
channel. The agent benefits from seeing the complete original message
when replying to a conversation thread.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:57:32 +08:00
Aleksandr Prilipko
01d6002d41 fix(channel): use [IMAGE:] marker for photo attachments, add e2e vision tests
Photos now use [IMAGE:/path] format instead of [Photo] /path, so the
existing multimodal pipeline validates vision capability and rejects
unsupported providers (Groq, OpenAI-compatible) with a user-facing
error before calling the LLM.

Tests added (all offline, no API keys required):
- attachment_photo_content_uses_image_marker
- attachment_document_content_uses_document_label
- photo_image_marker_detected_by_multimodal
- photo_image_marker_with_caption
- e2e_attachment_saves_file_and_formats_content
- groq_provider_rejects_photo_with_vision_error
- e2e_photo_attachment_rejected_by_non_vision_provider

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:57:32 +08:00
Aleksandr Prilipko
41619b8469 test(channel): add live e2e test for voice transcription + reply cache
Add an ignored integration test that exercises the full voice
transcription pipeline: load a pre-recorded MP3 fixture, transcribe via
Groq Whisper API, verify the result contains "hello", cache it in
TelegramChannel.voice_transcriptions, and assert extract_reply_context
returns "[Voice] <transcription>" instead of the fallback placeholder.

The test gracefully skips when GROQ_API_KEY is not set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:57:32 +08:00
Aleksandr Prilipko
3b29d0c90e feat(channel): surface Telegram reply context to the agent
When a user swipes to reply to a specific message, the agent now
receives the quoted original message as a blockquote prefix, e.g.:

  > @alice:
  > original message text

  translate this

This makes reply-to-voice ("translate this" → previous transcription)
and other reply-aware interactions work correctly.

Changes:
- Extract `extract_sender_info` helper (DRY: was duplicated in
  parse_update_message and try_parse_voice_message)
- Add `extract_reply_context` helper: parses reply_to_message,
  handles text/voice/photo/document/video/sticker, truncates >200
  chars, falls back from username to first_name
- Wire reply context into both parse_update_message and
  try_parse_voice_message
- Add 8 unit tests covering all branches

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:57:32 +08:00