diff --git a/docs/roadmap/bundled-openrouter.md b/docs/roadmap/bundled-openrouter.md new file mode 100644 index 0000000..d87a4b7 --- /dev/null +++ b/docs/roadmap/bundled-openrouter.md @@ -0,0 +1,177 @@ +# Bundled OpenRouter Backend And Profiles + +## Status And Purpose + +Proposed; no implementation changes yet. + +Ship a small OpenRouter configuration collection 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 collection 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. + +### OpenRouter Backend + +Include a 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 proposed initial set contains these three model selections: + +| Proposed profile ID | OpenRouter model value | Purpose | +| --- | --- | --- | +| `openrouter/gpt-sol-latest` | `~openai/gpt-sol-latest` | Follow the current GPT Sol family model. | +| `openrouter/auto` | `openrouter/auto` | Delegate model selection to OpenRouter's auto router. | +| `openrouter/free` | `openrouter/free` | Select OpenRouter's free-model router. | + +These names distinguish PromptKit resource IDs from provider model values: +the tilde and slash in a provider model slug remain part of that value. +Additional latest-family aliases can be selected before implementation or added +later when useful; completeness across vendors is not a launch requirement. + +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 identity layout and diagnostic-metadata decisions below. Confirm + the initial profile list and current provider endpoint/model values. +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 + +### 1. Backend Identity And Collection Layout + +**Recommendation:** Put profiles in the `openrouter` collection with the local +IDs shown above, and put the backend in that collection as local ID `default`. +Profiles would reference `openrouter/default`. This keeps the bundle together, +avoids an ambiguous doubled provider name, and supports normal collection +inspection. Applications can still replace those exact IDs. + +**Alternative:** Use a root backend ID `openrouter` with namespaced profiles. +This is concise and may align better with existing operator catalogs. Its +drawback is splitting the bundle between root and collection resources, and +making a common root backend name the shared override target. Before choosing, +compare maintained OpenRouter catalog conventions; the layout should minimize +consumer confusion rather than establish a new naming restriction. + +### 2. Smoke-Test Metadata In The Bundled Backend + +**Recommendation:** Include only the endpoint and credential-variable name in +the initial backend. Existing diagnostic behavior remains available, and the +feature stays focused on configuration convenience without choosing a diagnostic +inference model or expanding the maintained provider-specific configuration. + +**Alternative:** Also provide the existing OpenRouter authentication diagnostic +configuration, after verifying its endpoint and behavior, while leaving the +inference smoke-test profile unselected. This makes the bundle more useful for +explicit preflight calls with little data, but adds another upstream convention +to maintain and test. Neither option implies automatic diagnostics during +construction or execution.