Skip to content

Cached system prompt always tells model it is Sonnet 4.6, regardless of selected model #13

@BNasraoui

Description

@BNasraoui

Summary

The cached Claude Code system prompt at ~/.cache/opencode-claude-bridge/claude-system-prompt.json contains a self-identity line:

You are powered by the model named Sonnet 4.6. The exact model ID is claude-sonnet-4-6.

The bridge injects this prompt verbatim on every Anthropic request (src/index.ts:641-650), regardless of which model the user selected. As a result, Opus 4.7, Haiku 4.5, and any future model is told it is Sonnet 4.6.

Reproduction

# Validator was run with claude-sonnet-4-6 (as documented in README)
opencode run --model anthropic/claude-opus-4-7 "What is your exact model ID? Reply with ONLY the model ID."
# → claude-sonnet-4-6

The identity string comes from the cached system prompt — not model hallucination. Capability-bound responses (speed, reasoning quality) do still come from the actual model, but the prompt-driven self-identity is wrong.

Why this matters

Anthropic models are tuned per family. Telling Opus 4.7 "you are Sonnet 4.6" can bias:

  • Response length and verbosity patterns
  • Tool-use preferences and ordering
  • Confidence calibration / self-assessment
  • Refusal / safety behaviors that differ across generations

The magnitude of the effect is not published, but the fix is cheap and removes a known source of noise.

Design constraint

The prompt injection cannot simply be removed — per the README (README.md:186), it is the mechanism that makes OpenCode traffic classify as Claude Code (plan billing) rather than third-party OAuth (extra usage):

"After the first successful validator run, the bridge will automatically reuse that cached Claude Code system prompt. This is currently the key step that makes OpenCode traffic behave like standard Claude Code usage."

So the prompt must still be injected; only the model-identity lines inside it need to reflect the actual requested model.

Proposed fix

Rewrite just the identity line in-place before injection, using the parsed.model from the outbound body. Derive the display name from the model ID (claude-opus-4-7Opus 4.7) rather than a hardcoded map, so new models don't need plugin updates.

PR incoming.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions