85 lines
2.3 KiB
Python
85 lines
2.3 KiB
Python
"""
|
|
OpenAI/OpenRouter summarizer utility.
|
|
|
|
Uses OPENAI_API_KEY and OPENAI_URL from environment (via Config).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from typing import Dict, List
|
|
|
|
import requests
|
|
|
|
from config import Config
|
|
|
|
|
|
class SummarizationError(RuntimeError):
|
|
"""Raised when summarization fails."""
|
|
|
|
|
|
def summarize_text(text: str, max_points: int = 3) -> Dict[str, List[str] | str]:
|
|
"""
|
|
Summarize text into a short summary and key points.
|
|
|
|
Returns:
|
|
{
|
|
"summary": "string",
|
|
"key_points": ["point 1", "point 2", ...]
|
|
}
|
|
"""
|
|
if not text or not text.strip():
|
|
return {"summary": "", "key_points": []}
|
|
|
|
if not Config.OPENAI_API_KEY:
|
|
raise SummarizationError("OPENAI_API_KEY is not set")
|
|
|
|
payload = {
|
|
"model": Config.OPENAI_MODEL,
|
|
"messages": [
|
|
{
|
|
"role": "system",
|
|
"content": (
|
|
"You are a precise summarizer. Return JSON only with keys "
|
|
"`summary` and `key_points` (array of strings). Do not add extra keys."
|
|
),
|
|
},
|
|
{
|
|
"role": "user",
|
|
"content": (
|
|
"Summarize the following content in 2-4 sentences and provide "
|
|
f"{max_points} key points.\n\n"
|
|
f"CONTENT:\n{text}"
|
|
),
|
|
},
|
|
],
|
|
"temperature": 0.2,
|
|
"max_tokens": 400,
|
|
}
|
|
|
|
headers = {
|
|
"Authorization": f"Bearer {Config.OPENAI_API_KEY}",
|
|
"Content-Type": "application/json",
|
|
}
|
|
|
|
try:
|
|
response = requests.post(
|
|
Config.OPENAI_URL,
|
|
headers=headers,
|
|
json=payload,
|
|
timeout=Config.OPENAI_TIMEOUT,
|
|
)
|
|
response.raise_for_status()
|
|
data = response.json()
|
|
except Exception as exc:
|
|
raise SummarizationError(f"Request failed: {exc}") from exc
|
|
|
|
try:
|
|
content = data["choices"][0]["message"]["content"].strip()
|
|
result = json.loads(content)
|
|
summary = result.get("summary", "").strip()
|
|
key_points = [p.strip() for p in result.get("key_points", []) if p.strip()]
|
|
return {"summary": summary, "key_points": key_points}
|
|
except Exception as exc:
|
|
raise SummarizationError(f"Invalid response format: {exc}") from exc
|