Commit Graph

845 Commits

Author SHA1 Message Date
Argenis
d3c8ff6abe
feat(config): warn on unknown config keys to prevent silent misconfig (#1410)
* ci(homebrew): prefer HOMEBREW_UPSTREAM_PR_TOKEN with fallback

* ci(homebrew): handle existing upstream remote and main base

* fix(skills): allow cross-skill references in open-skills audit

Issue: #1391

The skill audit was too strict when validating markdown links in
open-skills, causing many skills to fail loading with errors like:
- "absolute markdown link paths are not allowed (../other-skill/SKILL.md)"
- "markdown link points to a missing file (skill-name.md)"

Root cause:
1. `looks_like_absolute_path()` rejected paths starting with ".."
   before canonicalization could validate they stay within root
2. Missing file errors were raised for cross-skill references that
   are valid but point to skills not installed locally

Fix:
1. Allow ".." paths to pass through to canonicalization check which
   properly validates they resolve within the skill root
2. Treat cross-skill references (parent dir traversal or bare .md
   filenames) as non-fatal when pointing to missing files

Cross-skill references are identified by:
- Parent directory traversal: `../other-skill/SKILL.md`
- Bare skill filename: `other-skill.md`
- Explicit relative: `./other-skill.md`

Added 6 new tests to cover edge cases for cross-skill references.

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

* feat(config): warn on unknown config keys to prevent silent misconfig

Issue: #1304

When users configure `[providers.ollama]` with `api_url`, the setting is
silently ignored because `[providers.*]` sections don't exist in the
config schema. This causes Ollama to always use localhost:11434 regardless
of the configured URL.

Fix: Use serde_ignored to detect and warn about unknown config keys at
load time. This helps users identify misconfigurations like:
- `[providers.ollama]` (should be top-level `api_url`)
- Typos in section names
- Deprecated/removed options

The warning is non-blocking - config still loads, but users see:
```
WARN Unknown config key ignored: "providers". Check config.toml...
```

This follows the fail-fast/explicit errors principle (CLAUDE.md §3.5).

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

---------

Co-authored-by: Will Sarg <12886992+willsarg@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 16:02:59 +08:00
Chummy
920568625b
refactor(telegram): remove redundant else in startup probe 2026-02-24 16:02:59 +08:00
Chummy
83e14a27aa
style(telegram): format startup probe warning log 2026-02-24 16:02:59 +08:00
zeroclaw
79a2d992b0
fix(telegram): add debug log at startup probe success
Add a debug-level log line confirming when the startup probe succeeds
and the main long-poll loop is entered. Aids diagnostics when
troubleshooting persistent 409s (e.g. from an external competing poller).

Note: persistent 409 despite the startup probe and 35s backoff indicates
an external process is actively polling the same bot token from another
host. In that case, rotating the bot token via @BotFather is the fix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 16:02:59 +08:00
zeroclaw
7c6430126b
fix(telegram): add startup probe + extend 409 backoff to eliminate polling conflict
Every daemon restart produced a flood of 409 Telegram polling conflicts for
up to several minutes. Two changes fix this:

1. **Startup probe (retry loop):** Before entering the long-poll loop,
   repeatedly issue `getUpdates?timeout=0` until a 200 OK is received.
   This claims the Telegram getUpdates slot before the 30-second long-poll
   starts, preventing the first long-poll from racing a stale server-side
   session left by the previous daemon. The probe retries every 5 seconds
   until the slot is confirmed free.

2. **Extended 409 backoff:** Increased from 2 s → 35 s (> the 30-second
   poll timeout). If a 409 still occurs despite the probe (e.g. in a genuine
   dual-instance scenario), the retry now waits long enough for the competing
   session to expire naturally before the next attempt, instead of hammering
   Telegram with ~15 retries per minute.

Fixes #1281.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 16:02:59 +08:00
Chummy
24720c5dd5
fix(composio): harden v3 slug candidate and test coverage 2026-02-24 16:02:59 +08:00
Bogdan
f1a1f3fdc7
fix tests 2026-02-24 16:02:59 +08:00
Bogdan
a01a84c8fe
feat(tools): stabilize composio slug resolution and drop v2 fallback
- add cache + candidate builder for Composio action/tool slugs so execute runs without manual priming @src/tools/composio.rs#285-320
- remove unused v2 execute/connect code paths and rely on HTTPS-only v3 endpoints @src/tools/composio.rs#339-502
- extend tooling tests to cover slug candidate generation variants @src/tools/composio.rs#1317-1324
2026-02-24 16:02:59 +08:00
argenis de la rosa
6729d34cf1
fix(skills): allow cross-skill references in open-skills audit
Issue: #1391

The skill audit was too strict when validating markdown links in
open-skills, causing many skills to fail loading with errors like:
- "absolute markdown link paths are not allowed (../other-skill/SKILL.md)"
- "markdown link points to a missing file (skill-name.md)"

Root cause:
1. `looks_like_absolute_path()` rejected paths starting with ".."
   before canonicalization could validate they stay within root
2. Missing file errors were raised for cross-skill references that
   are valid but point to skills not installed locally

Fix:
1. Allow ".." paths to pass through to canonicalization check which
   properly validates they resolve within the skill root
2. Treat cross-skill references (parent dir traversal or bare .md
   filenames) as non-fatal when pointing to missing files

Cross-skill references are identified by:
- Parent directory traversal: `../other-skill/SKILL.md`
- Bare skill filename: `other-skill.md`
- Explicit relative: `./other-skill.md`

Added 6 new tests to cover edge cases for cross-skill references.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 16:02:59 +08:00
Chummy
1b131b5256
fix: route heartbeat outputs to configured channels 2026-02-24 16:02:59 +08:00
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
cee ray
9d4c9b1af9
fix(providers): disable Responses API fallback for NVIDIA NIM
NVIDIA's NIM API (integrate.api.nvidia.com) does not support the
OpenAI Responses API endpoint. When chat completions returns a
non-success status, the fallback to /v1/responses also fails with
404, producing a confusing double-failure error.

Use `new_no_responses_fallback()` for the NVIDIA provider, matching
the approach already used for GLM and other chat-completions-only
providers.

Fixes #1282
2026-02-24 16:02:59 +08:00
Chummy
409a74c72b
fix(kimi-code): include empty reasoning_content in tool history 2026-02-24 16:02:59 +08:00
Chummy
4a2503605d
test(cron): add shell one-shot regression coverage 2026-02-24 16:02:59 +08:00
reidliu41
d6283d2bab
fix(cron): set delete_after_run for one-shot shell jobs 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
ce53dcde46
fix(minimax): avoid parsing merged system image markers as vision parts 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
f162eede13
fix(config): enforce 0600 on every config save 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
Chummy
742aa0208f
fix(security): honor explicit command paths in allowed_commands 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
Alex
10dd428de1
feat(providers): add Novita AI as OpenAI-compatible provider (#1496)
- Register Novita AI in provider factory with NOVITA_API_KEY env var
- Add to integrations registry with active/available status detection
- Configure onboarding wizard with default model and API endpoint
- Add to PR labeler provider keyword hints
- Update providers reference documentation

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-23 07:58:49 -05:00
Erica Stith
63f485e56a
feat(security): Add prompt injection defense and leak detection (#1433)
Contributed from RustyClaw (MIT licensed).

## PromptGuard (src/security/prompt_guard.rs)

Detects and blocks/warns about prompt injection attacks:
- System prompt override attempts ("ignore previous instructions")
- Role confusion attacks ("you are now...", "act as...")
- Tool call JSON injection
- Secret extraction attempts
- Command injection patterns in tool arguments
- Jailbreak attempts (DAN mode, developer mode, etc.)

Features:
- Configurable sensitivity (0.0-1.0)
- Configurable action (Warn/Block/Sanitize)
- Pattern-based detection with regex
- Normalized scoring across categories

## LeakDetector (src/security/leak_detector.rs)

Prevents credential exfiltration in outbound content:
- API key patterns (Stripe, OpenAI, Anthropic, Google, GitHub)
- AWS credentials (Access Key ID, Secret Access Key)
- Generic secrets (passwords, tokens in config)
- Private keys (RSA, EC, OpenSSH PEM blocks)
- JWT tokens
- Database connection URLs (PostgreSQL, MySQL, MongoDB, Redis)

Features:
- Automatic redaction of detected secrets
- Configurable sensitivity
- Returns both detection info and redacted content

## Integration

Both modules are exported from `security` module:
```rust
use zeroclaw::security::{PromptGuard, GuardResult, LeakDetector, LeakResult};
```

## Attribution

RustyClaw: https://github.com/rexlunae/RustyClaw
License: MIT
2026-02-23 07:48:18 -05:00
Vernon Stinebaker
7e6491142e fix(provider): preserve reasoning_content in tool-call conversation history
Thinking/reasoning models (Kimi K2.5, GLM-4.7, DeepSeek-R1) return a
reasoning_content field in assistant messages containing tool calls.
ZeroClaw was silently dropping this field when constructing conversation
history, causing provider APIs to reject follow-up requests with 400
errors: "thinking is enabled but reasoning_content is missing in
assistant tool call message".

Add reasoning_content: Option<String> as an opaque pass-through at every
layer of the pipeline: ChatResponse, ConversationMessage, NativeMessage
structs, parse/convert/build functions, and dispatcher. The field is
skip_serializing_if = None so it is invisible for non-thinking models.

Closes #1327
2026-02-22 17:40:48 +08: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
Will Sarg
7864118c40 fix(onboard): serialize quick-setup env tests safely 2026-02-21 20:46:02 -05:00
EC2 Default User
8c71aaa791 fix(provider): clamp gpt-5-codex reasoning effort 2026-02-21 23:37:20 +08:00
Chummy
9735253484 fix(tool): harden content_search parsing and output safety 2026-02-21 23:26:11 +08:00
Chummy
a36b1466ff feat(security): add otp and estop phase-1 foundation 2026-02-21 23:19:36 +08:00
Chummy
9098b379dd feat(skills): enforce static security audit for skill install/load 2026-02-21 22:54:55 +08:00
Chummy
1b8370f74b feat(channels): add immediate ack reactions for telegram discord and lark 2026-02-21 22:47:54 +08:00
Chummy
e5bc9514a4 security: close shell path-policy bypasses 2026-02-21 22:35:52 +08:00
reidliu41
007a7e2ec6 feat(tool): add content_search tool for regex-based file content search 2026-02-21 22:24:03 +08:00
Chummy
cb62135887 fix(channel/qq): preserve image attachments in inbound messages 2026-02-21 22:06:27 +08:00
Chummy
38e27ff629 test(schedule): lock in rate-limit blocking for mutating actions 2026-02-21 21:20:53 +08:00
Chummy
a92f5c94cd test(cron): cover rate-limit policy gates across cron tools 2026-02-21 21:04:22 +08:00
Chummy
9b40130a53 fix(agent): set tool_call_id for glm shortened parser 2026-02-21 20:48:06 +08:00
Chummy
09861fc52d fix(agent): make tool_call_id field initialization explicit 2026-02-21 20:48:06 +08:00
Chummy
74a29ec096 fix(agent): stabilize tool-call loop dedupe and id propagation
Refs #1242
2026-02-21 20:48:06 +08:00
Chummy
85f218eb0f feat(tools): add natural-language model routing config tool 2026-02-21 20:45:43 +08:00
Chummy
ccc3d6759f security: block plain shell variable expansion and forbidden path args 2026-02-21 20:42:48 +08:00
chumyin0912@gmail.com
13429566b8 fix(agent): map shortened browser alias args to shell command 2026-02-21 20:02:36 +08:00
Vernon Stinebaker
f0fa825e89 fix(agent): add cross-alias close tag resolution and GLM shortened body parsing
Models like GLM-4.7 emit malformed tool call formats that the existing
parser cannot handle: cross-alias close tags (e.g. <tool_call>...</invoke>),
shortened bodies (tool>value), YAML-style multi-line, and attribute-style
(tool key="value"). This adds defense-in-depth parsing for these formats
so tool calls are not silently dropped.

Changes:
- Add TOOL_CALL_CLOSE_TAGS constant for cross-alias close tag matching
- Add default_param_for_tool() for shortened body parameter inference
- Add parse_glm_shortened_body() for 3 GLM sub-formats inside tags
- Extend parse_tool_calls() with cross-alias resolution and GLM fallbacks
- Merge duplicate match arms in map_tool_name_alias() for clippy compliance
- Add 13 focused tests covering all new parsing paths
2026-02-21 20:02:36 +08:00
Chummy
7c7facc8cd fix: use Vercel AI Gateway base URL for vercel provider 2026-02-21 19:39:25 +08:00
chumyin0912@gmail.com
71b759f7c3 style: apply rustfmt for channel launchable helper 2026-02-21 19:38:19 +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