Skip to content

Discover OpenCode model list from opencode models #727

Description

@dcellison

Parent

Part of #705.

Summary

OpenCode model availability should come from OpenCode's own catalog command, opencode models [provider], instead of a static Kai model list. OpenCode already owns the provider/model namespace and runtime resolution. Kai should expose that catalog in /models where possible, while keeping direct /model <provider/model> input as the escape hatch.

Current state

Kai's OpenCode backend launches opencode acp and passes the selected model through OPENCODE_CONFIG_CONTENT as {"model":"<provider/model>"}.

OpenCode model validation in Kai currently checks only structural shape: the value must look like provider/model. This is the right runtime escape hatch because OpenCode ultimately decides whether the provider and model can run.

models_for_backend("opencode") currently returns no picker catalog, so OpenCode users get free-text model entry rather than a discoverable model list.

Kai currently has a static OpenCode provider list for first-class provider configuration. That list should not be treated as the complete OpenCode catalog boundary. OpenCode has providers under the backend, and the practical model list depends on OpenCode's installed version, local auth, configured providers, and its upstream model registry.

Problem

OpenCode model freshness has two axes that should not be collapsed into one static Kai table.

First, OpenCode supports providers and model IDs in provider/model form. That catalog is owned by OpenCode and its model source, not by Kai.

Second, Kai only needs to know which provider surfaces it intentionally supports for configuration, auth preservation, documentation, and defaults. Kai does not need to mirror every provider OpenCode could theoretically support.

A static Kai model list would go stale quickly and would duplicate data OpenCode already exposes. Fetching OpenCode's upstream model registry directly from Kai would also bypass the local OpenCode installation, provider config, auth state, and any OpenCode-specific filtering behavior. The safe source of truth is the installed OpenCode CLI under the effective Kai user.

Research notes

OpenCode documents model IDs as provider/model and uses provider-specific catalogs surfaced through the CLI.

OpenCode CLI exposes opencode models [provider] to list available models. It also supports --refresh, which refreshes OpenCode's model cache from its upstream registry, and --verbose, which returns richer metadata for each model.

Local command checks showed opencode models deepseek returning current DeepSeek model IDs in provider/model form. This matches the provider currently relevant to Kai's OpenCode path.

Local command checks also showed that not every provider documented by OpenCode is necessarily available in a given installation or configuration. That reinforces that Kai should ask OpenCode what is available instead of assuming a global provider universe.

Relevant public docs:

Desired behavior

For the OpenCode backend, /models should populate from opencode models [provider] under the same effective OS user and environment that Kai uses to run OpenCode.

When the current OpenCode provider is known, Kai should query opencode models <provider> and show those provider/model IDs.

When no provider filter is available, Kai may either query the unfiltered opencode models output if it is practical for the UI, or present a provider-first selection flow limited to the configured Kai OpenCode providers.

Kai should keep accepting direct /model <provider/model> input even when a model is not present in the discovered picker, because OpenCode can support custom or newly available models before Kai has refreshed.

A user-visible refresh path should call opencode models --refresh [provider] or the equivalent command ordering supported by OpenCode, then rebuild the cached picker list.

If OpenCode returns provider-not-found, auth failure, missing binary, malformed output, or a timeout, Kai should show a clear message and keep free-text /model <provider/model> available.

Scope

  • Add an OpenCode model discovery path backed by opencode models [provider].
  • Parse the CLI output into selectable provider/model IDs for /models.
  • Cache discovered results with freshness metadata scoped to the effective Kai user and provider.
  • Provide an explicit refresh path that invokes OpenCode's refresh behavior instead of silently refreshing on every picker render.
  • Keep structural validation for direct /model <provider/model> input.
  • Document that OpenCode provider availability is owned by the local OpenCode installation and configuration.
  • Add tests that mock OpenCode CLI output, refresh behavior, empty results, provider-not-found errors, missing binary, timeout, and malformed output.

Out of scope

  • Expanding Kai's OpenCode provider list to every provider OpenCode can document or support.
  • Treating OpenRouter or Ollama as active Kai targets for this issue.
  • Managing OpenCode provider authentication or creating provider accounts.
  • Fetching Models.dev directly as Kai's primary source of truth.
  • Changing OpenCode defaults automatically when a new model appears.
  • Replacing direct /model <provider/model> input with picker-only selection.

Acceptance criteria

  • OpenCode users can open /models and see discovered model IDs from opencode models [provider] for the configured provider path.
  • The displayed values preserve full provider/model IDs and selecting one stores the same value Kai passes to OpenCode.
  • Direct /model <provider/model> still works for structurally valid OpenCode model IDs even if discovery is unavailable or stale.
  • Discovery and refresh run under the same effective user and environment used for OpenCode execution.
  • Discovery failure does not break OpenCode model selection. The UI explains the failure and leaves free-text entry available.
  • Cached results are scoped so one user's OpenCode catalog cannot leak into another user's picker.
  • Defaults remain curated and stable. Newly discovered models become selectable but do not automatically become defaults.
  • Tests cover successful provider-specific discovery, refresh, missing provider, no models, malformed output, missing binary, timeout, and fallback to free-text behavior.
  • Documentation explains the three distinct concepts: Kai-supported OpenCode provider configuration, OpenCode-discovered model availability, and curated Kai defaults.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions