This release includes breaking changes for platform teams planning a safe upgrade.
✓ No known CVEs patched in this version
Topics
+13 more
Summary
AI summaryUpdates ๐ก๏ธ Robustness & observability, โจ Draft-editing UX, and non-deterministic across a mixed release.
Full changelog
๐ฏ Fix release โ trustworthy draft editing & bulk confirmations
LangGraph resume semantics re-execute the entire interrupted node: past interrupt() calls return their cached values, but every other statement โ LLM calls, provider API calls โ runs live again. Both HITL flows that looped around interrupt() inside a node therefore replayed their side effects on every user decision:
- Draft editing re-ran every past
DraftModificationService.modify()LLM call (non-deterministic): after two edits and a confirm, the email actually sent could differ from the last version you saw and approved, at O(nยฒ) LLM cost. - FOR_EACH bulk confirmation re-ran the provider pre-execution (real API calls) and every past LLM item-filter call: the list executed could diverge from the list you confirmed.
Both now follow the normative ADR-092 pattern โ one interrupt() per node execution, loop state flowing through the checkpointed graph state, iteration via conditional self-loop edges (new dedicated for_each_confirm node) โ proven by compiled replay harnesses (real nodes + real routers + InMemorySaver + Command(resume=...)).
Invariant: what you last saw is exactly what executes, and no LLM or provider side effect ever runs more than once per decision.
โจ Draft-editing UX (found during in-app validation)
- One chat bubble per re-presented draft โ the run-scoped SSE
message_idmade every revision overwrite the previous assistant bubble; it now derives from the LangGraphInterrupt.id. Live rendering finally matches the archived history. - "Sign with my name" works โ a new shared
resolve_user_display_name()flows the profile first name from every entry point (web, scheduled actions, Telegram) into the drafting and modification prompts. No more[Your name]placeholders, no invented names; no signature unless you ask. - Clarify questions are displayed โ the generated clarification question was logged then dropped; it is now persisted, carried on the next interrupt payload and streamed verbatim (with a 6-language generic fallback).
๐ก๏ธ Robustness & observability
CancelledErrorpropagates at both parallel-executor stages (Python 3.12: it is aBaseExceptionand escaped theExceptionfilter) โ closing the stream actually cancels in-flight bulk work.on_item_error="stop"forces sequential execution so "stop" can stop (FOR_EACH_STOP_FORCES_SEQUENTIAL, default true).- HTTP metric labels bounded to route templates (+
unmatchedfor bot scans,{id}-collapsing fallback for the in-progress gauge). โ ๏ธ Grafana queries filtering on raw paths must switch to templates. - Token-tracking run-records bounded (
RUN_RECORDS_MAX_RUNS); place-card/birthday/email/voice timestamps computed in the user timezone; quiet prod boot (Telegramset_webhookflood retry, "system" embedding skip).
๐ Docs & packaging
ADR-092 (new) + index cross-references, HITL.md v8.5, ARCHITECTURE_LANGRAPH.md ยง2.6/ยง2.8, GRAFANA_DASHBOARDS.md label warning, knowledge base, HOW ยง9.5 / WHY ยง8.4 guides and in-app FAQ changelog in all 6 languages.
No schema change, no migration. One new optional env var: FOR_EACH_STOP_FORCES_SEQUENTIAL.
Quality: Ruff / Black / MyPy strict clean (863 files); 8501 backend unit tests green (+32 new, incl. two compiled replay harnesses); every commit passed the full pre-commit hook.
Full changelog: https://github.com/jgouviergmail/LIA-Assistant/blob/main/CHANGELOG.md
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About LIA
All releases โRelated context
Related tools
Beta — feedback welcome: [email protected]