| Captured exchanges and continuation | Logical history, reusable branches, ordinary follow-up execution, exchange details and parent metadata | Which exchange to continue and which request to execute |
| Optional sequential coordinator | One branch's turn progression, additional-turn budget, callback delivery and cancellation checks | Response interpretation, next action, branch scheduling and broader failure policy |
| Optional execution groups | Explicitly selected observations, deduplication and execution-fact summaries | Membership selection, domain identifiers, final-report timing and presentation |
Continuation is independently usable. The coordinator builds on it; applications
can instead use their own loops. Groups work with ordinary runs as well as
continuations and require neither capture nor a coordinator. Selecting a group
does not change scheduling, capacity, cancellation, retries, or validation.
The scope is in-process use. Persistence, restartable workflows, cross-process
resumption, a conversation registry, batch reconciliation, and a branching-workflow
scheduler are outside this feature. Applications schedule branches, join results,
and decide whether one branch's failure should affect other work. This initial
scope is not a permanent prohibition on future capabilities.
## Captured Exchanges And Continuation
### Capture And Availability
Capture is opt-in per ordinary or prepared execution. Ordinary execution returns
the exchange alongside its usual result. A prepared handle retains the capture
choice; executing that exact prepared snapshot creates the exchange. Preparation
alone creates no completed exchange. Continuation implies capture so its result
can itself be continued.
Capture the request actually executed, including the complete rendered messages
with their content, roles, and cache metadata, followed by the full final
assistant content returned by the run. Consumers must not reconstruct the request
or pair a response with separately prepared data. “Full” means content supported
by PromptKit, not a new raw provider-envelope API.
Capture represents logical conversation history. Internal structural-repair
instructions and intermediate candidates are excluded; only the final returned
assistant content follows the original request. Existing attempt observations
| Completed response satisfying its output contract | Return the captured exchange. |
| Completed response with failed structural validation, including repair exhaustion | Return the exchange with the ordinary validation result intact. |
| Operational error with no completed result | Create no new exchange; the preceding exchange remains usable. |
| Completed response obtained before cancellation prevents coordinator delivery | Preserve that single undelivered response under the coordinator return contract. |
Capture does not imply structural validity or application acceptance. A completed
response with failed validation follows the normal coordinator callback path,
subject to cancellation; it is not reclassified as an operational error.
### Ownership And Reuse
An exchange is an immutable, reusable snapshot held by the caller. Continuing it
adds the rendered follow-up messages and final response to a new exchange, leaving
the source and independent branches unchanged. No previous templates or input
files need to be read or rendered again.
Another engine instance in the same process can continue the exchange, applying
its own configuration to the new request. The originating engine is not required.
This permits application engine replacement without promising serialized or
cross-process resumption.
Completed exchanges retain no backend admission lease, direct credential, or
execution callback. Ordinary Go memory management controls their lifetime; there
is no new `Close` or `Discard` lifecycle. The existing
[prepared execution handle](../../prepared_execution.go) remains a separate,
single-use execution capability.
### Exchange Details
Provide explicit access to the held exchange's logical message history, including
its final assistant content, originating run identity, and immediate parent
reference. Reuse existing run identifiers; no mandatory conversation, branch, or
sequence identifiers are introduced.
Follow the general pattern of `PreparedExecution.Details()`. Details must be
generically renderable through ordinary encoders. Reading or modifying returned
values must not affect retained history or another branch. Inspection reads the
snapshot without rendering, loading inputs, or making provider calls.
Existing results and preparation details continue to supply ordinary execution
information. Exchange inspection does not create a second comprehensive report,
a result archive, or an engine-level conversation lookup API. `InspectPrompt`,
`InspectProfile`, and `InspectBackend` keep their resource-inspection boundary.
Captured message content remains separate from metadata-only observations.
## Optional Sequential Coordinator
The coordinator starts from a captured exchange and executes one branch using
an application callback, a caller-selected additional-turn budget, and context.
The callback selects a new ordinary request, stops, or returns an error. It can
keep application state in a closure; PromptKit defines no domain-state or
feedback schema.
### Progression And Budget
With an active context, invoke the initial callback once, even with a zero-turn
budget. It receives the starting exchange and remaining budget; the starting
exchange is not a newly delivered response. Existing application findings can
be used without repeating earlier assessment.
After each continuation, deliver its completed response once through the same
callback before starting another execution, including the final permitted
response. Internal retries and structural repairs do not create extra callbacks.
| Callback action | Coordinator behavior |
| --- | --- |
| Stop | Return application-directed completion, including after the last permitted response. |
| Continue with budget remaining | Start the selected continuation. |
| Continue without budget remaining | Return exhaustion without executing the requested turn. |
| Error | Stop and propagate the error, subject to context checks. |
The budget permits at most N additional continuation executions to start.
Starting a continuation consumes one turn even if preparation or generation
fails. The initial exchange and callback invocations consume no turns; internal
transport retries and structural repairs stay within one turn. The first
operational error stops coordination, without refunds or recovery machinery.
Using the full budget alone does not mean exhaustion: exhaustion means the
application requested more work than the budget permits. The budget does not
bound provider attempts, cost, or work inside callbacks. Applications wanting
no callback work can skip the coordinator entirely.
### Cancellation And Failures
Check context immediately before every callback, including the initial callback.
If cancellation is already observed, skip delivery and return the context error
with its identity preserved. Retain a completed response already obtained but
not yet delivered; do not recover raw output from an underlying failed call that
returned no completed result.
Callbacks receive the same context and cooperate with cancellation. Check it
again after the callback returns and before starting another execution.
Cancellation may race with invocation; PromptKit does not forcibly terminate
callback code or promise callback delivery despite cancellation or panic.
An execution or callback error stops coordination. Preserve ordinary Go error
identities, including `errors.Is`/`errors.As`. Do not automatically replay the
failed continuation or callback. Ordinary transport retries and structural repair
remain execution-internal. Earlier deliveries and application work remain intact;
the application owns any broader consequences.
### Minimal Return Contract
Return only:
- An ordinary Go error for execution failure, callback failure, or cancellation.
- A small normal outcome distinguishing application-directed stop from budget
exhaustion; neither outcome is an error or a claim about content acceptance.
- An optional single completed response when cancellation prevented callback
delivery, reusing existing response types where practical.
Delivery means callback invocation, not successful processing or acceptance. If
the callback returns an error, its response is already delivered and is neither
returned as undelivered nor replayed. Previously delivered responses are not
archived in the termination result. No additional failure hierarchy, failure-stage
fields, run-ID references, or aggregate reporting is added to this contract.
Existing response and observation fields remain available; group summaries are
obtained separately.
## Shared Execution And Accounting Rules
### Follow-Up Configuration
A continuation is an ordinary new execution supplied with captured history.
Resolve its prompt, profile, credentials, output contract, and request overrides
using the receiving engine's existing rules. In particular:
- Use an explicit request profile or the follow-up prompt's default profile,
with ordinary missing-profile behavior when neither is available.
- A supplied output contract completely replaces the default; do not merge it
with or inherit the preceding execution's contract.
- Resolve credentials for the new execution; retained history does not preserve
the original direct key.
- Select session ID from the new request or follow-up prompt's session template.
Do not implicitly inherit it. Applications may explicitly reuse a session ID;
ancestry does not depend on one.
History introduces no additional execution-setting precedence. The follow-up
can change model or response schema without altering the original exchange.
Exact assembly order for captured history, follow-up definition messages, and
caller-appended messages remains an API-planning detail; preserve authored roles.
### Capacity And Application Work
Compose completed executions. Finish each turn and release its logical admission
lease before calling application code. Releasing only the active generation
permit is insufficient under the existing [run flow](../internal/runner.md#run-flow).
Each later execution acquires ordinary admission.
The coordinator holds no backend capacity while awaiting callback work.
Callbacks may inspect responses, consult data, wait for application input, or
call the same engine and backend, including when backend capacity is one.
### Ancestry And Per-Run Accounting
Each continuation retains its own originating run ID and exposes its immediate
parent exchange's run ID. Parent metadata describes history provenance; group
membership describes application-selected accounting. Neither implies the other.
A validator can join a continuation's accounting group without extending its
conversation.
Reuse ordinary per-run usage and observations, including attempt, retry, repair,
failure-path, and usage-presence/completeness semantics. Preserve the existing
[observation boundary](../internal/observation.md): arbitrary nested calls are
independent executions. Do not infer membership from a callback's purpose or
context.
If initial run A supplies branches B and C, its usage belongs only to A. B and C
do not inherit that cost. Usage reported for resending captured history in B and
C still belongs to those new runs. Count selected runs once each; never add
terminal totals to the attempt events they already summarize.
## Optional Execution Groups
### Explicit Membership And Observer Composition
Use an observer-compatible collector attached explicitly to selected executions.
Prepared requests retain the selection; membership starts when execution emits
observations. Preparation alone, discarded handles, and failed claims do not
enroll runs through observations.
Coordinator selection covers its continuation runs. Callback-initiated calls
require their own explicit selection. Neither nested context nor a captured
starting exchange automatically enrolls another run.
Support an application's existing diagnostic observer alongside one or more
collectors through a small observer-composition helper. Preserve synchronous
delivery and existing panic behavior. Do not introduce asynchronous queues,
panic recovery, or guaranteed delivery to later observers after an earlier one
panics; interrupted delivery can leave accounting incomplete.
A run may explicitly belong to multiple independent groups. Each group counts
its run identity once. Applications obtain operation-level and overall views by
attaching the corresponding collectors to each selected run. Overlapping totals
are not generally additive; no group hierarchy, inherited membership, or merging
facility is needed.
### Concurrent Snapshots And Lifetime
Provide detached, internally consistent snapshots from a caller-held group while
selected executions and snapshot reads may occur concurrently. Reading or
modifying a snapshot must not change the collector or another snapshot. There
is no mandatory close, seal, or wait lifecycle. Applications own scheduling and
decide when to read or discard the group.
Distinguish observed runs with terminal observations from those without them.
Missing terminal observations mean incomplete accounting; the group does not
infer whether work is active, delivery was interrupted, or another cause applies.
It promises no terminal delivery beyond ordinary observation semantics.
“All observed members have terminal observations” does not mean the application
operation is complete. More runs can join later, and PromptKit cannot know whether
the application selected all relevant calls. The application chooses when a
snapshot represents its final report.
### Summary Contents
The initial summary exposes:
- Member run identities and terminal-observation coverage.
- Existing provider-attempt, transient-retry, and structural-repair counters.
- Available token totals with per-field known/completeness information.
Aggregate one terminal observation per run. These observations already summarize
retries, repairs, and available failure-path usage, including executions returning
no ordinary result. Do not reconstruct totals from attempts.
Keep terminal coverage distinct from usage completeness. A terminal observation
may itself have incomplete usage. Two finished runs with fully reported usage
provide a useful known subtotal, but a third observed run lacking a terminal
event leaves group accounting incomplete. Preserve existing usage semantics and
expose missing coverage separately; unavailable evidence must not become known
zero.
Live attempt-level totals and duration aggregation are omitted from the initial
implementation. Applications can use existing events for progress displays. If
durations are later added, summed execution durations must be distinguished from
elapsed group time. Groups supply execution facts, not monetary cost, application
outcomes, or an application-wide reporting framework. Applications retain domain
mappings, interpretation, and report assembly.
## Consumer Sketches
These are pseudocode, not selected exported names or implemented Go APIs.
Each begins with an already captured exchange and uses ordinary follow-up request
selection. Both omit application-specific error handling, including checks for
failed structural validation before schema-specific decoding.
### Analysis Loop
The application records responses and selects its next question or decides that
its investigation is complete. PromptKit retains history and executes the turns.