fix(recommender): remove Todoist fallback on orchestrator failure; add snooze exclusion

When fetchOrchestratorTip returned null (LiteLLM timeout, bad JSON, etc.)
the recommender silently fell back to randomPolicy, serving a raw Todoist
task with no rationale — explaining both reported symptoms.

- Remove randomPolicy/signalToCandidate; return 204 when orchestrator fails
  so the UI shows "All clear" instead of a confusing Todoist task
- Pass recent_tip through the stack (frontend → POST /recommend →
  fetchOrchestratorTip → ml/serving RecommendRequest → build_orchestrator_messages)
  so after snooze the LLM is instructed not to repeat the snoozed content

Fixes #122

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-12 13:28:32 +00:00
parent d4b40e2590
commit 59c493323f
5 changed files with 29 additions and 41 deletions

View File

@@ -233,6 +233,7 @@ class RecommendRequest(BaseModel):
hour_of_day: int = 12
day_of_week: int = 0
science_destiny: int = 50 # 0=science (data-driven), 100=destiny (intuitive)
recent_tip: Optional[str] = None # content of last snoozed tip; LLM avoids repeating it
class TipResult(BaseModel):
@@ -430,6 +431,7 @@ async def recommend(req: RecommendRequest) -> RecommendResponse:
hour_of_day=req.hour_of_day,
day_of_week=req.day_of_week,
science_destiny=req.science_destiny,
recent_tip=req.recent_tip,
)
_end_span(ctx_span, outputs={"message_count": len(messages)})