Skip to content

JVNAUTOSCI-2517 Restore stable live LLM exchange/call IDs - #289

Merged
witbrock merged 1 commit into
mainfrom
JVNAUTOSCI-2517-live-llm-ids
Jun 14, 2026
Merged

witbrock merged 1 commit into
mainfrom
JVNAUTOSCI-2517-live-llm-ids

Conversation

@witbrock

Copy link
Copy Markdown
Member

Summary

Restores the producer half of the live-LLM exchange identity contract. 2515 (thinking-card recovery surfacing) added the consumer side — von_routes preserves call_id/llm_exchange_id from progress updates and chatTab.js groups live LLM rows by them — but the orchestrator stopped emitting those IDs, so live rows fell back to fragile composite keys. tests/backend/test_orchestrator_live_llm_call_ids.py was red (helpers removed; _build_live_llm_progress_payload no longer accepted the IDs).

What changed

  • _build_live_llm_exchange_id — deterministic per-exchange id (stage, workflow stage, prepared timestamp, request shape), prefixed llm-.
  • _build_live_llm_call_id — per-attempt id {exchange}:attempt:{n}.
  • _build_live_llm_progress_payload — accepts and emits llm_exchange_id/call_id.
  • Both _run_llm_with_fallbacks and _run_llm_with_tools_fallbacks compute one exchange id per prepared request; the prepared emit carries it directly, and attempt_meta (spread into every per-attempt lifecycle event: sent/received/completed/cancelled/failed) carries the exchange id + the attempt's call id. So every live lifecycle event carries the identity at top level — exactly the surface von_routes preserves and chatTab.js groups on.

This completes 2515's contract rather than reverting it; it's a faithful restoration of the design originally introduced in JVNAUTOSCI-2398/2447.

Tests

  • test_orchestrator_live_llm_call_ids.py — now green (helper + payload contract).
  • New test_run_llm_with_fallbacks_emits_stable_live_llm_exchange_identity — proves the orchestrator emits one shared exchange id with distinct per-attempt call ids through the real fallback path.
  • test_tool_progress_liveness.py (route serialisation side) green; test_orchestrator_model_fallback_execution.py green.

🤖 Generated with Claude Code

The live Thinking card groups a prepared/sent/received/completed/failed
LLM lifecycle (and each fallback attempt) by call_id / llm_exchange_id,
with von_routes preserving those IDs from progress updates and chatTab.js
grouping on them. The orchestrator producer side was missing, so live LLM
rows fell back to fragile composite keys (test_orchestrator_live_llm_call_ids
was red: the _build_live_llm_exchange_id / _build_live_llm_call_id helpers
were gone and _build_live_llm_progress_payload no longer accepted the IDs).

Restore the producer contract:
- _build_live_llm_exchange_id: deterministic per-exchange id (stage,
  workflow stage, prepared timestamp, request shape) prefixed "llm-".
- _build_live_llm_call_id: per-attempt id "{exchange}:attempt:{n}".
- _build_live_llm_progress_payload: accept and emit llm_exchange_id/call_id.
- Thread a single exchange id through both _run_llm_with_fallbacks and
  _run_llm_with_tools_fallbacks: the prepared emit carries it directly, and
  attempt_meta (spread into every per-attempt lifecycle event) carries the
  exchange id plus the attempt's call id.

Adds a production-wiring test proving the orchestrator emits one shared
exchange id with distinct per-attempt call ids through the real fallback
path, alongside the restored helper/payload unit contract.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@witbrock
witbrock merged commit 9a1a8a0 into main Jun 14, 2026
4 checks passed
@witbrock
witbrock deleted the JVNAUTOSCI-2517-live-llm-ids branch June 14, 2026 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant