Document and demonstrate execution controls

This commit is contained in:
2026-11-14 17:47:55 +00:00
parent 3de3e60c0c
commit 8831ae35f7
11 changed files with 131 additions and 16 deletions

View File

@@ -581,6 +581,59 @@ retained callback without invoking it. The function's closure is retained by
identity, so synchronize any shared state it uses. Prepared start events can
include identities already resolved in the frozen snapshot.
## Bound Execution And Retain Prepared Details
Select the optional controls on [RunRequest](../../types.go). The operation
budget is separate from the provider timeout and cancellation is cooperative.
Notification is conditional on reaching the prepared point, synchronous, and
runs while admission is held; its caller-owned details can be retained even if
generation later fails. Do not rely on notification for preparation or admission
failures. The application owns any subsequent diagnostic handling.
```go
var details *promptkit.PreparedRun
result, err := engine.Run(ctx, promptkit.RunRequest{
PromptID: "answer", OperationTimeout: 30 * time.Second,
OnPrepared: func(_ context.Context, prepared promptkit.PreparedRun) { details = &prepared },
})
if errors.Is(err, promptkit.ErrOperationTimeout) && errors.Is(err, context.DeadlineExceeded) {
// details is available only if the notification was reached.
}
```
For coordinated turns, put the controls on each returned request. Assessment
in the next-turn callback runs after the previous admission and child scope
are released, so it can select its own budget:
```go
next := func(ctx context.Context, turn promptkit.ConversationTurn) (*promptkit.RunRequest, error) {
if turn.Result != nil {
_, err := engine.Run(ctx, promptkit.RunRequest{PromptID: "assessment", OperationTimeout: 10 * time.Second})
return nil, err
}
return &promptkit.RunRequest{PromptID: "answer", OperationTimeout: 30 * time.Second,
OnPrepared: func(_ context.Context, prepared promptkit.PreparedRun) { details = &prepared }}, nil
}
```
For split execution, [PrepareExecution](../../engine.go) retains the controls
without starting their timer; idle time does not count. Use the same caller
deadline for both calls if preparation and execution need one shared bound.
```go
handle, err := engine.PrepareExecution(ctx, promptkit.RunRequest{
PromptID: "answer", OperationTimeout: 30 * time.Second,
OnPrepared: func(_ context.Context, prepared promptkit.PreparedRun) { details = &prepared },
})
if err != nil { return err }
defer handle.Discard()
result, err := engine.RunPrepared(ctx, handle)
```
See the [observation example](../../examples/go-library/observe/main.go) for an
offline coordinated workflow and [ErrOperationTimeout](../../engine.go) for
timeout attribution.
## Execute And Validate
[`Engine.Run`](../../engine.go) performs the same preparation, invokes the

View File

@@ -14,6 +14,9 @@ The public projection retains private operation-owner metadata separately from
inspectable child causes. Terminal classification uses that owner, preserving
context precedence and generation-specific transport/provider details rather
than mistaking a collaborator's nested lookup error for the parent's operation.
Timeout attribution is finalized and the child scope released before terminal
delivery, so observer latency cannot change the already selected outcome.
Prepared-content notification is a separate opt-in callback, not an event.
The facade masks inherited recorder and prepared-claim state when entering
preparation or execution. Delegated calls from an injected collaborator retain

View File

@@ -14,7 +14,7 @@ contributor workflow and validation.
| Root `promptkit` package | Provides the supported engine facade, ConfigKit source helpers, collection and resource mapping conveniences, injection options, public requests and results, resource and requirement inspection and identity inventories, concrete-request validation, explicit smoke diagnostics, observation values, opaque prepared-execution handles, value conversion, redacted formatting, and typed capacity and generation error mapping. | [Package GoDoc](../../doc.go), [observations](../../observations.go), [prepared execution](../../prepared_execution.go), [backend API](../../backends.go), [engine facade](../../engine.go), [smoke diagnostics](../../smoke_diagnostics.go), [identity listing](../../listing.go), [requirement facade](../../requirements.go) |
| `examples/go-library/prepare` | Demonstrates offline preparation from two explicitly selected synthetic collections, source-relative imported content, a scoped view, filtered listings, and operator inventory. It is not a public library package. | [Example program](../../examples/go-library/prepare/main.go), [collection inputs](../../examples/go-library/prepare/collections/support/collection.yaml) |
| `examples/go-library/run` | Demonstrates an offline downstream consumer using a prompt file, programmatic profile, inline input, an injected deterministic model client, and `Run`. It is not a public library package. | [Example program](../../examples/go-library/run/main.go) |
| `examples/go-library/observe` | Demonstrates offline built-in HTTP retry and synchronous metadata observation across structured proposal and assessment runs using embedded sources, two profiles on one finite backend, and an application decision. It is not a public library package. | [Example program](../../examples/go-library/observe/main.go) |
| `examples/go-library/observe` | Demonstrates offline retry, observation, prepared notification, and separately budgeted coordinated proposal and assessment runs using two profiles on one finite backend. It is not a public library package. | [Example program](../../examples/go-library/observe/main.go) |
| `internal/backend` | Holds a defensive, immutable lookup of final backend definitions, including diagnostic metadata, plus capacity policies validated by the configuration adapter. | [Backend registry](../../internal/backend/registry.go) |
| `internal/configuration` | Loads root and namespaced resources through ConfigKit; validates final values, captures indexed resource views and source-relative prompt content, compiled templates, requirement metadata, identity inventories, backend and presence-aware execution profiles, and the read-only provenance inspection view. | [Typed loader](../../internal/configuration/load.go), [identity listing](../../internal/configuration/listing.go), [internal sources](sources.md#typed-configuration-loading) |
| `internal/capacity` | Owns engine-local bounded execution admission and FIFO model-generation permits for limited backend IDs, including cancellation-safe waiter removal and client wrapping. | [Internal capacity management](capacity.md) |

View File

@@ -209,6 +209,16 @@ mapping and after the runner's deferred admission release. Preparation and
prepared execution follows the same terminal mapping after a successful claim;
invalid or discarded handles do not acquire an observer.
The facade establishes an optional operation scope for ordinary runs before
observation and preparation. A claimed prepared execution establishes its own
scope from the retained duration; preparation and idle time do not consume it.
The shared scope finalizer marks only a context failure caused by that scope's
own deadline, preserving its underlying operation and cause. The scope is
released before terminal delivery. At the shared prepared execution boundary,
the runner conditionally invokes the adapter for the actual prepared snapshot
while admission is held, with context checks before and after notification.
The facade adapter projects a detached public value only when selected.
Validation preparation and execution honor cancellation at every
Promptkit-controlled boundary and do not publish a partial plan or result.
Schema reads are bounded and context-checked between chunks; JSON decoding,

View File

@@ -398,6 +398,8 @@ be redesigned solely because its ordinary run gained options.
## Stage 8: Document, Demonstrate, And Validate The Assembled Feature
Status: complete.
Outcome: the implementation and its supported consumer workflow are complete,
with documentation in the canonical owners.