Preserve canonical model transcripts end to end#179
Merged
Conversation
Capture provider responses once, enforce lossless replay and stream contracts, and keep Temporal workflow state aligned with the selected model invocation.
Convert lossless JSON numbers to Smithy-supported numeric types so Bedrock receives valid tool schemas instead of quoted numeric constraints.
Treat the first text, citation, or reasoning delta as the block boundary because Bedrock only emits explicit content-block starts for tool use.
Bedrock can emit an empty initial tool-input fragment; retain the open tool block without publishing an invalid empty typed chunk.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A model turn should have one durable truth.
Previously, the runtime could rebuild a transcript from planner-facing events after the provider had already produced a richer ordered response. That created two competing representations of the same turn. Thinking blocks, citations, tool metadata, ordering, usage, or raw JSON could be lost or reshaped; retries could associate a plan with the wrong invocation; and provider history could become invalid when replayed.
This PR makes the provider-authored response canonical from receipt through workflow persistence and replay. Planners still receive the events they need, but those events are now a projection of the response—not a second transcript source.
What changes
How it works
This removes the old transcript ledger and collapses response ownership into a single path.
Contract impact
This intentionally strengthens several public contracts:
model.Chunkis now a typed interface, and streams terminate withStopChunkplus a canonicalStreamer.Response().Review guide
A useful dependency order is:
runtime/agent/model,rawjson, andtranscriptruntime/agent/runtime/model_invocation_journal.goand workflow transcript handlingfeatures/model/gateway,runtime/agent/planner, andruntime/agent/completionValidation
make lintgo test -race ./...