fix(anthropic): deep scan fixes — auth, retries, edge cases
Fixes from comprehensive code review and cross-referencing with clawdbot/OpenCode implementations: CRITICAL: - Add one-shot guard (anthropic_auth_retry_attempted) to prevent infinite 401 retry loops when credentials keep changing - Fix _is_oauth_token(): managed keys from ~/.claude.json are NOT regular API keys (don't start with sk-ant-api). Inverted the logic: only sk-ant-api* is treated as API key auth, everything else uses Bearer auth + oauth beta headers HIGH: - Wrap json.loads(args) in try/except in message conversion — malformed tool_call arguments no longer crash the entire conversation - Raise AuthError in runtime_provider when no Anthropic token found (was silently passing empty string, causing confusing API errors) - Remove broken _try_anthropic() from auxiliary vision chain — the centralized router creates an OpenAI client for api_key providers which doesn't work with Anthropic's Messages API MEDIUM: - Handle empty assistant message content — Anthropic rejects empty content blocks, now inserts '(empty)' placeholder - Fix setup.py existing_key logic — set to 'KEEP' sentinel instead of None to prevent falling through to the auth choice prompt - Add debug logging to _fetch_anthropic_models on failure Tests: 43 adapter tests (2 new for token detection), 3197 total passed
This commit is contained in:
parent
cd4e995d54
commit
4068f20ce9
7 changed files with 46 additions and 24 deletions
|
|
@ -449,21 +449,6 @@ def _try_custom_endpoint() -> Tuple[Optional[OpenAI], Optional[str]]:
|
|||
return OpenAI(api_key=custom_key, base_url=custom_base), model
|
||||
|
||||
|
||||
_ANTHROPIC_VISION_MODEL = "claude-sonnet-4-20250514"
|
||||
|
||||
|
||||
def _try_anthropic() -> Tuple[Optional[Any], Optional[str]]:
|
||||
"""Try Anthropic credentials for auxiliary tasks (vision-capable)."""
|
||||
from agent.anthropic_adapter import resolve_anthropic_token
|
||||
token = resolve_anthropic_token()
|
||||
if not token:
|
||||
return None, None
|
||||
# Return a simple wrapper that indicates Anthropic is available.
|
||||
# The actual client is created by resolve_provider_client("anthropic").
|
||||
logger.debug("Auxiliary client: Anthropic (%s)", _ANTHROPIC_VISION_MODEL)
|
||||
return resolve_provider_client("anthropic", model=_ANTHROPIC_VISION_MODEL)
|
||||
|
||||
|
||||
def _try_codex() -> Tuple[Optional[Any], Optional[str]]:
|
||||
codex_token = _read_codex_access_token()
|
||||
if not codex_token:
|
||||
|
|
@ -768,8 +753,8 @@ def get_vision_auxiliary_client() -> Tuple[Optional[OpenAI], Optional[str]]:
|
|||
# back to the user's custom endpoint. Many local models (Qwen-VL,
|
||||
# LLaVA, Pixtral, etc.) support vision — skipping them entirely
|
||||
# caused silent failures for local-only users.
|
||||
for try_fn in (_try_openrouter, _try_nous, _try_anthropic,
|
||||
_try_codex, _try_custom_endpoint):
|
||||
for try_fn in (_try_openrouter, _try_nous, _try_codex,
|
||||
_try_custom_endpoint):
|
||||
client, model = try_fn()
|
||||
if client is not None:
|
||||
return client, model
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue