Commit Graph

1431 Commits

Author SHA1 Message Date
argenis de la rosa
12018b4a03 fix(provider): include quota metadata in cursor chat response 2026-02-28 16:01:42 -05:00
argenis de la rosa
2d91536f92 feat(routing): support hint default_model during startup 2026-02-28 16:01:42 -05:00
xj
11e68485e9
fix(fmt): correct remaining rustfmt violations on main (#2282)
Fixes formatting in auth_profile.rs and quota_tools.rs missed by #2280.

Co-authored-by: xj <gh-xj@users.noreply.github.com>
2026-02-28 13:01:21 -08:00
maxtongwang
32150c85fb fix(channel/bluebubbles): address CodeRabbit review findings
- typing_handle → typing_handles: per-recipient HashMap to prevent
  concurrent conversations from cancelling each other's typing loops
- add is_sender_ignored() method; enforce ignore_senders before allowlist
  evaluation in parse_webhook_payload (precedence: ignore > allow)
- wire BlueBubblesConfig.password and .webhook_secret into
  decrypt_channel_secrets / encrypt_channel_secrets in config/schema.rs
- add 3 unit tests covering is_sender_ignored edge cases
2026-02-28 12:20:47 -08:00
maxtongwang
e37a53c690
fix(web-fetch): remove dead feature gates and add noise stripping (#2262)
* fix(web-fetch): remove dead feature gates, add noise stripping, add docstrings

The nanohtml2text and fast_html2md providers were both guarded by
cfg(feature) checks for features (web-fetch-plaintext, web-fetch-html2md)
that are never declared in Cargo.toml. This caused every web_fetch call
to silently return an error instead of fetching content.

Changes:
- Add strip_noise_elements() which removes <script>, <style>, <nav>,
  <header>, <footer>, <aside>, <noscript>, <form>, <button> blocks
  before text extraction, eliminating menu/ad/boilerplate noise.
- Fix fast_html2md path: when web-fetch-html2md feature is not compiled
  in, fall through to nanohtml2text rather than returning an error.
- Fix nanohtml2text path: remove dead cfg(feature = "web-fetch-plaintext")
  gate; nanohtml2text is a direct dependency and needs no feature flag.
- Both previously gated tests (html_to_markdown_conversion_preserves_structure,
  html_to_plaintext_conversion_removes_html_tags) are now always-on.
  Added strip_noise_removes_nav_scripts_footer test.
- Add docstrings to all public/private methods to meet coverage threshold.

Tavily and firecrawl providers are unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-fetch): align default provider to nanohtml2text, remove dead feature

- Change empty-provider default from deprecated 'fast_html2md' to
  'nanohtml2text' to match WEB_FETCH_PROVIDER_HELP and PR description.
- Remove dead 'web-fetch-plaintext' feature from Cargo.toml (no code
  references it after the feature-gate removal).
- Apply cargo fmt to strip_noise_elements array formatting.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: xj <gh-xj@users.noreply.github.com>
2026-02-28 12:19:40 -08:00
maxtongwang
4d195be713 feat(channel): add BlueBubbles iMessage channel
Adds a BlueBubbles channel so ZeroClaw can send and receive iMessages
via a locally-running BlueBubbles server on macOS.

What changed:
- src/channels/bluebubbles.rs — new BlueBubblesChannel implementing Channel
  - Webhook-based ingestion (push, no polling)
  - Allowlist + ignore_senders filtering
  - Rich text via iMessage Private API (attributedBody bold/italic/underline)
  - Typing indicator (start_typing / stop_typing) while LLM processes
  - Message effects ([EFFECT:confetti], [EFFECT:slam], etc.)
  - 500-entry fromMe FIFO cache for reply-context resolution
  - Attachment placeholder format matching OpenClaw (<media:image>)
  - 38 unit tests covering parsing, filtering, timestamps, effects
- src/config/schema.rs — BlueBubblesConfig struct + ChannelsConfig field
  - Fields: server_url, password, allowed_senders, webhook_secret, ignore_senders
  - Debug impl redacts password and webhook_secret
- src/gateway/mod.rs — POST /bluebubbles route + handler
  - Bearer token auth if webhook_secret is set
  - Typing indicator around LLM call
  - Memory auto-save on incoming messages
- src/channels/mod.rs — module + re-export + iMessage delivery instructions
- src/providers/cursor.rs — fix pre-existing missing quota_metadata field

Non-goals: BlueBubbles Private API pairing, polling mode, contact management.

Closes #2268
2026-02-28 12:08:24 -08:00
argenis de la rosa
3825eca3dc fix(memory): thread session IDs through runtime paths 2026-02-28 15:00:27 -05:00
argenis de la rosa
352adb5a82 fix(agent): avoid orphan tool messages after compaction 2026-02-28 14:41:13 -05:00
argenis de la rosa
9784e3bfc1 feat(channel): add github native channel MVP 2026-02-28 14:03:10 -05:00
argenis de la rosa
5aac1af065 feat(channel): support onebot aliases for napcat config 2026-02-28 14:00:35 -05:00
argenis de la rosa
aa319e71b0 test(cli): add coverage for config show/get/set 2026-02-28 14:00:35 -05:00
argenis de la rosa
20ed60d2a0 feat(config): add show/get/set subcommands for runtime config inspection and modification 2026-02-28 14:00:35 -05:00
dexter
f6278373cb
feat: add cursor headless cli support (#2195)
* Initial plan

* feat(providers): add Cursor headless CLI provider

Co-authored-by: langhuihui <3647405+langhuihui@users.noreply.github.com>

* fix(cursor): harden headless CLI invocation and safety guards

* chore(pr): retrigger intake after template and linear updates

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: langhuihui <3647405+langhuihui@users.noreply.github.com>
Co-authored-by: argenis de la rosa <theonlyhennygod@gmail.com>
2026-02-28 13:41:56 -05:00
argenis de la rosa
3f70cbbf9b feat(gateway): add paired devices API and dashboard tab 2026-02-28 13:34:33 -05:00
argenis de la rosa
0253752bc9 feat(memory): add observation memory tool 2026-02-28 13:32:13 -05:00
argenis de la rosa
e3e648eea7 fix(tools): harden pptx_read ordering and extraction limits 2026-02-28 13:29:05 -05:00
argenis de la rosa
5cc482ebe1 fix(pptx_read): handle empty a:t tags safely 2026-02-28 13:29:05 -05:00
reidliu41
cb1cd14cbb feat(tools): add pptx_read tool for PowerPoint text extraction
- Problem: Agent cannot read PPTX files — file_read returns garbled binary, making presentations inaccessible
  - Why it matters: PPTX is the last major Office format gap after pdf_read and docx_read; presentations are ubiquitous in
  business and education workflows
  - What changed: Added pptx_read tool using existing zip + quick-xml to extract plain text from all slides in order
  - What did not change: No changes to existing tools, agent loop, security policy, config schema, or dependencies

  Label Snapshot (required)

  - Risk label: risk: low
  - Size label: size: S
  - Scope labels: tool
  - Module labels: tool: pptx_read

  Change Metadata

  - Change type: feature
  - Primary scope: tool

  Linked Issue

  - Closes #

  Validation Evidence (required)

  cargo fmt --all -- --check   # pass
  cargo clippy --all-targets -- -D warnings   # pass (zero new warnings)
  cargo test pptx_read   # 14/14 passed

  - Evidence provided: test results

  Security Impact (required)

  - New permissions/capabilities? No
  - New external network calls? No
  - Secrets/tokens handling changed? No
  - File system access scope changed? No

  Privacy and Data Hygiene (required)

  - Data-hygiene status: pass
  - Redaction/anonymization notes: Test fixtures use neutral content ("Hello PPTX", "Slide One", "Slide Two")
  - Neutral wording confirmation: Yes

  Compatibility / Migration

  - Backward compatible? Yes
  - Config/env changes? No
  - Migration needed? No

  i18n Follow-Through

  - i18n follow-through triggered? No

  Human Verification (required)

  - Verified scenarios: Multi-slide extraction produces correct ordered text
  - Edge cases checked: invalid ZIP, missing slides, symlink escape, path traversal, rate limiting, truncation
  - What was not verified: encrypted PPTX (out of scope), speaker notes

  Side Effects / Blast Radius (required)

  - Affected subsystems/workflows: Tool registry only
  - Potential unintended effects: None — additive only
  - Guardrails/monitoring: Identical security chain as pdf_read/docx_read

  Rollback Plan (required)

  - Fast rollback command/path: git revert <commit>
  - Feature flags or config toggles: None needed
  - Observable failure symptoms: pptx_read tool missing from tool list

  Risks and Mitigations

  - Risk: None — zero new dependencies, follows established pattern exactly
    - Mitigation: N/A
2026-02-28 13:29:05 -05:00
argenis de la rosa
83f7399c72 fix(copilot): preserve first text while merging split tool calls 2026-02-28 13:29:04 -05:00
Tim Stewart
8b7b0b0776 fix(copilot): merge tool_calls from all response choices
The Copilot API proxy for Claude models (Opus 4.6, Opus 4.6-1m) splits
text content and tool_calls into separate choices. Previously only
choices[0] was read, causing all tool calls to be silently dropped
when they appeared in choices[1].

Merge text and tool_calls from all choices so tool calling works
regardless of how the proxy splits the response.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 13:29:04 -05:00
Argenis
a25ca6524f
feat(skills): support front-matter metadata and always-inject skills (#2248)
* feat(skills): support front matter always injection in compact mode

* chore(pr): retrigger intake after template and linear updates
2026-02-28 13:11:57 -05:00
argenis de la rosa
6500f048bc feat(email): add IMAP ID extension support 2026-02-28 13:05:49 -05:00
argenis de la rosa
cc0bc49b2f feat(channel): add napcat support for qq protocol 2026-02-28 13:02:55 -05:00
Chummy
6e444e0311 fix(zip): adapt test zip writers for zip 8.1 2026-02-28 12:33:32 -05:00
Argenis
db16188c74
Merge pull request #2241 from zeroclaw-labs/supersede-pr-1923-v2-20260228
fix(channel:discord): robust inbound image marker detection
2026-02-28 12:10:41 -05:00
argenis de la rosa
376d965088 Merge remote-tracking branch 'origin/main' into supersede-pr-1923-mergefix 2026-02-28 12:05:28 -05:00
Argenis
2f1380a03f
Merge pull request #2064 from peitschie/fix/cron-matrix-delivery
RMN-218: feat(channels): add matrix integration for sovereign communication
2026-02-28 12:05:26 -05:00
weykon
9ecb8dffa6 feat(memory): add sqlite_journal_mode config for shared filesystem support
SQLite WAL mode requires shared-memory (mmap/shm) which is unavailable
on many network and virtual shared filesystems (NFS, SMB/CIFS,
UTM/VirtioFS, VirtualBox shared folders), causing xShmMap I/O errors
at startup.

Add `sqlite_journal_mode` config option under `[memory]` that accepts
"wal" (default) or "delete". When set to "delete", SQLite uses the
legacy DELETE journal mode and disables mmap, allowing ZeroClaw to run
with workspaces on shared/network filesystems.

Usage:
  [memory]
  sqlite_journal_mode = "delete"

Changes:
- config/schema.rs: Add sqlite_journal_mode field to MemoryConfig
- memory/sqlite.rs: Add with_options() supporting journal mode selection
- memory/mod.rs: Pass journal_mode from config to SqliteMemory
- onboard/wizard.rs: Include new field in default MemoryConfig
2026-02-28 12:04:46 -05:00
loydccc
2044e828de fix(channel): mark discord inbound image attachments as [IMAGE]
# Conflicts:
#	src/channels/discord.rs
2026-02-28 11:57:17 -05:00
argenis de la rosa
b287b2420a fix(cron): avoid merge conflict in matrix scheduler tests 2026-02-28 11:48:22 -05:00
Chummy
3aa1eb1fd5 chore(fmt): normalize rustfmt output to satisfy quality gate 2026-03-01 00:45:18 +08:00
argenis de la rosa
74c8cae95d fix(quota): wire provider quota modules on main replay 2026-02-28 11:45:02 -05:00
ZeroClaw Bot
5ac9c3e955 fix(quota): address CodeRabbit review feedback
- Fix low-quota warning format string readability (parenthesized percentage)
- Add QuotaFormat enum for CLI --format validation (fail-fast on invalid input)
- Fix backoff eviction strategy comments (soonest-to-expire, not LRU)
- Custom Default for ProviderUsageMetrics (last_reset_at = Utc::now())
- Fix fail_count==0 always-fail case in stress test
- Add providers-quota to commands-reference.md
- Document fresh ProviderHealthTracker intent in quota_tools.rs

Made-with: Cursor
2026-02-28 11:45:02 -05:00
ZeroClaw Bot
d5fe47acff feat(tools): wire auth_profile + quota tools into agent loop and persist switch_provider
- Register 4 new tools (ManageAuthProfileTool, CheckProviderQuotaTool,
  SwitchProviderTool, EstimateQuotaCostTool) in all_tools_with_runtime
- SwitchProviderTool now loads config from disk and calls save() to
  persist default_provider/default_model to config.toml
- Inject Provider & Budget Context section into system prompt when
  Config is available
- Remove emoji from tool output for cleaner parsing
- Replace format! push_str with std::fmt::Write for consistency

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 11:45:02 -05:00
ZeroClaw Bot
8c0be20422 feat(providers): add quota_metadata to ChatResponse across all providers
Wire QuotaMetadata into ChatResponse for all provider implementations,
enabling quota tracking data to flow from API responses through the
agent loop to quota monitoring tools.

Depends on: circuit breaker (#1842) + quota monitoring (#1904)

Made-with: Cursor
2026-02-28 11:45:02 -05:00
ZeroClaw Bot
247d89e39e feat(providers): implement quota monitoring system with CLI and agent tools
Add comprehensive quota monitoring: QuotaMetadata types, quota-aware
agent loop with proactive warnings, CLI providers-quota command, and
3 built-in tools (check_provider_quota, switch_provider,
estimate_quota_cost).

Depends on: circuit breaker + provider health (#1842)

Made-with: Cursor
2026-02-28 11:45:02 -05:00
argenis de la rosa
e854238a39 fix(channels): resolve main drift for matrix cron delivery 2026-02-28 11:44:21 -05:00
Chummy
cf59171937 test: align channel context defaults and de-flake proxy assertion 2026-02-28 23:01:53 +08:00
Chummy
a89f5c25be fix: resolve rebase drift in channel approval runtime 2026-02-28 23:01:53 +08:00
Chummy
42471f4d3e fix: restore ws query-token fallback and telegram test fixtures 2026-02-28 23:01:53 +08:00
Chummy
be8f7efe82 test: stabilize flaky threshold assertions 2026-02-28 23:01:53 +08:00
Chummy
5ee6024914 Fix channel turn persistence and low-sensitivity leak detection 2026-02-28 23:01:53 +08:00
argenis de la rosa
4cc156611c fix(channel:discord): robust image marker detection for inbound attachments 2026-02-28 09:56:35 -05:00
Tim Stewart
f1adc79f38 fix(browser): add return before snapshot IIFE in rust_native backend
WebDriver's execute() wraps the script as a function body. The snapshot
script used an IIFE without a top-level return, so the IIFE's return
value was discarded and the WebDriver function returned undefined (null).

All other execute() calls in the file (scroll, scrollIntoView, click)
correctly use explicit return statements.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 09:27:42 -05:00
argenis de la rosa
b9d9798774 fix: resolve compilation errors in channels, tools, and gateway modules 2026-02-28 09:18:30 -05:00
argenis de la rosa
bb25e5fbf6 fix(tests): align channel runtime fixtures for main compatibility 2026-02-28 09:17:35 -05:00
Chummy
5cced82e3f fix(channels): import ApprovalResponse for runtime approval handling 2026-02-28 21:58:52 +08:00
argenis de la rosa
57fd23c381 fix: resolve 3 compilation errors 2026-02-28 08:54:29 -05:00
argenis de la rosa
a029c720a6 feat(security): add safety heartbeat reinjection with cadence fixes 2026-02-28 08:52:16 -05:00
Chummy
3341608d52 fix(channels): remove duplicate perplexity snapshot helper 2026-02-28 21:49:11 +08:00
Chummy
aa401f29c3 fix(channels): restore pending approval flow and docx tool export 2026-02-28 21:49:11 +08:00
Chummy
1509cc5b69 fix(telegram): unify mention gate and typing target handling 2026-02-28 21:49:11 +08:00
argenis de la rosa
62b719c447 fix(gateway): allow ws query fallback without subprotocol header 2026-02-28 08:36:18 -05:00
Chummy
d9cdaa0757 fix: resolve post-rebase compile and test stability issues 2026-02-28 21:30:37 +08:00
Chummy
51ad52d0e8 security: harden sensitive I/O and outbound leak controls 2026-02-28 21:30:37 +08:00
ake117
87fa327e0d feat(telegram): add ack_enabled option to control emoji reactions
Add configuration option to enable/disable Telegram emoji reaction
acknowledgments (️, 👌, 👀, 🔥, 👍) sent to incoming messages.

Changes:
- Add ack_enabled field to TelegramConfig (default: true)
- Add ack_enabled field to TelegramChannel struct
- Add with_ack_enabled() builder method
- Conditionally send reactions in try_add_ack_reaction_nonblocking()
- Update all call sites and tests
- Update documentation with usage example

Usage:
  [channels_config.telegram]
  ack_enabled = false  # Disable emoji reactions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 08:23:04 -05:00
Chummy
61e738287b chore(ws): mention query token auth in unauthorized hint 2026-02-28 21:21:33 +08:00
Chummy
2a865ac713 chore(gateway): remove unused ws chat artifacts 2026-02-28 21:21:33 +08:00
Chummy
32205fb038 fix(gateway): accept websocket token query fallback 2026-02-28 21:21:33 +08:00
Chummy
5ca656be07 fix(qq): keep sender-level history across messages 2026-02-28 08:19:23 -05:00
Argenis
58cf5b4cf3
Merge pull request #2197 from zeroclaw-labs/issue-2175
fix(build): restore missing runtime approval and docx symbols
2026-02-28 08:17:22 -05:00
Chummy
bebb881b5b fix(android): harden Termux source-build and wasm-tools fallback 2026-02-28 21:16:52 +08:00
argenis de la rosa
40de96ed77 fix(build): resolve main conflict for runtime approval wiring 2026-02-28 08:14:34 -05:00
argenis de la rosa
f0a5bbdb1b feat(http_request): add env credential profiles and onboarding guards 2026-02-28 08:07:37 -05:00
Chummy
46b50cbb49 fix: reconcile supersede replay with current main runtime 2026-02-28 20:56:09 +08:00
Jaime Linares
a88d37f3cb fix(whatsapp-web): strip MIME parameters before matching in audio_mime_to_filename
MIME strings like 'audio/webm; codecs=opus' were incorrectly matched by
the 'opus' branch (contains-check) before reaching the 'webm' branch,
returning 'voice.opus' instead of 'voice.webm'. This could cause the
Groq Whisper API to reject or misidentify the file format.

Fix: split on ';' to extract only the base MIME type, then match
exhaustively. Also add 'audio/x-wav' as a wav alias.

Adds a regression test: audio_mime_to_filename('audio/webm; codecs=opus')
must return 'voice.webm'.

Reported by CodeRabbit in PR review.

(cherry picked from commit 84861c727a)
2026-02-28 20:56:09 +08:00
Jaime Linares
f8eef67a03 feat(whatsapp-web): transcribe voice messages via Groq Whisper
Audio/voice messages on the WhatsApp Web channel were silently dropped
because `text_content()` returns an empty string for non-text messages
and no transcription path existed (unlike the Telegram channel which
already uses `transcription::transcribe_audio()`).

Changes:

- **Cargo.toml**: Move `qrcode` and all `wa-rs-*` crates out of the
  `[target.'cfg(any(linux|macos|windows))'.dependencies]` section into
  the unconditional `[dependencies]` section.  All affected crates are
  `optional = true`, so they add no compile cost unless
  `--features whatsapp-web` is active.  The previous placement caused
  Cargo to exclude them when targeting `android` (target_os = "android"
  does not match the cfg predicate), producing E0433 unresolved-crate
  errors for every wa-rs import in `whatsapp_web.rs` and
  `whatsapp_storage.rs` on Android cross-compilation.

- **whatsapp_web.rs**:
  - Add `transcription: Option<TranscriptionConfig>` field.
  - Add `with_transcription()` builder (mirrors `TelegramChannel`).
  - Add `audio_mime_to_filename()` helper mapping WhatsApp MIME types
    (e.g. `audio/ogg; codecs=opus`) to filenames the Groq Whisper API
    accepts.
  - Extend `Event::Message` handler: when text is empty, check
    `msg.audio_message`; download and decrypt audio via
    `client.download(audio_msg.as_ref())` (`.as_ref()` required because
    prost boxes nested proto fields as `Box<AudioMessage>`, which does
    not itself implement `Downloadable`); forward decrypted bytes to
    `transcription::transcribe_audio()`.
  - Add three unit tests: builder enable/disable guard and MIME mapping.

- **mod.rs**: Chain `.with_transcription(config.transcription.clone())`
  onto `WhatsAppWebChannel::new(...)` in the `"web"` factory branch so
  transcription is active whenever the global `[transcription]` section
  is enabled.

Activation: set `[transcription] enabled = true` and export
`GROQ_API_KEY` in the environment.

(cherry picked from commit 325241aeb6)
2026-02-28 20:56:09 +08:00
Chummy
6b89446b46
test(tools): guard docx_read registration in all_tools 2026-02-28 12:51:17 +00:00
argenis de la rosa
006eb4b9c2 fix(delivery): handle HEARTBEAT_OK sentinel case-insensitively 2026-02-28 07:31:45 -05:00
cyberpapi
4fe18d3548 fix(telegram): redact raw response body in register_commands error log
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:59:22 +08:00
cyberpapi
1177a83e4a feat(telegram): register bot commands with setMyCommands on startup
Register /new, /model, and /models commands with Telegram's Bot API
on startup so they appear in the command menu for users. Registration
is non-fatal — if the API call fails, a warning is logged and the
bot continues listening normally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:59:22 +08:00
cyberpapi
9125651775 fix(telegram): log specific deleteMessage failure reason in finalize_draft
Split the catch-all `_` match arm on the deleteMessage result into
separate `Ok(r)` and `Err(e)` arms so that HTTP status codes and
network errors are logged individually. The response body is not
logged (security policy).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:59:20 +08:00
cyberpapi
b2fc063d88 fix(telegram): prevent duplicate messages in finalize_draft fallback
When editMessageText returns 'message is not modified', the draft
already contains the correct content from update_draft. Detect this
Telegram API response and treat it as success rather than falling
through to the delete+send fallback, which would create a visible
duplicate message.

Also guard the final fallback: only send a new message after
successfully deleting the draft. If deleteMessage fails, the draft
still shows the response text, so sending would create a duplicate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:59:20 +08:00
Chummy
dea0d5e447
fix(build): restore missing runtime approval and docx symbols 2026-02-28 11:37:46 +00:00
VirtualHotBar
1ac510283f Fix tests after AutonomyLevel move 2026-02-28 19:16:14 +08:00
VirtualHotBar
857cb3c054 Merge remote-tracking branch 'origin/main' 2026-02-28 19:00:27 +08:00
VirtualHotBar
0f321994c5 session: make get_history side-effect free 2026-02-28 18:51:30 +08:00
VirtualHotBar
0a357064d9 session/history: allowlist persistable roles (user, assistant) via ROLE_* constants; unify filtering in channel + agent; memory/session: reduce read contention with RwLock+AtomicI64 and refresh updated_at on get_history; providers: export role constants and helper; security: switch HMAC verifications to ring::hmac for Linq/Nextcloud/WhatsApp; channels tests: auto-approve mock_price to avoid non-CLI approval dead-wait; misc: ignore target_ci/.idea; main: use local rag module. 2026-02-28 18:40:48 +08:00
VirtualHotBar
824ce19622 Share SessionManager across runtime 2026-02-28 17:45:29 +08:00
VirtualHotBar
2a4902c3a5 fix(qq): stabilize conversation history key 2026-02-28 17:34:00 +08:00
VirtualHotBar
fae10cd5c4 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/channels/mod.rs
#	src/config/mod.rs
#	src/config/schema.rs
2026-02-28 16:12:02 +08:00
Chummy
7470bded5d fix: harden browser and web search validation paths 2026-02-28 15:50:06 +08:00
Chummy
6716391502 feat: harden web access policy and add flexible web search/runtime config 2026-02-28 15:50:06 +08:00
killf
955c572c02 feat(tools): add Chrome/Firefox/Edge support to browser_open tool
Add support for Chrome, Firefox, and Edge browsers to the browser_open tool,
which previously only supported Brave. Users can now specify the browser
via the browser_open config option.

Changes:
- Add browser_open config field: "disable" | "brave" | "chrome" | "firefox" | "edge" | "default"
- Implement platform-specific launch commands for Chrome, Firefox, and Edge
- When set to "disable", only the browser automation tool is registered, not the browser_open tool
- Update tool descriptions and error messages to reflect browser selection

Co-Authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:50:06 +08:00
VirtualHotBar
0a42329ca5 fix: session leftovers after db47f56
- Demote session normal flow logs to debug\n- Skip session operations when CHANNEL_SESSION_CONFIG is uninitialized\n- Add spawn_blocking panic context for SQLite session manager\n- Fix fmt/clippy regressions (Box::pin large futures, cfg features, misc lints)
2026-02-28 15:23:42 +08:00
xj
a381963623
fix(ci): stabilize post-2142 local quality gates (COM-2142) (#2171)
* chore(ci): retrigger PR checks after intake body update

* fix(ci): stabilize local quality gates on rebased main

---------

Co-authored-by: Chummy <chumyin0912@gmail.com>
Co-authored-by: xj <gh-xj@users.noreply.github.com>
2026-02-27 23:18:25 -08:00
Preventnetworkhacking
479b6da4ce feat(cost): wire provider token usage to cost tracking (#2111)
Implement CostObserver that intercepts LlmResponse observer events and
records token usage to the CostTracker with proper cost calculations.

Changes:
- Add src/observability/cost.rs: CostObserver implementation
  - Listens for LlmResponse events with token counts
  - Looks up model pricing from CostConfig (with fallback defaults)
  - Records usage via CostTracker.record_usage()
  - Includes model family matching for pricing lookups

- Update src/observability/mod.rs:
  - Export CostObserver
  - Add create_observer_with_cost_tracking() helper that wraps base
    observer with CostObserver when cost tracking is enabled

- Update src/gateway/mod.rs:
  - Use create_observer_with_cost_tracking() to wire cost observer
    into the gateway observer stack when config.cost.enabled is true

The /api/cost endpoint already exists and will now return accurate
session/daily/monthly cost data populated by the CostObserver.

Resolves #2111
2026-02-28 02:00:13 -05:00
Argenis
43e3e9b897
Merge pull request #2134 from Preventnetworkhacking/feat/economic-agents-mvp
feat(economic): ZeroClaw Economic Agents - Phase 1 Foundation [CDV-20]
2026-02-28 01:29:57 -05:00
Argenis
7b1c63cf27
Merge pull request #2157 from zeroclaw-labs/feat/providers-sf-volcengine
feat: integrate Volcengine ARK and SiliconFlow providers
2026-02-28 01:28:09 -05:00
Argenis
e620a63fee
Merge pull request #1973 from zeroclaw-labs/supersede-pr-1879-20260226144348-3162467-theirs
[supersede #1879] fix(approvals): clear non-cli exclusions when approving tools
2026-02-28 01:27:46 -05:00
Argenis
0d695746e6
Merge pull request #1968 from zeroclaw-labs/supersede-pr-1853-20260226143137-2982344-theirs
[supersede #1853] feat(tools): add Feishu document operation tool with 13 actions
2026-02-28 01:27:41 -05:00
argenis de la rosa
f0d091d348 fix(cron): filter NO_REPLY sentinel in delivery paths 2026-02-28 01:26:43 -05:00
Preventnetworkhacking
a2f1f09364 feat(economic): add TaskClassifier for BLS occupation-based task valuation
Phase 2 of ClawWork integration. Implements:
- TaskClassifier with 44 BLS occupations and wage data
- OccupationCategory enum (Tech/Business/Healthcare/Legal)
- Keyword-based classification with confidence scoring
- Hours estimation based on instruction complexity
- Fuzzy matching for occupation lookup

Reference: ClawWork/clawmode_integration/task_classifier.py
2026-02-27 22:26:04 -08:00
reidliu41
6662601a6c feat(agent): add result-aware loop detection for tool-call loop 2026-02-28 00:58:31 -05:00
Chummy
e57173333f test(dingtalk): add onboarding regression coverage 2026-02-28 00:58:30 -05:00
Chummy
da1f805cf7
test(providers): harden Volcengine/SiliconFlow alias coverage 2026-02-28 05:55:31 +00:00
Chummy
1b82597eac fix(codex): harden transport validation and fallback 2026-02-28 13:48:41 +08:00
Chummy
81387f9896 fix(codex): preserve transport overrides across runtimes 2026-02-28 13:48:41 +08:00
Chummy
b721754ead feat(codex): add websocket-first transport selection 2026-02-28 13:48:41 +08:00
Preventnetworkhacking
055e9b7b31 fix: remove trailing whitespace from economic module 2026-02-27 21:42:19 -08:00
Chummy
f3f44c48f4
feat(providers): integrate Volcengine ARK and SiliconFlow
Add SiliconFlow provider factory support and alias/env handling.

Normalize onboarding UX to volcengine while preserving doubao/ark runtime aliases.

Add integration registry entries and provider resolution coverage tests.

Expand provider and command docs with setup and validation examples.
2026-02-28 05:25:15 +00:00
VirtualHotBar
db47f569ce channels: persist sessions via SessionManager
Fix channel runtime history persistence (load/seed/update) and remove duplicate agent turn call in process_message.
2026-02-28 12:51:03 +08:00
VirtualHotBar
fa8a98113e Merge remote-tracking branch 'origin/main' 2026-02-28 12:06:01 +08:00
VirtualHotBar
32dc3a460a fix(mcp): 修复 SSE 传输并兼容 endpoint/messages
- 修复 /sse/message 404:支持 legacy SSE endpoint 事件与单请求 SSE 响应两种模式

- 新增 mcp_smoke 二进制用于联通性验证

- Windows 增大默认栈并忽略 otp-secret
2026-02-28 12:01:51 +08:00
argenis de la rosa
1a0bb175f2 fix(agent): retry deferred tool follow-through in CJK contexts 2026-02-27 22:48:51 -05:00
argenis de la rosa
684503f5fc feat(onboard): add GitHub Copilot to interactive wizard 2026-02-27 21:34:40 -05:00
Preventnetworkhacking
b238e8fd5e feat(config): add economic agent configuration schema
Adds EconomicConfig to config schema:

- enabled: bool (default false, opt-in)
- initial_balance: f64 (default 1000.0)
- signature: String (agent identifier)
- data_path: PathBuf (persistence location)
- token_pricing: EconomicTokenPricing
  - input_price_per_million: f64 (default 3.0)
  - output_price_per_million: f64 (default 15.0)
- min_evaluation_threshold: f64 (default 0.6)

Integrates with existing config loading and onboard wizard.

Relates to: CDV-20
2026-02-27 15:54:58 -08:00
Preventnetworkhacking
9798b34f8d feat(economic): add ClawWork economic tracking module
Phase 1 of ZeroClaw Economic Agents (CDV-20):

## New Module: src/economic/

- **tracker.rs** (995 lines): EconomicTracker with balance management,
  token cost tracking, income ledger, and JSONL persistence
- **status.rs** (212 lines): SurvivalStatus enum with 5 states
  (Thriving/Stable/Struggling/Critical/Bankrupt)
- **costs.rs** (369 lines): TokenCostAccumulator for multi-channel
  cost tracking (LLM, search, OCR, etc.)
- **mod.rs** (81 lines): Module exports with comprehensive docs

## Features

- Track agent balance and economic health
- Configurable token pricing (input/output per million)
- Task-level cost isolation with start_task/end_task
- Work income with quality threshold (0.6 default)
- Persistent ledger (balance.jsonl, token_costs.jsonl)
- Daily cost aggregation

## Next Steps

- Phase 2: Task classifier (44 occupations)
- Phase 3: Work evaluator (LLM scoring)
- Phase 4: Economic tools (decide_activity, submit_work, etc.)

Relates to: CDV-20, Discussion #2132
2026-02-27 15:54:47 -08:00
argenis de la rosa
498fca9d08 feat(memory): add sqlite+qdrant hybrid backend 2026-02-27 15:28:56 -05:00
argenis de la rosa
1a0372709d feat(whatsapp): support heartbeat and cron delivery for whatsapp_web 2026-02-27 15:28:48 -05:00
argenis de la rosa
8004260e4d fix(agent): retry deferred-action replies missing tool calls 2026-02-27 15:28:38 -05:00
argenis de la rosa
281236a94d feat(identity): add openclaw extra_files support 2026-02-27 15:15:39 -05:00
argenis de la rosa
5981e50514 fix(agent): avoid anthropic vision preflight false negatives 2026-02-27 15:15:17 -05:00
argenis de la rosa
b8de8ce8b9 feat(transcription): support config-level api_key 2026-02-27 15:15:02 -05:00
argenis de la rosa
a09f146145 feat(security): add role-policy and otp challenge foundations 2026-02-27 14:29:31 -05:00
argenis de la rosa
cb67aac265 fix(telegram): redact bot token and reduce transient poll noise 2026-02-27 14:29:17 -05:00
VirtualHotBar
e8310a7841 fix(pr-review): address code review comments for session persistence 2026-02-28 00:41:31 +08:00
VirtualHotBar
0d68992fb7 feat(session): Add channel session persistence 2026-02-28 00:41:30 +08:00
VirtualHotBar
5619aac366 fix(mcp): add SSE Accept header and parse data: prefix for阿里云MCP 2026-02-28 00:41:30 +08:00
argenis de la rosa
ff1f2d6c1a feat(gateway): add streaming mode for webhook responses 2026-02-27 11:32:48 -05:00
argenis de la rosa
1ebaa673b5 feat(gateway): add streaming mode for webhook responses 2026-02-27 11:28:48 -05:00
argenis de la rosa
eed4f0651d fix(telegram): redact bot token and reduce transient poll noise 2026-02-27 11:24:44 -05:00
argenis de la rosa
60b73b6cd3 feat(slack): add socket mode listener fallback 2026-02-27 11:15:27 -05:00
xuhao
af731149b5
fix(tools): address remaining fourth-round review findings for feishu_doc
Addresses 4 findings from CodeRabbit's fourth review that were not
covered by the maintainer's commit 7ef075e:

1. [Major] http_client() per-call allocation: cache reqwest::Client in
   FeishuDocTool struct field, return &reqwest::Client. Enables
   connection pooling across all API calls.

2. [Major] SSRF bypass via HTTP redirects: download_media now uses a
   no-redirect reqwest client (Policy::none()) to prevent attackers
   from using a public URL that 301/302-redirects to internal IPs.

3. [Minor] Missing empty-conversion guard in action_upload_image:
   added converted.is_empty() check consistent with all other
   convert_markdown_blocks callers.

4. [Minor] Schema description for link_share stale: updated from
   'default: true' to 'default: false' to match actual behavior.

Validation:
- cargo check --features channel-lark 
- cargo clippy -p zeroclaw --lib --features channel-lark -- -D warnings 
- cargo test --features channel-lark -- feishu_doc  (7/7 tests pass)

(cherry picked from commit e846604a13)
2026-02-27 15:58:43 +00:00
argenis de la rosa
7dbdd030a1
fix(tools): address final feishu_doc review blockers
(cherry picked from commit 7ef075e6c9)
2026-02-27 15:58:43 +00:00
xuhao
a66866c367
fix(tools): address third-round code review findings for feishu_doc
Addresses all 5 findings from CodeRabbit's third review on PR #1853:

1. [Minor] action_append: add empty-conversion guard to prevent silent
   no-op (blocks_appended: 0). Consistent with action_write/update_block.

2. [Major] link_share default: change from opt-out (true) to opt-in
   (false). Documents no longer become publicly link-readable by default.
   Follows 'never silently broaden permissions' guideline.

3. [Minor] optional_usize: strict validation. Now returns Result and
   rejects invalid/negative/non-integer values with clear error instead
   of silently converting to None.

4. [Major] Media size bound: add MAX_MEDIA_BYTES (25 MiB) limit for
   both remote downloads (content-length pre-check + post-download
   check) and local file reads (metadata size check). Prevents memory
   exhaustion from oversized uploads.

5. [Major] Malformed JSON handling: parse_json_or_empty now returns
   Result (propagates parse errors instead of swallowing to {}).
   ensure_api_success now requires 'code' field presence instead of
   defaulting missing code to 0 (success). Prevents misclassifying
   malformed 2xx responses as success.

Validation:
- cargo check --features channel-lark 
- cargo clippy -p zeroclaw --lib --features channel-lark -- -D warnings 
- cargo test --features channel-lark -- feishu_doc  (7/7 tests pass)

(cherry picked from commit e9352b793e)
2026-02-27 15:58:43 +00:00
xuhao
b0f3c13db1
fix(tools): address second-round code review findings for feishu_doc
Addresses all 5 findings from CodeRabbit's second review on PR #1853:

1. [Major] list_all_blocks: add MAX_PAGES (200) hard cap to prevent
   unbounded pagination loops on misbehaving APIs or huge documents.

2. [Major] Empty conversion guard: action_write, action_update_block,
   and write_single_cell now bail with explicit error when
   convert_markdown_blocks returns empty results, preventing silent
   data loss (delete-then-write-nothing scenario).

3. [Minor] action_create: grant_owner_permission failure is now a soft
   warning instead of hard error. Document is already created and
   verified; permission failure is reported in the response JSON
   'warning' field instead of propagating as an error.

4. [Nitpick] extract_ttl_seconds: remove unreachable as_i64 fallback
   branch (as_u64 already covers all non-negative integers).

5. [Nitpick] Add unit tests: test_extract_ttl_seconds_defaults_and_clamps
   and test_write_rejects_empty_conversion.

Validation:
- cargo check --features channel-lark 
- cargo clippy -p zeroclaw --lib --features channel-lark -- -D warnings 
- cargo test --features channel-lark -- feishu_doc  (7/7 tests pass)

(cherry picked from commit 762e6082ec)
2026-02-27 15:58:43 +00:00
xuhao
a579cdfbec
fix(tools): address code review findings for feishu_doc
- Reorder convert-before-delete in action_write, action_update_block,
  and write_single_cell to prevent data loss if markdown conversion fails
- Separate create POST from verification retry loop in action_create
  to prevent duplicate document creation on retry
- Add resolve_doc_token to upload_image and upload_file so wiki
  node_token resolution works for upload actions
- Add SSRF protection to download_media: validate URL scheme (http/https
  only), block local/private hosts via existing url_validation module
- Guard empty credentials in mod.rs: skip FeishuDocTool registration
  when app_id or app_secret are empty/whitespace-only

(cherry picked from commit feb1d46f41)
2026-02-27 15:58:43 +00:00
xuhao
dcd712d825
feat(tools): add Feishu document operation tool with 13 actions
Add FeishuDocTool implementing the Tool trait with full Feishu/Lark
document API coverage: read, write, append, create, list_blocks,
get_block, update_block, delete_block, create_table, write_table_cells,
create_table_with_values, upload_image, and upload_file.

Key design decisions:
- Self-contained tenant_access_token auth with auto-refresh cache
- Feishu/Lark dual-domain support via use_feishu config flag
- Wiki node_token resolution for wiki-hosted documents
- Autonomy-level enforcement: read ops always allowed, write ops
  require Act permission
- Prompt-level behavioral rules in tool description for agent guidance
- Create verification with retry to prevent phantom document tokens

Gated behind existing channel-lark feature flag. Reads app_id and
app_secret from channels_config.feishu or channels_config.lark.

14/14 integration tests pass against live Feishu API.

(cherry picked from commit 6a228944ae)
2026-02-27 15:58:43 +00:00
argenis de la rosa
dcb3aaab91 fix(channels): avoid UTF-8 panic in approval prompt truncation 2026-02-27 10:50:46 -05:00
argenis de la rosa
15457cc368 fix(agent): parse direct XML tool tags in web chat 2026-02-27 10:42:13 -05:00
reidliu41
df6f7455e7 feat(tools): add docx_read tool for DOCX text extraction
Summary

  - Problem: Agent cannot read DOCX files — file_read returns garbled binary/XML, making Word documents inaccessible to the
  agent
  - Why it matters: DOCX is the most common business document format; without native extraction, users must manually convert
  files, breaking autonomous workflows
  - What changed: Added docx_read tool using zip (existing) + quick-xml (new) to extract plain text from DOCX Office Open XML
  - What did not change: No changes to file_read, agent loop, security policy, config schema, or any existing tool behavior

  Label Snapshot (required)

  - Risk label: risk: low
  - Size label: size: S
  - Scope labels: tool
  - Module labels: tool: docx_read
  - If any auto-label is incorrect: N/A

  Change Metadata

  - Change type: feature
  - Primary scope: tool

  Linked Issue

  - Closes #(issue number)

  Validation Evidence (required)

  cargo fmt --all -- --check   # pass
  cargo clippy --all-targets -- -D warnings   # pass (zero new warnings)
  cargo test docx_read   # 14/14 passed

  - Evidence provided: test results, manual verification with zeroclaw agent -m against real DOCX file

  Security Impact (required)

  - New permissions/capabilities? No (mirrors existing pdf_read security model exactly)
  - New external network calls? No
  - Secrets/tokens handling changed? No
  - File system access scope changed? No

  Privacy and Data Hygiene (required)

  - Data-hygiene status: pass
  - Redaction/anonymization notes: Test fixtures use neutral content ("Hello DOCX", "First", "Second")
  - Neutral wording confirmation: Yes

  Compatibility / Migration

  - Backward compatible? Yes
  - Config/env changes? No
  - Migration needed? No

  i18n Follow-Through

  - i18n follow-through triggered? No (no docs or user-facing wording changes)

  Human Verification (required)

  - Verified scenarios: zeroclaw agent -m "read the file test-test.docx and output the content" — model selected docx_read,
  extracted text correctly
  - Edge cases checked: invalid ZIP, missing word/document.xml, symlink escape, path traversal, rate limiting, truncation
  - What was not verified: encrypted DOCX (out of scope), extremely large files (>50MB)

  Side Effects / Blast Radius (required)

  - Affected subsystems/workflows: Tool registry only — one new tool added
  - Potential unintended effects: None — additive only, no existing behavior changed
  - Guardrails/monitoring: Tool follows identical security chain as pdf_read

  Rollback Plan (required)

  - Fast rollback command/path: git revert <commit>
  - Feature flags or config toggles: None needed (always-on, like pdf_read)
  - Observable failure symptoms: docx_read tool missing from tool list

  Risks and Mitigations

  - Risk: quick-xml new dependency adds to compile time
    - Mitigation: quick-xml is lightweight pure Rust (~15K LOC), widely used (100M+ downloads), and will be shared when
  XLSX/PPTX tools are added later
2026-02-27 10:39:53 -05:00
argenis de la rosa
ffdf66b77e
fix(approvals): clear non-cli exclusions when approving tools
(cherry picked from commit a7557cd28d)
2026-02-27 15:27:26 +00:00
argenis de la rosa
c8980a047a feat(agent): add slash command tab completion and hints 2026-02-27 08:09:18 -05:00
argenis de la rosa
7307aab103 feat(tools): add Tavily provider and API-key round-robin 2026-02-27 06:37:57 -05:00
Philip Peitsch
276ff7bd42 feat(channels): add matrix integration for sovereign communication 2026-02-27 20:34:16 +11:00
argenis de la rosa
e2a08f2536 fix(lark): accept object-shaped websocket message content 2026-02-27 02:44:55 -05:00
Argenis
e356c42b4f fix(config): remove duplicate default_otp_enabled definition
Resolves compile error E0428 reported in #2038.
2026-02-27 05:02:45 +00:00
argenis de la rosa
b63dfb8985 fix(config): resolve windows compile blockers (#2032) 2026-02-26 23:44:35 -05:00
argenis de la rosa
5ecea422c7 feat(security): enable otp by default in quick setup
(cherry picked from commit 9319ba2521)
2026-02-26 23:43:31 -05:00
Samy
860e8b2442 fix: address remaining CodeRabbit review items
- Fix convert_channels() return type: dict → tuple[dict, list[str]]
- Remove unnecessary f-string prefixes on plain string literals
- Add blank lines after markdown headings (MD022 compliance)
- Handle triple-quote edge case in TOML multiline string output
- Add handler-level validation tests: missing message rejection,
  empty messages detection, whitespace-only user message, and
  context extraction correctness

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 04:43:16 +00:00
sudomove
0aa2994423 fix: address PR review issues — auth guard, doc refs, TOML escaping
- Add non-loopback auth guard to /v1/chat/completions (matching /api/chat)
- Fix migration guide references to non-existent files (api_chat.rs,
  openai_compat_shim.rs, mod_patch.rs) — endpoints live in openclaw_compat.rs
- Remove phantom `provider` field from /api/chat response docs
- Add TOML string escaping to config converter to handle special chars
- Add proper JSON parse error handling in config converter
- Update deployment checklist and troubleshooting to match actual file layout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 04:43:16 +00:00
Samy
dde8b82ea0 feat(gateway): add OpenClaw migration compat layer with /api/chat and tools-enabled /v1/chat/completions
Add a complete OpenClaw → ZeroClaw migration toolkit:

- POST /api/chat: ZeroClaw-native endpoint with full agent loop (tools, memory,
  context enrichment). Supports session_id scoping and context[] injection for
  conversation history. Same code path as Linq/WhatsApp/Nextcloud handlers.

- POST /v1/chat/completions: OpenAI-compatible shim that routes through
  run_gateway_chat_with_tools instead of the simple provider.chat_with_history
  path. Extracts last user message + up to 10 messages of conversation context
  from the messages[] array. Supports streaming (simulated SSE). Drop-in
  replacement for OpenClaw callers with zero code changes.

Both endpoints include full observability instrumentation (AgentStart, LlmRequest,
LlmResponse, RequestLatency, AgentEnd), auth (pairing + webhook secret), rate
limiting, auto-save to memory, and response sanitization.

Also adds:
- scripts/convert-openclaw-config.py: Converts openclaw.json → config.toml with
  provider mapping, channel detection, and migration notes
- docs/migration/openclaw-migration-guide.md: Full migration walkthrough with
  endpoint reference, config mapping, callsite examples, and deployment checklist

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 04:43:16 +00:00
argenis de la rosa
e3e4878ade fix(gateway): add explicit webhook usage and empty-message errors 2026-02-26 23:24:35 -05:00
argenis de la rosa
bfe3e4295d feat(security): add opt-in perplexity adversarial suffix filter 2026-02-26 22:55:23 -05:00
argenis de la rosa
6e8b95d709 fix(slack): use lossless cast for retry jitter 2026-02-26 22:55:22 -05:00
argenis de la rosa
2f250bfbf7 fix(slack): retry history requests after rate limits 2026-02-26 22:55:22 -05:00
argenis de la rosa
21e13c8ae5 fix(qq): add sandbox mode and passive msg id fallback 2026-02-26 22:53:06 -05:00
argenis de la rosa
bde9d45ead feat(cron): add lark and feishu delivery targets 2026-02-26 22:52:46 -05:00
argenis de la rosa
96d941f83a feat(discord): forward inbound image attachments as markers 2026-02-26 22:50:45 -05:00