feat: correx-managed model lifecycle slice 5 — Go TUI model swap + telemetry
Go TUI decodes model.changed / model.list / resource.status and renders a status-bar VRAM/GPU%/RAM gauge plus a models overlay (m key / palette 'models'): lists configured models with the resident one marked, enter swaps (SwapModel), c clears the pin (ClearModelPin). All three new server messages are non-event-bearing control/gauge frames, applied immediately like provider.status_changed. Server addition required for the picker: ServerMessage.ModelList (model.list, NonEventMessage) sent once in the initial snapshot from ManagedInferenceRouter.availableModelIds()/currentModelId() — the TUI otherwise cannot enumerate swap targets. Completes the 5-slice model-lifecycle feature. ./gradlew check green; go build/vet clean. Plan: docs/plans/2026-05-31-model-lifecycle-management.md (slice 5 of 5).
This commit is contained in:
@@ -37,6 +37,8 @@ func (m Model) renderOverlay(base string) string {
|
||||
return m.center(m.diffModal())
|
||||
case OverlayToolPalette:
|
||||
return m.center(m.toolPaletteModal())
|
||||
case OverlayModels:
|
||||
return m.center(m.modelsModal())
|
||||
}
|
||||
return base
|
||||
}
|
||||
@@ -243,6 +245,38 @@ func (m Model) toolPaletteModal() string {
|
||||
return m.center(modal)
|
||||
}
|
||||
|
||||
func (m Model) modelsModal() string {
|
||||
t := m.theme
|
||||
w := m.modalWidth()
|
||||
|
||||
var b strings.Builder
|
||||
b.WriteString(m.titleLine("models") + "\n\n")
|
||||
|
||||
if g := m.gaugeText(); g != "" {
|
||||
b.WriteString(mbg(t, g, t.P.Faint) + "\n\n")
|
||||
}
|
||||
|
||||
if len(m.availableModels) == 0 {
|
||||
b.WriteString(mbg(t, " model management not enabled", t.P.Faint) + "\n")
|
||||
}
|
||||
for i, id := range m.availableModels {
|
||||
marker := mbg(t, " ", t.P.BgPanel)
|
||||
nameFg := t.P.Fg
|
||||
if i == m.modelsIndex {
|
||||
marker = lipgloss.NewStyle().Foreground(t.P.Accent).Background(t.P.BgPanel).Render("▌ ")
|
||||
nameFg = t.P.FgStrong
|
||||
}
|
||||
line := marker + lipgloss.NewStyle().Foreground(nameFg).Background(t.P.BgPanel).Render(padRaw(id, 28))
|
||||
if id == m.currentModel {
|
||||
line += lipgloss.NewStyle().Foreground(t.P.Accent2).Background(t.P.BgPanel).Render(" ◂ resident")
|
||||
}
|
||||
b.WriteString(line + "\n")
|
||||
}
|
||||
b.WriteString("\n" + modalHints(t, [][2]string{{"↑↓", "select"}, {"enter", "swap"}, {"c", "clear pin"}, {"esc", "close"}}))
|
||||
modal := t.Overlay.Width(w).Render(b.String())
|
||||
return m.center(modal)
|
||||
}
|
||||
|
||||
func tierColor(t Theme, tier int) lipgloss.Color {
|
||||
switch {
|
||||
case tier >= 3:
|
||||
|
||||
Reference in New Issue
Block a user