Commit graph

20 commits

Author SHA1 Message Date
argenis de la rosa
1fc5ecc4ff fix: resolve clippy lint warnings
- Remove unused import AsyncBufReadExt in compatible.rs
- Remove unused mut keywords from response and tx
- Remove unused variable 'name'
- Prefix unused parameters with _ in traits.rs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 05:15:59 -05:00
argenis de la rosa
4070131bb8 fix: apply cargo fmt to fix formatting issues
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 05:05:23 -05:00
argenis de la rosa
d94e78c621 feat(streaming): add streaming support for LLM responses (fixes #211)
Implement Server-Sent Events (SSE) streaming for OpenAI-compatible providers:

- Add StreamChunk, StreamOptions, and StreamError types to traits module
- Add supports_streaming() and stream_chat_with_system() to Provider trait
- Implement SSE parser for OpenAI streaming responses (data: {...} format)
- Add streaming support to OpenAiCompatibleProvider
- Add streaming support to ReliableProvider with error propagation
- Add futures dependency for async stream support

Features:
- Token-by-token streaming for real-time feedback
- Token counting option (estimated ~4 chars per token)
- Graceful error handling and logging
- Channel-based stream bridging for async compatibility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 05:01:13 -05:00
mai1015
b341fdb368 feat: add agent structure and improve tooling for provider 2026-02-17 01:01:56 +08:00
ehu shubham shaw
de3ec87d16
Ehu shubham shaw contribution --> Hardware support (#306)
* feat: add ZeroClaw firmware for ESP32 and Nucleo

* Introduced new firmware for ZeroClaw on ESP32 and Nucleo-F401RE, enabling JSON-over-serial communication for GPIO control.
* Added `zeroclaw-esp32` with support for commands like `gpio_read` and `gpio_write`, along with capabilities reporting.
* Implemented `zeroclaw-nucleo` firmware with similar functionality for STM32, ensuring compatibility with existing ZeroClaw protocols.
* Updated `.gitignore` to include new firmware targets and added necessary dependencies in `Cargo.toml` for both platforms.
* Created README files for both firmware projects detailing setup, build, and usage instructions.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: enhance hardware peripheral support and documentation

- Added `Peripheral` trait implementation in `src/peripherals/` to manage hardware boards (STM32, RPi GPIO).
- Updated `AGENTS.md` to include new extension points for peripherals and their configuration.
- Introduced comprehensive documentation for adding boards and tools, including a quick start guide and supported boards.
- Enhanced `Cargo.toml` to include optional dependencies for PDF extraction and peripheral support.
- Created new datasheets for Arduino Uno, ESP32, and Nucleo-F401RE, detailing pin aliases and GPIO usage.
- Implemented new tools for hardware memory reading and board information retrieval in the agent loop.

This update significantly improves the integration and usability of hardware peripherals within the ZeroClaw framework.

* feat: add ZeroClaw firmware for ESP32 and Nucleo

* Introduced new firmware for ZeroClaw on ESP32 and Nucleo-F401RE, enabling JSON-over-serial communication for GPIO control.
* Added `zeroclaw-esp32` with support for commands like `gpio_read` and `gpio_write`, along with capabilities reporting.
* Implemented `zeroclaw-nucleo` firmware with similar functionality for STM32, ensuring compatibility with existing ZeroClaw protocols.
* Updated `.gitignore` to include new firmware targets and added necessary dependencies in `Cargo.toml` for both platforms.
* Created README files for both firmware projects detailing setup, build, and usage instructions.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: enhance hardware peripheral support and documentation

- Added `Peripheral` trait implementation in `src/peripherals/` to manage hardware boards (STM32, RPi GPIO).
- Updated `AGENTS.md` to include new extension points for peripherals and their configuration.
- Introduced comprehensive documentation for adding boards and tools, including a quick start guide and supported boards.
- Enhanced `Cargo.toml` to include optional dependencies for PDF extraction and peripheral support.
- Created new datasheets for Arduino Uno, ESP32, and Nucleo-F401RE, detailing pin aliases and GPIO usage.
- Implemented new tools for hardware memory reading and board information retrieval in the agent loop.

This update significantly improves the integration and usability of hardware peripherals within the ZeroClaw framework.

* feat: Introduce hardware auto-discovery and expanded configuration options for agents, hardware, and security.

* chore: update dependencies and improve probe-rs integration

- Updated `Cargo.lock` to remove specific version constraints for several dependencies, including `zerocopy`, `syn`, and `strsim`, allowing for more flexibility in version resolution.
- Upgraded `bincode` and `bitfield` to their latest versions, enhancing serialization and memory management capabilities.
- Updated `Cargo.toml` to reflect the new version of `probe-rs` from `0.24` to `0.30`, improving hardware probing functionality.
- Refactored code in `src/hardware` and `src/tools` to utilize the new `SessionConfig` for session management in `probe-rs`, ensuring better compatibility and performance.
- Cleaned up documentation in `docs/datasheets/nucleo-f401re.md` by removing unnecessary lines.

* fix: apply cargo fmt

* docs: add hardware architecture diagram.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 11:40:10 -05:00
Chummy
8882746ced
fix(onboard): refresh MiniMax defaults and endpoint (#299) 2026-02-16 23:40:44 +08:00
chumyin
3b4a4de457 refactor(provider): unify Provider responses with ChatResponse
- Switch Provider trait methods to return structured ChatResponse
- Map OpenAI-compatible tool_calls into shared ToolCall type
- Update reliable/router wrappers and provider tests for new interface
- Make agent loop prefer structured tool calls with text fallback parsing
- Adapt gateway replies to structured responses with safe tool-call fallback
2026-02-16 19:16:22 +08:00
Chummy
2b04ebd2fb
fix(provider): normalize responses fallback
* fix(provider): avoid duplicate /v1 in responses endpoint

* fix(provider): derive precise responses endpoint from configured path
2026-02-16 05:26:01 -05:00
Chummy
13f6ed7871
fix(provider): require exact chat endpoint suffix match (#277) 2026-02-16 01:57:48 -05:00
Chummy
b442a07530
fix(memory): prevent autosave key collisions across runtime flows
Fixes #221 - SQLite Memory Override bug.

This PR resolves memory overwrite behavior in autosave paths by replacing fixed memory keys with unique keys, and improves short-horizon recall quality in channel runtime.

**Root Cause**
SQLite memory uses a unique constraint on `memories.key` and writes with `ON CONFLICT(key) DO UPDATE`.
Several autosave paths reused fixed keys (or sender-stable keys), so newer messages overwrote earlier conversation entries.

**Changes**
- Channel runtime: autosave key changed from `channel_sender` to `channel_sender_messageId`
- Added memory-context injection before provider calls (aligned with agent loop behavior)
- Agent loop: autosave keys changed from fixed `user_msg`/`assistant_resp` to UUID-suffixed keys
- Gateway: Webhook/WhatsApp autosave keys changed to UUID-suffixed keys

All CI checks passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:55:52 -05:00
argenis de la rosa
7456692e9c fix: pass OpenAI-style tool_calls from provider to parser
The OpenAI-compatible provider was not properly handling tool_calls
in API responses. When providers like MiniMax return tool_calls in
OpenAI's native format, the provider was only extracting the content
field and discarding the tool_calls.

Changes:
- Update ResponseMessage struct to include optional tool_calls field
- Add ToolCall and Function structs for deserializing tool_calls
- Serialize full message as JSON when tool_calls are present
- Fall back to plain content when no tool_calls

This allows the parse_tool_calls function in the agent loop to
properly handle OpenAI-style tool_calls format.

All 1080 tests pass.

Related to #226

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 20:56:36 -05:00
Edvard Schøyen
89b1ec6fa2
feat: add multi-turn conversation history and tool execution
* feat: add multi-turn conversation history and tool execution

Major enhancement to the agent loop:

**Multi-turn conversation:**
- Add `ChatMessage` type with system/user/assistant constructors
- Add `chat_with_history` method to Provider trait (default impl
  delegates to `chat_with_system` for backward compatibility)
- Implement native `chat_with_history` on OpenRouter, Compatible,
  Reliable, and Router providers to send full message history
- Interactive mode now maintains persistent history across turns

**Tool execution:**
- Agent loop now parses `<tool_call>` XML tags from LLM responses
- Executes tools from the registry and feeds results back as
  `<tool_result>` messages
- Agentic loop continues until LLM produces final text (no tool calls)
- MAX_TOOL_ITERATIONS (10) safety limit prevents runaway loops
- System prompt includes structured tool-use protocol with JSON schemas

**Types:**
- `ChatMessage`, `ChatResponse`, `ToolCall`, `ToolResultMessage`,
  `ConversationMessage` — full conversation modeling types

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

* fix: address review comments on multi-turn + tool execution

- Add history sliding window (MAX_HISTORY_MESSAGES=50) to prevent
  unbounded conversation history growth in interactive mode
- Add 404→Responses API fallback in compatible.rs chat_with_history,
  matching chat_with_system behavior
- Use super::api_error() for error sanitization in compatible.rs
  instead of raw error body (prevents secret leakage)
- Add missing operational logs in reliable.rs chat_with_history:
  recovery, non-retryable, fallback switch warnings
- Add trim_history tests

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

* fix: address second round of review comments

- Sanitize raw error text in compatible.rs chat_with_system using
  sanitize_api_error (prevents leaking secrets in error messages)
- Add chat_with_history to MockProvider in reliable.rs tests so
  the retry/fallback path is exercised end-to-end
- Add chat_with_history_retries_then_recovers and
  chat_with_history_falls_back tests
- Log warning on malformed <tool_call> JSON instead of silent drop
- Flush stdout after print! in agent_turn so output appears before
  tool execution on line-buffered terminals
- Make interactive mode resilient to transient errors (continue
  loop instead of terminating session)

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 14:43:02 -05:00
Edvard Schøyen
49bb20f961
fix(providers): use Bearer auth for Gemini CLI OAuth tokens
* fix(providers): use Bearer auth for Gemini CLI OAuth tokens

When credentials come from ~/.gemini/oauth_creds.json (Gemini CLI),
send them as Authorization: Bearer header instead of ?key= query
parameter. API keys from env vars or config continue using ?key=.

Fixes #194

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

* refactor(gemini): harden OAuth bearer auth flow and tests

* fix(gemini): granular auth source tracking and review fixes

Build on chumyin's auth model refactor with:
- Expand GeminiAuth to 4 variants (ExplicitKey/EnvGeminiKey/EnvGoogleKey/
  OAuthToken) so auth_source() uses stored discriminant without re-reading
  env vars at call time
- Add is_api_key()/credential() helpers on the enum
- Upgrade expired OAuth token log from debug to warn
- Add tests: provider_rejects_empty_key, auth_source_explicit_key,
  auth_source_none_without_credentials

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

* style: apply rustfmt to fix CI lint failures

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: root <root@instance-20220913-1738.vcn09131738.oraclevcn.com>
Co-authored-by: argenis de la rosa <theonlyhennygod@gmail.com>
2026-02-15 14:32:33 -05:00
Argenis
716fb382ec
fix: correct API endpoints for z.ai, opencode, and glm providers (#167)
Fixes #167

- z.ai: https://api.z.aihttps://api.z.ai/api/paas/v4
- opencode: https://api.opencode.aihttps://opencode.ai/zen/v1  
- glm: https://open.bigmodel.cn/api/paashttps://open.bigmodel.cn/api/paas/v4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:22:03 -05:00
Argenis
a5241f34ea
fix(discord): track gateway sequence number and handle reconnect opcodes (#159)
* feat(providers): add provider-aware API key resolution

- Add resolve_api_key() function that checks provider-specific env vars first
- For Anthropic, checks ANTHROPIC_OAUTH_TOKEN before ANTHROPIC_API_KEY
- Falls back to generic ZEROCLAW_API_KEY and API_KEY env vars
- Update create_provider() to use resolved_key instead of raw api_key
- Trim and filter empty strings from input keys

This enables setup-token support for Anthropic by checking ANTHROPIC_OAUTH_TOKEN
before ANTHROPIC_API_KEY when resolving credentials.

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

* feat(providers): add Anthropic setup-token support

- Rename api_key field to credential for clarity
- Add is_setup_token() method to detect setup-token format (sk-ant-oat01-)
- Add input trimming and empty string filtering
- Use Bearer auth for setup-tokens, x-api-key for regular API keys
- Update error message to mention both ANTHROPIC_API_KEY and ANTHROPIC_OAUTH_TOKEN
- Add test for setup-token detection
- Add test for whitespace trimming in new()

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

* fix: skip serialization of config_path and workspace_dir to prevent save() failures

The config_path and workspace_dir fields are computed paths that should not be
serialized to the config file. When loading from TOML, these fields would be
deserialized as empty paths (or stale paths), causing save() to fail with
"Failed to write config file".

Fixes #112

Changes:
- Add #[serde(skip)] to config_path and workspace_dir fields
- Set computed paths in load_or_init() after deserializing from TOML

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

* fix(discord): track gateway sequence number and handle reconnect opcodes

Three Discord Gateway issues fixed:

1. **Heartbeat sent `null` sequence** — Per Discord docs, the Gateway may
   disconnect bots that don't include the last sequence number in heartbeats.
   Now tracked via `sequence: i64` and included in every heartbeat.

2. **Dispatch sequence ignored** — The `s` field from dispatch events was
   never stored. Now extracted and tracked from every event.

3. **Opcodes 7/9 silently ignored** — Reconnect (op 7) and Invalid Session
   (op 9) caused the bot to hang on a dead connection. Now breaks the event
   loop so the daemon supervisor can restart the channel cleanly.

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

* fix(memory): use SHA-256 for embedding cache keys instead of DefaultHasher

- Replace DefaultHasher with SHA-256 for deterministic cache keys
- DefaultHasher is explicitly documented as unstable across Rust versions
- Truncate SHA-256 to 8 bytes (16 hex chars) to match previous format
- Ensures embedding cache is deterministic across Rust compiler versions

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 10:25:38 -05:00
Argenis
1eadd88cf5
feat: Support Responses API fallback for OpenAI-compatible providers (#134)
- Add new structs for Responses API request/response format
- Add helper functions for extracting text from Responses API responses
- Refactor auth header application into a shared apply_auth_header method
- When chat completions returns 404 NOT_FOUND, fall back to Responses API
- Add tests for Responses API text extraction

This enables compatibility with providers that implement the Responses API
instead of Chat Completions (e.g., some newer Groq models).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 09:03:42 -05:00
Argenis
5cc02c5813
fix: add WhatsApp webhook signature verification (X-Hub-Signature-256)
Closes #51

- Add HMAC-SHA256 signature verification for WhatsApp webhooks
- Prevents message spoofing attacks (CWE-345)
- Add whatsapp_app_secret config field with ZEROCLAW_WHATSAPP_APP_SECRET env override
- Add 13 comprehensive unit tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 06:17:24 -05:00
argenis de la rosa
976c5bbf3c hardening: fix 7 production weaknesses found in codebase scan
Scan findings and fixes:

1. Gateway buffer overflow (8KB → 64KB)
   - Fixed: Increased request buffer from 8,192 to 65,536 bytes
   - Large POST bodies (long prompts) were silently truncated

2. Gateway slow-loris attack (no read timeout → 30s)
   - Fixed: tokio::time::timeout(30s) on stream.read()
   - Malicious clients could hold connections indefinitely

3. Webhook secret timing attack (== → constant_time_eq)
   - Fixed: Now uses constant_time_eq() for secret comparison
   - Prevents timing side-channel on webhook authentication

4. Pairing brute force (no limit → 5 attempts + 5min lockout)
   - Fixed: PairingGuard tracks failed attempts with lockout
   - Returns 429 Too Many Requests with retry_after seconds

5. Shell tool hang (no timeout → 60s kill)
   - Fixed: tokio::time::timeout(60s) on Command::output()
   - Commands that hang are killed and return error

6. Shell tool OOM (unbounded output → 1MB cap)
   - Fixed: stdout/stderr truncated at 1MB with warning
   - Prevents memory exhaustion from verbose commands

7. Provider HTTP timeout (none → 120s request + 10s connect)
   - Fixed: All 5 providers (OpenRouter, Anthropic, OpenAI,
     Ollama, Compatible) now have reqwest timeouts
   - Ollama gets 300s (local models are slower)

949 tests passing, 0 clippy warnings, cargo fmt clean
2026-02-14 01:47:08 -05:00
argenis de la rosa
bc31e4389b style: cargo fmt — fix all formatting for CI
Ran cargo fmt across entire codebase to pass CI's cargo fmt --check.
No logic changes, only whitespace/formatting.
2026-02-13 16:03:50 -05:00
argenis de la rosa
05cb353f7f feat: initial release — ZeroClaw v0.1.0
- 22 AI providers (OpenRouter, Anthropic, OpenAI, Mistral, etc.)
- 7 channels (CLI, Telegram, Discord, Slack, iMessage, Matrix, Webhook)
- 5-step onboarding wizard with Project Context personalization
- OpenClaw-aligned system prompt (SOUL.md, IDENTITY.md, USER.md, AGENTS.md, etc.)
- SQLite memory backend with auto-save
- Skills system with on-demand loading
- Security: autonomy levels, command allowlists, cost limits
- 532 tests passing, 0 clippy warnings
2026-02-13 12:19:14 -05:00