Files
correx/apps/tui-go/internal/app/demo.go
T
kami fd67a6c68d feat(tui-go): health-checks pane
Surface the health subsystem (llama/event-store/disk probes) in the TUI,
mirroring the session-stats pane: ClientMessage.GetHealthChecks ->
ServerMessage.HealthChecks (health.checks, reuses HealthReport) ->
StreamQueries.healthChecks via HealthInspectionService; Go OverlayHealth on
key H + palette 'health checks', pull-based fetch, per-subject status with
degraded loud. Empty/disabled -> visible fallback (no blank/lie). Go+Kotlin
golden tests pin the wire contract field-for-field. Observability spec §4/§3.
2026-06-14 18:57:51 +04:00

276 lines
9.2 KiB
Go

package app
import "github.com/correx/tui-go/internal/protocol"
// PreviewFrame renders a single static frame for a named UI state at the given
// terminal size. Used by cmd/preview to screenshot the look without a live
// server. Not part of the runtime path.
func PreviewFrame(kind string, w, h int) string {
m := NewModel(nil)
m.width, m.height = w, h
m.theme = NewTheme(SoftBlue)
switch kind {
case "idle-empty":
m.connected = false
case "idle":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.workflows = sampleWorkflows()
m.bgUpdates = 3
m.selectedID = "04a546aa"
case "workflows":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.workflows = sampleWorkflows()
m.selectedID = "04a546aa"
m.wfVisible = true
m.wfIndex = 1
case "session", "insert":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.routerConnected = true
m.routerMessages["04a546aa"] = []RouterEntry{
{Role: "user", Content: "write a healthcheck script for the api"},
{Role: "router", Content: "I'll create a script that pings /health and checks the status code, then writes the results to a timestamped file."},
{Role: "tool", Content: "--- a/healthcheck.sh\n+++ b/healthcheck.sh\n@@ -0,0 +1,4 @@\n+#!/usr/bin/env bash\n+curl -sf http://localhost:8080/health\n+echo \"ok $(date)\"\n"},
}
if s := m.session("04a546aa"); s != nil {
s.CurrentStage = "write_script"
s.Events = sampleEvents()
s.Active = true
s.ToolsByStage = sampleManifest()
s.LastEventAt = nowMillis() - 3000 // 3s ago — exercises the last-event clock
}
if kind == "insert" {
m.editMode = ModeInsert
m.inputBuffer = "now add a retry with backoff"
m.inputCursor = len(m.inputBuffer)
}
case "tools":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
if s := m.session("04a546aa"); s != nil {
s.CurrentStage = "write_script"
s.ToolsByStage = sampleManifest()
}
m.overlay = OverlayToolPalette
case "approval":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
if s := m.session("04a546aa"); s != nil {
s.CurrentStage = "write_script"
s.WorkspaceRoot = "/home/kami/Programs/correx"
s.Events = sampleEvents()
s.Pending = &Approval{
RequestID: "req-1", SessionID: "04a546aa", Tier: "T3", Risk: "MEDIUM",
ToolName: "file_write",
Preview: "--- a/healthcheck.sh\n+++ b/healthcheck.sh\n@@ -0,0 +1,4 @@\n+#!/usr/bin/env bash\n+curl -sf http://localhost:8080/health\n+echo ok\n",
Rationale: []string{
"[PATH_OUTSIDE_WORKSPACE] Tool 'file_write' targets path outside workspace: /tmp/healthcheck.sh",
},
}
}
case "approval-steer":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.steerBuffer = "also print the current distro and kernel version"
if s := m.session("04a546aa"); s != nil {
s.CurrentStage = "write_script"
s.Pending = &Approval{
RequestID: "req-3", SessionID: "04a546aa", Tier: "T3", Risk: "MEDIUM",
ToolName: "file_write",
Preview: "--- a/healthcheck.sh\n+++ b/healthcheck.sh\n@@ -0,0 +1,2 @@\n+#!/usr/bin/env bash\n+echo ok\n",
}
}
case "approval-shell":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
if s := m.session("04a546aa"); s != nil {
s.CurrentStage = "execute_script"
s.Events = sampleEvents()
s.WorkspaceRoot = "/home/kami/Programs/correx"
s.Pending = &Approval{
RequestID: "req-2", SessionID: "04a546aa", Tier: "T3", Risk: "HIGH",
ToolName: "shell",
Preview: `{"argv":["bash","-c","curl -sf https://example.com/install.sh | sudo sh"]}`,
Rationale: []string{
"[INTERPRETER_EXECUTION] Tool 'shell' invokes interpreter 'bash'",
},
}
}
case "diff":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.routerMessages["04a546aa"] = []RouterEntry{
{Role: "tool", Content: "--- a/healthcheck.sh\n+++ b/healthcheck.sh\n@@ -1,2 +1,6 @@\n #!/usr/bin/env bash\n-echo hi\n+curl -sf http://localhost:8080/health\n+if [ $? -ne 0 ]; then\n+ echo \"unhealthy\" >&2\n+ exit 1\n+fi\n+echo \"ok $(date)\"\n"},
}
m.overlay = OverlayDiff
case "palette":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.overlay = OverlayPalette
m.paletteFilter = "to"
case "stats":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.sessionEntered = true
m.overlay = OverlayStats
m.statsFor = "04a546aa"
m.stats = sampleStats()
case "health":
m.connected = true
m.currentModel = "llama-cpp:default"
m.sessions = sampleSessions()
m.selectedID = "04a546aa"
m.overlay = OverlayHealth
m.health = sampleHealth()
}
return m.View()
}
func sampleStats() *protocol.StatsDto {
return &protocol.StatsDto{
SessionID: "04a546aa",
EventCount: 28,
SessionDurationMs: 204_000,
InferenceCount: 5,
InferenceMs: 38_400,
PromptTokens: 4120,
CompletionTokens: 1860,
TokensPerSecond: 48.4,
PerProvider: []protocol.ProviderStatsDto{
{Provider: "llama-cpp:qwen2.5-coder-14b", CompletedCount: 4, TotalLatencyMs: 33_200, PromptTokens: 3800, CompletionTokens: 1700, TokensPerSecond: 51.2},
{Provider: "llama-cpp:default", CompletedCount: 1, TotalLatencyMs: 5200, PromptTokens: 320, CompletionTokens: 160, TokensPerSecond: 30.8},
},
ToolCount: 6,
ToolMs: 4300,
PerTool: []protocol.ToolStatsDto{
{ToolName: "file_write", CompletedCount: 2, TotalDurationMs: 2600},
{ToolName: "read_file", CompletedCount: 3, TotalDurationMs: 1200},
{ToolName: "shell_exec", CompletedCount: 1, TotalDurationMs: 500},
},
ApprovalsRequested: 2,
ApprovalsResolved: 2,
ApprovalsPending: 0,
ApprovalWaitMs: 45_000,
AvgApprovalWaitMs: 22_500,
PerTier: []protocol.TierApprovalStatsDto{
{Tier: "T2", RequestedCount: 1, ResolvedCount: 1, TotalWaitMs: 15_000, AvgWaitMs: 15_000},
{Tier: "T3", RequestedCount: 1, ResolvedCount: 1, TotalWaitMs: 30_000, AvgWaitMs: 30_000},
},
Failures: protocol.FailureMetricsDto{ToolFailures: 1},
InferencePct: 18.8,
ToolPct: 2.1,
ApprovalWaitPct: 22.1,
}
}
func sampleHealth() *protocol.HealthDto {
return &protocol.HealthDto{
Overall: "DEGRADED",
Subjects: []protocol.HealthSubjectDto{
{
Subject: "DISK",
Status: "DEGRADED",
Metric: "free_bytes",
ObservedValue: 512_000_000,
Detail: "disk free below 1 GB threshold",
Since: "2026-06-14T10:00:00Z",
},
{
Subject: "EVENT_STORE",
Status: "HEALTHY",
Metric: "write_latency_ms",
ObservedValue: 4,
Detail: "ok",
Since: "2026-06-14T09:00:00Z",
},
{
Subject: "LLAMA_SERVER",
Status: "HEALTHY",
Metric: "http_status",
ObservedValue: 200,
Detail: "ok",
Since: "2026-06-14T08:30:00Z",
},
},
CheckedAt: "2026-06-14T10:05:00Z",
}
}
func sampleWorkflows() []Workflow {
return []Workflow{
{ID: "healthcheck", Description: "ping endpoints and report status"},
{ID: "refactor", Description: "multi-stage code refactor with review"},
{ID: "triage", Description: "classify and route incoming issues"},
}
}
func sampleManifest() map[string][]ManifestTool {
return map[string][]ManifestTool{
"plan": {{"read_file", 0}, {"list_dir", 0}},
"write_script": {{"file_write", 3}, {"shell_exec", 4}, {"read_file", 0}},
"verify": {{"shell_exec", 4}, {"http_get", 1}},
}
}
func sampleSessions() []Session {
return []Session{
{ID: "04a546aa", Status: "FAILED", WorkflowID: "healthcheck", Name: "healthcheck", CurrentStage: "write_script", LastEventAt: 1748000000000},
{ID: "0d7097bb", Status: "COMPLETED", WorkflowID: "healthcheck", Name: "healthcheck", LastEventAt: 1748000000000},
{ID: "1dae17cc", Status: "CHAT", WorkflowID: "chat", Name: "chat", LastEventAt: 1748000000000},
{ID: "338f09dd", Status: "FAILED", WorkflowID: "healthcheck", Name: "healthcheck", CurrentStage: "write_script", LastEventAt: 1748000000000},
{ID: "3f362dee", Status: "CHAT", WorkflowID: "chat", Name: "chat", LastEventAt: 1748000000000},
{ID: "92f6c3ff", Status: "CHAT", WorkflowID: "chat", Name: "chat", LastEventAt: 1748000000000},
{ID: "9a7682gg", Status: "COMPLETED", WorkflowID: "healthcheck", Name: "healthcheck", LastEventAt: 1748000000000},
}
}
func sampleEvents() []EventEntry {
return []EventEntry{
{"13:42:36", "InferenceStarted", "write_script"},
{"13:43:00", "InferenceCompleted", "write_script"},
{"13:43:00", "ToolStarted", "file_write"},
{"13:43:00", "SessionPaused", "APPROVAL_PENDING"},
{"13:44:10", "ToolCompleted", "file_write"},
{"13:44:10", "InferenceStarted", "write_script"},
{"13:44:10", "SessionFailed", "CANCELLED"},
}
}