Skip to content

V2: Reconcile provider catalogs with /models endpoints #40524

Open

Description

@opencode-agent

Problem

V2 should reconcile each provider's model catalog with the provider's /models endpoint instead of relying only on a static or stale catalog.

Today this can fail in both directions:

  • models exposed by the provider may be missing from OpenCode
  • models no longer exposed or usable by the provider may remain selectable

That leaves new models unavailable and stale or irrelevant models visible until hardcoded metadata catches up.

Desired behavior

  • Fetch model availability from supported providers' /models endpoints.
  • Merge endpoint results with OpenCode metadata needed for capabilities, limits, variants, and display names.
  • Drop models that the authoritative endpoint does not expose or marks unavailable for the current account or organization.
  • Preserve explicitly configured custom models where appropriate.
  • Define fallback behavior when discovery is unsupported, unauthenticated, malformed, or temporarily unavailable.
  • Refresh without making startup or model selection depend indefinitely on a slow provider.

Acceptance criteria

  • A newly exposed provider model becomes selectable without a static catalog update when the endpoint supplies enough information.
  • A model removed from the endpoint is no longer offered unless explicitly configured or covered by a documented fallback.
  • Account- or organization-scoped model lists are respected.
  • Endpoint failures retain a usable bounded fallback and surface diagnostics without silently replacing a known-good catalog with an empty list.
  • Tests cover additions, removals, explicit overrides, scoped availability, malformed responses, and request failure/timeout.

Related scope

This is broader than generic OpenAI-compatible custom-provider discovery: it covers V2's model-catalog reconciliation and filtering semantics across providers that expose authoritative model-list endpoints.

Activity

  1. oscarcpozas commented on Aug 27, 2026

    @oscarcpozas

    Aixy is a concrete gateway use case for this reconciliation.

    Aixy exposes an authenticated, project-scoped GET /v1/models endpoint. It returns both provider-qualified direct models (for example openai/gpt-...) and tenant-defined virtual routing models in the aixy/<alias> namespace. The latter can be created or changed by the customer, so they cannot be represented in a global models.dev snapshot.

    The models.dev entry is still valuable as a metadata seed and bounded fallback, but runtime availability should come from the authenticated endpoint. Ideally OpenCode would:

    • reconcile models.dev metadata with /models;
    • add IDs returned only by the endpoint, including virtual models;
    • hide unavailable catalog entries for the current credential/project;
    • preserve explicit config overrides; and
    • fall back to the last known/static catalog on timeout or malformed responses.

    Aixy already returns the standard OpenAI model-list envelope and can be used to test account-scoped discovery. We would be happy to help validate the behavior, including virtual models whose capability metadata must represent the guarantees of the route rather than a single underlying model.

  2. pawel-adamczyk commented on Sep 3, 2026

    @pawel-adamczyk

    Confirmed against OpenCode Zen on Windows after upgrading the CLI to v1.18.27.

    This is an account-scoped provider-catalog gap, not a stale local config:

    • The authenticated GET https://opencode.ai/zen/v1/models response contains 8 models, including muse-spark-1.3-contributor-free and muse-spark-1.2-contributor-free.
    • The current Zen workspace has Muse Spark 1.3 Contributor Free enabled.
    • opencode models --refresh succeeds but still omits opencode/muse-spark-1.3-contributor-free; it only lists Muse 1.2 / 1.2 Contributor Free.
    • opencode models stealth --refresh reports Provider not found: stealth, even though the Zen workspace UI exposes the relevant upstream provider as Stealth.
    • The active Zen profile has no explicit model or models map, so this is not a local allow-list.

    The public Zen docs name the same model ID and document the authoritative model endpoint: https://dev.opencode.ai/docs/zen

    For Zen specifically, the desired reconciliation behavior is:

    1. fetch the authenticated /zen/v1/models response during provider discovery;
    2. use that account/workspace-scoped response to add and remove selectable opencode/<id> models;
    3. merge static metadata from models.dev when present, but do not hide endpoint-only models;
    4. retain a last-known-good cache with a visible freshness state when the endpoint fails;
    5. expose the same resolved list to ACP clients such as Zed after a new agent connection.

    This directly covers a model that is enabled for the account and officially documented, but cannot currently appear in the local picker without a manual configuration entry.

  3. pawel-adamczyk commented on Sep 3, 2026

    @pawel-adamczyk

    Additional verification for the Zen case: the exact endpoint-only ID muse-spark-1.3-contributor-free succeeds through a minimal direct request to the documented Zen Responses endpoint with the same credential. The local stock OpenCode client fails only because its refreshed catalog omits the model. This confirms that endpoint discovery must provide enough route/SDK metadata for the normal client execution path, not merely add a display entry.

  4. 4uva4ek commented on Oct 15, 2026

    @4uva4ek

    I built a manual version of this in my fork and would like to know if it fits before I open a PR.

    It adds a Sync button to each provider in Settings > Models. It calls POST /api/provider/:providerID/sync.

    • Remote providers: it fetches {baseURL}/models with the active credential. Missing chat models are added to the global config. Embedding, speech and image models are skipped. New models start hidden in the model picker.
    • Local providers (Ollama, LM Studio, vLLM): it forces the plugin to rediscover right away instead of waiting for the 30-second poll. Nothing is written to config.

    It only adds models and never removes them, so it covers the "missing models" half of this issue, not the full reconciliation.

    Branch: https://github.com/4uva4ek/opencode/tree/provider-model-sync

    Is a manual sync action like this acceptable as a step toward this issue, or would you prefer discovery to stay automatic only?

  5. neriousy commented on Oct 23, 2026

    @neriousy
    Member

    Preserving requirements from #58122: automatic model discovery should cover custom providers beyond OpenAI-compatible endpoints, with Anthropic explicitly requested. The report also points to the configured-provider/OpenAI-compatible slice in #57161 rather than treating it as the whole solution.

  6. scrossen commented on Oct 24, 2026

    @scrossen

    I’d keep the manual refresh, with remote discoveries cached per account/project rather than saved as user overrides. Your local-provider path already makes that distinction. For reconciliation, a successful empty list and a timeout deserve separate tests, with explicit user models preserved.

    Scott, Talavine Code maker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions