Commit graph

595 commits

Author SHA1 Message Date
Chummy
63a59e3735 test(channels): assert single tool protocol block in final prompt 2026-02-20 10:25:48 +08:00
Edvard
35a3520621 fix(channel): remove duplicated tool protocol from system prompt
build_system_prompt() included a "## Tool Use Protocol" section with
the tag format and usage instructions. build_tool_instructions() then
appended another identical "## Tool Use Protocol" section with full
JSON schemas. This wasted ~1-2K tokens on every API call.

Remove the duplicate protocol block from build_system_prompt(), keeping
only the compact tool name/description list. The complete protocol with
schemas is provided by build_tool_instructions().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 10:25:48 +08:00
Edvard
3a8a1754ef fix(channel): replace hardcoded Discord bot text with generic channel text
The Channel Capabilities section in build_system_prompt() was hardcoded
to say "You are running as a Discord bot" for ALL channels, including
Telegram. This caused the LLM to misidentify itself and reference
Discord-specific features regardless of the actual channel.

Replace with generic "messaging bot" text. Per-channel delivery
instructions already exist via channel_delivery_instructions().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 10:25:07 +08:00
Alex Gorevski
36f971a3d0 fix(security): address CodeQL code-scanning alerts
- Extract hard-coded test vector keys into named constants in bedrock.rs
  and linq.rs to resolve rust/hard-coded-cryptographic-value alerts
- Replace derived Debug impls with manual impls that redact sensitive
  fields (access_token, refresh_token, credential, api_key) on
  QwenOauthCredentials, QwenOauthProviderContext, and
  ResolvedEmbeddingConfig to resolve rust/cleartext-logging alerts
- Redact Matrix user_id and device_id hints in tracing::warn! diagnostic
  messages via crate::security::redact() to resolve cleartext-logging
  alert in matrix.rs

Addresses CodeQL alerts: #77, #95-106

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 16:31:03 -08:00
Alex Gorevski
7d945aea6a
Merge pull request #1017 from zeroclaw-labs/test/peripherals-unit-tests
test(peripherals): add unit tests for peripheral module configuration and listing
2026-02-19 16:17:07 -08:00
Alex Gorevski
9d0ff54037
Merge pull request #1016 from zeroclaw-labs/test/improve-test-assertions
test(quality): replace bare .unwrap() with .expect() in agent and shell tests
2026-02-19 16:16:42 -08:00
Alex Gorevski
1708243470
Merge pull request #1015 from zeroclaw-labs/test/gateway-idempotency-tests
test(gateway): add edge-case idempotency store tests
2026-02-19 16:16:28 -08:00
Alex Gorevski
2a106d051a
Merge pull request #1013 from zeroclaw-labs/fix/docs-inline-code-comments
docs(code): add decision-point comments to agent loop, security policy, and reliable provider
2026-02-19 16:01:19 -08:00
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
867a7a5cbd test(gateway): add edge-case idempotency store tests
Add five new idempotency store tests covering: different-key acceptance,
max_keys clamping to minimum of 1, rapid duplicate rejection, TTL-based
key expiry and re-acceptance, and eviction preserving newest entries.
Addresses audit finding on weak gateway idempotency test coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 13:28:24 -08:00
Alex Gorevski
673697a43e test(peripherals): add unit tests for peripheral module configuration and listing
Add tests for list_configured_boards() covering enabled/disabled states and
empty/non-empty board configurations. Add test verifying create_peripheral_tools()
returns empty when peripherals are disabled. Addresses audit finding CRITICAL-1
for the untested peripherals module — covers all non-hardware-gated logic paths.

Fix pre-existing Windows build errors in config/schema.rs: make non-unix
sync_directory async and gate unix-only imports behind #[cfg(unix)].

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 13:28:22 -08:00
Alex Gorevski
22bd03c65a test(quality): replace bare .unwrap() with .expect() in agent and shell tests
Replace bare .unwrap() calls with descriptive .expect() messages in
src/agent/agent.rs and src/tools/shell.rs test modules. Adds meaningful
failure context for memory creation, agent builder, and tool execution
assertions. Addresses audit finding on test assertion quality (§5.2).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 13:23:33 -08:00
Alex Gorevski
dd541bd7e4 docs(code): add decision-point comments to agent loop, security policy, and reliable provider
Adds section markers and decision-point comments to the three most complex
control-flow modules. Comments explain loop invariants, retry/fallback
strategy, security policy precedence rules, and error handling rationale.

This improves maintainability by making the reasoning behind complex
branches explicit for reviewers and future contributors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 13:19:53 -08: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