88c1ea297e
All feature containers now POST messages to ai-service (port 8010) instead of calling AI providers directly. ai-service routes to LM Studio, Ollama, or Anthropic based on /config/ai_service_config.json. doc-service AI providers removed; replaced by httpx ai_client.py. Backend settings restructured to /api/settings/ai. Frontend gets dedicated AIAdminSettingsPage and AI Service card in AppsPage. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
50 lines
1.4 KiB
Python
50 lines
1.4 KiB
Python
"""HTTP client for the shared ai-service container."""
|
|
import json
|
|
|
|
import httpx
|
|
|
|
from app.core.config import settings
|
|
from app.services.prompts import SYSTEM_PROMPT, USER_PROMPT_TEMPLATE
|
|
|
|
_client = httpx.AsyncClient(timeout=120.0)
|
|
|
|
|
|
class AIServiceError(Exception):
|
|
pass
|
|
|
|
|
|
async def classify_document(text: str) -> dict:
|
|
"""
|
|
Send document text to ai-service for classification.
|
|
Returns the parsed JSON result dict.
|
|
Raises AIServiceError on HTTP errors or unexpected response shapes.
|
|
"""
|
|
messages = [
|
|
{"role": "system", "content": SYSTEM_PROMPT},
|
|
{"role": "user", "content": USER_PROMPT_TEMPLATE.format(text=text[:50_000])},
|
|
]
|
|
|
|
try:
|
|
response = await _client.post(
|
|
f"{settings.AI_SERVICE_URL}/chat",
|
|
json={
|
|
"messages": messages,
|
|
"max_tokens": 2048,
|
|
"temperature": 0,
|
|
"response_format": "json",
|
|
},
|
|
)
|
|
except httpx.RequestError as exc:
|
|
raise AIServiceError(f"Could not reach ai-service: {exc}") from exc
|
|
|
|
if response.status_code != 200:
|
|
raise AIServiceError(
|
|
f"ai-service returned {response.status_code}: {response.text[:200]}"
|
|
)
|
|
|
|
try:
|
|
content = response.json()["content"]
|
|
return json.loads(content)
|
|
except (KeyError, json.JSONDecodeError) as exc:
|
|
raise AIServiceError(f"Unexpected ai-service response: {exc}") from exc
|