Document conversation capture and continuation contracts

This commit is contained in:
2026-11-14 14:26:39 +00:00
parent 5aae5df5fb
commit c23393b2cc
5 changed files with 31 additions and 2 deletions

View File

@@ -697,6 +697,10 @@ its opaque rendered-prompt hash before invoking `RunPrepared`.
### Capture And Continue A Conversation
The [request GoDoc](../../types.go), [exchange GoDoc](../../exchange.go), and
[prepared-execution GoDoc](../../prepared_execution.go) own the exact capture,
continuation, inspection, and lifetime contracts.
Capture records the messages actually executed and the final assistant content.
An exchange is an immutable in-process capability; `Details()` returns detached,
encodable history that may contain sensitive content. Ordinary result encoding

View File

@@ -43,7 +43,11 @@ group members on each incremental update.
## 1. Complete The Public Exchange Capture And Continuation Contract
**Priority:** P2. **Status:** Open. **Plan stage:** 13.
**Priority:** P2. **Status:** Complete. **Plan stage:** 13.
**Completion:** Expanded the public request, exchange, details, and prepared-handle
GoDoc and linked the consumer walkthrough to those owners. Checked comments
against capture, preparation, and repair behavior; local links and diff verified.
**Locations:** [request fields](../../types.go),
[exchange declarations and accessor](../../exchange.go), and

View File

@@ -7,17 +7,28 @@ const exchangeString = "promptkit.Exchange{opaque}"
// Exchange is an immutable, reusable in-process snapshot of a completed
// conversation. It is not a persistence or restart format. Different engines
// can continue it, and independent branches do not alter one another.
//
// History preserves the effective request's message content, roles, and cache
// metadata, followed by the exact final [RunResult.RawOutput] as an assistant
// message. Intermediate structural-repair candidates and corrective instructions
// are excluded. A continuation extends that logical history according to
// [RunRequest.ContinueFrom], without changing its source exchange.
type Exchange struct{ internal *domain.Exchange }
// ExchangeDetails contains a detached copy of an exchange's logical history.
type ExchangeDetails struct {
RunID string `json:"run_id"`
// RunID identifies the execution that produced this exchange.
RunID string `json:"run_id"`
// ParentRunID identifies the immediate source execution, or is empty.
ParentRunID string `json:"parent_run_id,omitempty"`
Messages []RenderedMessage `json:"messages"`
}
// Details returns detached history, or zero details for a nil or empty handle.
// Messages include caller and model content and require appropriate handling.
// Inspection uses only retained state, without rendering, filesystem reads, or
// provider calls. Mutating returned messages or cache metadata cannot affect
// this exchange, another branch, or subsequent Details calls.
func (e *Exchange) Details() ExchangeDetails {
if e == nil || e.internal == nil {
return ExchangeDetails{}

View File

@@ -15,6 +15,9 @@ const preparedExecutionString = "promptkit.PreparedExecution{opaque}"
// A successful PrepareExecution may retain an Observer function in this
// handle's private payload. The callback and other private execution settings
// are cleared on claim completion or Discard. Details never exposes them.
// It also retains RunRequest.CaptureExchange and RunRequest.ContinueFrom for
// execution of the frozen snapshot. Only RunPrepared can produce its completed
// [Exchange]; preparation alone does not.
type PreparedExecution struct {
internal *usecase.PreparedExecution
}

View File

@@ -87,10 +87,17 @@ const (
type RunRequest struct {
// CaptureExchange requests an immutable snapshot of a completed run, even
// when its structural validation fails. Operational errors return no result.
// The snapshot is returned in RunResult.Exchange; see [Exchange] for its
// logical history contract. Prepare and ValidateRequest create no exchange.
// PrepareExecution retains this choice for its eventual RunPrepared call.
CaptureExchange bool
// ContinueFrom supplies captured history and implies capture of the new run.
// A non-nil zero-value exchange is invalid. Follow-up settings are selected
// normally and are not inherited from the exchange.
// Messages are assembled as captured history, rendered definition messages,
// then AppendedMessages. Prior templates and inputs are not rendered or read
// again. Continuation adds no history-size limit or truncation; upstream
// rejection follows the ordinary generation-error contract.
ContinueFrom *Exchange `json:"-" yaml:"-"`
// PromptID is the required prompt identifier. A namespace-scoped engine view
// qualifies a slashless caller value; otherwise it selects the exact