You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(llm/flow/replay): review wf_6783a4b3 — CRITICAL history poisoning + 9 majors
CRITICAL: max_rounds bail in BOTH tool loops (B-G4 run_tool_loop, B-G3
run_flow_loop) left the already-recorded assistant{tool_calls} unpaired —
every later request 400s on strict providers, permanently bricking the
session (the backstop fired exactly when models loop). Both loops now write
synthetic terminal results ("aborted: max rounds") for the final batch
before stopping; pinned with a history-pairing audit in the capped-loop test.
- ConversationHistory trim is pair-aware: evictions never leave a leading
orphan tool result (the same 400-forever shape) — pinned.
- Tool-result batches append under ONE history-lock acquisition
(add_tool_results_batch): a concurrent turn's user message can no longer
interleave inside a batch (persisted pairing corruption).
- B-G5 double-commit closed: once the initial inference completes (recorded
with its preamble), the streamed accumulator is cleared before the tool
loop — a cancel inside the loop no longer commits the preamble twice.
- spoke-flag fix: a turn that streamed a round-0 preamble then ran the tool
loop now SPEAKS the loop's final answer (was: bot permanently silent after
"let me check..."); pinned end-to-end through the orchestrator with a
preamble+tool_calls SSE mock.
- Flows: stale pending_transition from an aborted turn is discarded at the
next turn's start (state machine no longer jumps nodes uncommanded);
initialize() routes entry-inference tool calls through the flow loop
(lookup-then-greet nodes work; no dangling tool_calls from turn one);
flow MAX_ROUNDS bail pairs terminal results (same critical shape);
persona is tracked EXPLICITLY (seeded from the client's configured
system_prompt, updated by role_message) instead of inferred from
history[0] — embedders wiring flows from the standard config keep their
system instruction.
- D-G1: clear() now keeps the most recent ~250ms onset window (a final
never covers audio still in flight — clear-all lost the next utterance's
first syllables when the socket died before the next final); clear_all()
added for teardown; chaos choreography re-pinned (pre-window audio never
replays, onset survivor may, tail byte-identical in order).
- Cheap hardening from the unverified tail: orchestrator tool-loop guard
requires a NON-EMPTY registry; continue_from_history injects the system
prompt on an empty session instead of sending an empty messages array;
LiveKit forwarder warn properly rate-limited (1 per 100 sheds) and its
doc now matches the newest-drop behavior it implements.
Floor: 6094/0 lib (all features) + chaos 6/6 + conversation_loop 10/10 +
flow_manager 7/7 + clippy clean.
Live: Sarvam tool loop, 3-node intake flow, Deepgram nova-3 STT roundtrip
all green post-fix.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0 commit comments