Replace unbounded HashSet<String> with a BoundedSeenSet that evicts
the oldest message IDs (FIFO) when the 100k capacity is reached. This
prevents memory growth proportional to email volume over the process
lifetime, capping the set at ~100k entries regardless of runtime.
Closes#349
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
A duplicate ModelCommands enum was introduced in a recent merge,
causing E0119/E0428 compile errors on CI (Rust 1.92).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sanitize_headers was replacing sensitive header values with
***REDACTED*** before passing them to the actual HTTP request,
breaking any authenticated API call. Split into parse_headers
(preserves original values for the request) and
redact_headers_for_display (returns redacted copy for output/logging).
Closes#348
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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
Unifies scheduled task capabilities and consolidates overlapping implementations from #337 and #338 into a single security-first integration path.
Co-authored-by: Edvard <ecschoye@users.noreply.github.com>
Co-authored-by: stawky <stakeswky@users.noreply.github.com>
A duplicate ModelCommands enum was introduced in a recent merge,
causing E0119/E0428 compile errors on CI (Rust 1.92).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sanitize_headers was replacing sensitive header values with
***REDACTED*** before passing them to the actual HTTP request,
breaking any authenticated API call. Split into parse_headers
(preserves original values for the request) and
redact_headers_for_display (returns redacted copy for output/logging).
Closes#348
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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
Unifies scheduled task capabilities and consolidates overlapping implementations from #337 and #338 into a single security-first integration path.\n\nCo-authored-by: Edvard <ecschoye@stud.ntnu.no>\nCo-authored-by: stawky <stakeswky@gmail.com>
Implement Lark/Feishu as a new channel for ZeroClaw (Issue #164).
- Add LarkChannel with Channel trait impl (name, listen, send)
- listen: HTTP server (axum) for event callback with URL verification
(challenge response) and im.message.receive_v1 text message parsing
- send: POST /open-apis/im/v1/messages with tenant_access_token auth
- get_tenant_access_token with caching and auto-refresh on 401
- Allowlist filtering by open_id (same pattern as other channels)
- Add LarkConfig to schema (app_id, app_secret, verification_token, port, allowed_users)
- Register lark in channel list, doctor, and start_channels
- 18 unit tests: config serde, allowlist, channel name, message parsing,
edge cases (unicode, missing fields, invalid JSON, wrong event type)
- Fix pre-existing SchedulerConfig compile error on main
- 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