digest: record AICall rows so digest LLM spend counts toward monthly cap
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1fdf7d6a23
commit
ce4b19dbb8
1 changed files with 22 additions and 3 deletions
|
|
@ -69,9 +69,15 @@ async def _already_sent_today(session, user_id: int, kind: str, today: datetime)
|
||||||
return (await session.execute(stmt)).first() is not None
|
return (await session.execute(stmt)).first() is not None
|
||||||
|
|
||||||
|
|
||||||
async def _generate_variants(client, kind: str, ctx: dict) -> dict[str, str]:
|
async def _generate_variants(session, client, kind: str, ctx: dict) -> dict[str, str]:
|
||||||
"""Returns {tone: html_content}. Missing tone means generation failed
|
"""Returns {tone: html_content}. Missing tone means generation failed
|
||||||
for that variant — skip recipients on that tone."""
|
for that variant — skip recipients on that tone.
|
||||||
|
|
||||||
|
Persists an AICall row per attempt so digest LLM spend counts toward
|
||||||
|
the monthly cost cap on subsequent runs."""
|
||||||
|
from app.models import AICall
|
||||||
|
from app.services.openrouter import active_model
|
||||||
|
|
||||||
builder = build_weekly_digest_prompt if kind == "weekly" else build_daily_digest_prompt
|
builder = build_weekly_digest_prompt if kind == "weekly" else build_daily_digest_prompt
|
||||||
out: dict[str, str] = {}
|
out: dict[str, str] = {}
|
||||||
for tone in ("NOVICE", "INTERMEDIATE"):
|
for tone in ("NOVICE", "INTERMEDIATE"):
|
||||||
|
|
@ -83,10 +89,23 @@ async def _generate_variants(client, kind: str, ctx: dict) -> dict[str, str]:
|
||||||
{"role": "user", "content": usr}],
|
{"role": "user", "content": usr}],
|
||||||
)
|
)
|
||||||
out[tone] = result.content
|
out[tone] = result.content
|
||||||
|
session.add(AICall(
|
||||||
|
model=result.model,
|
||||||
|
prompt_tokens=result.prompt_tokens,
|
||||||
|
completion_tokens=result.completion_tokens,
|
||||||
|
cost_usd=result.cost_usd,
|
||||||
|
status="ok",
|
||||||
|
))
|
||||||
|
await session.commit()
|
||||||
log.info("digest.variant_ok", kind=kind, tone=tone,
|
log.info("digest.variant_ok", kind=kind, tone=tone,
|
||||||
prompt_tokens=result.prompt_tokens,
|
prompt_tokens=result.prompt_tokens,
|
||||||
completion_tokens=result.completion_tokens)
|
completion_tokens=result.completion_tokens)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
session.add(AICall(
|
||||||
|
model=active_model(), status="error",
|
||||||
|
error=f"{kind}/{tone}: {str(e)[:480]}",
|
||||||
|
))
|
||||||
|
await session.commit()
|
||||||
log.error("digest.variant_failed", kind=kind, tone=tone,
|
log.error("digest.variant_failed", kind=kind, tone=tone,
|
||||||
error=str(e)[:200])
|
error=str(e)[:200])
|
||||||
return out
|
return out
|
||||||
|
|
@ -173,7 +192,7 @@ async def run() -> None:
|
||||||
)
|
)
|
||||||
|
|
||||||
async with httpx.AsyncClient(follow_redirects=True) as client:
|
async with httpx.AsyncClient(follow_redirects=True) as client:
|
||||||
variants = await _generate_variants(client, kind, ctx)
|
variants = await _generate_variants(session, client, kind, ctx)
|
||||||
|
|
||||||
if not variants:
|
if not variants:
|
||||||
log.warning("digest.all_variants_failed", kind=kind)
|
log.warning("digest.all_variants_failed", kind=kind)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue