diff --git a/cmd/lk/simulate.go b/cmd/lk/simulate.go index c7d1a14f..4b3cfc7a 100644 --- a/cmd/lk/simulate.go +++ b/cmd/lk/simulate.go @@ -31,12 +31,14 @@ import ( "github.com/urfave/cli/v3" "gopkg.in/yaml.v3" + "github.com/klauspost/compress/zstd" "github.com/livekit/livekit-cli/v2/pkg/agentfs" "github.com/livekit/livekit-cli/v2/pkg/config" "github.com/livekit/livekit-cli/v2/pkg/util" "github.com/livekit/protocol/livekit" lksdk "github.com/livekit/server-sdk-go/v2" "github.com/livekit/server-sdk-go/v2/pkg/cloudagents" + "google.golang.org/protobuf/proto" ) func init() { @@ -601,3 +603,23 @@ func simulationJobCounts(run *livekit.SimulationRun) (total, done, passed, faile } return } + +func decodeRunSummary(run *livekit.SimulationRun) *livekit.SimulationRunSummary { + if run == nil || len(run.SummaryZstd) == 0 { + return nil + } + dec, err := zstd.NewReader(nil) + if err != nil { + return nil + } + defer dec.Close() + raw, err := dec.DecodeAll(run.SummaryZstd, nil) + if err != nil { + return nil + } + summary := &livekit.SimulationRunSummary{} + if err := proto.Unmarshal(raw, summary); err != nil { + return nil + } + return summary +} diff --git a/cmd/lk/simulate_ci.go b/cmd/lk/simulate_ci.go index 55ee32e2..2bae9f0b 100644 --- a/cmd/lk/simulate_ci.go +++ b/cmd/lk/simulate_ci.go @@ -205,6 +205,7 @@ func writeRunResults(w io.Writer, run *livekit.SimulationRun, ap *AgentProcess) if run == nil { return } + summary := decodeRunSummary(run) if run.Status == livekit.SimulationRun_STATUS_FAILED && len(run.Jobs) == 0 { fmt.Fprintf(w, "✗ Simulation failed: %s\n", run.Error) @@ -249,8 +250,8 @@ func writeRunResults(w io.Writer, run *livekit.SimulationRun, ap *AgentProcess) } } - if run.Summary != nil && run.Summary.ChatHistory != nil { - writeChatHistory(w, run.Summary.ChatHistory[job.Id]) + if summary != nil && summary.ChatHistory != nil { + writeChatHistory(w, summary.ChatHistory[job.Id]) } if ap != nil && job.RoomName != "" { @@ -271,8 +272,8 @@ func writeRunResults(w io.Writer, run *livekit.SimulationRun, ap *AgentProcess) } } - if run.Summary != nil { - writeRunSummary(w, run) + if summary != nil { + writeRunSummary(w, run, summary) } else { msg := "The summary for this run is not available" if run.Error != "" { @@ -283,8 +284,7 @@ func writeRunResults(w io.Writer, run *livekit.SimulationRun, ap *AgentProcess) } } -func writeRunSummary(w io.Writer, run *livekit.SimulationRun) { - summary := run.Summary +func writeRunSummary(w io.Writer, run *livekit.SimulationRun, summary *livekit.SimulationRunSummary) { total, _, passed, failed := simulationJobCounts(run) fmt.Fprintln(w) diff --git a/cmd/lk/simulate_tui.go b/cmd/lk/simulate_tui.go index a0bb4aab..c064d552 100644 --- a/cmd/lk/simulate_tui.go +++ b/cmd/lk/simulate_tui.go @@ -40,8 +40,8 @@ func runSimulateTUI(config *simulateConfig) error { _, runErr := p.Run() if m.launcher != nil { - // A second ctrl+c during cleanup would kill the CLI and leak the worker - // (own process group, port stays bound); escalate to SIGKILL instead. + // A second ctrl+c during cleanup would kill the CLI and leak the worker + // (own process group, port stays bound); escalate to SIGKILL instead. sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, os.Interrupt) defer signal.Stop(sigCh) @@ -157,6 +157,7 @@ type simulateModel struct { // Run phase run *livekit.SimulationRun + summary *livekit.SimulationRunSummary runFinished bool brokenAgent bool numSimulations int32 @@ -362,6 +363,7 @@ func (m *simulateModel) runSetup() tea.Cmd { m.err = err } m.run = run + m.summary = decodeRunSummary(run) m.setupDone = true return nil } @@ -575,6 +577,7 @@ func (m *simulateModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case simulationRunMsg: if msg.err == nil && msg.run != nil { m.run = msg.run + m.summary = decodeRunSummary(msg.run) m.reporter.RunUpdate(msg.run, m.config.numSimulations) if m.startTime.IsZero() && msg.run.Status == livekit.SimulationRun_STATUS_RUNNING { m.startTime = time.Now() @@ -1101,7 +1104,7 @@ func (m *simulateModel) viewRunning() string { if m.run.Status == livekit.SimulationRun_STATUS_SUMMARIZING { fmt.Fprintf(&b, "\n %s %s %s\n", yellowStyle().Render("⏺"), yellowStyle().Render("Generating summary..."), m.spinner()) - } else if m.run.Summary != nil { + } else if m.summary != nil { b.WriteString(m.renderSummary()) } else if isTerminalRunStatus(m.run.Status) { msg := "The summary for this run is not available" @@ -1553,7 +1556,7 @@ func (m *simulateModel) scrolledDetail() string { } func (m *simulateModel) renderSummary() string { - summary := m.run.Summary + summary := m.summary if summary == nil { return "" } @@ -1622,10 +1625,10 @@ func (m *simulateModel) renderSummary() string { } func (m *simulateModel) renderChatTranscript(jobID string) string { - if m.run.Summary == nil || m.run.Summary.ChatHistory == nil { + if m.summary == nil || m.summary.ChatHistory == nil { return "" } - chatCtx, ok := m.run.Summary.ChatHistory[jobID] + chatCtx, ok := m.summary.ChatHistory[jobID] if !ok || chatCtx == nil || len(chatCtx.Items) == 0 { return "" } diff --git a/go.mod b/go.mod index e31f7c2a..6f1fa5f2 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,8 @@ require ( github.com/google/go-containerregistry v0.20.7 github.com/google/go-querystring v1.2.0 github.com/joho/godotenv v1.5.1 - github.com/livekit/protocol v1.49.1-0.20260707153508-a36bd7e4afe5 + github.com/klauspost/compress v1.18.6 + github.com/livekit/protocol v1.49.1-0.20260712215709-8847d7456816 github.com/livekit/server-sdk-go/v2 v2.17.0 github.com/mattn/go-isatty v0.0.22 github.com/moby/patternmatcher v0.6.1 @@ -155,7 +156,6 @@ require ( github.com/in-toto/attestation v1.1.2 // indirect github.com/in-toto/in-toto-golang v0.11.0 // indirect github.com/jxskiss/base62 v1.1.0 // indirect - github.com/klauspost/compress v1.18.6 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/pgzip v1.2.6 // indirect github.com/lithammer/shortuuid/v4 v4.2.0 // indirect diff --git a/go.sum b/go.sum index 9b0a8e7a..f387965b 100644 --- a/go.sum +++ b/go.sum @@ -357,8 +357,8 @@ github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731 h1:9x+U2HGLrSw5AT github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ= github.com/livekit/mediatransportutil v0.0.0-20260605212259-862d4a7bcb1e h1:SkgQRcG2VYEhh80Qb/zYZo8rWKJzNfJcfUQnXe6su2M= github.com/livekit/mediatransportutil v0.0.0-20260605212259-862d4a7bcb1e/go.mod h1:o8CFmAdrVwzJNOCsQCLUzXRjokkufNshnQHOe4fRaqU= -github.com/livekit/protocol v1.49.1-0.20260707153508-a36bd7e4afe5 h1:6ItjuVJkxz/fpxz9eo4pt8FNtEoRSWUUSIZqGl4wOcE= -github.com/livekit/protocol v1.49.1-0.20260707153508-a36bd7e4afe5/go.mod h1:jO+y05AU9Ec4JswDyuzKCZ4bhziOS0CzMqgnbj60Dzs= +github.com/livekit/protocol v1.49.1-0.20260712215709-8847d7456816 h1:MDWDlH5dmcZY4OSljwE4e6B39libPQJIEmBRYaeGAn0= +github.com/livekit/protocol v1.49.1-0.20260712215709-8847d7456816/go.mod h1:jO+y05AU9Ec4JswDyuzKCZ4bhziOS0CzMqgnbj60Dzs= github.com/livekit/psrpc v0.7.2 h1:6oZ+NODJ2pLyaT6VqDq1F4Qc/3TpDUSpyphj/P9MhQc= github.com/livekit/psrpc v0.7.2/go.mod h1:rAI+m2+/cb4x9RXhLRtUx5ZwdfjjXOl4zi46IjEetaw= github.com/livekit/server-sdk-go/v2 v2.17.0 h1:FzVQMoxHv0WIg164yGqSxLeV+h3aJomjAv1lFeR9MMw=