Finalize v0.18.0 notes and retire completed plans
This commit is contained in:
@@ -5,6 +5,29 @@ and derived queue-capacity defaults through ConfigKit v1.1.0. Engines also
|
||||
include a default-on OpenRouter configuration. The minimum supported Go
|
||||
version remains 1.27.0.
|
||||
|
||||
## Bundled OpenRouter Backend And Profiles
|
||||
|
||||
New engines include an embedded OpenRouter backend and seventeen root profiles:
|
||||
ten latest-family aliases, the auto and free routers, and five auto-router
|
||||
cost-tier variants. Select a profile explicitly in a prompt or request; the
|
||||
bundle does not supply an implicit execution profile or contact providers
|
||||
during construction. The backend uses `OPENROUTER_API_KEY` when available under
|
||||
the existing optional-credential rules.
|
||||
|
||||
The bundle is the lowest-priority underlay. Applications can replace its records
|
||||
or derive named variants through ordinary configuration, and external collections
|
||||
remain supported. Cost-tier variants inherit the effective `auto` profile, so
|
||||
replacing that parent changes their inherited target while retaining plugins.
|
||||
The [bundle reference](../formats.md#bundled-openrouter-configuration) owns the
|
||||
inventory and composition details.
|
||||
|
||||
Explicit smoke diagnostics now have OpenRouter authentication metadata and an
|
||||
inference fallback profile. They remain opt-in and may incur provider costs.
|
||||
Latest aliases and routers can change upstream; configured slugs do not pin
|
||||
the concrete model, pricing, or availability. See the
|
||||
[consumer guide](../consumers/pkg-promptkit.md#construct-an-engine) for selection
|
||||
and opt-out examples.
|
||||
|
||||
## Recorded Configuration Normalization
|
||||
|
||||
Inspection shows normalized backend and profile settings, prompt metadata, and
|
||||
@@ -24,7 +47,7 @@ Inventory listings and inspection sources therefore change, and references to
|
||||
bundled IDs that previously failed may now resolve. Pass
|
||||
`promptkit.WithBundledOpenRouter(false)` to retain application-only behavior.
|
||||
Caller records can replace bundled definitions through ordinary composition;
|
||||
see the [bundle inventory and precedence](../formats.md#bundled-openrouter-configuration).
|
||||
same-ID replacements replace complete records rather than merging selected fields.
|
||||
No configuration-format migration is required from v0.17.0.
|
||||
Consumers that display or compare configuration inspection results should account
|
||||
for normalized values and derived defaults replacing their earlier authored
|
||||
|
||||
@@ -1,246 +0,0 @@
|
||||
# Bundled OpenRouter Backend And Profiles
|
||||
|
||||
## Status And Purpose
|
||||
|
||||
Implemented: engine construction installs the embedded OpenRouter underlay by
|
||||
default, with an option to disable it and ordinary caller composition.
|
||||
|
||||
Ship a small OpenRouter configuration bundle with PromptKit so consumers
|
||||
can begin using named profiles without installing a separate catalog. Include
|
||||
the backend definition those profiles require. Keep separately maintained
|
||||
operator collections fully supported through the existing configuration path.
|
||||
|
||||
The bundle should favor provider-maintained latest aliases and routers, reducing
|
||||
the need for PromptKit releases just to refresh individual model versions.
|
||||
This is a convenience catalog, not an exhaustive model inventory or a promise
|
||||
of stable upstream model behavior.
|
||||
|
||||
## Historical Baseline
|
||||
|
||||
PromptKit depends on ConfigKit v1.1.0 and records field normalization and derived
|
||||
defaults during resolution. At that baseline it installed no backend or profile
|
||||
definitions. Consumers supply configuration inputs, which ConfigKit composes
|
||||
before PromptKit validates and materializes effective resources.
|
||||
|
||||
The existing [configuration format](../formats.md) supports root and namespaced
|
||||
resource lists, explicit IDs, sibling inheritance, and ordered underlays.
|
||||
A higher-layer same-ID resource replaces the lower record in full. Inputs in
|
||||
the same underlay group are strictly composed; file order is not precedence.
|
||||
The bundle can use these mechanisms without introducing another catalog loader
|
||||
or restoring the former dependency on provider-specific Go modules.
|
||||
|
||||
ConfigKit v1.1.0's normalization and inspection support will apply to bundled
|
||||
configuration just as it does to caller configuration. Layering itself predates
|
||||
that release; no further upstream enhancement is required for this feature.
|
||||
|
||||
## Target Behavior
|
||||
|
||||
### Ordinary Embedded Configuration
|
||||
|
||||
Embed a small YAML bundle in PromptKit and load it through the existing
|
||||
ConfigKit adapter. Place it in its own lowest-priority underlay, before every
|
||||
caller underlay and the main input. Preserve the existing order and grouping
|
||||
of caller inputs.
|
||||
|
||||
Enable the bundle by default, with `WithBundledOpenRouter(bool)` to disable or
|
||||
enable it explicitly.
|
||||
This follows the agreed convenience-oriented direction while preserving the
|
||||
ability to supply an application's complete catalog.
|
||||
|
||||
Bundling a profile makes it available for explicit selection by a prompt or
|
||||
request. It does not establish an implicit execution profile, change profile
|
||||
selection precedence, or send a network request during engine construction.
|
||||
Credentials remain runtime inputs under the existing credential rules.
|
||||
|
||||
Use ordinary configuration identities and expose the bundle through existing
|
||||
listing and inspection APIs. Source explanations should identify embedded
|
||||
configuration meaningfully. There is no need for a parallel built-in catalog
|
||||
API or special provenance model.
|
||||
|
||||
### Root Resource Layout
|
||||
|
||||
Use root entries for both the backend and all built-in profiles. The backend
|
||||
ID is `openrouter`; each bundled profile supplies or inherits
|
||||
`backend: openrouter` and is selected using its unqualified ID. No built-in `openrouter` collection is
|
||||
created, so an externally supplied collection can expose names such as
|
||||
`openrouter/gpt-sol-latest` alongside the root `gpt-sol-latest` profile.
|
||||
|
||||
Built-ins at the root and external libraries under `collections` is a
|
||||
convention, not an enforced distinction. Applications may supply root entries,
|
||||
override built-ins, and organize external configuration using either form.
|
||||
Root names favor convenient selection; their backend remains explicit in the
|
||||
definition and inspection even though it is absent from the profile ID.
|
||||
|
||||
### OpenRouter Backend
|
||||
|
||||
Include the root `openrouter` backend with OpenRouter's API base endpoint,
|
||||
`https://openrouter.ai/api/v1`, and the conventional environment-variable name
|
||||
`OPENROUTER_API_KEY`. Store the name only; no credential value belongs in the
|
||||
bundle. Reuse the existing OpenAI-compatible client and credential resolution.
|
||||
|
||||
Keep the backend minimal. Leave concurrency limits, queue policy, and provider
|
||||
request parameters to existing defaults or application configuration.
|
||||
|
||||
### Smoke-Test Defaults
|
||||
|
||||
Include the following metadata on the root `openrouter` backend:
|
||||
|
||||
```yaml
|
||||
smoke_tests:
|
||||
default_profile: gpt-luna-latest
|
||||
authentication:
|
||||
kind: openrouter_key
|
||||
```
|
||||
|
||||
Omit the reachability endpoint to use the existing backend-endpoint fallback.
|
||||
Omit the authentication endpoint to use the adapter's backend-relative `/key`
|
||||
destination. OpenRouter documents the authenticated
|
||||
[current-key endpoint](https://openrouter.ai/docs/api/api-reference/api-keys/get-current-api-key).
|
||||
|
||||
Use `gpt-luna-latest` as the inference diagnostic default when the caller supplies
|
||||
neither a prompt nor a profile. Explicit prompt/profile selection continues to
|
||||
follow existing smoke-test selection rules. The default names the effective
|
||||
root profile, so an application replacement of that profile also affects this
|
||||
fallback. Applications can change the backend metadata through ordinary
|
||||
configuration composition.
|
||||
|
||||
These defaults make explicit diagnostics usable without additional setup; they
|
||||
do not run tests automatically or establish a default for ordinary prompt
|
||||
execution. Results describe the selected diagnostic path, not backend-wide
|
||||
readiness. The inference smoke test makes a small request with potentially
|
||||
non-zero cost; no fixed cost or model-availability guarantee is introduced.
|
||||
|
||||
### Small Profile Set
|
||||
|
||||
The initial set contains seventeen root profiles:
|
||||
|
||||
| Profile ID | Intended model selection |
|
||||
| --- | --- |
|
||||
| `gpt-astra-latest` | OpenAI GPT Astra latest-family alias through OpenRouter. |
|
||||
| `gpt-sol-latest` | OpenAI GPT Sol latest-family alias (`~openai/gpt-sol-latest`). |
|
||||
| `gpt-terra-latest` | OpenAI GPT Terra latest-family alias through OpenRouter. |
|
||||
| `gpt-luna-latest` | OpenAI GPT Luna latest-family alias through OpenRouter. |
|
||||
| `claude-fable-latest` | Anthropic Claude Fable latest-family alias through OpenRouter. |
|
||||
| `claude-opus-latest` | Anthropic Claude Opus latest-family alias through OpenRouter. |
|
||||
| `claude-sonnet-latest` | Anthropic Claude Sonnet latest-family alias through OpenRouter. |
|
||||
| `claude-haiku-latest` | Anthropic Claude Haiku latest-family alias through OpenRouter. |
|
||||
| `gemini-pro-latest` | Google Gemini Pro latest-family alias through OpenRouter. |
|
||||
| `gemini-flash-latest` | Google Gemini Flash latest-family alias through OpenRouter. |
|
||||
| `auto` | OpenRouter auto router (`openrouter/auto`). |
|
||||
| `auto-low` | Inherits `auto`; sets cost tier `low`. |
|
||||
| `auto-medium` | Inherits `auto`; sets cost tier `medium`. |
|
||||
| `auto-high` | Inherits `auto`; sets cost tier `high`. |
|
||||
| `auto-xhigh` | Inherits `auto`; sets cost tier `xhigh`. |
|
||||
| `auto-max` | Inherits `auto`; sets cost tier `max`. |
|
||||
| `free` | OpenRouter free-model router (`openrouter/free`). |
|
||||
|
||||
These profile IDs are selected. The companion [implementation plan](implementation.md)
|
||||
records the exact provider `model` slugs checked against the public alias pages.
|
||||
Keep those mappings explicit rather than deriving them mechanically from IDs.
|
||||
If a requested alias becomes unavailable, surface that mismatch
|
||||
instead of silently substituting a pinned model or dropping the profile.
|
||||
The tilde and slash in a provider model slug remain part of that value; they
|
||||
do not change the root placement of the PromptKit profile.
|
||||
|
||||
Define each cost-tier profile using `extends: {id: auto}` and the matching
|
||||
`cost_tier` inside an `auto-router` plugin entry under `extra_params.plugins`:
|
||||
|
||||
```yaml
|
||||
profiles:
|
||||
- id: auto
|
||||
backend: openrouter
|
||||
model: openrouter/auto
|
||||
- id: auto-medium
|
||||
extends: {id: auto}
|
||||
extra_params:
|
||||
plugins:
|
||||
- id: auto-router
|
||||
cost_tier: medium
|
||||
```
|
||||
|
||||
Keep the base `auto` profile without an explicit cost tier. Link to
|
||||
[OpenRouter's cost-tier documentation](https://openrouter.ai/docs/guides/routing/routers/auto-router#cost-tier)
|
||||
for routing semantics rather than duplicating that explanation here.
|
||||
|
||||
Each profile should primarily specify or inherit its backend and model. Avoid
|
||||
baking in temperature, reasoning, token-budget, timeout, or capability assumptions merely
|
||||
to make profiles appear more complete. Operator profiles remain the place for
|
||||
application-specific tuning and fixed model versions.
|
||||
|
||||
OpenRouter documents the
|
||||
[GPT Sol latest alias](https://openrouter.ai/~openai/gpt-sol-latest),
|
||||
[auto router](https://openrouter.ai/docs/guides/routing/routers/auto-router), and
|
||||
[free router](https://openrouter.ai/docs/guides/routing/routers/free-router).
|
||||
Stable selectors reduce maintenance but do not freeze model selection, price,
|
||||
availability, supported parameters, or output behavior. Describe the free router
|
||||
as the provider's offering rather than adding PromptKit guarantees about future
|
||||
pricing or availability.
|
||||
|
||||
### Application Control And Compatibility
|
||||
|
||||
Applications may replace bundled records through higher configuration layers or
|
||||
disable the bundle and supply their own definitions. No namespace is reserved
|
||||
against operator use. A same-ID replacement is a complete replacement, so an
|
||||
application supplying only a new model value does not inherit the replaced
|
||||
profile's backend. A distinct sibling using `extends` remains the ordinary way
|
||||
to create a variant while retaining base fields.
|
||||
|
||||
These replacement semantics describe ordinary identified-list upsert behavior.
|
||||
Honor explicit ConfigKit sequence modes as well: `append` rejects duplicate
|
||||
identities, while `replace` replaces the complete lower list. The bundle adds no
|
||||
special conflict handling or exception to those composition rules.
|
||||
|
||||
Loading definitions by default changes inventory and inspection results, and
|
||||
previously unresolved references matching bundled IDs may become resolvable.
|
||||
Document these effects. Higher-layer application records take precedence under
|
||||
the applicable ConfigKit composition mode. Changing a bundled backend may
|
||||
also affect surviving bundled profiles that reference it; that is ordinary
|
||||
backend completion, not a special override exception.
|
||||
|
||||
The five cost-tier profiles inherit from the effective `auto` profile. An
|
||||
application replacement of `auto` can therefore change their inherited backend
|
||||
or model while their OpenRouter plugin settings remain present. Cover this
|
||||
interaction in a focused test and a short example note; it does not require a
|
||||
new restriction on replacing the parent.
|
||||
|
||||
Bundled profile and backend IDs are consumer-facing names. Review future removal
|
||||
or repurposing through the ordinary compatibility process, since application
|
||||
configuration may reference them. This does not introduce a separate catalog
|
||||
lifecycle or a guarantee that upstream aliases retain fixed behavior.
|
||||
|
||||
The embedded data ships with the PromptKit release. No catalog download or
|
||||
automatic refresh mechanism is planned. Provider aliases and routers may change
|
||||
their targets independently of that release; the inspected configured slug
|
||||
does not identify or pin the concrete model selected upstream.
|
||||
|
||||
## Acceptance And Documentation
|
||||
|
||||
The companion implementation plan owns the staged work. The integrated result
|
||||
should demonstrate:
|
||||
|
||||
- Default availability and full disabling through the ordinary configuration
|
||||
lifecycle, without construction-time provider or credential access.
|
||||
- Caller precedence, whole-record replacement, inherited variants, explicit
|
||||
append/replace modes, and coexistence with an external OpenRouter collection.
|
||||
- All five cost-tier profiles inheriting the effective `auto` backend/model,
|
||||
retaining their plugin settings even after parent replacement, and producing
|
||||
the expected top-level `plugins` array through the built-in HTTP client.
|
||||
- Listing and inspection of effective definitions with meaningful source evidence.
|
||||
- Explicit smoke diagnostics using backend endpoint fallbacks, authentication,
|
||||
inference defaults, explicit selection precedence, and effective application
|
||||
replacements of the default profile or backend metadata.
|
||||
|
||||
Offline HTTP tests establish payload construction, not provider acceptance.
|
||||
Credential-dependent live checks are not recurring test requirements. Existing
|
||||
credential behavior remains authoritative; coverage should focus on new
|
||||
integration risks rather than duplicate that suite.
|
||||
|
||||
The format reference, consumer guide, relevant GoDoc, and maintained examples
|
||||
should explain disabling, replacement, and inheritance. Release notes should
|
||||
identify inventory and inspection changes. Provider latest aliases and routers
|
||||
remain distinct from fixed models and carry no PromptKit upstream guarantees.
|
||||
|
||||
Keep current-state documentation unchanged until implementation lands. Retire
|
||||
this roadmap after the implemented behavior reaches its durable owners. No new
|
||||
configuration syntax or collection specification version is needed solely to
|
||||
distribute this data.
|
||||
@@ -1,304 +0,0 @@
|
||||
# Bundled OpenRouter Implementation Plan
|
||||
|
||||
Implement [bundled-openrouter.md](bundled-openrouter.md) in the sequential stages
|
||||
below. Each stage is one Luna-sized assignment. The feature roadmap owns scope
|
||||
and consumer policy; this document owns the implementation sequence and choices.
|
||||
|
||||
## Baseline And Working Rules
|
||||
|
||||
The baseline is `9e05c3a`: Go 1.27.0, ConfigKit v1.1.0, recorded field
|
||||
normalization, and no installed backend/profile catalog. The facade in
|
||||
`engine.go` applies options; `internal/engine.New` passes caller configuration
|
||||
to `internal/configuration.Load` before assembling execution collaborators.
|
||||
|
||||
Read `docs/development.md` and applicable agent, architecture, testing,
|
||||
documentation, OSS, and release policies. Follow
|
||||
[ADR 0001](../adr/0001-configuration-boundary.md). Reuse current source-loading,
|
||||
generation, and smoke-diagnostic contracts. Preserve unrelated changes.
|
||||
|
||||
This is one end-to-end sprint: intermediate stages need not compile or form a
|
||||
deployable state. Do not introduce compatibility scaffolding or intermediate
|
||||
human-review/publication gates. Record incomplete checks honestly and reuse
|
||||
successful checks for unchanged content. Do not publish a release or make paid
|
||||
provider requests. No dependency upgrade, configuration-version change, or
|
||||
provider-specific catalog module is required.
|
||||
|
||||
## Implementation Choices
|
||||
|
||||
- Add `internal/configuration/bundled/openrouter.yaml` and embed it from a small
|
||||
`bundled.go` in that package. Provide an internal exported
|
||||
`BundledOpenRouterUnderlay() configkit.Underlay` for engine assembly. It returns
|
||||
one input created through `configkit.NewFilesystem` and its `File` method,
|
||||
with a meaningful label such as `Promptkit bundled OpenRouter`.
|
||||
- Use the existing source loader once. Do not independently parse, validate,
|
||||
normalize, or cache a separate bundle registry before final composition.
|
||||
Tests inspect the assembled effective configuration, not raw-source validity.
|
||||
- Prepend the bundle as its own underlay in `internal/engine.New`. Allocate a
|
||||
new outer slice and copy caller groups so spare slice capacity cannot let
|
||||
assembly mutate caller-owned input. Preserve every caller group's contents,
|
||||
order, main input, imports, and source context.
|
||||
- Add `WithBundledOpenRouter(enabled bool) Option` in the facade. Add
|
||||
`disableBundledOpenRouter bool` to internal engine options and a setter
|
||||
`SetBundledOpenRouter(bool)` following existing setter style. The zero internal
|
||||
options value enables the bundle; the setter stores `!enabled`. Apply options
|
||||
in the existing order, so the last supplied bundle option wins. The facade
|
||||
only delegates; embedding and composition stay internal.
|
||||
- Disabled means no bundle source or definitions are installed. It does not
|
||||
reserve names, remove caller definitions, or disable the OpenAI-compatible
|
||||
client. Scoped views share the engine's captured configuration; they do not
|
||||
reload the bundle.
|
||||
- Keep the root backend and profiles described below. No built-in collection,
|
||||
prompts, implicit execution profile, tuning defaults, catalog download, or
|
||||
constructor-time provider/credential access is added.
|
||||
|
||||
## Exact Data To Install
|
||||
|
||||
The root backend is `openrouter`, with endpoint `https://openrouter.ai/api/v1`,
|
||||
`api_key_env: OPENROUTER_API_KEY`, and:
|
||||
|
||||
```yaml
|
||||
smoke_tests:
|
||||
default_profile: gpt-luna-latest
|
||||
authentication:
|
||||
kind: openrouter_key
|
||||
```
|
||||
|
||||
Leave concurrency, queue, provider parameters, and diagnostic endpoint overrides
|
||||
unset. Existing reachability and authentication endpoint fallback applies.
|
||||
|
||||
Use these exact root profile IDs and model values. Each non-cost-tier profile
|
||||
sets `backend: openrouter`. The ten family mappings were checked against the
|
||||
linked provider pages on 2026-11-03; this is authoring evidence, not a guarantee
|
||||
of future availability or a recurring release check.
|
||||
|
||||
| Profile ID | Model | Provider reference |
|
||||
| --- | --- | --- |
|
||||
| `gpt-astra-latest` | `~openai/gpt-astra-latest` | [Alias](https://openrouter.ai/~openai/gpt-astra-latest) |
|
||||
| `gpt-sol-latest` | `~openai/gpt-sol-latest` | [Alias](https://openrouter.ai/~openai/gpt-sol-latest) |
|
||||
| `gpt-terra-latest` | `~openai/gpt-terra-latest` | [Alias](https://openrouter.ai/~openai/gpt-terra-latest) |
|
||||
| `gpt-luna-latest` | `~openai/gpt-luna-latest` | [Alias](https://openrouter.ai/~openai/gpt-luna-latest) |
|
||||
| `claude-fable-latest` | `~anthropic/claude-fable-latest` | [Alias](https://openrouter.ai/~anthropic/claude-fable-latest) |
|
||||
| `claude-opus-latest` | `~anthropic/claude-opus-latest` | [Alias](https://openrouter.ai/~anthropic/claude-opus-latest) |
|
||||
| `claude-sonnet-latest` | `~anthropic/claude-sonnet-latest` | [Alias](https://openrouter.ai/~anthropic/claude-sonnet-latest) |
|
||||
| `claude-haiku-latest` | `~anthropic/claude-haiku-latest` | [Alias](https://openrouter.ai/~anthropic/claude-haiku-latest) |
|
||||
| `gemini-pro-latest` | `~google/gemini-pro-latest` | [Alias](https://openrouter.ai/~google/gemini-pro-latest) |
|
||||
| `gemini-flash-latest` | `~google/gemini-flash-latest` | [Alias](https://openrouter.ai/~google/gemini-flash-latest) |
|
||||
| `auto` | `openrouter/auto` | [Router](https://openrouter.ai/docs/guides/routing/routers/auto-router) |
|
||||
| `free` | `openrouter/free` | [Router](https://openrouter.ai/docs/guides/routing/routers/free-router) |
|
||||
|
||||
The five remaining profiles are `auto-low`, `auto-medium`, `auto-high`,
|
||||
`auto-xhigh`, and `auto-max`. Each uses `extends: {id: auto}` and only adds
|
||||
`extra_params.plugins: [{id: auto-router, cost_tier: TIER}]`, where TIER is its
|
||||
suffix. Do not duplicate backend/model in these children: they inherit the
|
||||
effective parent, including an application replacement. Base `auto` sets no
|
||||
cost tier. OpenRouter documents these five values and plugin spelling in its
|
||||
[cost-tier contract](https://openrouter.ai/docs/guides/routing/routers/auto-router#cost-tier).
|
||||
The [current-key endpoint](https://openrouter.ai/docs/api/api-reference/api-keys/get-current-api-key)
|
||||
documents the existing authentication adapter's destination.
|
||||
|
||||
Preserve `~` and `/` in model values; neither makes the profile namespaced.
|
||||
Do not add sampling, reasoning, timeout, token, or capability settings. If
|
||||
contradictory provider evidence appears, report it rather than silently selecting
|
||||
a fixed model or dropping a requested profile. A credentialed generation probe
|
||||
is not needed to implement this data-backed plan.
|
||||
|
||||
## Stage 1: Add The Embedded Configuration Source
|
||||
|
||||
Scope: new YAML and small helper in `internal/configuration`.
|
||||
|
||||
1. Define one root backend and seventeen root profiles exactly as above. Use
|
||||
ordinary identified lists and ConfigKit sibling inheritance for the five
|
||||
cost-tier children. No collection wrapper or prompt definitions are needed.
|
||||
2. Embed the file with `embed.FS`; expose only the internal underlay helper.
|
||||
Use a fresh public ConfigKit source/context for loading, without mutable
|
||||
package-level decoded data or filesystem discovery.
|
||||
3. Add a focused loader-level test composing that underlay through `Load`.
|
||||
Check the effective backend, the selected profile/model mapping, cost-tier
|
||||
inheritance, smoke metadata, and meaningful source evidence. These assertions
|
||||
protect the chosen catalog contents, not upstream model availability.
|
||||
4. Do not create raw-YAML validation or live-provider tests. No public catalog
|
||||
export, custom parser, catalog dependency, or parallel registry is needed.
|
||||
|
||||
Validation: `go test ./internal/configuration` after the helper is wired.
|
||||
|
||||
Completion: the embedded OpenRouter underlay and loader-level catalog test are
|
||||
in place; the focused configuration suite passed with Go 1.27.0.
|
||||
|
||||
## Stage 2: Enable The Bundle Through Engine Construction
|
||||
|
||||
Scope: facade/internal options, assembly, and default/disabled contract tests.
|
||||
|
||||
1. Implement the option and default-on internal flag as specified. Prepend the
|
||||
underlay only when enabled, using a new outer slice. Keep schema/client/
|
||||
artifact options and main-source handling unchanged.
|
||||
2. Add external-package facade tests showing `NewEngine(Config{})` exposes the
|
||||
root backend and all seventeen profiles, but creates no prompts or synthetic
|
||||
`openrouter` collection. Exercise representative `InspectProfile` values and
|
||||
`InspectConfiguration` source explanations.
|
||||
3. Test false disables installation, true retains it, and option ordering follows
|
||||
ordinary last-option behavior. With false, caller-owned `openrouter` records
|
||||
remain available. Construction succeeds with the API-key variable unset and
|
||||
an HTTP transport that rejects unexpected calls.
|
||||
4. Verify assembly leaves caller underlay slice/backing-array contents unchanged.
|
||||
5. Adapt preexisting tests whose intended fixture is an application-only or empty
|
||||
catalog by explicitly disabling the bundle in their local helpers. Update
|
||||
default-inventory expectations where that is the behavior under test. Do not
|
||||
globally hide default-on behavior or weaken not-found/validation assertions.
|
||||
Internal direct configuration-loader tests do not need to install the bundle.
|
||||
|
||||
Validation: focused construction/listing/inspection tests, then
|
||||
`go test ./internal/engine ./...` when intermediate wiring is coherent.
|
||||
|
||||
Completion: engine construction installs the bundle by default, with an
|
||||
ordered opt-out option and a copied underlay slice. Facade contracts and the
|
||||
full Go suite pass with Go 1.27.0.
|
||||
|
||||
## Stage 3: Protect Composition And Application Control
|
||||
|
||||
Scope: focused real-loader integration tests through the facade.
|
||||
|
||||
1. Verify a caller underlay and then the main input can replace a bundled ID in
|
||||
order, and caller strict groups remain strict. Demonstrate complete record
|
||||
replacement: a model-only replacement does not recover the old backend.
|
||||
Preserve partial-profile support rather than demanding construction readiness.
|
||||
2. Verify a distinct profile extending a bundled profile retains inherited
|
||||
fields and applies selected overrides. Add an application-provided OpenRouter
|
||||
collection with qualified references; root and collection profiles coexist.
|
||||
3. Replace root backend `openrouter` with a complete local endpoint definition.
|
||||
Confirm surviving bundled profiles use the replacement backend's settings.
|
||||
No reserved-ID checks or special merge semantics are added.
|
||||
4. Replace root `auto` with a profile selecting a different caller backend and
|
||||
model. All five cost-tier children must inherit that target and retain their
|
||||
plugin entries. Do not reject this customization or strip plugin settings.
|
||||
5. Exercise explicit sequence modes using ConfigKit's existing controls:
|
||||
`config.sequences: [{destination: [profiles], mode: append}]` with a duplicate
|
||||
bundled ID fails normally; `mode: replace` with an application profile list
|
||||
replaces all lower profiles. Include a nonconflicting append case. Keep
|
||||
backend/profile references valid where testing successful replacement.
|
||||
6. Show that clearing/replacing backend definitions without maintaining surviving
|
||||
profile references follows existing validation, not a hidden fallback.
|
||||
Disabling the bundle remains the simple application-only configuration path.
|
||||
|
||||
Validation: targeted new composition tests plus existing source, inheritance,
|
||||
namespace, and profile-completion tests. Avoid reproducing ConfigKit's generic
|
||||
sequence implementation suite.
|
||||
|
||||
Completion: facade integration tests cover caller precedence, whole-record
|
||||
replacement, inheritance, scoped resources, sequence modes, strict conflicts,
|
||||
and missing backend rejection. Targeted tests pass on Go 1.27.0.
|
||||
|
||||
## Stage 4: Verify Preparation And HTTP Request Construction
|
||||
|
||||
Scope: bundled-profile execution integration with existing runner/client paths.
|
||||
|
||||
1. With a minimal caller prompt and an injected deterministic client, prepare
|
||||
and run using an explicit bundled profile. Check selected profile/backend,
|
||||
model slug, and ordinary defaults/overrides. A prompt with no default and
|
||||
no request profile must still produce the existing profile-required error.
|
||||
2. For every cost tier, use the built-in HTTP client and an offline recording
|
||||
RoundTripper or local server to inspect the outbound JSON. Assert the model
|
||||
is `openrouter/auto` and `plugins` is a top-level array with the matching
|
||||
`auto-router`/`cost_tier` entry, not nested under an `extra_params` member.
|
||||
3. Verify base `auto` sends no explicit cost-tier plugin and `free` preserves
|
||||
`openrouter/free`. Check at least one `~`-prefixed model reaches the request
|
||||
unchanged. Return a minimal valid synthetic chat response.
|
||||
4. Reuse existing runtime credential tests and override tests. Add only missing
|
||||
bundle integration assertions, such as selecting `OPENROUTER_API_KEY` from
|
||||
the installed backend. No real credentials, calls, provider capability
|
||||
assumptions, hardcoded prices, or changes to optional-key behavior are needed.
|
||||
|
||||
Validation: new request cases and existing generation/profile/override tests.
|
||||
Offline HTTP assertions prove payload construction, not provider acceptance.
|
||||
|
||||
Completion: offline preparation, injected-client execution, and HTTP payload
|
||||
tests verify profile selection, overrides, credentials, router plugins, and model
|
||||
slugs. Focused execution tests pass on Go 1.27.0.
|
||||
|
||||
## Stage 5: Verify Bundled Smoke-Test Defaults
|
||||
|
||||
Scope: facade-level smoke integration with a synthetic HTTP boundary.
|
||||
|
||||
1. On a default engine, explicitly request reachability with
|
||||
`BackendID: openrouter`. Verify the existing backend-endpoint fallback.
|
||||
Authentication should select the `openrouter_key` adapter and
|
||||
`https://openrouter.ai/api/v1/key`, using an isolated synthetic key and a
|
||||
recording transport. Return the existing adapter's minimal success fixture.
|
||||
2. For text and structured inference, specify the backend without prompt/profile.
|
||||
Assert fallback to `gpt-luna-latest` and its exact model slug. Return suitable
|
||||
private-case responses using the existing smoke-test fixtures. Preserve
|
||||
factual reports and nil-error concluded-failure semantics.
|
||||
3. Show explicit profile selection wins over prompt default and backend metadata,
|
||||
and a prompt default wins over backend metadata when no profile is supplied.
|
||||
Smoke tests must still use their private cases, not execute caller prompt
|
||||
content or output contracts.
|
||||
4. Replace `gpt-luna-latest` through application configuration and verify fallback
|
||||
uses the effective replacement. Replace backend smoke metadata to select a
|
||||
different caller profile and confirm the ordinary selection path follows it.
|
||||
5. Verify listing/inspection are not modified by diagnostics. Keep the existing
|
||||
rule that diagnostics run only on explicit invocation; no new constructor,
|
||||
ordinary-run, CI, or release probe is introduced.
|
||||
|
||||
Validation: targeted bundled smoke tests and existing smoke contract/integration
|
||||
tests. Reuse existing endpoint/auth fixtures instead of adding an adapter or
|
||||
duplicating the full diagnostic suite.
|
||||
|
||||
Completion: offline smoke tests verify reachability, authentication, both
|
||||
inference cases, fallback and override selection, replacement behavior, and
|
||||
unchanged inspection. Targeted smoke tests pass on Go 1.27.0.
|
||||
|
||||
## Stage 6: Update Documentation And Verify The Sprint
|
||||
|
||||
Scope: public GoDoc, current guidance/examples, and end-to-end verification.
|
||||
|
||||
1. Update `ConfigurationSources`, `Config`/`NewEngine`, and new-option GoDoc to
|
||||
describe the dedicated lower underlay, default-on behavior, disabling, and
|
||||
changed inventories. Keep exact option semantics in GoDoc.
|
||||
2. Update `docs/formats.md` and `docs/consumers/pkg-promptkit.md` with the bundle,
|
||||
root layout, explicit selection, optional credentials, smoke fallback, and
|
||||
disabling/whole-record replacement/inherited-variant examples. Make one
|
||||
canonical bundle inventory in the format reference; link rather than repeat
|
||||
it throughout guidance. Link provider docs for alias/router behavior.
|
||||
3. Remove stale claims of no installed catalogs from current migration guidance
|
||||
and internal source/assembly documentation. Explain that an external
|
||||
collection is still supported, and replacing `auto` changes inherited child
|
||||
targets while retaining plugins. Do not add a rule that external catalogs
|
||||
must be namespaced or upstream aliases must have fixed capabilities.
|
||||
4. Keep the three maintained examples offline. Where their caller-only inventories
|
||||
are intentional, pass `WithBundledOpenRouter(false)` and explain that choice;
|
||||
retain useful fixture assertions rather than expanding them with unrelated
|
||||
default inventory. Add a short consumer-guide bundled-profile example instead
|
||||
of another live example program. Recheck README quickstart claims.
|
||||
5. Add the feature and compatibility effects to the currently untagged
|
||||
`docs/releases/v0.18.0.md`, including how to retain application-only behavior.
|
||||
Explain that previously unresolved references matching bundled IDs can now
|
||||
resolve, alongside the changed default inventories and inspection sources.
|
||||
If that release has been published by implementation time, use the next
|
||||
unreleased minor note instead; preserve published notes/tags. Follow the
|
||||
release procedure for the note/footer. No release operation is part of this
|
||||
sprint.
|
||||
6. Format changes, prepare dependency caches, and run with the compatible local
|
||||
Go toolchain:
|
||||
|
||||
```sh
|
||||
go test -race -vet=off ./...
|
||||
go vet ./...
|
||||
go run ./examples/go-library/prepare
|
||||
go run ./examples/go-library/run
|
||||
go run ./examples/go-library/observe
|
||||
git diff --check
|
||||
```
|
||||
|
||||
7. Review the complete diff for unexpected API changes, caller mutation, new
|
||||
source/history validation, implicit selection, network access, credential
|
||||
values, and stale links. Confirm only intended documentation and inventories
|
||||
changed. Follow the focused commit policy and record completion in the
|
||||
feature roadmap; retire completed plans during release preparation.
|
||||
|
||||
Completion requires default availability, full disabling, ordinary caller
|
||||
composition and provenance, correct cost-tier payloads and explicit diagnostic
|
||||
fallbacks, and current documentation. There are no unresolved product choices,
|
||||
external publication prerequisites, or new recurring release gates.
|
||||
|
||||
Completion: public guidance, GoDoc, offline examples, and the unreleased v0.18.0
|
||||
note describe the bundle and opt-out. The race-enabled suite, vet, three example
|
||||
commands, and diff checks passed on Go 1.27.0; no release was published.
|
||||
Reference in New Issue
Block a user