feat: new Claude/GPT generation support and OpenCode Zen/Go presets#53
Merged
Conversation
Anthropic provider:
- honor ModelConfig base_url ({base}/messages) and custom headers, with
Bearer auth for gateways via AnthropicCompat.bearer_auth or a
user-supplied authorization header
- adaptive thinking by default (thinking: {type: adaptive} +
output_config.effort); Claude Fable 5 / Opus 4.8 / Sonnet 5 reject
budget-based thinking. AnthropicCompat::legacy() keeps budgets for
pre-4.6 models, clamped to the 1024-token API minimum
- map stop_reason refusal -> new StopReason::Refusal and
model_context_window_exceeded -> Length
- max_tokens falls back to ModelConfig.max_tokens before 8192
Presets:
- claude_fable_5/claude_opus_4_8/claude_sonnet_5/claude_haiku_4_5/gpt_5_5
with real context windows, output caps, and pricing
- opencode_zen/opencode_go select the API protocol from the model family
(Responses / Anthropic Messages / Chat Completions)
Closes #48
Co-Authored-By: Claude Fable 5 <[email protected]>
claude-sonnet-4-20250514 -> claude-sonnet-5, gpt-4o -> gpt-5.5, gemini-2.0-flash -> gemini-2.5-flash, grok-3 -> grok-4.1, Bedrock Claude 3 id -> anthropic.claude-opus-4-8; update thinking and pricing tables for the adaptive-thinking behavior. Co-Authored-By: Claude Fable 5 <[email protected]>
Review fixes from the multi-agent PR review: - refusal: populate error_message, keep the tool-call fallback from masking Refusal/Error stop reasons, skip empty assistant messages when serializing history (a refused turn previously poisoned the conversation with an empty content block the API rejects), and show refusals in the CLI example - context overflow: map in-stream model_context_window_exceeded to StopReason::Error with an overflow-phrase error_message so Message::is_context_overflow() and compaction-retry hooks keep firing - back-compat: tolerate the pre-0.9 un-versioned official base_url in request_url; container-level serde(default) on AnthropicCompat - opencode: OpenCodeGateway enum replaces correlated params, warn on gemini-* ids, set reasoning on Anthropic-protocol configs - pricing/docs: fill gpt_5_5 cached-input pricing, distinguish configured default from model max output in preset docs, restore the Anthropic qualifier in ThinkingLevel docs, fix stale display names - tests: wiremock-based stream tests (refusal + overflow mapping, all auth branches), serde-compat tests, max_tokens precedence, empty assistant filter, Refusal round-trip Co-Authored-By: Claude Fable 5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #48
What this does
Modernizes the Anthropic provider (
src/provider/anthropic.rs) — previously the only provider that ignoredModelConfig:base_url({base}/messages) and custom headers; Bearer auth for gateways viaAnthropicCompat.bearer_author a user-suppliedauthorizationheader. Pre-0.9 configs with the un-versioned official host keep working.thinking: {type: "adaptive"}+output_config.effort). Claude Fable 5 / Opus 4.8 / Sonnet 5 reject budget-based thinking with a 400.AnthropicCompat::legacy()keepsbudget_tokensfor pre-4.6 models, clamped to the API's 1024 minimum (fixes a latent 400 onMinimal/Low).refusal→ newStopReason::Refusal(witherror_messageset, and empty refused turns no longer poison the conversation history) and in-streammodel_context_window_exceeded→ the standard overflow-error shape so compaction-retry hooks keep working.max_tokensfalls back toModelConfig.max_tokensbefore the hardcoded 8192.New model presets with verified context windows, output caps, and real pricing:
claude_fable_5(),claude_opus_4_8(),claude_sonnet_5(),claude_haiku_4_5(),gpt_5_5().OpenCode Zen & Go presets (#48):
opencode_zen(id)/opencode_go(id)select the API protocol from the model family (GPT → Responses, Claude/Qwen → Anthropic Messages + Bearer, rest → Chat Completions). New docs page atdocs/providers/opencode.md; Gemini-via-Zen documented as unsupported (warns at construction). Key-gated integration test intests/integration_opencode.rs.Docs refresh: stale model IDs replaced across ~25 files (
claude-sonnet-4-20250514→claude-sonnet-5,gpt-4o→gpt-5.5, etc.); thinking and pricing tables updated.Breaking changes (batch with reqwest 0.13 → release as 0.9.0)
StopReason::Refusalvariant (breaks exhaustive matches downstream)ModelConfig.anthropic: Option<AnthropicCompat>field (breaks struct-literal construction; serde-compatible with old JSON)ModelConfig::anthropic()base_url now includes/v1and defaults changed (max_tokens 8192 → 16000, reasoning true)AnthropicCompat::legacy()Testing
-Dwarnings --all-features, 270+ tests across 13 suitesx-api-keyabsence)integration_anthropic.rsagainstclaude-sonnet-5with thinking on;integration_opencode.rsagainst a Zen key) — no API keys in the dev environment. Recommend running both before tagging 0.9.0.🤖 Generated with Claude Code