Files
promptkit/docs/roadmap/bundled-openrouter.md

201 lines
11 KiB
Markdown

# Bundled OpenRouter Backend And Profiles
## Status And Purpose
Proposed; no implementation changes yet.
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.
## Current Baseline
PromptKit depends on ConfigKit v1.1.0 and records field normalization and derived
defaults during resolution. It currently installs 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 a public engine option to disable it entirely.
This follows the agreed convenience-oriented direction while preserving the
ability to supply an application's complete catalog. Choose the exact option
name during implementation using existing facade conventions.
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 references `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
metadata is a separate decision below; bundling does not automatically run
diagnostics or select an inference smoke-test profile.
### Small Profile Set
The initial set contains twelve 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`). |
| `free` | OpenRouter free-model router (`openrouter/free`). |
These profile IDs are selected. Confirm the exact provider `model` slugs for
all family aliases during implementation rather than deriving them mechanically
from profile IDs. If a requested alias is 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.
Each profile should primarily specify 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).
Verify the chosen slugs against current provider documentation when implementing.
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.
Loading definitions by default changes inventory and inspection results, and
previously unresolved references matching bundled IDs may become resolvable.
Document these effects. Existing valid application records at higher layers
continue to win through normal composition. Changing a bundled backend may
also affect surviving bundled profiles that reference it; that is ordinary
backend completion, not a special override exception.
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.
## Implementation Work
1. Resolve the diagnostic-metadata decision below. Verify the provider endpoint
and exact model values for the twelve selected root profiles.
2. Add the embedded YAML backend and profiles, and integrate their dedicated
underlay with engine construction. Add the disable option using the existing
facade option pattern. Apply the ordinary load/normalize/validate lifecycle.
3. Verify default availability, disabling, caller precedence, whole-record
replacement, and inherited variants through the real configuration loader.
Include an application-provided OpenRouter collection and a replaced backend
to exercise interaction with external catalogs.
4. Verify listing and inspection reflect effective definitions and meaningful
source evidence. Exercise request preparation with a fake client or local
server as appropriate; construction must not depend on provider reachability
or a live API key. Reuse existing credential tests and add coverage only for
new integration behavior.
5. Update the format reference, consumer guide, relevant GoDoc, and maintained
examples when implementation lands. Explain how to disable, replace, or derive
from bundled profiles, and distinguish routers/latest aliases from fixed
models. Include the inventory/inspection change in release notes.
Keep current-state documentation unchanged until implementation lands. Retire
this roadmap after the behavior and remaining decisions reach their durable
owners. No new configuration syntax or collection specification version is
needed solely to distribute this data.
## Open Decisions
### Smoke-Test Metadata In The Bundled Backend
**Recommendation:** Include `smoke_tests.authentication.kind: openrouter_key`
using the existing adapter's backend-relative `/key` endpoint. Leave a separate
reachability endpoint and inference `default_profile` unspecified. The adapter
already exists, so this is a small configuration addition that makes explicit
API-key diagnostics useful out of the box without choosing an inference model.
OpenRouter documents the authenticated
[current-key endpoint](https://openrouter.ai/docs/api/api-reference/api-keys/get-current-api-key).
Its acceptance of a key is evidence about that endpoint, not a guarantee that
an arbitrary inference request will succeed.
This revises the initial recommendation to omit diagnostic metadata: given the
existing adapter and the bundle's convenience purpose, the added utility seems
worth maintaining the small declaration. The decision remains open pending
maintainer agreement.
**Alternative:** Include only the backend endpoint and credential-variable name.
This keeps the shipped configuration smaller and leaves diagnostic declarations
entirely with the consumer, but applications wanting authentication diagnostics
must configure the existing adapter themselves. Ordinary inference is unaffected.
Either approach uses existing diagnostic APIs and execution rules. Neither
implies automatic diagnostics during construction or execution. Selecting a
built-in inference smoke-test default would be a separate choice; this proposal
leaves callers able to select a profile explicitly without prescribing one.