Commit Graph

370 Commits

Author SHA1 Message Date
Chummy 3ea7b6a996 feat(telegram): support custom Bot API base_url 2026-02-26 12:18:55 +08:00
Chummy ddaab9250a test(telegram): satisfy strict-delta lint in mention-only cases 2026-02-26 12:02:34 +08:00
argenis de la rosa 419376b1f1 fix(channels/telegram): respect mention_only for non-text messages in groups
When mention_only=true is set, the bot should not respond to non-text
messages (photos, documents, videos, stickers, voice) in group chats
unless the caption contains a bot mention.

Changes:
- Add mention_only check in try_parse_attachment_message() for group messages
  - Check if caption contains bot mention before processing
  - Skip attachment if no caption or no mention
- Add mention_only check in try_parse_voice_message() for group messages
  - Voice messages cannot contain mentions, so always skip in groups
- Add unit tests for the new behavior

Fixes #1662

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 12:02:34 +08:00
Argenis 83dfb38fe5 Merge pull request #1860 from zeroclaw-labs/issue-1836-session-context-iteration
fix(agent): improve iteration-limit recovery and continuity
2026-02-25 22:08:18 -05:00
argenis de la rosa 1e8c09d34a fix(agent): improve iteration-limit recovery and defaults 2026-02-25 17:33:32 -05:00
argenis de la rosa ae0159bad6 fix(linq): support current v3 webhook payload shape 2026-02-25 17:25:08 -05:00
Chummy 8888dc6bc5 fix(codeql): avoid logging raw matrix error payloads 2026-02-26 02:19:14 +08:00
Chummy 2958ff417f fix(codeql): sanitize matrix error logs and clear note alert 2026-02-26 02:19:14 +08:00
Chummy 134850733d fix(tests): align channel runtime context mutex types 2026-02-26 02:19:14 +08:00
Chummy 410ece8458 fix(ci): resolve strict-delta clippy regressions 2026-02-26 02:19:14 +08:00
Chummy 1ad2d71c9b feat(approval): add one-time all-tools non-cli approval flow 2026-02-26 02:19:14 +08:00
Chummy d8a1d1d14c fix: reconcile non-cli approval governance with current dev APIs 2026-02-26 02:19:14 +08:00
Chummy 1fcf2df28b feat: harden non-CLI approval governance and runtime policy sync 2026-02-26 02:19:14 +08:00
dave 067eb8a188 feat(tools): add sub-agent orchestration (spawn, list, manage)
Add background sub-agent orchestration tools that extend the existing
delegate tool with async execution, session tracking, and lifecycle
management.

New tools:
- subagent_spawn: Spawn delegate agents in background via tokio::spawn,
  returns session_id immediately. Respects security policy, depth limits,
  rate limits, and configurable concurrent session cap.
- subagent_list: List running/completed/failed/killed sessions with
  status filtering. Read-only, allowed in all autonomy modes.
- subagent_manage: Kill running sessions via CancellationToken or
  query status with partial output. Enforces Act policy for kill.

Shared state:
- SubAgentRegistry: Thread-safe session store using
  Arc<parking_lot::RwLock<HashMap>> with lazy cleanup of sessions
  older than 1 hour. Tracks session metadata, status, timing, and
  results.

Test coverage: 56 tests across all 4 modules covering happy paths,
error handling, security enforcement, concurrency, parameter
validation, and edge cases.

No new dependencies added. No existing tests broken.
2026-02-26 02:14:20 +08:00
Chummy 4eddc70ae4 fix(test): align draft update mock return type with Channel trait 2026-02-26 01:39:47 +08:00
Chummy 21696e1956 fix(lark): add new draft config fields in tests 2026-02-26 01:21:32 +08:00
Chummy 4e9752f5da fix(channels): align draft update signatures with lark config defaults 2026-02-26 01:21:32 +08:00
Allen Huang cc8aac5918 feat: channel improvements (Lark rich-text, WhatsApp QR, draft config)
- lark: convert send to rich-text post format with markdown parsing
- lark: add draft edit throttling and shell polling guidance
- lark: auto-detect receive_id_type from recipient prefix
- lark: deliver heartbeat as interactive card
- lark: use valid Feishu API emoji_type keys for ack reactions
- lark: handle flat post format from WS and add diagnostic logging
- lark: replace unsupported code_inline tag and strip leaked tool blocks
- lark: gate LarkChannel behind channel-lark feature flag
- whatsapp: render WhatsApp Web pairing QR in terminal
- channels: update_draft returns Option<String> for new draft IDs
- config: add draft_update_interval_ms and max_draft_edits to Lark/FeishuConfig

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-26 01:21:32 +08:00
Chummy 16961bab84 feat(channels): hide internal tool progress unless explicitly requested 2026-02-26 01:00:06 +08:00
Chummy 42f280abf4 fix(ci): satisfy strict-delta clippy manual_string_new 2026-02-26 00:05:32 +08:00
Chummy a9e8526d67 feat(channels): add unified group-reply policy and sender overrides 2026-02-26 00:05:32 +08:00
Chummy efdd40787c feat(config): add deprecated runtime reasoning_level compatibility alias 2026-02-25 21:00:59 +08:00
Chummy 268b01fcf0 hardening(security): sanitize upstream error bodies across channels 2026-02-25 20:41:51 +08:00
Chummy 495d7717c7 hardening(logging): sanitize channel API error bodies 2026-02-25 19:59:31 +08:00
Chummy 3b6786d0d7 Fix tool-call artifact leaks across channel and gateway replies 2026-02-25 19:54:09 +08:00
Chummy 2ecfa0d269 hardening: enforce channel tool boundaries and websocket auth 2026-02-25 18:33:28 +08:00
Chummy 1941906169 style(channels): apply rustfmt for query classification routing 2026-02-25 18:07:37 +08:00
argenis de la rosa 883f92409e feat(channels): add query classification routing with logging for channels
Add query classification support to channel message processing (Telegram,
Discord, Slack, etc.). When query_classification is enabled with model_routes,
each incoming message is now classified and routed to the appropriate model
with an INFO-level log line.

Changes:
- Add query_classification and model_routes fields to ChannelRuntimeContext
- Add classify_message_route function that logs classification decisions
- Update process_channel_message to try classification before default routing
- Initialize new fields in channel runtime context
- Update all test contexts with new fields

The logging matches the existing agent.rs implementation:
- target: "query_classification"
- fields: hint, model, rule_priority, message_length
- level: INFO

Closes #1367

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 18:07:37 +08:00
argenis de la rosa aac87ca437 feat(provider): add reasoning level override
(cherry picked from commit 8d46469c40)
2026-02-25 17:51:00 +08:00
FlashFamily 931cf40636 fix: resolve all clippy warnings across codebase
Fix all clippy errors reported by `cargo clippy --all-targets -- -D warnings`
on Rust 1.93, covering both the original codebase and upstream dev changes.

Changes by category:
- format!() appended to String → write!/writeln! (telegram, discord)
- Redundant field names, unnecessary boolean not (agent/loop_)
- Long numeric literals (wati, nextcloud, telegram, gemini)
- Wildcard match on single variant (security/leak_detector)
- Derivable Default impls (config/schema)
- &Option<T> → Option<&T> or allow (config/schema, config/mod, gateway/api)
- Identical match arms merged (gateway/ws, observability, providers, main, onboard)
- Cast truncation allowed with rationale (discord, lark)
- Unnecessary borrows/returns removed (multiple files)
- Unused imports removed (channels/mod, peripherals/mod, tests)
- MSRV-gated APIs allowed locally (memory/hygiene, tools/shell, tools/screenshot)
- Unnecessary .get().is_none() → !contains_key() (gemini)
- Explicit iteration → reference loop (gateway/api)
- Test-only: useless vec!, field_reassign_with_default, doc indentation

Validated: cargo fmt, cargo clippy --all-targets -- -D warnings, cargo test
Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit 49e90cf3e4)
2026-02-25 17:50:56 +08:00
Chummy d4e5cb73e3 fix(channels): support /clear alias and cross-channel history reset 2026-02-25 17:50:45 +08:00
Chummy afc49486f3 supersede: replay changes from #1664
Automated conflict recovery onto latest dev.
2026-02-25 17:50:41 +08:00
Chummy 8bbf256fa9 supersede: replay changes from #1661
Automated conflict recovery onto latest dev.
2026-02-25 17:39:37 +08:00
Chummy cd4d816a83 fix(providers): keep runtime options backward compatible 2026-02-25 10:56:31 +08:00
reidliu41 3a38c80c05 feat(config): add model_support_vision override for per-model vision control
`supports_vision` is currently hardcoded per-provider. The same Ollama instance can run `llava` (vision) or
  `codellama` (no vision), but the code fixes vision support at the provider level with no user override.

  This adds a top-level `model_support_vision: Option<bool>` config key — tri-state:
  - **Unset (default):** provider's built-in value, zero behavior change
  - **`true`:** force vision on (e.g. Ollama + llava)
  - **`false`:** force vision off

  Follows the exact same pattern as `reasoning_enabled`. Override is applied at the wrapper layer (`ReliableProvider` /
   `RouterProvider`) — no concrete provider code is touched.

  ## Changes

  **Config surface:**
  - Top-level `model_support_vision` field in `Config` struct with `#[serde(default)]`
  - Env override: `ZEROCLAW_MODEL_SUPPORT_VISION` / `MODEL_SUPPORT_VISION`

  **Provider wrappers (core logic):**
  - `ReliableProvider`: `vision_override` field + `with_vision_override()` builder + `supports_vision()` override
  - `RouterProvider`: same pattern

  **Wiring (1-line each):**
  - `ProviderRuntimeOptions` struct + factory functions
  - 5 construction sites: `loop_.rs`, `channels/mod.rs`, `gateway/mod.rs`, `tools/mod.rs`, `onboard/wizard.rs`

  **Docs (i18n parity):**
  - `config-reference.md` — Core Keys table
  - `providers-reference.md` — new "Ollama Vision Override" section
  - Vietnamese sync: `docs/i18n/vi/` + `docs/vi/` (4 files)

  ## Non-goals

  - Does not change any concrete provider implementation
  - Does not auto-detect model vision capability

  ## Test plan

  - [x] `cargo fmt --all -- --check`
  - [x] `cargo clippy --all-targets -- -D warnings` (no new errors)
  - [x] 5 new tests passing:
    - `model_support_vision_deserializes` — TOML parse + default None
    - `env_override_model_support_vision` — env var override + invalid value ignored
    - `vision_override_forces_true` — ReliableProvider override
    - `vision_override_forces_false` — ReliableProvider override
    - `vision_override_none_defers_to_provider` — passthrough behavior

  ## Risk and Rollback

  - **Risk:** Low. `None` default = zero behavior change for existing users.
  - **Rollback:** Revert commit. Field is `#[serde(default)]` so old configs without it will deserialize fine.

(cherry picked from commit a1b8dee785)
2026-02-25 10:56:31 +08:00
Chummy bfe87b1c55 fix: resolve supersede 1267 CI failures 2026-02-25 10:45:00 +08:00
Chummy b5ec2dce88 supersede: replay changes from #1267
Automated replay on latest dev.
2026-02-25 10:45:00 +08:00
Argenis 9ed863584a fix(channels): add wildcard pattern for non-exhaustive Relation enum in matrix channel (#1702)
The Relation enum in the Matrix SDK is marked as non-exhaustive,
causing a compilation error when building with the channel-matrix feature.
Add a wildcard pattern to handle any future relation types.

Fixes #1693

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:33:38 -05:00
Argenis 51073af2d7 Merge branch 'dev' into fix/issue-1469-voice-log 2026-02-24 11:37:12 -05:00
Chummy f00db63598 fix(telegram): infer audio filename for transcription fallback 2026-02-25 00:35:25 +08:00
Argenis 0935e5620e Merge branch 'dev' into fix/issue-1469-voice-log 2026-02-24 11:26:13 -05:00
Chummy 79c3c6ac50 fix(matrix): avoid logging user/device identifiers in cleartext 2026-02-25 00:23:22 +08:00
Chummy 46c9f0fb45 feat(matrix): add mention_only gate for group messages 2026-02-25 00:23:22 +08:00
Argenis 09f401183d Merge branch 'dev' into fix/issue-1469-voice-log 2026-02-24 11:13:58 -05:00
Chummy 817f783881 feat(agent): inject shell allowlist policy into system prompt 2026-02-25 00:01:49 +08:00
argenis de la rosa b545d17ed0 fix(telegram): add debug logging for voice transcription skip reasons
Voice messages were being silently ignored when transcription was disabled
or user was unauthorized, making it difficult to diagnose configuration
issues. This change adds:

- Debug log when voice/audio message received but transcription disabled
- Debug log when voice message skipped due to unauthorized user
- Info log on successful voice transcription

Closes #1469

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:58:12 -05:00
guitaripod b556a4bdce fix(telegram): handle brackets in attachment filenames
parse_attachment_markers used .find(']') which returns the first ']', so
filenames containing brackets (e.g. yt-dlp output 'Video [G4PvTrTp7Tc].mp4')
were truncated at the inner bracket, producing a wrong path and a send failure.

Replace the naive search with find_matching_close, a depth-tracking scanner
that correctly skips nested '[...]' pairs and returns the index of the
outermost closing bracket.

Adds regression tests for the bracket-in-filename case and for the
unclosed-bracket fallback (no match → message passed through unchanged).
2026-02-24 22:48:26 +08:00
guitaripod bd924a90dd fix(telegram): route image-extension Documents through vision pipeline
format_attachment_content was matching only Photo for [IMAGE:] routing.
Documents with image extensions (jpg, png, gif, webp, bmp) were formatted as
[Document: name] /path, bypassing the multimodal pipeline entirely.

Extend the match arm to cover Document when is_image_extension returns true,
so both Photos and image Documents produce [IMAGE:/path] and reach the provider
as proper vision input blocks.

Adds regression tests covering Document+image extension → [IMAGE:] and
Document+non-image extension → [Document:] paths.
2026-02-24 20:41:34 +08:00
Chummy 54dd7a4a9b feat(qq): add webhook receive mode with challenge validation 2026-02-24 19:30:36 +08:00
Chummy 5505465f93 chore: fix lint gate formatting and codex test runtime options 2026-02-24 15:59:49 +08:00