Skip to content

feat(opencode): allow changing model mid-session #143

@NathanFlurry

Description

@NathanFlurry

Problem

When an OpenCode session is created and the first message is sent, the agent/provider/model is locked into the session runtime context. Subsequent messages cannot change the provider or model because the runtime is only set on the first message:

state.opencode.update_runtime(session_id, |runtime| {
    if runtime.session_agent_id.is_none() {
        runtime.session_agent_id = Some(agent);
        runtime.session_provider_id = Some(provider_id);
        runtime.session_model_id = Some(model_id);
    }
});

While SessionMessageRequest accepts a model field on every message, the resolved model from the first message is reused for all subsequent messages. The set_session_overrides() function can update the SessionState, but the OpenCode runtime context does not reflect the change.

This means users cannot switch models mid-conversation (e.g., start with a fast model for simple tasks, then switch to a more capable model for complex reasoning).

Expected Behavior

Users should be able to change the model on any message within an existing session. When a model field is provided in SessionMessageRequest, it should override the session-level model for that message and update the session runtime accordingly.

Proposed Approach

  1. In resolve_session_agent() (opencode_compat.rs), update the runtime even when session_agent_id is already set, if the incoming message specifies a different model.
  2. When the model changes mid-session, terminate the existing backing agent process and start a new one with the updated model, or pass the model switch through to agents that support it natively.
  3. Emit a synthetic event (e.g., session.model_changed) so the frontend can reflect the model switch.
  4. Consider whether changing the agent (not just the model within the same agent) mid-session should also be supported, or scoped out for now.

Considerations

  • Some agents may not support model switching natively — the daemon may need to restart the backing process.
  • The PATCH /opencode/session/{sessionID} endpoint could also be extended to accept model changes, giving the frontend an explicit way to switch before sending the next message.
  • Need to decide how model changes interact with conversation history — the new model should still receive the full conversation context.

Metadata

Metadata

Assignees

No one assigned

    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