247 lines
12 KiB
Markdown
247 lines
12 KiB
Markdown
# 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.
|