Commit graph

583 commits

Author SHA1 Message Date
Alex Gorevski
7d7362439e
Merge pull request #1011 from zeroclaw-labs/fix/docs-config-struct-fields
docs(code): add comprehensive doc comments to config schema public fields
2026-02-19 16:00:34 -08:00
Alex Gorevski
200ce0d6fd
Merge pull request #1010 from zeroclaw-labs/fix/docs-trait-doc-comments
docs(code): expand doc comments on security, observability, runtime, and peripheral traits
2026-02-19 15:59:56 -08:00
Alex Gorevski
c6de02b93b
Merge pull request #1008 from zeroclaw-labs/fix/docs-module-level-docs
docs(code): add module-level doc blocks to providers, channels, tools, and security
2026-02-19 15:58:56 -08:00
Argenis
96d5ae0c43
fix(composio): pick first usable account when multiple exist, add connected_accounts alias (#1003)
Root cause of #959: resolve_connected_account_ref returned None when the entity had more than one connected account for an app, silently dropping auto-resolve and causing every execute call to fail with 'cannot find connected account'. The LLM then looped re-issuing the OAuth URL even though the account was already connected.

- resolve_connected_account_ref now picks the first usable account (ordered by updated_at DESC from the API) instead of returning None when multiple accounts exist
- Add 'connected_accounts' as a dispatch alias for 'list_accounts' in handler, schema enum, and description
- 8 new regression tests

Closes #959
2026-02-19 17:19:04 -05:00
Alex Gorevski
eae8a99584 docs(code): add comprehensive doc comments to config schema public fields
Every public field in the Config struct hierarchy now has a /// doc comment
explaining its purpose, default value, and usage context. This ensures
operators and extension developers can understand config options directly
from rustdoc without cross-referencing the config reference documentation.

Comments are consistent with docs/config-reference.md descriptions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 13:19:52 -08:00
Alex Gorevski
25fd10a538 docs(code): expand doc comments on security, observability, runtime, and peripheral traits
The four underdocumented core trait files now include trait-level doc blocks
explaining purpose and architecture role, method-level documentation with
parameter/return/error descriptions, and public struct/enum documentation.

This brings parity with the well-documented provider, channel, tool, and
memory traits, giving extension developers clear guidance for implementing
these core extension points.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 13:19:46 -08:00
Alex Gorevski
4a7dff6ef1 docs(code): add module-level doc blocks to providers, channels, tools, and security
Each major subsystem mod.rs now includes a //! doc block explaining the
subsystem purpose, trait-driven architecture, factory registration pattern,
and extension guidance. This improves the generated rustdoc experience for
developers navigating ZeroClaw's modular architecture.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 13:19:46 -08:00
Alex Gorevski
141d483aa4
Merge pull request #987 from ecschoye/fix/openrouter-embedding-provider
fix(memory): add openrouter as recognized embedding provider
2026-02-19 12:47:25 -08:00
Edvard
832facf5ef fix(memory): add openrouter as recognized embedding provider
The embedding provider factory only recognized "openai" and "custom:*",
causing "openrouter" to silently fall through to NoopEmbedding. This
made vector/semantic search completely non-functional — memory recall
fell back to BM25 keyword-only matching, with 70% of the hybrid score
always returning zero.

Route "openrouter" through OpenAiEmbedding with the OpenRouter API base
URL (https://openrouter.ai/api/v1), which is OpenAI-compatible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:10:25 -05:00
Alex Gorevski
007e9fa7ea
Merge pull request #984 from zeroclaw-labs/fix/improve-config-error-messages
fix(errors): improve config error messages with section paths and remediation hints
2026-02-19 11:56:45 -08:00
Alex Gorevski
b6f99c31d1
Merge pull request #982 from zeroclaw-labs/fix/cli-help-text-improvements
docs(cli): add detailed help text and examples to complex subcommands
2026-02-19 11:54:38 -08:00
Alex Gorevski
f308353ab2
Merge pull request #981 from zeroclaw-labs/fix/config-validation-on-load
fix(config): add startup validation to catch invalid config values early
2026-02-19 11:52:57 -08:00
Alex Gorevski
39a09f007b fix(cli): add range validation for temperature argument
Add a custom value_parser for the --temperature CLI argument to enforce
the documented 0.0-2.0 range at parse time. Previously, the comment
stated the valid range but clap did not reject out-of-range values,
allowing invalid temperatures to propagate to provider API calls.

- Add parse_temperature() validator that rejects values outside 0.0..=2.0
- Wire it into the Agent subcommand's temperature arg via value_parser

Addresses API surface audit §2.3 (CLI argument range validation).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 11:45:12 -08:00
Alex Gorevski
cc07cb66c3 fix(errors): improve config error messages with section paths and remediation hints
Improve vague error messages in channel initialization and tool setup
to include specific config key paths and remediation steps, matching
the quality standard set by proxy validation errors.

Changes:
- telegram.rs: Include [channels.telegram] section path and required
  fields (bot_token, allowed_users) in missing-config error; add
  onboard hint; specify channels.telegram.allowed_users in pairing
  message; improve parse error context
- whatsapp.rs: Specify channels.whatsapp.allowed_numbers key path
  in unauthorized-number warning
- linq.rs: Specify channels.linq.allowed_senders key path in
  unauthorized-sender warning; add onboard hint
- web_search_tool.rs: Include tools.web_search.provider config path
  and valid values in unknown-provider error

Addresses API surface audit §8.2 (config context in error messages).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 11:44:04 -08:00
Alex Gorevski
9f1a306962 docs(cli): add detailed help text and examples to complex subcommands
Add long_about attributes with usage examples to the following commands:

src/main.rs (binary CLI):
- Agent: interactive/single-message modes, provider/peripheral options
- Gateway: port/host binding with examples
- Daemon: full runtime explanation with service install reference
- Cron: cron expression format, timezone handling, all scheduling modes
- Channel: supported types, JSON config format, bind-telegram
- Hardware: discover, introspect, info subcommands
- Peripheral: add, flash, board types
- Config: schema export

src/lib.rs (library enums):
- CronCommands::Add: cron syntax and timezone examples
- CronCommands::AddAt: RFC 3339 timestamp format
- CronCommands::AddEvery: interval in milliseconds
- CronCommands::Once: human-readable duration syntax
- CronCommands::Update: partial field update
- ChannelCommands::Add: JSON config and supported types
- ChannelCommands::BindTelegram: username/numeric ID format
- HardwareCommands::Discover, Introspect, Info: device paths and chip names
- PeripheralCommands::Add: board types and transport paths
- PeripheralCommands::Flash: serial port options

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 11:42:31 -08:00
Alex Gorevski
99cf2fdfee fix(config): add startup validation to catch invalid config values early
Add Config::validate() called from load_or_init() after env overrides
are applied. This catches obviously invalid configuration values at
startup instead of allowing them to silently cause runtime failures.

Validated fields:
- gateway.host: must not be empty
- autonomy.max_actions_per_hour: must be > 0
- scheduler.max_concurrent: must be > 0
- scheduler.max_tasks: must be > 0
- model_routes[*]: hint, provider, model must not be empty
- embedding_routes[*]: hint, provider, model must not be empty
- proxy: delegates to existing ProxyConfig::validate()

Previously, ProxyConfig::validate() was only called during
apply_env_overrides() and only warned/disabled on failure. The new
Config::validate() runs it as a hard error after all overrides are
resolved, ensuring proxy misconfiguration is surfaced early.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 11:37:30 -08:00
Alex Gorevski
77609777ab
Merge pull request #951 from zeroclaw-labs/fix/per-client-pairing-lockout
fix(security): change pairing lockout to per-client accounting
2026-02-19 11:26:46 -08:00
Chummy
3733856093 Fix skill instruction/tool injection in system prompts 2026-02-20 02:16:41 +08:00
Chummy
f2ffd653de fix(channel): preserve trailing user turn in normalization 2026-02-20 02:01:42 +08:00
Chummy
c5834b1077 fix(channel): normalize telegram history for MiniMax 2026-02-20 02:01:42 +08:00
Chummy
4531c342f5 fix(onboard): remove fragile numeric channel dispatch
Use enum-backed channel menu dispatch to prevent duplicated match-arm indices and unreachable-pattern warnings (issue #913).

Also switch OpenAI native tool spec parsing to owned serde structs so tool-schema validation compiles.
2026-02-20 01:56:41 +08:00
Chummy
ef82c7dbcd fix(channels): interrupt in-flight telegram requests on newer sender messages 2026-02-20 01:54:07 +08:00
Chummy
d9a94fc763 fix(skills): escape inlined skill XML content 2026-02-20 01:28:49 +08:00
Edvard
8a4da141d6 fix(skills): inject skill prompts and tools into agent system prompt
Skill prompts and tool definitions from SKILL.toml were parsed and stored
correctly but never included in the agent's system prompt. Both prompt-building
paths (channels/mod.rs and agent/prompt.rs) only emitted skill metadata (name,
description, location), telling the LLM to "read" the SKILL.toml on demand.
This caused the agent to attempt manual file reads that often failed, leaving
skills effectively ignored.

Now both paths inline <instructions> and <tools> blocks inside each <skill>
XML element, so the agent receives full skill context without extra tool calls.

Closes #877

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 01:28:49 +08:00
Chummy
14fb3fbcae fix(composio): resolve connected account refs after OAuth 2026-02-20 01:28:19 +08:00
Chummy
d714d3984e fix(memory): stop autosaving assistant summaries and filter legacy entries 2026-02-20 01:14:08 +08:00
Chummy
6d745e9cb3 fix(openai): deserialize native tool specs with owned fields 2026-02-20 00:07:28 +08:00
Chummy
4c249c579f fix(composio): repair v3 execute path and enable alias 2026-02-20 00:07:28 +08:00
argenis de la rosa
a03ddc3ace fix: gate nusb/hardware discovery to Linux/macOS/Windows only
Android (Termux) reports target_os="android" which is not supported
by nusb::list_devices(). This caused E0425 and E0282 compile errors
when building on Termux.

Changes:
- Cargo.toml: move nusb to a target-gated dependency block so it is
  only compiled on linux/macos/windows
- src/hardware/discover.rs: add #![cfg(...)] file-level gate matching
  the nusb platform support matrix
- src/hardware/mod.rs: gate discover/introspect module declarations,
  discover_hardware() call, handle_command() dispatch, and all helper
  fns on the same platform set; add a clear user-facing message on
  unsupported platforms
- src/security/pairing.rs: replace deprecated rand::thread_rng() with
  rand::rng() to keep clippy -D warnings clean

Fixes #880
2026-02-20 00:02:01 +08:00
Alex Gorevski
56af0d169e fix(security): change pairing lockout to per-client accounting
Replace global failed-attempt counter with per-client HashMap keyed by
client identity (IP address for gateway, chat_id for Telegram).  This
prevents a single attacker from locking out all legitimate clients.

Bounded state: entries are evicted after lockout expiry, and the map is
capped at 1024 tracked clients.

Closes #603

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 07:33:11 -08:00
Alex Gorevski
8f8641d9fb fix(onboard): correct channel selector default to 'Done' item
The hardcoded .default(11) became stale when Lark/Feishu was
added at index 11, shifting 'Done — finish setup' to index 12.
The wizard now pre-selects the wrong channel instead of 'Done'.

Use options.len() - 1 so the default always tracks the last
item regardless of how many channels exist.

Fixes #913

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 07:19:20 -08:00
Alex Gorevski
a4b27d2afe perf: eliminate unnecessary heap allocations across agent loop, memory, and channels
- Replace clone()+clear() with std::mem::take() in chunker (items 1, 6)
- Add Vec::with_capacity() hints in chunker split functions (item 2)
- Replace collect::<Vec<_>>().join() with direct iteration in IRC and
  email channels (item 3)
- Share heading strings via Rc<str> instead of cloning per chunk (item 5)
- Use borrowed references in provider tool spec types to avoid cloning
  name/description/parameters per tool per request (item 7)

Closes #712

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 07:06:27 -08:00
Alex Gorevski
dce7280812
Merge pull request #865 from agorevski/feat/systematic-test-coverage-852
test: add systematic test coverage for 7 bug pattern groups (#852)
2026-02-19 07:02:20 -08:00
Chummy
7b4fe96c8a fix(provider): align qwen oauth alias with qwen base-url mapping 2026-02-19 21:46:48 +08:00
Chummy
05404c6e7a perf(build): gate Matrix channel for faster iteration 2026-02-19 21:29:53 +08:00
Chummy
87dcda638c fix: resolve post-rebase config and ollama test regressions 2026-02-19 21:25:21 +08:00
Chummy
ce6ba36f4e test: account for ellipsis when compacting channel history 2026-02-19 21:25:21 +08:00
Chummy
3d068c21be fix: correct Lark/Feishu channel selection index in wizard 2026-02-19 21:25:21 +08:00
Chummy
dcd0bf641d feat: add multimodal image marker support with Ollama vision 2026-02-19 21:25:21 +08:00
Chummy
63aacb09ff fix(provider): preserve full history in responses fallback 2026-02-19 21:16:55 +08:00
Chummy
48b51e7152 test(config): make tokio::test schema cases async 2026-02-19 21:05:19 +08:00
Chummy
a5d7911923 feat(runtime): add reasoning toggle for ollama 2026-02-19 21:05:19 +08:00
Chummy
8f13fee4a6 test: stabilize qwen oauth env tests and gateway fixtures 2026-02-19 20:54:20 +08:00
Chummy
bca58acdcb feat(provider): add qwen-code oauth credential support 2026-02-19 20:54:20 +08:00
Chummy
e9c280324f test(config): make schema export test async 2026-02-19 20:49:53 +08:00
Chummy
c57f3f51a0 fix(config): derive JsonSchema for embedding routes 2026-02-19 20:49:53 +08:00
Chummy
572aa77c2a feat(memory): add embedding hint routes and upgrade guidance 2026-02-19 20:49:53 +08:00
T. Budiman
2b8547b386 feat(gateway): enrich webhook and WhatsApp with workspace system prompt
Add workspace context (IDENTITY.md, AGENTS.md, etc.) to gateway webhook
and WhatsApp message handlers by using chat_with_system() with a
build_system_prompt()-generated system prompt instead of simple_chat().

This aligns gateway behavior with other channels (Telegram, Discord, etc.)
and the agent loop, which all pass system prompts via structured
ChatMessage::system() or chat_with_system().

Changes:
- handle_webhook: build system prompt and use chat_with_system()
- handle_whatsapp_message: build system prompt and use chat_with_system()

Risk: Low - uses existing build_system_prompt() function, no new dependencies
Rollback: Revert commit removes system prompt enrichment
2026-02-19 20:30:02 +08:00
Chummy
2016382f42 fix(channels): compact sender history and filter oversized memory context 2026-02-19 20:05:35 +08:00
Chummy
2c07fb1792 fix: fail fast on context-window overflow and reset channel history 2026-02-19 19:38:28 +08:00