anomalyco / anomalyco/opencode

GitHub Copilot provider shows zero models: all models return `model_picker_enabled: false`

Open
#42,083 9 comments 5 reactions 1 assignee View on GitHub

@nexxeln is already working on this.

Since Aug 12, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Summary

On opencode 1.18.15 (Arch package), the github-copilot provider never appears in the model picker. opencode auth login -p github-copilot works (auth succeeds), but opencode models github-copilot returns "Provider not found", and /models in the TUI shows no Copilot models.

Root cause

In packages/opencode/src/plugin/github-copilot/copilot.ts, the models() hook returns only models where result.pickerEnabled.has(model.api.id):

return CopilotModels.get(...)
  .then((result) => {
    models = result.models
    return Object.fromEntries(
      Object.entries(result.models).filter(([, model]) => result.pickerEnabled.has(model.api.id)),
    )
  })

pickerEnabled (built in models.ts:257) is the set of models with model_picker_enabled: true in the API response:

pickerEnabled: new Set([...remote].filter(([, item]) => item.model_picker_enabled).map(([id]) => id)),

GitHub's GET https://api.githubcopilot.com/models currently returns model_picker_enabled: false for every single model — even ones that are policy.state: "enabled" and fully usable. So pickerEnabled is always empty, the filter drops everything, and the provider surfaces zero models.

Evidence

Using a valid, freshly-authenticated Copilot OAuth token (device flow, client_id=Ov23li8tweQw6odWQebz):

HTTP 200, total models: 47
policy states:  disabled: 18 | none: 23 (internal: copilot-search-*, exec-agent-*) | enabled: 6
model_picker_enabled=true: 0

The 6 policy.state: "enabled" models (gpt-4o, gpt-5-mini, claude-haiku-4.5, gpt-4.1, mai-code-1-flash, mai-code-1.1-flash) pass the existing usable() check (models.ts:207), and chat completions against them work fine:

POST https://api.githubcopilot.com/chat/completions → 200, "Hi there! ..."

So the account/subscription is fine — the filter is the problem. Note: exchanging the OAuth token for a Copilot session token via api.github.com/copilot_internal/v2/token and using that against /models returns 403, so the session-token route is not a workaround either.

Suggested fix

Filter by the already-existing usable() predicate (policy.state !== "disabled" + has max_output_tokens/max_prompt_tokens + has tool_calls) instead of, or in addition to, model_picker_enabled. Either:

  • Return result.models (already filtered by usable() inside CopilotModels.get) without the pickerEnabled filter, or
  • Union pickerEnabled with the usable set.

model_picker_enabled appears to be a deprecated/no-longer-reliable signal from GitHub's API.

Workaround

A local plugin overriding the provider's models() hook to return all usable models (same usable() criteria, no picker filter) restores all 25 available Copilot models:

// ~/.config/opencode/plugins/copilot-picker-fix.js
export const CopilotPickerFix = async () => ({
  provider: {
    id: "github-copilot",
    async models(provider, ctx) {
      if (ctx.auth?.type !== "oauth") return provider.models
      const base = ctx.auth.enterpriseUrl
        ? `https://copilot-api.${ctx.auth.enterpriseUrl.replace(/^https?:\/\//, "").replace(/\/$/, "")}`
        : "https://api.githubcopilot.com"
      const r = await fetch(`${base}/models`, {
        headers: { Authorization: `Bearer ${ctx.auth.refresh}`, "User-Agent": "opencode/1.18.15", "X-GitHub-Api-Version": "2026-06-01" },
        signal: AbortSignal.timeout(5000),
      })
      if (!r.ok) return provider.models
      const j = await r.json()
      const models = {}
      for (const m of j.data || []) {
        if (m.policy?.state === "disabled") continue
        const lim = m.capabilities?.limits
        if (!lim?.max_output_tokens || !lim?.max_prompt_tokens) continue
        if (m.capabilities?.supports?.tool_calls === undefined) continue
        const isMsg = m.supported_endpoints?.includes("/v1/messages")
        models[m.id] = {
          id: m.id, providerID: "github-copilot",
          api: { id: m.id, url: isMsg ? `${base}/v1` : base, npm: isMsg ? "@ai-sdk/anthropic" : "@ai-sdk/github-copilot" },
          status: "active",
          limit: { context: lim.max_context_window_tokens ?? lim.max_prompt_tokens, input: lim.max_prompt_tokens, output: lim.max_output_tokens },
          capabilities: { temperature: true, reasoning: true, attachment: true, toolcall: m.capabilities.supports.tool_calls, input: { text: true, audio: false, image: !!m.capabilities.supports.vision, video: false, pdf: false }, output: { text: true, audio: false, image: false, video: false, pdf: false }, interleaved: false },
          family: m.capabilities.family, name: m.name, cost: { input: 0, output: 0, cache: { read: 0, write: 0 } }, options: {}, headers: {},
          release_date: m.version.startsWith(`${m.id}-`) ? m.version.slice(m.id.length + 1) : m.version,
        }
      }
      return models
    },
  },
})

Environment

  • opencode 1.18.15-1 (Arch Linux package)
  • GitHub Copilot subscription: active (chat completions return 200)
  • OAuth apps tested: opencode's own (Ov23li8tweQw6odWQebz) and the VSCode Copilot app (Iv1.b507a08c87ecfe98) — same result either way

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.