-
-
Notifications
You must be signed in to change notification settings - Fork 2k
feat: add Anthropic Claude Code OAuth provider and adaptive thinking support #5209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Soulter
merged 3 commits into
AstrBotDevs:master
from
Minidoracat:feat/anthropic-claude-code-oauth
Feb 21, 2026
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
140 changes: 140 additions & 0 deletions
140
astrbot/core/provider/sources/anthropic_oauth_source.py
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| from collections.abc import AsyncGenerator | ||
|
|
||
| from anthropic import AsyncAnthropic | ||
|
|
||
| from astrbot.core.provider.entities import LLMResponse | ||
|
|
||
| from ..register import register_provider_adapter | ||
| from .anthropic_source import ProviderAnthropic | ||
|
|
||
| _OAUTH_DEFAULT_HEADERS = { | ||
| "anthropic-beta": "claude-code-20250219,oauth-2025-04-20,context-1m-2025-08-07", | ||
| "user-agent": "claude-cli/1.0.0 (external, cli)", | ||
| "x-app": "cli", | ||
| "anthropic-dangerous-direct-browser-access": "true", | ||
| } | ||
|
|
||
| _CLAUDE_CODE_SYSTEM_PREFIX = ( | ||
| "You are Claude Code, Anthropic's official CLI for Claude.\n\n" | ||
| ) | ||
|
|
||
| # 支持 1M 上下文窗口的模型前缀(需配合 context-1m beta header)。 | ||
| # 新增 4.6+ 模型时需同步更新此列表。 | ||
| _1M_CONTEXT_MODEL_PREFIXES = ( | ||
| "claude-opus-4-6", | ||
| "claude-sonnet-4-6", | ||
| ) | ||
|
|
||
|
|
||
| @register_provider_adapter( | ||
| "anthropic_oauth", | ||
| "Anthropic Claude Code OAuth provider adapter", | ||
| ) | ||
| class ProviderAnthropicOAuth(ProviderAnthropic): | ||
| def __init__( | ||
| self, | ||
| provider_config: dict, | ||
| provider_settings: dict, | ||
| ) -> None: | ||
| # 禁用父类的 API key 客户端初始化,避免重复构造客户端 | ||
| super().__init__(provider_config, provider_settings, use_api_key=False) | ||
|
|
||
| # 手动解析 key 列表(父类跳过了 _init_api_key) | ||
| self.api_keys: list = self.get_keys() | ||
| self.chosen_api_key: str = self.api_keys[0] if self.api_keys else "" | ||
|
|
||
| # 使用 auth_token(OAuth Bearer 认证)构建客户端 | ||
| self.client = AsyncAnthropic( | ||
| auth_token=self.chosen_api_key, | ||
| timeout=self.timeout, | ||
| base_url=self.base_url, | ||
| default_headers=_OAUTH_DEFAULT_HEADERS, | ||
| http_client=self._create_http_client(provider_config), | ||
| ) | ||
|
|
||
| def set_model(self, model_name: str) -> None: | ||
| super().set_model(model_name) | ||
| if any(model_name.startswith(p) for p in _1M_CONTEXT_MODEL_PREFIXES): | ||
| if self.provider_config.get("max_context_tokens", 0) <= 0: | ||
| self.provider_config["max_context_tokens"] = 1_000_000 | ||
|
|
||
| def get_model_metadata_overrides(self, model_ids: list[str]) -> dict[str, dict]: | ||
| overrides = {} | ||
| for mid in model_ids: | ||
| if any(mid.startswith(p) for p in _1M_CONTEXT_MODEL_PREFIXES): | ||
| overrides[mid] = {"limit": {"context": 1_000_000}} | ||
| return overrides | ||
|
|
||
| def set_key(self, key: str) -> None: | ||
| self.chosen_api_key = key | ||
| # 切换 key 时需要重建客户端以使用新的 auth_token | ||
| self.client = AsyncAnthropic( | ||
| auth_token=key, | ||
| timeout=self.timeout, | ||
| base_url=self.base_url, | ||
| default_headers=_OAUTH_DEFAULT_HEADERS, | ||
| http_client=self._create_http_client(self.provider_config), | ||
| ) | ||
|
|
||
| async def get_models(self) -> list[str]: | ||
| return await super().get_models() | ||
|
|
||
| async def test(self, timeout: float = 45.0) -> None: | ||
| await super().test(timeout) | ||
|
|
||
| async def text_chat( | ||
| self, | ||
| prompt=None, | ||
| session_id=None, | ||
| image_urls=None, | ||
| func_tool=None, | ||
| contexts=None, | ||
| system_prompt=None, | ||
| tool_calls_result=None, | ||
| model=None, | ||
| extra_user_content_parts=None, | ||
| **kwargs, | ||
| ) -> LLMResponse: | ||
| system_prompt = _CLAUDE_CODE_SYSTEM_PREFIX + (system_prompt or "") | ||
|
|
||
| return await super().text_chat( | ||
| prompt=prompt, | ||
| session_id=session_id, | ||
| image_urls=image_urls, | ||
| func_tool=func_tool, | ||
| contexts=contexts, | ||
| system_prompt=system_prompt, | ||
| tool_calls_result=tool_calls_result, | ||
| model=model, | ||
| extra_user_content_parts=extra_user_content_parts, | ||
| **kwargs, | ||
| ) | ||
|
|
||
| async def text_chat_stream( | ||
| self, | ||
| prompt=None, | ||
| session_id=None, | ||
| image_urls=None, | ||
| func_tool=None, | ||
| contexts=None, | ||
| system_prompt=None, | ||
| tool_calls_result=None, | ||
| model=None, | ||
| extra_user_content_parts=None, | ||
| **kwargs, | ||
| ) -> AsyncGenerator[LLMResponse, None]: | ||
| system_prompt = _CLAUDE_CODE_SYSTEM_PREFIX + (system_prompt or "") | ||
|
|
||
| async for llm_response in super().text_chat_stream( | ||
| prompt=prompt, | ||
| session_id=session_id, | ||
| image_urls=image_urls, | ||
| func_tool=func_tool, | ||
| contexts=contexts, | ||
| system_prompt=system_prompt, | ||
| tool_calls_result=tool_calls_result, | ||
| model=model, | ||
| extra_user_content_parts=extra_user_content_parts, | ||
| **kwargs, | ||
| ): | ||
| yield llm_response |
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
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
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
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
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
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
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
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.
Uh oh!
There was an error while loading. Please reload this page.