Commit graph

146 commits

Author SHA1 Message Date
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
Will Sarg
3c4ed2e28e
fix(providers): clarify reliable failure entries for custom providers (#594)
* fix(workflows): standardize runner configuration for security jobs

* ci(actionlint): add Blacksmith runner label to config

Add blacksmith-2vcpu-ubuntu-2404 to actionlint self-hosted-runner labels config
to suppress "unknown label" warnings during workflow linting.

This label is used across all workflows after the Blacksmith migration.

* fix(actionlint): adjust indentation for self-hosted runner labels

* feat(security): enhance security workflow with CodeQL analysis steps

* fix(security): update CodeQL action to version 4 for improved analysis

* fix(security): remove duplicate permissions in security workflow

* fix(security): revert CodeQL action to v3 for stability

The v4 version was causing workflow file validation failures.
Reverting to proven v3 version that is working on main branch.

* fix(security): remove duplicate permissions causing workflow validation failure

The permissions block had duplicate security-events and actions keys,
which caused YAML validation errors and prevented workflow execution.

Fixes: workflow file validation failures on main branch

* fix(security): remove pull_request trigger to reduce costs

* fix(security): restore PR trigger but skip codeql on PRs

* fix(security): resolve YAML syntax error in security workflow

* refactor(security): split CodeQL into dedicated scheduled workflow

* fix(security): update workflow name to Rust Package Security Audit

* fix(codeql): remove push trigger, keep schedule and on-demand only

* feat(codeql): add CodeQL configuration file to ignore specific paths

* Potential fix for code scanning alert no. 39: Hard-coded cryptographic value

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix(ci): resolve auto-response workflow merge markers

* fix(build): restore ChannelMessage reply_target usage

* ci(workflows): run workflow sanity on workflow pushes for all branches

* ci(workflows): rename auto-response workflow to PR Auto Responder

* ci(workflows): require owner approval for workflow file changes

* ci: add lint-first PR feedback gate

* ci(workflows): split label policy checks from workflow sanity

* ci(workflows): consolidate policy and rust workflow setup

* ci: add safe pull request intake sanity checks

* ci(security): switch audit to pinned rustsec audit-check

* fix(providers): clarify reliable failure entries for custom providers

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-02-17 13:53:03 -05:00
argenis de la rosa
34af6a223a Merge remote-tracking branch 'origin/main' into feat/glm-provider
Resolved conflicts in:
- Cargo.toml: kept both `ring` (JWT auth) and `prost` (protobuf) dependencies
- src/onboard/wizard.rs: accepted main branch version
- src/providers/mod.rs: accepted main branch version
- Cargo.lock: accepted main branch version

Note: The custom `glm::GlmProvider` from this PR was replaced with
main's OpenAiCompatibleProvider approach for GLM, which uses base URLs.
The main purpose of this PR is Windows daemon support via Task Scheduler.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 13:27:58 -05: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
0aa35eb669 fix(build): complete strict lint and test cleanup (replacement for #476) 2026-02-18 00:18:54 +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
b2690f6809 feat(provider): add native tool calling API (supersedes #450)
Co-authored-by: YubinghanBai <baiyubinghan@gmail.com>
2026-02-17 22:47:10 +08:00
Will Sarg
a62c7a5893 fix(clippy): satisfy strict delta lints in SSE streaming path 2026-02-17 09:26:21 -05:00
Will Sarg
9e0958dee5 fix(ci): repair parking_lot migration regressions in PR #535 2026-02-17 09:10:40 -05:00
Will Sarg
ee05d62ce4
Merge branch 'main' into pr-484-clean 2026-02-17 08:54:24 -05: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
argenis de la rosa
1908af3248 fix(discord): use channel_id instead of sender for replies (fixes #483)
fix(misc): complete parking_lot::Mutex migration (fixes #505)

- DiscordChannel: store actual channel_id in ChannelMessage.channel
  instead of hardcoded "discord" string
- channels/mod.rs: use msg.channel instead of msg.sender for replies
- Migrate all std::sync::Mutex to parking_lot::Mutex:
  * src/security/audit.rs
  * src/memory/sqlite.rs
  * src/memory/response_cache.rs
  * src/memory/lucid.rs
  * src/channels/email_channel.rs
  * src/gateway/mod.rs
  * src/observability/traits.rs
  * src/providers/reliable.rs
  * src/providers/router.rs
  * src/agent/agent.rs
- Remove all .lock().unwrap() and .map_err(PoisonError) patterns
  since parking_lot::Mutex never poisons

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:05:25 -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
0087bcc496 fix(security): resolve rebase conflicts and provider regressions 2026-02-17 19:19:06 +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
Chummy
e9e45acd6d providers: map native tool support from capabilities 2026-02-17 18:59:04 +08:00
YubinghanBai
b5869d424e feat(provider): add capabilities detection mechanism
Add ProviderCapabilities struct to enable runtime detection of
provider-specific features, starting with native tool calling support.

This is a foundational change that enables future PRs to implement
intelligent tool calling mode selection (native vs prompt-guided).

Changes:
- Add ProviderCapabilities struct with native_tool_calling field
- Add capabilities() method to Provider trait with default impl
- Add unit tests for capabilities equality and defaults

Why:
- Current design cannot distinguish providers with native tool calling
- Needed to enable Gemini/Anthropic/OpenAI native function calling
- Fully backward compatible (all providers inherit default)

What did NOT change:
- No existing Provider methods modified
- No behavior changes for existing code
- Zero breaking changes

Testing:
- cargo test: all tests passed
- cargo fmt: pass
- cargo clippy: pass
2026-02-17 18:59:04 +08:00
Chummy
42fa802bad fix(ollama): sanitize provider payload logging 2026-02-17 18:48:45 +08:00
Kieran
1c0d7bbcb8 feat: ollama tools 2026-02-17 18:48:45 +08:00
Kieran
808450c48e feat: custom global api_url 2026-02-17 18:48:45 +08:00
Kieran
c4c1272580 feat: ollama tool calls 2026-02-17 18:48:45 +08:00
Kieran
9e456336b2 chore: add ollama logs 2026-02-17 18:48:45 +08:00
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
69a9adde33
Merge PR #500: streaming support and security fixes
- feat(streaming): add streaming support for LLM responses (fixes #211)
- security(deps): remove vulnerable xmas-elf dependency via embuild (fixes #399)
- fix: resolve merge conflicts and integrate chat_with_tools from main

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 05:05:57 -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
915ce58a8c fix: add futures dependency and fix stream imports in traits.rs
This commit fixes compilation errors when running tests by:
1. Adding `futures = "0.3"` dependency to Cargo.toml
2. Adding proper import `use futures_util::{stream, StreamExt};`
3. Replacing `futures::stream` with `stream` (using imported module)

The `futures_util` crate already had the `sink` feature but was missing
the stream-related types. Adding the full `futures` crate provides
the complete stream API needed for the streaming chat functionality.

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
Chummy
f75f73a50d fix(agent): preserve native tool-call fallbacks and history fidelity 2026-02-17 17:55:38 +08:00
Vernon Stinebaker
f322360248 feat(providers): add native tool-call API support via chat_with_tools
Add chat_with_tools() to the Provider trait with a default fallback to
chat_with_history(). Implement native tool calling in OpenRouterProvider,
reusing existing NativeChatRequest/NativeChatResponse structs. Wire the
agent loop to use native tool calls when the provider supports them,
falling back to XML-based parsing otherwise.

Changes are purely additive to traits.rs and openrouter.rs. The only
deletions (36 lines) are within run_tool_call_loop() in loop_.rs where
the LLM call section was replaced with a branching if/else for native
vs XML tool calling.

Includes 5 new tests covering:
- chat_with_tools error path (missing API key)
- NativeChatResponse deserialization (tool calls only, mixed)
- parse_native_response conversion to ChatResponse
- tools_to_openai_format schema validation
2026-02-17 17:55:38 +08:00
Chummy
e197cc5b04 fix(onboard,anthropic): stabilize oauth setup-token flow and model defaults
- fix onboard command ownership handling before spawn_blocking

- restore memory helper imports in wizard to resolve build regression

- centralize Anthropic OAuth beta header in apply_auth for all request paths

- correct OpenRouter Anthropic Sonnet 4.5 model ID format

- add regression tests for auth headers and curated model IDs
2026-02-17 16:15:38 +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
Chummy
b2dd3582a4 fix(ci): align reliable tests with simple_chat contract 2026-02-17 01:01:56 +08:00
mai1015
dc5e14d7d2 refactor: improve code formatting and structure across multiple files 2026-02-17 01:01:56 +08: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