diff --git a/services/meet_kevin_watcher/config.py b/services/meet_kevin_watcher/config.py index 99d55e9..b5e8d53 100644 --- a/services/meet_kevin_watcher/config.py +++ b/services/meet_kevin_watcher/config.py @@ -21,6 +21,7 @@ class MeetKevinWatcherConfig(BaseConfig): meet_kevin_llm_model: str = "claude-sonnet-4-5" meet_kevin_prompt_version: str = "v1" meet_kevin_daily_cost_cap_usd: float = 5.0 + meet_kevin_inter_video_sleep_seconds: int = 30 # API credentials anthropic_oauth_token: str = "" diff --git a/services/meet_kevin_watcher/main.py b/services/meet_kevin_watcher/main.py index 0e8f96a..79b167f 100644 --- a/services/meet_kevin_watcher/main.py +++ b/services/meet_kevin_watcher/main.py @@ -104,7 +104,10 @@ async def _process_pending_videos( ) videos = result.scalars().all() - for video in videos: + for i, video in enumerate(videos): + # Throttle between videos to avoid bursting into Anthropic's per-account RPM limit + if i > 0: + await asyncio.sleep(deps.inter_video_sleep_seconds) async with session_factory() as session: # Re-fetch inside its own session so we can commit per-video result = await session.execute( @@ -207,6 +210,7 @@ async def run() -> None: prompt_version=config.meet_kevin_prompt_version, daily_cost_cap_usd=Decimal(str(config.meet_kevin_daily_cost_cap_usd)), workdir=config.meet_kevin_workdir, + inter_video_sleep_seconds=config.meet_kevin_inter_video_sleep_seconds, ) # Graceful shutdown diff --git a/services/meet_kevin_watcher/pipeline.py b/services/meet_kevin_watcher/pipeline.py index 0f114ef..93fe6e1 100644 --- a/services/meet_kevin_watcher/pipeline.py +++ b/services/meet_kevin_watcher/pipeline.py @@ -66,6 +66,9 @@ class PipelineDeps: workdir: str """Filesystem directory for yt-dlp caption downloads.""" + inter_video_sleep_seconds: int = 30 + """Sleep between consecutive videos to stay under the LLM provider RPM limit.""" + # --------------------------------------------------------------------------- # Daily cost accounting