feat(email): scheduled daily inbox briefing (off by default)#1918
feat(email): scheduled daily inbox briefing (off by default)#1918kovtcharov wants to merge 1 commit into
Conversation
The pre-scan briefing content existed but only ran when a user asked; there was no way to get the morning triage card without a prompt. The email sidecar can now generate it on a daily timer and any surface can pull the latest run from GET /v1/email/briefing. - New gaia_agent_email.briefing: env-driven BriefingScheduleConfig (off by default, invalid values fail sidecar startup loudly), run_briefing_job reusing pre_scan_inbox_impl (same email_pre_scan envelope, nothing re-classified), and an asyncio daily scheduler wired into the sidecar lifespan. run_briefing_job is the seam the gaia schedule dispatcher (#1371) / autonomy engine (#555) will call directly when they land. - Delivery: each run atomically persists the envelope with a generated_at stamp; new additive GET /v1/email/briefing serves the latest run (404 before the first one). SCHEMA_VERSION stays 2.1. - Regenerated openapi.email.json; spec page + specification.html, npm README/SPEC/SKILL/CHANGELOG, and docs/guides/email.mdx updated together. Closes #1608
|
Verdict: Approve ✅ This adds a scheduled daily inbox briefing to the email sidecar: a daily timer runs the existing pre-scan (no re-classification), persists the The bottom line: no blocking issues. Config is genuinely fail-loud (no silent coercion), writes are atomic, the schedule-off path is proven to produce nothing, and every doc surface (README, SPEC, SKILL, CHANGELOG, spec_html, OpenAPI, specification.html, guide) is updated in sync — exactly what CLAUDE.md requires for a contract change. One minor, non-blocking note on DST below. 🔍 Technical details🟢 MinorNaive-local scheduling can drift across a DST boundary ( Verified, not issues
Strengths
|
The morning triage card existed only on demand — a user had to ask for a pre-scan every time. Now the email sidecar can generate it on a daily schedule with no prompt: each run reuses the agent's own
pre_scan_inboxpath (sameemail_pre_scanenvelope, nothing re-classified), persists it with agenerated_atstamp, and any surface pulls the latest run from the new additiveGET /v1/email/briefing. Off by default — enabled explicitly withGAIA_EMAIL_BRIEFING_ENABLED=true(fire timeGAIA_EMAIL_BRIEFING_TIME, default 08:00); an invalid value fails sidecar startup loudly instead of guessing a schedule.The
gaia scheduledispatcher (#1371) is approved but not merged, so the in-process timer is deliberately minimal and email-scoped:run_briefing_job()is the one-shot seam the #1371 dispatcher / autonomy engine (#555) will invoke directly when they land, at which point the timer can be deleted without touching the job or delivery.SCHEMA_VERSIONstays 2.1 (additive, like #1887).Closes #1608 (capability 16 in #1691).
Test plan
pre_scan_inboxand produces theemail_pre_scanenvelope —test_briefing_job_produces_email_pre_scan_envelopetest_disabled_schedule_produces_no_briefingmaybe/8am/0/101each raise at startup —test_config_invalid_values_fail_loudGET /v1/email/briefing: 404 before the first run, conforms toEmailBriefingResponseafter one (tests/test_email_openapi_conformance.py::test_briefing_conforms_to_spec)python -m pytest hub/agents/python/email/tests/ tests/test_email_openapi_conformance.py tests/unit/agents/email/ tests/unit/email/— 762 passedpython -m gaia_agent_email.export_openapi --check(artifact regenerated) ·python util/lint.py --allcleanpackaging/server.py's app with the lifespan — health OK, briefing 404 with actionable detail, invalid env aborts startup withBriefingConfigError