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.
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>
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
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>
- 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>
- LICENSE: add trademark notice and dual-license reference to MIT file
- LICENSE-APACHE: add full Apache 2.0 license text with ZeroClaw
trademark clause in section 6
- TRADEMARK.md: define permitted/prohibited uses of the ZeroClaw name,
list known unauthorized forks (openagen/zeroclaw), and document
contributor trademark protections
- CLA.md: add Contributor License Agreement granting rights under both
MIT and Apache 2.0, with explicit patent grant and attribution
guarantees; contributors retain copyright ownership
- NOTICE: add official repository notice, dual-license summary, and
contributor protection statement
- README.md: add impersonation warning section with official repo link,
replace single MIT badge with dual-license table, add trademark and
contributor protection summary, link CLA.md from Contributing section
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
Add comprehensive e2e test coverage for chat_with_history and RAG
enrichment pipeline:
- RecordingProvider mock that captures all messages sent to the provider
- StaticMemoryLoader mock that simulates RAG context injection
- e2e_multi_turn_history_fidelity: verifies growing history across 3 turns
- e2e_memory_enrichment_injects_context: verifies RAG context prepended
- e2e_multi_turn_with_memory_enrichment: combined multi-turn + enrichment
- e2e_empty_memory_context_passthrough: verifies no corruption on empty RAG
- e2e_live_openai_codex_multi_turn (#[ignore]): real API call verifying
the model recalls facts from prior messages via chat_with_history
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The OpenAI Responses API requires assistant messages to use content type
"output_text" while user messages use "input_text". The prior implementation
used "input_text" for both roles, causing 400 errors on multi-turn history.
Extract build_responses_input() helper for testability and add 3 unit tests
covering role→content-type mapping, default instructions, and unknown roles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both providers only implemented chat_with_system, so the default
chat_with_history trait method was discarding all conversation history
except the last user message. This caused the Telegram bot to lose
context between messages.
Changes:
- OpenAiCodexProvider: extract send_responses_request helper, add
chat_with_history that maps full ChatMessage history to ResponsesInput
- GeminiProvider: extract send_generate_content helper, add
chat_with_history that maps ChatMessage history to Gemini Content
(with assistant→model role mapping)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the non-functional OpenAI-compatible stub with a purpose-built
Bedrock provider that implements AWS SigV4 signing from first principles
using hmac/sha2/hex crates — no AWS SDK dependency.
Key capabilities:
- SigV4 authentication (AKSK + optional session token)
- Converse API with native tool calling support
- Prompt caching via cachePoint heuristics
- Proper URI encoding for model IDs containing colons
- Resilient response parsing with unknown block type fallback
Also updates:
- Factory wiring and credential resolution bypass for AKSK auth
- Onboard wizard with Bedrock-specific model selection and guidance
- Provider reference docs with auth, region, and model ID details
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add optional thread_ts field to ChannelMessage and SendMessage for
platform-specific threading (e.g. Slack threads, Discord threads).
- ChannelMessage.thread_ts captures incoming thread context
- SendMessage.thread_ts propagates thread context to replies
- SendMessage::in_thread() builder for fluent API
- Slack: send with thread_ts, capture ts from incoming messages
- All reply paths in runtime preserve thread context via in_thread()
- All other channels initialize thread_ts: None (forward-compatible)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>