phase 4
This commit is contained in:
73
core/detect/providers/claude.py
Normal file
73
core/detect/providers/claude.py
Normal file
@@ -0,0 +1,73 @@
|
||||
"""Anthropic Claude provider — uses the official SDK."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from .base import ModelInfo, ProviderResponse
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Claude-specific env vars
|
||||
# ANTHROPIC_API_KEY is read by the SDK automatically
|
||||
CLAUDE_MODEL = os.environ.get("CLAUDE_MODEL", "claude-sonnet-4-20250514")
|
||||
|
||||
MODELS = {
|
||||
"claude-sonnet-4-20250514": ModelInfo(
|
||||
id="claude-sonnet-4-20250514",
|
||||
vision=True,
|
||||
cost_per_input_token=0.000003,
|
||||
cost_per_output_token=0.000015,
|
||||
notes="Best balance of quality/cost with vision",
|
||||
),
|
||||
"claude-haiku-4-5-20251001": ModelInfo(
|
||||
id="claude-haiku-4-5-20251001",
|
||||
vision=True,
|
||||
cost_per_input_token=0.0000008,
|
||||
cost_per_output_token=0.000004,
|
||||
notes="Fastest, cheapest, good for simple brand ID",
|
||||
),
|
||||
"claude-opus-4-6": ModelInfo(
|
||||
id="claude-opus-4-6",
|
||||
vision=True,
|
||||
cost_per_input_token=0.000015,
|
||||
cost_per_output_token=0.000075,
|
||||
notes="Highest quality, use for ambiguous cases",
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
class ClaudeProvider:
|
||||
name = "claude"
|
||||
models = MODELS
|
||||
|
||||
def __init__(self):
|
||||
from anthropic import Anthropic
|
||||
self.client = Anthropic()
|
||||
self.model = CLAUDE_MODEL
|
||||
|
||||
def call(self, image_b64: str, prompt: str) -> ProviderResponse:
|
||||
message = self.client.messages.create(
|
||||
model=self.model,
|
||||
max_tokens=150,
|
||||
messages=[{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "image",
|
||||
"source": {
|
||||
"type": "base64",
|
||||
"media_type": "image/jpeg",
|
||||
"data": image_b64,
|
||||
},
|
||||
},
|
||||
{"type": "text", "text": prompt},
|
||||
],
|
||||
}],
|
||||
)
|
||||
|
||||
answer = message.content[0].text.strip()
|
||||
total_tokens = message.usage.input_tokens + message.usage.output_tokens
|
||||
|
||||
return ProviderResponse(answer=answer, total_tokens=total_tokens)
|
||||
Reference in New Issue
Block a user