Commit graph

68 commits

Author SHA1 Message Date
Chummy
ba018a38ef chore(provider): normalize fallback test comments to ASCII punctuation 2026-02-19 18:43:45 +08:00
Chummy
435c33d408 fix(provider): preserve fallback runtime options when resolving credentials 2026-02-19 18:43:45 +08:00
Vernon Stinebaker
bb22bdc8fb fix(provider): resolve fallback provider credentials independently
Fallback providers in create_resilient_provider_with_options() were
created via create_provider_with_options() which passed the primary
provider's api_key as credential_override.  This caused
resolve_provider_credential() to short-circuit on the override and
never check the fallback provider's own env var (e.g. DEEPSEEK_API_KEY
for a deepseek fallback), resulting in auth failures (401) when the
primary and fallback use different API services.

Switch to create_provider_with_url(fallback, None, None) so each
fallback resolves its own credential via provider-specific env vars.
This also enables custom: URL prefixes (e.g.
custom:http://host.docker.internal:1234/v1) to work as fallback
entries, which was previously impossible through the options path.

Add three focused tests covering independent credential resolution,
custom URL fallbacks, and mixed fallback chains.
2026-02-19 18:43:45 +08:00
YubinghanBai
db7b24b319 fix(provider): strip <think> tags and merge system messages for MiniMax
MiniMax API rejects role: system in the messages array with error
2013 (invalid message role: system). In channel mode, the history
builder prepends a system message and optionally appends a second
one for delivery instructions, causing 400 errors on every channel
turn.

Additionally, MiniMax reasoning models embed chain-of-thought in
the content field as <think>...</think> blocks rather than using
the separate reasoning_content field, causing raw thinking output
to leak into user-visible responses.

Changes:
- Add merge_system_into_user flag to OpenAiCompatibleProvider;
  when set, all system messages are concatenated and prepended to
  the first user message before sending to the API
- Add new_merge_system_into_user() constructor used by MiniMax
- Add strip_think_tags() helper that removes <think>...</think>
  blocks from response content before returning to the caller
- Apply strip_think_tags in effective_content() and
  effective_content_optional() so all non-streaming paths are covered
- Update MiniMax factory registration to use new_merge_system_into_user
- Fix pre-existing rustfmt violation on apply_auth_header call

All other providers continue to use the default path unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 16:54:52 +08:00
Alex Gorevski
4a9fc9b6cc fix(security): prevent cleartext logging of sensitive data
Address CodeQL rust/cleartext-logging alerts by breaking data-flow taint
chains from sensitive variables (api_key, credential, session_id, user_id)
to log/print sinks. Changes include:

- Replace tainted profile IDs in println! with untainted local variables
- Add redact() helper for safe logging of sensitive values
- Redact account identifiers in auth status output
- Rename session_id locals in memory backends to break name-based taint
- Rename user_id/user_id_hint in channels to break name-based taint
- Custom Debug impl for ComputerUseConfig to redact api_key field
- Break taint chain in provider credential factory via string reconstruction
- Remove client IP from gateway rate-limit log messages
- Break taint on auth token extraction and wizard credential flow
- Rename composio account ref variable to break name-based taint

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-18 20:12:45 -08:00
Youhana Sheriff
b43e9eb325 fix(provider): polish kimi-code wiring and onboarding parity 2026-02-19 01:15:02 +08:00
Youhana Sheriff
cb91a2f914 feat(provider): add dedicated kimi-code provider support 2026-02-19 01:15:02 +08:00
Chummy
e8e9c0ea6c Revert "feat(provider): add dedicated kimi-code provider support"
This reverts commit 88dcd17a30.
2026-02-19 01:15:02 +08:00
Chummy
5563b755dc Revert "fix(provider): polish kimi-code wiring and onboarding parity"
This reverts commit 0b66ed026c.
2026-02-19 01:15:02 +08:00
Chummy
0bd2fbba2a feat(providers): add MiniMax OAuth credential flow 2026-02-18 22:31:20 +08:00
Chummy
0b66ed026c fix(provider): polish kimi-code wiring and onboarding parity 2026-02-18 22:22:10 +08:00
Chummy
88dcd17a30 feat(provider): add dedicated kimi-code provider support 2026-02-18 22:22:10 +08:00
Lucien Loiseau
6062888d1b feat(providers): add OVHcloud AI Endpoints as native provider
Route OVHcloud through OpenAiProvider (with proper tool_call_id
serialization) instead of OpenAiCompatibleProvider, fixing tool-call
round-trips against vLLM-based endpoints.

- Add base_url field and with_base_url() constructor to OpenAiProvider
- Replace all hardcoded api.openai.com URLs with self.base_url
- Pass api_url through for the openai provider arm
- Register ovhcloud/ovh provider with env var OVH_AI_ENDPOINTS_ACCESS_TOKEN
2026-02-18 20:54:49 +08:00
Chummy
d42cb1e906 fix(auth): rebase PR #200 onto main and restore auth CLI flow 2026-02-18 12:57:44 +08:00
Codex
007368d586 feat(auth): add subscription auth profiles and codex/claude flows 2026-02-18 12:57:44 +08:00
Maya Walcher
c830a513a5 fix(provider): address Astrai follow-up review from #486
- Add "astrai" to factory_all_providers_create_successfully test
- Add "astrai" => "ASTRAI_API_KEY" in provider_env_var() for onboarding
- Add Astrai to onboarding provider selection list (Gateway tier)
- Add provider_env_var("astrai") assertion in known_providers test

Addresses review comments from @chumyin on #486.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:00:32 +08:00
Chummy
f97f995ac0 refactor(provider): unify China alias families across modules 2026-02-18 01:01:57 +08:00
Chummy
ce23cbaeea fix(cli): harden providers listing and keep provider map aligned 2026-02-18 00:50:51 +08:00
reidliu41
feaa4aba60 feat(cli): add zeroclaw providers command to list supported providers
- Add `zeroclaw providers` CLI command that lists all 28 supported AI providers
- Each entry shows: config ID, display name, local/cloud tag, active marker, and aliases
- Also shows `custom:<URL>` and `anthropic-custom:<URL>` escape hatches at the bottom

Previously users had no way to discover available providers without reading source code. The
unknown-provider error message suggests `run zeroclaw onboard --interactive` but doesn't list
options. This command gives immediate visibility.
2026-02-18 00:50:51 +08:00
Chummy
fc6e8eb521
fix(provider): follow-up CN/global consistency for Z.AI and aliases (#554)
* fix(provider): harden CN/global routing consistency for Chinese vendors

* fix(agent): migrate CLI channel send to SendMessage

* fix(onboard): deduplicate Z.AI key URL match arms
2026-02-18 00:04:56 +08:00
Chummy
d94d7baa14 feat(ollama): unify local and remote endpoint routing
Integrate cloud endpoint behavior into existing ollama provider flow, avoid a separate standalone doc, and keep configuration minimal via api_url/api_key.

Also align reply_target and memory trait call sites needed for current baseline compatibility.
2026-02-17 22:52:09 +08:00
Chummy
85de9b5625
fix(provider): split CN/global endpoints for Chinese provider variants (#542)
* fix(providers): add CN/global endpoint variants for Chinese vendors

* fix(onboard): deduplicate provider key-url match arms

* chore(i18n): normalize non-English literals to English
2026-02-17 22:51:51 +08:00
Chummy
01c419bb57 test(providers): keep unicode boundary test in English text 2026-02-17 21:51:58 +08:00
Khoi Tran
3c62b59a72 fix(copilot): add proper OAuth device-flow authentication
The existing Copilot provider passes a static Bearer token, but the
Copilot API requires short-lived session tokens obtained via GitHub's
OAuth device code flow, plus mandatory editor headers.

This replaces the stub with a dedicated CopilotProvider that:

- Runs the OAuth device code flow on first use (same client ID as VS Code)
- Exchanges the OAuth token for a Copilot API key via
  api.github.com/copilot_internal/v2/token
- Sends required Editor-Version/Editor-Plugin-Version headers
- Caches tokens to disk (~/.config/zeroclaw/copilot/) with auto-refresh
- Uses Mutex to prevent concurrent refresh races / duplicate device prompts
- Writes token files with 0600 permissions (owner-only)
- Respects GitHub's polling interval and code expiry from device flow
- Sanitizes error messages to prevent token leakage
- Uses async filesystem I/O (tokio::fs) throughout
- Optionally accepts a pre-supplied GitHub token via config api_key

Fixes: 403 'Access to this endpoint is forbidden'
Fixes: 400 'missing Editor-Version header for IDE auth'
2026-02-17 21:51:58 +08:00
beee003
8ad5b6146b
feat: add Astrai as a named provider (#486)
Add Astrai (https://as-trai.com) as a first-class OpenAI-compatible
provider. Astrai is an AI inference router with built-in cost
optimization, PII stripping, and compliance logging.

- Register ASTRAI_API_KEY env var in resolve_api_key
- Add "astrai" entry in provider factory → as-trai.com/v1
- Add factory_astrai unit test
- Add Astrai to compatible provider test list
- Update README provider count (22+ → 23+) and list

Co-authored-by: Maya Walcher <maya.walcher@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:22:38 -05:00
reidliu41
77640e2198 feat(provider): add LM Studio provider alias
- Add `lmstudio` / `lm-studio` as a built-in provider alias for local LM Studio instances
(`http://localhost:1234/v1`)
- Uses a dummy API key when none is provided, since LM Studio does not require authentication
- Users can connect to remote LM Studio instances via `custom:http://<ip>:1234/v1`
2026-02-17 20:02:40 +08:00
DeadManAI
4fca1abee8 fix: resolve all clippy warnings, formatting, and Mistral endpoint
- Fix Mistral provider base URL (missing /v1 prefix caused 404s)
- Resolve 55 clippy warnings across 28 warning types
- Apply cargo fmt to 44 formatting violations
- Remove unused imports (process_message, MultiObserver, VerboseObserver,
  ChatResponse, ToolCall, Path, TempDir)
- Replace format!+push_str with write! macro
- Fix unchecked Duration subtraction, redundant closures, clamp patterns
- Declare missing feature flags (sandbox-landlock, sandbox-bubblewrap,
  browser-native) in Cargo.toml
- Derive Default where manual impls were redundant
- Add separators to long numeric literals (115200 → 115_200)
- Restructure unreachable code in arduino_flash platform branches

All 1,500 tests pass. Zero clippy warnings. Clean formatting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 20:00:08 +08:00
Chummy
5d131a8903 fix(security): tighten provider credential log hygiene
- remove as_deref credential routing path in provider factory
- avoid raw provider error text in warmup/retry failure summaries
- keep retry telemetry while reducing secret propagation risk
2026-02-17 19:19:06 +08:00
Chummy
a1bb72767a fix(security): remove provider init error detail logging 2026-02-17 19:19:06 +08:00
Chummy
e5a8cd3f57 fix(ci): suppress option_as_ref_deref on credential refs 2026-02-17 19:19:06 +08:00
Chummy
a6ca68a4fb fix(ci): satisfy strict lint delta on security follow-ups 2026-02-17 19:19:06 +08:00
Chummy
60d81fb706 fix(security): reduce residual CodeQL logging flows
- remove secret-presence logging path in gateway startup output
- reduce credential-derived warning path in provider fallback setup
- avoid as_deref credential propagation in delegate/provider wiring
- harden Composio error rendering to avoid raw body leakage
- simplify onboarding secrets status output to non-sensitive wording
2026-02-17 19:19:06 +08:00
Chummy
1711f140be fix(security): remediate unassigned CodeQL findings
- harden URL/request handling for composio and whatsapp integrations
- reduce cleartext logging exposure across providers/tools/gateway
- hash and constant-time compare gateway webhook secrets
- expand nested secret encryption coverage in config
- align feature aliases and add regression tests for security paths
- fix bubblewrap all-features test invocation surfaced during deep validation
2026-02-17 19:19:06 +08:00
Chummy
f9d681063d fix(fmt): align providers test formatting with rustfmt 2026-02-17 19:10:09 +08:00
Kieran
808450c48e feat: custom global api_url 2026-02-17 18:48:45 +08:00
Argenis
e3ca2315d3
fix(nvidia): use correct NVIDIA_API_KEY environment variable
- Fixes the environment variable name from `NVIDIA_NIM_API_KEY` to `NVIDIA_API_KEY` to match NVIDIA's official documentation
- Adds model suggestions for NVIDIA NIM provider in the onboarding wizard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 23:23:02 -05:00
Anton Dieterle
4d4c1e4965 Fix OpenCode API URL in provider configuration
Hey not sure why it was changed, but this is the correct URL for opencode zen
2026-02-16 23:01:53 -05:00
mai1015
b341fdb368 feat: add agent structure and improve tooling for provider 2026-02-17 01:01:56 +08:00
Chummy
e2c966d31e
Merge pull request #389 from reidliu41/add-qwen
feat(provider): add Qwen/DashScope provider with multi-region support
2026-02-17 00:58:04 +08:00
reidliu41
6bb9bc47c0 feat(provider): add Qwen/DashScope provider with multi-region support
- Add Alibaba Qwen as an OpenAI-compatible provider via DashScope API
- Support three regional endpoints: China (Beijing), Singapore, and US (Virginia)
- All regions share a single `DASHSCOPE_API_KEY` environment variable

| Config Value | Region | Base URL |
|---|---|---|
| `qwen` / `dashscope` | China (Beijing) | `dashscope.aliyuncs.com/compatible-mode/v1` |
| `qwen-intl` / `dashscope-intl` | Singapore | `dashscope-intl.aliyuncs.com/compatible-mode/v1` |
| `qwen-us` / `dashscope-us` | US (Virginia) | `dashscope-us.aliyuncs.com/compatible-mode/v1` |
2026-02-17 00:42:53 +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
53844f7207
feat(memory): lucid memory integration with optional backends (#285) 2026-02-17 00:31:50 +08:00
cd slash
5b19502bd9
fix(providers): correct Fireworks AI base URL to include /v1 path (#346)
The Fireworks API endpoint requires /v1/chat/completions, but the
base URL was missing the /v1 path segment, causing 404 errors and
triggering a broken responses fallback.

Fix: Add /v1 to base URL so correct endpoint is built:
  https://api.fireworks.ai/inference/v1/chat/completions
2026-02-16 23:53:34 +08:00
Chummy
8882746ced
fix(onboard): refresh MiniMax defaults and endpoint (#299) 2026-02-16 23:40:44 +08:00
stawky
9a5db46cf7 feat(providers): model failover chain + API key rotation
- Add model_fallbacks and api_keys to ReliabilityConfig
- Implement per-model fallback chain in ReliableProvider
- Add API key rotation on auth failures (401/403)
- Add retry-after header parsing and exponential backoff
- Integrate failover into chat_with_system and chat_with_history
- 20 unit tests covering failover, rotation, and retry logic
2026-02-16 21:59:35 +08:00
chumyin
34306e32d8 fix(provider): complete ChatResponse integration across runtime surfaces 2026-02-16 19:18:12 +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
ce7f811c0f
fix(provider): validate custom provider URL format and scheme (#281) 2026-02-16 01:57:43 -05:00
Argenis
3014926687
fix(providers): correct GLM API base URL to /api/paas/v4
* fix: add OpenAI-style tool_calls support for MiniMax and other providers

MiniMax and some other providers return tool calls in OpenAI's native
JSON format instead of ZeroClaw's XML-style <invoke> tag format.

This fix adds support for parsing OpenAI-style tool_calls:
- {"tool_calls": [{"type": "function", "function": {"name": "...", "arguments": "{...}"}}]}

The parser now:
1. First tries to parse as OpenAI-style JSON with tool_calls array
2. Falls back to ZeroClaw's original <invoke> tag format
3. Correctly handles the nested JSON string in the arguments field

Added 3 new tests covering:
- Single tool call in OpenAI format
- Multiple tool calls in OpenAI format
- Tool calls without content field

Fixes #226

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

* fix(providers): correct GLM API base URL to /api/paas/v4

The GLM (Zhipu) provider was using the incorrect base URL
`https://open.bigmodel.cn/api/paas` which resulted in 404 errors
when making API calls. The correct endpoint is
`https://open.bigmodel.cn/api/paas/v4`.

This fixes issue #238 where the agent would appear unresponsive
when using GLM-5 as the default model.

The fix aligns with the existing test `chat_completions_url_glm`
which already expected the correct v4 endpoint.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 20:21:19 -05:00
Edvard Schøyen
9b2f90018c
feat: add screenshot and image_info vision tools
* feat: add screenshot and image_info vision tools

Add two new tools for visual capabilities:

- `screenshot`: captures screen using platform-native commands
  (screencapture on macOS, gnome-screenshot/scrot/import on Linux),
  returns file path + base64-encoded PNG data
- `image_info`: reads image metadata (format, dimensions, size) from
  header bytes without external deps, optionally returns base64 data
  for future multimodal provider support

Both tools are registered in the tool registry and agent system prompt.
Includes 24 inline tests covering format detection, dimension extraction,
schema validation, and execution edge cases.

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

* fix: resolve unused variable warning after rebase

Prefix unused `resolved_key` with underscore to suppress compiler
warning introduced by upstream changes. Update Cargo.lock.

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

* fix: address review comments on vision tools

Security fixes:
- Fix JPEG parser infinite loop on malformed zero-length segments
- Add workspace path restriction to ImageInfoTool (prevents arbitrary
  file exfiltration via include_base64)
- Quote paths in Linux screenshot shell commands to prevent injection
- Add autonomy-level check in ScreenshotTool::execute

Robustness:
- Add file size guard in read_and_encode before loading into memory
- Wire resolve_api_key through all provider match arms (was dead code)
- Gate screenshot_command_exists test on macOS/Linux only
- Infer MIME type from file extension instead of hardcoding image/png

Tests:
- Add JPEG dimension extraction test
- Add JPEG malformed zero-length segment test

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: argenis de la rosa <theonlyhennygod@gmail.com>
2026-02-15 14:53:56 -05:00