No US session closes into Monday KST, so Mondays (default 07:00, cron in the daemon with restart catch-up) now publish a weekly review built entirely from stored data: the quotes table collapsed into week-over- week changes and the week's daily briefing headlines as the narrative. The recap is a BriefingResult kind="weekly" reusing MarketPayload, so the store, verification pass, all delivery channels (Blogger title "미국 주간 리뷰 <monday>") and the dashboard (주간 리뷰 badge) work unchanged. Manual runs via `run-once --weekly [--date <monday>]`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
40 lines
1.3 KiB
Python
40 lines
1.3 KiB
Python
"""LLM provider interface. Implementations must be side-effect free apart from the HTTP call."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Protocol
|
|
|
|
from us2kr.models import MarketPayload, Report, Verification, VerificationIssue
|
|
|
|
|
|
class LLMError(RuntimeError):
|
|
"""Raised when every configured model failed to produce a valid Report."""
|
|
|
|
|
|
class LLMProvider(Protocol):
|
|
def summarize(self, payload: MarketPayload) -> tuple[Report, str]:
|
|
"""Return (validated Report, model id that produced it). Raise LLMError on total failure."""
|
|
...
|
|
|
|
def summarize_weekly(self, payload: MarketPayload, week_sessions: list) -> tuple[Report, str]:
|
|
"""Weekly recap over a payload whose quotes carry week-over-week changes."""
|
|
...
|
|
|
|
def verify(
|
|
self, payload: MarketPayload, report: Report, data_message: str | None = None
|
|
) -> tuple[Verification, str]:
|
|
"""Fact-check `report` against the payload (or `data_message`). Raise LLMError on total failure."""
|
|
...
|
|
|
|
def revise(
|
|
self,
|
|
payload: MarketPayload,
|
|
report: Report,
|
|
issues: list[VerificationIssue],
|
|
*,
|
|
system_prompt: str | None = None,
|
|
data_message: str | None = None,
|
|
) -> tuple[Report, str]:
|
|
"""Return a corrected Report addressing `issues`. Raise LLMError on total failure."""
|
|
...
|