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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions