auto-backup: 2025-12-11 20:35:05 (68 files: +19 ~23 -25)

Generated by DSS Git Backup Hook
This commit is contained in:
2025-12-11 17:35:05 -03:00
parent 09b234a07f
commit 1ff198c177
68 changed files with 3229 additions and 7102 deletions

View File

@@ -7,6 +7,7 @@ Handles model-specific API calls and tool execution
import asyncio
import json
import os
import subprocess
from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional
@@ -39,19 +40,68 @@ class AIProvider(ABC):
class ClaudeProvider(AIProvider):
"""Anthropic Claude provider."""
# SoFi LLM Proxy configuration
PROXY_BASE_URL = "https://internal.sofitest.com/llm-proxy"
API_KEY_HELPER = os.path.expanduser("~/.local/bin/llm-proxy-keys")
def __init__(self):
self.api_key = os.getenv("ANTHROPIC_API_KEY")
self.base_url = os.getenv("ANTHROPIC_BASE_URL", self.PROXY_BASE_URL)
self.default_model = "claude-sonnet-4-5-20250929"
self._proxy_key = None
def _get_proxy_key(self) -> Optional[str]:
"""Get API key from SoFi LLM proxy helper script"""
if self._proxy_key:
return self._proxy_key
try:
if os.path.exists(self.API_KEY_HELPER):
result = subprocess.run(
[self.API_KEY_HELPER],
capture_output=True,
text=True,
timeout=10
)
if result.returncode == 0:
# Extract the key from output (last line with sk- prefix)
for line in result.stdout.strip().split('\n'):
if line.startswith('sk-'):
self._proxy_key = line.strip()
return self._proxy_key
except Exception as e:
print(f"Error getting proxy key: {e}")
return None
def is_available(self) -> bool:
"""Check if Claude is available."""
try:
from anthropic import Anthropic
return bool(self.api_key)
# Available if SDK is installed (proxy may have keys)
return True
except ImportError:
return False
def _create_client(self):
"""Create Anthropic client configured for SoFi proxy"""
from anthropic import Anthropic
import httpx
# Create httpx client that skips SSL verification (for corporate proxy)
http_client = httpx.Client(verify=False)
# Get API key: prefer env var, then proxy helper
api_key = self.api_key or self._get_proxy_key()
if not api_key:
raise ValueError("No API key available. Set ANTHROPIC_API_KEY or ensure llm-proxy-keys is installed.")
return Anthropic(
api_key=api_key,
base_url=self.base_url,
http_client=http_client
)
async def chat(
self,
message: str,
@@ -67,7 +117,7 @@ class ClaudeProvider(AIProvider):
if not self.is_available():
return {
"success": False,
"response": "Claude not available. Install anthropic SDK or set ANTHROPIC_API_KEY.",
"response": "Claude not available. Install anthropic SDK.",
"model": "error",
"tools_used": [],
"stop_reason": "error",
@@ -75,7 +125,17 @@ class ClaudeProvider(AIProvider):
from anthropic import Anthropic
client = Anthropic(api_key=self.api_key)
# Create client with SoFi proxy settings
try:
client = self._create_client()
except ValueError as e:
return {
"success": False,
"response": str(e),
"model": "error",
"tools_used": [],
"stop_reason": "error"
}
# Build messages
messages = []
@@ -99,8 +159,20 @@ class ClaudeProvider(AIProvider):
if tools:
api_params["tools"] = tools
# Initial call
response = await asyncio.to_thread(client.messages.create, **api_params)
# Make API call via SoFi proxy
try:
response = await asyncio.to_thread(
client.messages.create,
**api_params
)
except Exception as e:
return {
"success": False,
"response": f"Claude API error: {str(e)}",
"model": "error",
"tools_used": [],
"stop_reason": "error"
}
# Handle tool use loop
tools_used = []