Repository navigation
v0.9.0
A breaking release batching the changes anticipated in #33: the reqwest 0.13/rustls upgrade, support for the current model generation, two new provider gateways, queue inspection, and a crate-wide exhaustiveness policy.
⚠️ Breaking changes
Dependencies / MSRV
- reqwest 0.12 → 0.13 with rustls as the TLS backend — OpenSSL is no longer a build dependency (faster builds on Android/Windows).
reqwest-eventsourcereplaced by the maintainedkameleoon-reqwest-eventsourcefork (aliased;reqwest_eventsource::paths unchanged). Rust 1.85+ required (was 1.75). Public API surfaces reqwest 0.13 / fork types (classify_eventsource_error,OpenApiError::HttpError). (#52)
Anthropic provider
- Adaptive thinking is the default (
thinking: {"type": "adaptive"}+output_config.effort) — required by Claude Fable 5 / Opus 4.7+/4.8 / Sonnet 5. Pre-4.6 models with thinking enabled needAnthropicCompat::legacy()(budget-based, now clamped to the API's 1024-token minimum). (#53) ModelConfig.base_urlis now honored ({base}/messages); theanthropic()preset default includes/v1(old persisted configs with the un-versioned host keep working). Custom headers apply; Bearer auth available viaAnthropicCompat.bearer_auth.- New
StopReason::Refusalvariant (safety-system declines, e.g. Claude Fable 5);model_context_window_exceededmaps to the standard overflow-error shape so compaction-retry hooks fire. anthropic()preset defaults:max_tokens8192 → 16000,reasoning: true.
Exhaustiveness policy (#33 item 1, #55)
#[non_exhaustive]onContent(matches need a wildcard arm), on theToolCall/Thinkingvariants andMessage::Assistant(construct viaContent::tool_call()/tool_call_with_metadata()/thinking()/thinking_signed()andMessage::assistant(); patterns need..), and onModelConfig(construct via presets or the newModelConfig::custom(); field mutation still works, literals/FRU do not). Future field additions become non-breaking.StopReasonstays deliberately exhaustive: a new variant should be a compile error downstream, not a silent wildcard fall-through.ModelConfiggains theanthropic: Option<AnthropicCompat>field (serde-compatible with older persisted configs).
Features
- New model presets with real pricing:
claude_fable_5(),claude_opus_4_8(),claude_sonnet_5(),claude_haiku_4_5(),gpt_5_5()— correct context windows, output caps, andCostConfigvalues. (#53) - OpenCode Zen & Go gateways (#48):
ModelConfig::opencode_zen(id)/opencode_go(id)select the API protocol from the model family (Responses / Anthropic Messages with Bearer auth / Chat Completions). Seedocs/providers/opencode.md. - Queue inspection API (#50):
steering_queue_snapshot()/follow_up_queue_snapshot(),_len(), atomictake_*_queue(), and batchsteer_all()/follow_up_all()— enables pi-style pending-message UIs. Edit-window semantics documented indocs/concepts/agent-loop.md. ModelConfig::custom(api, provider, base_url, id, name)for protocols without a preset (Bedrock, Vertex, Azure).
Fixes
- Google/Gemini: mid-stream
{"error": ...}payloads and transport failures now surface as errors (previously a silently truncated "successful" turn);SAFETY-family finish reasons map toStopReason::Refusal; SSE splitting takes the earliest separator (mixed CRLF/LF buffers no longer merge events); an empty text part no longer swallows afunctionCallin the same part. (#55) - Anthropic: a refused turn no longer poisons the conversation (empty assistant messages are skipped when serializing history) and carries an explanatory
error_message; legacy thinking budgets below the API minimum no longer 400. - CI now builds with
--all-features, so theopenapifeature is compiled and linted on every PR.
Testing
New wiremock-based provider stream tests (Anthropic + Google) cover refusal/overflow stop-reason mapping, all auth branches, thought-signature round-trips, and SSE edge cases — scenarios previously reachable only with live API keys.
Full changelog: v0.8.4...v0.9.0