From f3cd09a65d01e299033f60d2c0ec13a66ed183f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Troed=20S=C3=A5ngberg?= Date: Fri, 21 Aug 2026 12:15:28 +0200 Subject: [PATCH] docs: design spec for provider-list based discovery --- ...26-08-21-provider-list-discovery-design.md | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-21-provider-list-discovery-design.md diff --git a/docs/superpowers/specs/2026-08-21-provider-list-discovery-design.md b/docs/superpowers/specs/2026-08-21-provider-list-discovery-design.md new file mode 100644 index 0000000..e1012f2 --- /dev/null +++ b/docs/superpowers/specs/2026-08-21-provider-list-discovery-design.md @@ -0,0 +1,58 @@ +# Provider-list based discovery for oc-ls-stats + +Date: 2026-08-21 +Status: Approved design, pending implementation plan +Follows: 2026-08-21-explicit-server-option-design.md + +## Problem + +Server discovery parses the raw config object (`config.provider[key].options.baseURL`), +coupling the plugin to the config-file layout. OpenCode exposes `api.state.provider`, +a typed, resolved list of providers gathered from all sources (`env`, `config`, +`custom`, `api`). Depending on the raw config shape is less future-proof and misses +non-config sources. + +## Goal + +Use the resolved provider list for detection while keeping compatibility with +hosts that do not populate it. + +## Decision + +- New pure function `extractProviderUrlsFromList(providers: unknown): string[]` in + `src/stats.ts`. Accepts an SDK-shaped array of `{ id, name, options }` records. + A provider matches when its `id` or `name` contains "llama" and neither contains + "ollama". URL extraction per provider is unchanged (`options.baseURL` or + `options.base_url`, string check, `stripBaseUrlPath`). +- Matching against `name` in addition to `id` is a deliberate superset of the old + key-only match: a provider whose display name mentions llama is now detected. + The explicit `server` option remains the precise override. +- `resolveServerUrls(options, providers, config)` gains a second source parameter. + Resolution order: explicit `server` → provider list → legacy config parse → + `http://localhost:8080`. The legacy config parse stays as a fallback for hosts + where the provider list is missing/unusable or yields no URLs. +- `tui.tsx` call site becomes `resolveServerUrls(options, api.state.provider, + api.state.config)`. + +## Changes + +- `src/stats.ts`: add `extractProviderUrlsFromList`; extend `resolveServerUrls` + signature and resolution order. Existing helpers unchanged. +- `tui.tsx`: update the single call site. +- `test-backoff.ts`: rewrite detection tests against provider-list fixtures; + keep one legacy-config fallback test; explicit-server tests updated for the new + signature only. +- `README.md`: Server Discovery wording ("resolved provider list", multi-source). +- `package.json`: version bump to 1.3.0 (explicit server option + this change). + +## Error handling + +Non-array provider input returns `[]` (falls through). Per-provider extraction +errors are impossible by construction (field checks); no new failure modes. + +## Testing + +1. Provider list: id match, name match, ollama exclusion, non-string baseURL ignored. +2. Explicit server still wins over provider list. +3. Empty/missing provider list falls back to legacy config parse. +4. Nothing anywhere → localhost fallback.