|
|
|
@@ -269,6 +269,39 @@ class AnthropicOAuthProvider(LLMProvider):
|
|
|
|
|
json=payload,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Dump rate limit headers for analysis
|
|
|
|
|
try:
|
|
|
|
|
import datetime
|
|
|
|
|
import os
|
|
|
|
|
header_dump = {
|
|
|
|
|
"timestamp": datetime.datetime.utcnow().isoformat(),
|
|
|
|
|
"status_code": response.status_code,
|
|
|
|
|
"model": payload.get("model"),
|
|
|
|
|
"headers": dict(response.headers),
|
|
|
|
|
}
|
|
|
|
|
dump_path = "/root/.nanobot/workspace/api_headers.jsonl"
|
|
|
|
|
with open(dump_path, "a") as f:
|
|
|
|
|
f.write(json.dumps(header_dump) + "\n")
|
|
|
|
|
# Capture rate limit state for quota-based model switching
|
|
|
|
|
hdrs = response.headers
|
|
|
|
|
rate_limit_state = {
|
|
|
|
|
"updated_at": datetime.datetime.utcnow().isoformat(),
|
|
|
|
|
"model": payload.get("model"),
|
|
|
|
|
"weekly_all_models": float(hdrs["anthropic-ratelimit-unified-7d-utilization"]) if hdrs.get("anthropic-ratelimit-unified-7d-utilization") else None,
|
|
|
|
|
"weekly_sonnet": float(hdrs["anthropic-ratelimit-unified-7d_sonnet-utilization"]) if hdrs.get("anthropic-ratelimit-unified-7d_sonnet-utilization") else None,
|
|
|
|
|
"session_5h": float(hdrs["anthropic-ratelimit-unified-5h-utilization"]) if hdrs.get("anthropic-ratelimit-unified-5h-utilization") else None,
|
|
|
|
|
"weekly_reset": int(hdrs["anthropic-ratelimit-unified-7d-reset"]) if hdrs.get("anthropic-ratelimit-unified-7d-reset") else None,
|
|
|
|
|
"session_reset": int(hdrs["anthropic-ratelimit-unified-5h-reset"]) if hdrs.get("anthropic-ratelimit-unified-5h-reset") else None,
|
|
|
|
|
"binding_limit": hdrs.get("anthropic-ratelimit-unified-representative-claim"),
|
|
|
|
|
"sonnet_fallback": hdrs.get("anthropic-ratelimit-unified-fallback"),
|
|
|
|
|
}
|
|
|
|
|
state_path = "/root/.nanobot/workspace/memory/rate_limits.json"
|
|
|
|
|
os.makedirs(os.path.dirname(state_path), exist_ok=True)
|
|
|
|
|
with open(state_path, "w") as f:
|
|
|
|
|
json.dump(rate_limit_state, f, indent=2)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.warning("Rate limit header capture failed: {}", e)
|
|
|
|
|
|
|
|
|
|
if response.status_code != 200:
|
|
|
|
|
error_text = response.text
|
|
|
|
|
raise Exception(f"Anthropic API error {response.status_code}: {error_text}")
|
|
|
|
|