Skip to content

[FEATURE]: decouple the wire model name (api.id) from the id used to select the system prompt #34770

Closed as not planned

Description

@asoriano-stratio

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Summary

SystemPrompt.provider() picks the base system prompt purely by substring-matching
model.api.id. For providers where the model id is an arbitrary alias —
@ai-sdk/openai-compatible behind a proxy (LiteLLM, a custom gateway, OpenRouter aliases,
on-prem vLLM) — the id carries no recognizable family token, so selection silently falls back
to default.txt even when the underlying model is GPT/Claude/Gemini.

The only lever today is
to rename the model so its id contains gpt/claude/… — but that same id is what gets sent to
the backend as the request model, so prompt selection and the wire model name cannot be set
independently.

The ask: let the alias sent to the provider be separate from the id used to pick the system prompt.

Environment

  • opencode: 1.17.0 (also reproduces on dev — the relevant code is identical)
  • provider npm: @ai-sdk/openai-compatible (LiteLLM proxy in front of the models)

Reproduction

  1. Configure an @ai-sdk/openai-compatible provider pointing at a proxy.
  2. Register a model whose public/alias id is opaque, e.g. llm-model, that actually routes to
    gpt-5.x on the backend.
  3. Start a session on that model.
  4. The base system prompt is default.txt, not gpt.txt. Renaming the model to something
    containing gpt fixes the prompt — but that same string is what gets sent to the backend
    as the model name, so it's not a free rename.

Root cause

packages/opencode/src/session/system.ts — provider():

export function provider(model: Provider.Model) {
  if (model.api.id.includes("gpt-4") || model.api.id.includes("o1") || model.api.id.includes("o3"))
    return [PROMPT_BEAST]
  if (model.api.id.includes("gpt")) { /* … */ return [PROMPT_GPT] }
  if (model.api.id.includes("gemini-")) return [PROMPT_GEMINI]
  if (model.api.id.includes("claude"))  return [PROMPT_ANTHROPIC]
  // …
  return [PROMPT_DEFAULT]
}

model.api.id is also the model name sent over the wire
(packages/opencode/src/provider/provider.ts):

const apiID = model.id ?? existingModel?.api.id ?? modelID   // api.id derivation
// …
: sdk.languageModel(model.api.id)                            // outbound model name

So api.id is overloaded: it is (1) the prompt-selection key and (2) the outbound model
name. You cannot change one without the other — renaming to get gpt.txt forces the backend to
receive that alias too.

Why current workarounds fall short

  • Rename the model / add a provider alias: couples prompt selection to the wire model name;
    not possible when the gateway's public model name is fixed. It also mis-fires — an alias that
    merely contains gpt-4 gets beast.txt.
  • Agent prompt (packages/opencode/src/session/llm/request.ts): if set it replaces the
    base provider prompt entirely rather than selecting one, dropping the maintained
    provider-specific prompts. See agent: support additive custom system prompts #34721 (additive vs replace semantics).

Proposal

The root problem is that api.id is overloaded. The cleanest fix is to decouple the two
roles
: keep api.id as the alias sent in the request model field, and add a separate,
optional per-model field carrying the underlying model id used only to select the system
prompt. provider() then matches against the underlying id when present, and falls back to
api.id (today's behavior) otherwise.

"provider": {
  "litellm": {
    "npm": "@ai-sdk/openai-compatible",
    "models": {
      "llm-model": {              // alias — this is what gets sent as `model` in the request body (api.id)
        "base_model": "gpt-5.4"   // identity used ONLY to pick the system prompt (name TBD: underlying / base_model / …)
      }
    }
  }
}

Selection in provider() becomes provider(model.base_model ?? model.api.id) — reusing the
existing substring classifier unchanged, so new prompt families/rules are picked up
automatically. Fully backward-compatible (field absent → today's behavior).

Activity

  1. github-actions commented on Jul 1, 2026

    @github-actions
    Contributor

    This issue does not fully meet our contributing guidelines.

    What needs to be fixed:

    • The issue is explicitly noted as AI-generated ("filed automatically using Claude Code"). We do not accept AI-generated issue submissions.
    • The issue does not use one of the required templates (Bug Report, Feature Request, or Question). Feature requests must use the [FEATURE]: title prefix and include the required verification checkbox confirming the feature has not been suggested before.

    Please edit this issue to address the above within 2 hours, or it will be automatically closed.

    If you believe this was flagged incorrectly, please let a maintainer know.

  2. changed the title [-]feat(prompt): decouple the wire model name (api.id) from the id used to select the system prompt[/-] [+][FEATURE]: decouple the wire model name (api.id) from the id used to select the system prompt[/+] on Jul 1, 2026
  3. github-actions commented on Jul 1, 2026

    @github-actions
    Contributor

    Thank you for updating the issue! It now follows our contributing guidelines — the Feature Request template is properly filled out with the verification checkbox and a clear, detailed description of the problem and proposed solution. The needs:compliance label has been removed.

  4. github-actions commented on Sep 2, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions