feat: full Claude Code OAuth provider support#518
Open
blackopsrepl wants to merge 1 commit intoRightNow-AI:mainfrom
Open
feat: full Claude Code OAuth provider support#518blackopsrepl wants to merge 1 commit intoRightNow-AI:mainfrom
blackopsrepl wants to merge 1 commit intoRightNow-AI:mainfrom
Conversation
Anthropic's API rejects Bearer tokens with "OAuth authentication is not
supported". The init wizard was writing provider="anthropic" when the user
chose Claude Code OAuth, sending requests through AnthropicDriver with a
Bearer header — causing every message to fail.
Additionally, the ClaudeCodeDriver had three independent bugs preventing it
from working at all:
- Subprocess crashed with "cannot launch inside another Claude Code session"
because the CLAUDECODE env var was inherited
- Stream parser expected a flat content string but the CLI emits a nested
message.content[{type,text}] block array
- complete() JSON parser typed content as String, failing to deserialize the
block array format
- Add AnthropicAuthMode enum (Pick / EnterKey / OAuthReady / OAuthMissing)
with full UI flow: method picker → key entry or OAuth confirmation screen
- Add use_claude_code_oauth: bool to State; set on OAuthReady confirm
- Add load_models_for_provider_name() helper to load catalog by name string
(used when provider name diverges from the selected PROVIDERS entry)
- OAuthReady + Enter: set use_claude_code_oauth=true, load claude-code models,
advance to Model step
- Provider Enter: detect OAuth-only case (no ANTHROPIC_API_KEY env var but
credentials file present) and route directly to claude-code without showing
ApiKey step
- save_config(): branch on use_claude_code_oauth → write provider="claude-code"
with empty api_key_env instead of provider="anthropic"
- Reset use_claude_code_oauth on all back-navigation paths
- Remove Priority 3 OAuth fallback from the anthropic branch; AnthropicDriver
now only accepts ANTHROPIC_API_KEY, never a Bearer token
- Update error message accordingly
- Remove AuthMode::OAuth variant, new_oauth() constructor, and OAuth arm of
apply_auth_headers() — dead code after the above change
- Unset CLAUDECODE env var before spawning subprocess (fixes nested-session crash)
- Fix ClaudeStreamEvent: add message: Option<serde_json::Value> field to capture
the nested assistant event format; split "assistant" arm to extract text from
message.content[].text blocks
- Fix ClaudeJsonOutput: change content field from Option<String> to
Option<serde_json::Value>; parse both string and block-array formats
5e25f31 to
9eafeb9
Compare
4 tasks
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.
What this PR does
Adds full Anthropic support beyond the direct API key — specifically, users who authenticate via Claude Code (OAuth) can now use their existing Claude Code session as the LLM backend, without needing a separate
ANTHROPIC_API_KEY.Previously the only way to use Anthropic models was a raw API key. This PR adds a second path: if you have Claude Code installed and authenticated, OpenFang can delegate all LLM calls to the
claudeCLI subprocess, which handles auth internally.How it works
When the user selects Anthropic in the init wizard and chooses "Claude Code OAuth", the wizard now writes
provider = "claude-code"to config instead ofprovider = "anthropic". This routes all requests throughClaudeCodeDriver(which shells out toclaude -p) rather than hittingapi.anthropic.comdirectly with a Bearer token — which Anthropic's API rejects.Changes
init_wizard.rs— OAuth auth method picker (API key vs Claude Code OAuth),use_claude_code_oauthstate flag, correct provider written to config, auto-detection of existing Claude Code credentialsdrivers/mod.rs— remove the OAuth token fallback from theanthropicbranch (it never worked;AnthropicDriveronly supports API keys)drivers/anthropic.rs— remove deadAuthMode::OAuth/new_oauth()/ Bearer header codedrivers/claude_code.rs— three runtime fixes required to make the driver actually work:CLAUDECODEenv var before spawning (CLI refuses to run in nested sessions)message.content[{type,text}]blocks, not a flat stringcomplete()parser: same nested block-array format for JSON outputTest plan
openfang init→ Anthropic → Claude Code OAuth → model list shows claude-code models~/.openfang/config.tomlhasprovider = "claude-code"ANTHROPIC_API_KEYstill works normally