Document the v0.2.0 upgrade path
This commit is contained in:
@@ -31,6 +31,11 @@ Contributors should start with the [development guide](docs/development.md).
|
||||
The [architecture policy](docs/policy/architecture.md) defines the library
|
||||
boundary and constraints that framework work must preserve.
|
||||
|
||||
## Release Guidance
|
||||
|
||||
Consumers moving from `v0.1.0` to `v0.2.0` should read the
|
||||
[v0.2.0 changelog and migration guide](docs/releases/v0.2.0.md).
|
||||
|
||||
## Related Project
|
||||
|
||||
[Scriptorium](https://gitea.maximumdirect.net/eric/scriptorium) is the CLI and
|
||||
|
||||
@@ -78,6 +78,7 @@ mechanisms, not secret values.
|
||||
| Framework file formats | `docs/formats.md` | Prompt-definition and profile YAML fields, schema references, defaults, validation modes, built-in profiles, credentials, and file-to-request precedence. | Exported Go declarations, outbound wire behavior, internal parsing mechanics, and application configuration. |
|
||||
| Consumer guidance | `docs/consumers/`, when consumer workflows require dedicated guidance | Task-oriented use of implemented public APIs, minimal examples, and consumer responsibilities. | Exact exported declarations and internal mechanics. |
|
||||
| Durable integration contracts | `docs/integrations/`, when integrations exist | External formats and protocols, compatibility behavior, and upstream or downstream responsibilities. | Internal transformations and public Go declarations. |
|
||||
| Supplemental release guidance | None. `docs/releases/` may be used when a release benefits from a changelog or migration guide. | No canonical content. These files may briefly summarize release-specific changes, compatibility, and consumer migration paths, and may be corrected, consolidated, archived, or removed when no longer useful. | Public API and behavior contracts, formats, integrations, architecture, release procedure, and the authoritative annotated-tag release record. |
|
||||
| Implemented component inventory | `docs/internal/overview.md` | Current packages and components, their implemented responsibilities, and links to focused internal documents. | Normative architecture, contributor workflow, external contracts, and proposed components. |
|
||||
| Internal subsystem behavior | Other files under `docs/internal/`, when a subsystem needs durable detail | Implementation flow, internal collaborators and state transitions, package-local guarantees and failures, and relevant tests. | Global architecture invariants, public API definitions, and future package plans. |
|
||||
| Architectural decision history | `docs/adr/`, when repository-local decisions require records | Significant decisions, context, alternatives, rationale, consequences, and supersession history. | Current behavior reference, implementation status, and task sequencing. |
|
||||
@@ -85,9 +86,9 @@ mechanisms, not secret values.
|
||||
| Complete copyable artifacts | `examples/` | Valid inputs, Go programs, and other files intended to be copied or run. | Field-by-field reference, exact API declarations, and prose explanation. |
|
||||
|
||||
Conditional owners do not require placeholder files or directories. Create a
|
||||
consumer, integration, subsystem, ADR, roadmap, or example document only when
|
||||
the corresponding implemented interface, decision, planned effort, or
|
||||
maintained artifact exists.
|
||||
consumer, integration, release, subsystem, ADR, roadmap, or example document
|
||||
only when the corresponding implemented interface, release, decision, planned
|
||||
effort, or maintained artifact exists.
|
||||
|
||||
## Boundary Rules
|
||||
|
||||
@@ -109,6 +110,23 @@ but must link to its canonical definition rather than restate it.
|
||||
The [framework format reference](../formats.md) owns exact prompt, profile, and
|
||||
schema-file contracts. Integration documents own external wire formats.
|
||||
|
||||
### Supplemental Release Guidance
|
||||
|
||||
Files under `docs/releases/` may provide changelog-style summaries and
|
||||
migration guidance for a particular release. They are navigation and
|
||||
orientation aids, not canonical owners of public APIs, behavior, formats,
|
||||
integrations, architecture, release procedure, or other durable facts. When a
|
||||
reader needs detail beyond a short release-specific note, the release document
|
||||
must link to the applicable canonical documentation rather than reproduce its
|
||||
contract.
|
||||
|
||||
The annotated tag message required by the
|
||||
[release procedure](../release.md#write-the-release-note) remains the
|
||||
authoritative release record. Supplemental release documents may be corrected,
|
||||
consolidated, archived, or removed at any time when they are no longer useful,
|
||||
provided maintained documentation does not depend on them and the annotated
|
||||
tag record remains intact.
|
||||
|
||||
### Security Topics
|
||||
|
||||
This policy owns what documentation and examples may contain. Architecture owns
|
||||
@@ -160,6 +178,10 @@ durable owners, update incoming links, and archive or remove the roadmap
|
||||
according to repository practice. Do not preserve completed roadmaps as a
|
||||
second current-state reference.
|
||||
|
||||
Supplemental release documents may likewise be removed without preserving a
|
||||
replacement. Before removal, update maintained incoming links so current
|
||||
documentation does not depend on an optional historical guide.
|
||||
|
||||
Before completing documentation work:
|
||||
|
||||
- verify affected behavior and examples;
|
||||
|
||||
243
docs/releases/v0.2.0.md
Normal file
243
docs/releases/v0.2.0.md
Normal file
@@ -0,0 +1,243 @@
|
||||
# Promptkit v0.2.0
|
||||
|
||||
This supplemental changelog and migration guide summarizes the consumer-facing
|
||||
changes from `v0.1.0` to `v0.2.0`. The annotated `v0.2.0` tag is the
|
||||
authoritative release record. Exact current contracts belong to the linked
|
||||
GoDoc and durable documentation.
|
||||
|
||||
## Summary
|
||||
|
||||
`v0.2.0` adds three major capabilities:
|
||||
|
||||
- an engine-scoped registry for reusable OpenAI-compatible backend
|
||||
definitions;
|
||||
- bounded, backend-specific run admission and model-generation concurrency;
|
||||
and
|
||||
- direct per-run session IDs and tri-state reasoning-effort overrides.
|
||||
|
||||
Existing endpoint-only profiles remain supported. Consumers can adopt backend
|
||||
registration and runtime overrides incrementally rather than rewriting all
|
||||
profiles during the upgrade.
|
||||
|
||||
## Compatibility At A Glance
|
||||
|
||||
Promptkit remains pre-`v1`, and this minor release includes source-level and
|
||||
behavioral changes that deserve review.
|
||||
|
||||
| Area | `v0.1.0` consumer impact |
|
||||
| --- | --- |
|
||||
| Endpoint-only profiles | Continue to work without migration. |
|
||||
| Built-in profiles | Continue to use OpenRouter and `OPENROUTER_API_KEY`; they now select the built-in `openrouter` backend. |
|
||||
| Custom backends | Registration is optional. Existing profiles may keep their endpoint and credential configuration. |
|
||||
| Reasoning overrides | String assignments must migrate to the new pointer field. |
|
||||
| `RunRequest.Metadata` | Removed; delete assignments to this field. |
|
||||
| OpenRouter concurrency | Now limited to 16 active generations with waiting capacity of 1024 per engine. |
|
||||
| Public JSON | `v0.2.0` formalizes supported JSON representations; consumers relying on `v0.1.0` encodings should review the notes below. |
|
||||
| Unkeyed public struct literals | May require updates because fields were added. Keyed literals are recommended. |
|
||||
|
||||
## Upgrade
|
||||
|
||||
After the `v0.2.0` tag is published, update the module dependency with:
|
||||
|
||||
```sh
|
||||
go get gitea.maximumdirect.net/eric/promptkit@v0.2.0
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
Run the consuming project's ordinary tests and race-enabled tests after the
|
||||
upgrade, especially if it calls one engine concurrently or persists Promptkit
|
||||
JSON values.
|
||||
|
||||
## Backend Registry
|
||||
|
||||
Consumers may now register reusable OpenAI-compatible backend definitions with
|
||||
`WithBackend`, then select them by ID from file-backed or in-memory profiles.
|
||||
A backend can supply its endpoint, API-key environment-variable name,
|
||||
request-wide extra parameters, and optional capacity policy.
|
||||
|
||||
Registrations are immutable and belong to one engine. Consumer registrations
|
||||
can add new IDs but cannot replace Promptkit's reserved `openrouter` backend.
|
||||
Profiles that select a backend may still override its endpoint without losing
|
||||
the backend's routing or capacity identity.
|
||||
|
||||
An existing endpoint-only in-memory profile remains valid:
|
||||
|
||||
```go
|
||||
promptkit.Profile{
|
||||
ID: "local",
|
||||
Endpoint: "http://localhost:8000/v1",
|
||||
Model: "example-model",
|
||||
}
|
||||
```
|
||||
|
||||
Adopting the registry is optional and can be done when several profiles should
|
||||
share connection or capacity settings:
|
||||
|
||||
```go
|
||||
engine, err := promptkit.NewEngine(
|
||||
promptkit.Config{PromptDir: "prompts"},
|
||||
promptkit.WithBackend(promptkit.Backend{
|
||||
ID: "local",
|
||||
Endpoint: "http://localhost:8000/v1",
|
||||
APIKeyEnv: "LOCAL_LLM_API_KEY",
|
||||
}),
|
||||
promptkit.WithProfiles(promptkit.Profile{
|
||||
ID: "local-summary",
|
||||
BackendID: "local",
|
||||
Model: "example-model",
|
||||
}),
|
||||
)
|
||||
```
|
||||
|
||||
See the
|
||||
[custom-backend consumer guide](../consumers/pkg-promptkit.md#register-a-custom-backend)
|
||||
for task-oriented usage. The
|
||||
[`Backend` and `WithBackend` GoDoc](../../backends.go) owns exact registration,
|
||||
validation, copying, defaulting, and uniqueness semantics. The
|
||||
[framework format reference](../formats.md) owns the profile `backend` field
|
||||
and execution precedence.
|
||||
|
||||
## Backend-Specific Concurrency
|
||||
|
||||
Each registered backend may now define:
|
||||
|
||||
- an active model-generation limit; and
|
||||
- a bounded number of additional admitted `Run` calls.
|
||||
|
||||
Promptkit owns scheduling for both its built-in model client and an injected
|
||||
`LLMClient`. `Run` remains synchronous: an admitted caller waits for its
|
||||
ordinary result, while a call beyond the bounded admission capacity returns
|
||||
`ErrCapacityExceeded`. Capacity is engine-local and keyed by backend ID.
|
||||
Endpoint-only profiles and custom backends without a configured limit remain
|
||||
unlimited.
|
||||
|
||||
The built-in OpenRouter backend now permits 16 active generations and 1024
|
||||
additional admitted calls per engine. Applications that can exceed this bound
|
||||
should handle capacity exhaustion separately from provider and request
|
||||
failures:
|
||||
|
||||
```go
|
||||
result, err := engine.Run(ctx, request)
|
||||
if errors.Is(err, promptkit.ErrCapacityExceeded) {
|
||||
// Apply application-specific overload or retry policy.
|
||||
}
|
||||
```
|
||||
|
||||
Promptkit does not prescribe retries or map this error to an HTTP status. See
|
||||
the
|
||||
[concurrency consumer guidance](../consumers/pkg-promptkit.md#limit-backend-concurrency)
|
||||
and the [`Backend` GoDoc](../../backends.go) for the canonical configuration
|
||||
contract. Runtime behavior and public error identities belong to the
|
||||
[`Engine.Run` GoDoc](../../engine.go).
|
||||
|
||||
## Per-Run Session IDs
|
||||
|
||||
`RunRequest.SessionID` can now supply a consumer-managed correlation ID for one
|
||||
`Prepare` or `Run` invocation. A nonblank direct value overrides the prompt's
|
||||
session template and is exposed in prepared values, results, injected-client
|
||||
requests, and provider observability. Session IDs should therefore be stable,
|
||||
non-secret values.
|
||||
|
||||
```go
|
||||
result, err := engine.Run(ctx, promptkit.RunRequest{
|
||||
PromptID: "meeting.summary",
|
||||
SessionID: "conversation-42",
|
||||
})
|
||||
```
|
||||
|
||||
The built-in OpenAI-compatible client sends a nonempty effective session as the
|
||||
top-level `session_id` request-body field, not as an `x-session-id` header. See
|
||||
the
|
||||
[session and reasoning consumer guide](../consumers/pkg-promptkit.md#set-a-per-run-session-and-reasoning),
|
||||
the [`RunRequest` GoDoc](../../types.go), and the
|
||||
[OpenAI-compatible request contract](../integrations/openai-compatible-chat.md#request-body)
|
||||
for exact normalization, length, exposure, and wire behavior.
|
||||
|
||||
## Per-Run Reasoning Effort
|
||||
|
||||
`ExecutionTargetOverride.ReasoningEffort` changed from `string` to `*string` so
|
||||
one request can distinguish inheritance, replacement, and explicit clearing.
|
||||
|
||||
Update a `v0.1.0` override like this:
|
||||
|
||||
```go
|
||||
// v0.1.0
|
||||
Execution: &promptkit.ExecutionTargetOverride{
|
||||
ReasoningEffort: "high",
|
||||
}
|
||||
```
|
||||
|
||||
to:
|
||||
|
||||
```go
|
||||
// v0.2.0
|
||||
reasoning := "high"
|
||||
Execution: &promptkit.ExecutionTargetOverride{
|
||||
ReasoningEffort: &reasoning,
|
||||
}
|
||||
```
|
||||
|
||||
The three states are:
|
||||
|
||||
- `nil` inherits the selected profile's value;
|
||||
- a pointer to a nonblank string replaces it for that invocation; and
|
||||
- a pointer to an empty or whitespace-only string clears it for that
|
||||
invocation.
|
||||
|
||||
This allows consumers to consolidate profiles that differed only by reasoning
|
||||
effort. The [`ExecutionTargetOverride` GoDoc](../../types.go) owns the exact
|
||||
override contract.
|
||||
|
||||
## Other Migration Notes
|
||||
|
||||
### Remove `RunRequest.Metadata`
|
||||
|
||||
`RunRequest.Metadata` is no longer part of the public request. Remove any
|
||||
assignment to that field. Use application-owned state keyed by `RunResult.RunID`
|
||||
or a direct `SessionID` when correlation is needed; these identifiers have
|
||||
different purposes, so choose according to the application's lifecycle.
|
||||
|
||||
### Review Persisted JSON
|
||||
|
||||
`v0.2.0` defines stable JSON representations for the public result, artifact,
|
||||
execution, validation, and model-client values listed in the
|
||||
[package documentation](../../doc.go). Consumers that treated `v0.1.0`
|
||||
reflection-derived encodings as stable should update fixtures and stored-data
|
||||
adapters.
|
||||
|
||||
In particular:
|
||||
|
||||
- `RunResult` encodes elapsed time as integer milliseconds in `duration_ms`
|
||||
instead of encoding `time.Duration` under `duration`;
|
||||
- result JSON can include the new `session_id` and `selected_backend_id`
|
||||
fields;
|
||||
- execution-target JSON can include `backend_id`; and
|
||||
- artifact and target-presence fields now use their documented lower-case
|
||||
names.
|
||||
|
||||
The `v0.2.0` `RunResult` decoder reads `duration_ms`; it does not translate a
|
||||
persisted `v0.1.0` `duration` field. Transform old payloads before decoding
|
||||
when preserving their elapsed duration matters.
|
||||
|
||||
### Prefer Keyed Struct Literals
|
||||
|
||||
New fields were added to several public structs. Replace positional composite
|
||||
literals with keyed literals so future additive fields do not cause another
|
||||
source migration.
|
||||
|
||||
## Migration Checklist
|
||||
|
||||
- Update the module dependency and run the consumer's tests.
|
||||
- Change reasoning overrides from strings to pointers.
|
||||
- Remove uses of `RunRequest.Metadata`.
|
||||
- Review unkeyed Promptkit struct literals.
|
||||
- Decide whether shared endpoints should move into registered backends.
|
||||
- If using built-in OpenRouter profiles at high concurrency, handle
|
||||
`ErrCapacityExceeded` and review the new engine-local bound.
|
||||
- Review stored JSON, fixtures, and downstream decoders.
|
||||
- Optionally replace profile-specific session or reasoning variants with
|
||||
per-run overrides.
|
||||
|
||||
For complete consumer workflows, use the
|
||||
[package consumer guide](../consumers/pkg-promptkit.md) and maintained
|
||||
[offline execution example](../../examples/go-library/run/main.go).
|
||||
Reference in New Issue
Block a user