v1.20.11 — ReAct Initiative parity + configurable Today Briefing limits
⚡ ReAct mode becomes proactive
ReAct mode now runs the proactive Initiative phase it previously had only in Pipeline mode: after answering, it can perform read-only cross-domain lookups and weave them into the reply — for example the weather and the drive time before your next appointment. Gated by the new INITIATIVE_REACT_ENABLED flag (default off); the draft path is untouched, so default-off behaviour is identical to before. (ADR-070 / ADR-062)
🌅 Today Briefing
- Configurable widget content limits via
BriefingSettings(BRIEFING_*env vars): the agenda now shows up to 10 upcoming events instead of 3 by default, plus lookahead, mails, birthdays, reminders, health window and weather days. - Greeting now reflects your real agenda — it tells today from tomorrow, names the next appointment, and reacts to the shape of your day instead of vaguely implying something is happening "today".
🐛 Fixes
- Currency amounts (
$) are no longer mangled into broken LaTeX in chat and proactive notifications (single-$inline math disabled;$$…$$display math still works). - Exchange-rate API (Frankfurter) endpoint corrected to
.dev/v1, restoring accurate USD→EUR LLM-cost conversion. - Scheduler leader-election "lock busy" log demoted from warning to info (the normal non-leader case); a genuinely stuck lock is still escalated to warning.
🧰 Under the hood
Idempotent ReAct-answer merge in response_node; _format_execution_summary normalizes dict + Pydantic RegistryItem; briefing defaults centralized in core/constants (avoids a config↔domain circular import). New test suites (routing, merge, execution-summary, briefing settings, greeting). FAQ changelog + "How LIA works" feature updated in all 6 languages. Full pre-commit suite green: Ruff, Black, MyPy, 8293 unit tests, i18n parity, ESLint, TypeScript.
See CHANGELOG.md for the full technical detail.