Skip to content

mecatui initial session ignores saved global/workspace model default when boot model inventory is stale #41

Closed

Description

@JAORMX

Summary

mecatui appears to persist and display the selected global/default model correctly, but on a fresh boot it can still create the initial session on the server default (GPT-5) instead of the saved global/workspace default (OpenRouter: GPT-5.5). After manually selecting GPT-5.5 in /models and restarting the session, the header correctly shows OpenAI: GPT-5.5.

Observed local state on the affected machine:

# ~/.local/state/mecatui/models.yaml
version: 1
default:
    providerId: openrouter
    modelId: openai/gpt-5.5
workspaces:
    /var/home/jaosorior/Development/stacklok/mecatl:
        providerId: openrouter
        modelId: openai/gpt-5.5

So the persisted selection is present and correct.

Diagnosis

The likely failure is in the connect-time ListModels reconciliation path clearing the persisted selection before CreateSession runs.

Relevant path:

  • cmd/mecatui/main.go loads persisted model state:
    • newSelectionStore(...)
    • store.Load(cfg.workspace)
    • store.LoadWorkspace(cfg.workspace)
    • store.LoadGlobalDefault()
  • cmd/mecatui/state.go load order is per-workspace first, then global default:
    • Load: workspace entry if present, else default, else zero selection.
  • cmd/mecatui/ui/model.go seeds activeModel from Deps.InitialModel.
  • cmd/mecatui/ui/model.go Init() fetches ListModels before creating the session.
  • cmd/mecatui/ui/models.go handles ModelsMsg and calls reconcileSelection().
  • reconcileSelection() clears m.models.active and m.activeModel to zero if the persisted selection is not present in the current model inventory.
  • cmd/mecatui/ui/update.go createSessionCmd() then sends m.activeModel to CreateSession; if it has been cleared, the server default is used.

This matches the symptom:

  1. Saved selection is openrouter/openai/gpt-5.5.
  2. At boot, initial ListModels likely does not include that exact (provider_id, model_id) pair yet.
  3. reconcileSelection() clears the persisted selection to zero.
  4. Initial CreateSession uses server default, which resolves to GPT-5.
  5. Later, /models selection explicitly sends openrouter/openai/gpt-5.5 through the restart-now path, and the header correctly shows GPT-5.5.

The curated catalog does include bare OpenAI gpt-5.5, but the saved selection is OpenRouter’s namespaced openai/gpt-5.5. The race/mismatch may involve the startup snapshot vs background live model refresh for OpenRouter.

Expected behavior

If a saved global or per-workspace default exists and the provider is configured, boot should create the initial session on that saved selection, or at minimum not silently fall back to server default because an early model inventory snapshot was incomplete/stale.

Actual behavior

Boot header shows GPT-5 even though saved default/workspace selection is openrouter/openai/gpt-5.5. Manual selection/restart immediately fixes the header/session.

Pointers

Relevant files/functions:

  • cmd/mecatui/main.go — persisted state is loaded and threaded into ui.Deps.
  • cmd/mecatui/state.go — selectionStore.Load, LoadWorkspace, LoadGlobalDefault.
  • cmd/mecatui/ui/model.go — New seeds activeModel; Init fetches ListModels before create.
  • cmd/mecatui/ui/models.go — updateModelsMsg, reconcileSelection, restart-now model switch path.
  • cmd/mecatui/ui/update.go — createSessionCmd sends activeModel.
  • internal/app/build.go / internal/app/modellister.go — startup model snapshot plus background live model refresh.

Verification already run

go test ./cmd/mecatui ./internal/app ./internal/adapter/server

All passed locally. No code changes were made during diagnosis.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtuimecatui terminal UI (rendering, keybindings, footer, panes, scrollback)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions