feat: trackeo de coste por llamada Claude — tabla api_usage + /costs
Build & Deploy ResearchOwl / build-and-push (push) Successful in 6s

This commit is contained in:
ChemaVX
2026-05-03 20:06:06 +00:00
parent 65917518ce
commit b33ae202b8
4 changed files with 129 additions and 8 deletions
+14 -4
View File
@@ -182,7 +182,7 @@ class ContentProcessor:
if words < 30:
continue
quality = await self._score_quality(chunk, topic)
quality = await self._score_quality(chunk, topic, session_id)
if quality < settings.quality_threshold:
filtered_quality += 1
logger.debug("Chunk filtered by quality", source_id=source_id,
@@ -215,13 +215,15 @@ class ContentProcessor:
logger.info("Source processed", source_id=source_id, stored=stored)
return stored
async def _score_quality(self, chunk: str, topic: str) -> float:
async def _score_quality(self, chunk: str, topic: str,
session_id: int | None = None) -> float:
"""Score 0-1 relevance to topic. Uses Claude Haiku if API key set, else Ollama."""
if settings.anthropic_api_key:
return await self._score_with_claude(chunk, topic)
return await self._score_with_claude(chunk, topic, session_id)
return await self._score_with_ollama(chunk, topic)
async def _score_with_claude(self, chunk: str, topic: str) -> float:
async def _score_with_claude(self, chunk: str, topic: str,
session_id: int | None = None) -> float:
import anthropic
prompt = (
f'Rate 0-10 how relevant this text is to the topic "{topic}". '
@@ -234,6 +236,14 @@ class ContentProcessor:
max_tokens=10,
messages=[{"role": "user", "content": prompt}]
)
if session_id is not None:
try:
await self.db.log_api_call(
session_id, "scoring", settings.claude_model,
msg.usage.input_tokens, msg.usage.output_tokens
)
except Exception as log_err:
logger.warning("Failed to log API usage", error=str(log_err))
response = msg.content[0].text.strip()
numbers = re.findall(r'\b(\d+(?:\.\d+)?)\b', response)
if numbers: