Skip to content

Show which model actually answered - #1

Open
android6 wants to merge 1 commit into
openchamber:mainfrom
android6:feat/model-fallback-note
Open

Show which model actually answered#1
android6 wants to merge 1 commit into
openchamber:mainfrom
android6:feat/model-fallback-note

Conversation

@android6

@android6 android6 commented Aug 20, 2026

Copy link
Copy Markdown

Claude Code can switch models mid-conversation: when the safety classifiers refuse a request on Fable 5, the CLI silently re-runs it on Opus. OpenCode keeps displaying the model the user picked, so there is no way to tell.

This adds a short callout at the end of the answer whenever the answering model differs from the selected one:

  • model switched - from the SDK model_refusal_fallback event (models, safeguard category, scope).
  • model refused - model_refusal_no_fallback: the turn ended with an error and no retry ran.
  • model mismatch (answer starts on X) - init.model differs from the user's pick: the session was left on a fallback model by an earlier turn.
  • model mismatch (answered by X) - assistant.message.model differs from what was announced: catches switches the CLI doesn't report.

One note per leg, always after the text so it can't land inside a code fence. OPENCODE_CLAUDE_MODEL_NOTES=reasoning moves it into the thinking trace instead. CLI system/notification events (medium+) are forwarded to the reasoning trace as [notice].

Seen live with CLI 2.1.237: bio -> claude-opus-5, cyber -> claude-opus-4-8.

@android6

Copy link
Copy Markdown
Author

Closing to trim scope; will reopen a smaller version.

@android6 android6 closed this Aug 20, 2026
@android6 android6 changed the title feat(proxy): tell the user which model actually answered Show which model actually answered Aug 20, 2026
@android6 android6 reopened this Aug 20, 2026
@android6
android6 force-pushed the feat/model-fallback-note branch 2 times, most recently from c81642e to cdbfe44 Compare August 20, 2026 21:11
Claude Code can switch models mid-conversation: when the safety
classifiers refuse a request on Fable 5, the CLI re-runs it on Opus.
OpenCode kept showing the requested model, so the user never knew.

Surface the real model as a short callout after the answer:

- model switched: system/model_refusal_fallback (models, category, scope)
- model refused: model_refusal_no_fallback, turn ended with an error
- model mismatch: init.model or assistant.message.model differs from the
  user's pick (catches switches the CLI does not announce)

One note per leg, after the text so it cannot land inside a code fence.
OPENCODE_CLAUDE_MODEL_NOTES=reasoning moves it to the thinking trace.
system/notification events (medium+) go to the reasoning trace as [notice].
@android6
android6 force-pushed the feat/model-fallback-note branch from cdbfe44 to 69a7ab4 Compare August 20, 2026 21:31
HarikiRito referenced this pull request in HarikiRito/opencode-claude Sep 4, 2026
…l calls in parallel

The SDK streams one assistant event per completed content block, so a
turn with N parallel tool_use requests arrives as N separate events
sharing a message id, all before the SDK invokes any tool handler.
Handlers are then invoked serially, awaiting handler #1's return before
starting openchamber#2. The bridge only ever knew about a tool once its handler
ran, so a park always carried just the one tool the SDK had gotten
around to calling — every later handler in the batch waited its turn.

Register each tool_use block as it streams past, before any handler
runs, keyed by Claude's own id with a deferred result promise. The
first handler to park now emits the whole batch; handlers invoked
later just look up their already-registered promise instead of
re-parking one at a time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant