Skip to content

feat(reconciler): repair broken client transcripts before persist#73

Merged
manojp99 merged 1 commit into
mainfrom
feat/reconciler-repair
Jun 23, 2026
Merged

feat(reconciler): repair broken client transcripts before persist#73
manojp99 merged 1 commit into
mainfrom
feat/reconciler-repair

Conversation

@manojp99

Copy link
Copy Markdown
Collaborator

Why

The CLI face's _runtime.py:_repair_loaded_transcript_if_needed() runs diagnose_transcript / repair_transcript (from amplifier_foundation.session) before replaying a resumed session — catching orphaned tool_use without paired tool_result, ordering violations, and incomplete assistant turns. Without this, providers (notably Anthropic) reject the next LLM call with HTTP 400.

The HTTP face had no equivalent. _reconciler.py:reconcile_client_history would overwrite the stored copy with whatever the client sent (broken or not), the runner would replay it as-is, and Anthropic would return 400. This gap was discovered because _session_runner.py was a copy-and-adapt of make_turn_handler that dropped the repair step.

What changed

src/amplifier_agent_http/_reconciler.pyreconcile_client_history now runs Layer-1 repair as Step 1, before the store.save persist:

  1. Annotates messages with line_num (required by foundation's incomplete-turns fallback path)
  2. Calls diagnose_transcript — returns immediately on healthy transcripts (<10ms, pure)
  3. On broken transcripts: calls repair_transcript, strips line_num from output, logs a WARNING with failure_modes/orphaned_tool_ids/session_id for operator visibility
  4. Persists the (now repaired) view and returns it

Healthy transcripts are identity-equal after the pass — no mutation, no overhead beyond the diagnostic call.

tests/http/test_reconciler.py — 3 new tests (8 existing pass unchanged):

  • test_reconciler_repairs_orphaned_tool_use_before_persist — broken transcript (OpenAI-style orphaned tool_calls) is repaired; no unmatched tool call ids in result
  • test_reconciler_healthy_transcript_passes_through_unchanged — healthy transcript is identity-equal after the pass
  • test_reconciler_logs_warning_with_failure_modes_on_repaircaplog captures WARNING containing failure_modes= and the session_id

CHANGELOG.md — entry under [Unreleased] ### Changed.

Mirror CLI face's _repair_loaded_transcript_if_needed pattern in the
HTTP chat-completions reconciler. Catches orphaned tool_use, ordering
violations, and incomplete assistant turns before they reach the
provider — without this, Anthropic returns HTTP 400.

Healthy transcripts pass through unchanged (Layer 1 diagnostic is
<10ms). The repair runs as Step 1 of reconcile_client_history, before
the store.save persist.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
@manojp99 manojp99 merged commit 7be99bd into main Jun 23, 2026
2 of 3 checks passed
manojp99 added a commit that referenced this pull request Jun 23, 2026
Cuts v0.9.0 release with chat-completions session resume, client-authoritative
reconciliation, and zero-config opencode session continuity via X-Session-Id header.

See CHANGELOG.md [0.9.0] for details: PR #71, #72, #73.

Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-authored-by: Manoj Prabhakar Paidiparthy <mpaidiparthy@microsoft.com>
Co-authored-by: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
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