Skip to content

feat(simulate): export a run as JSON with --export - #925

Open
u9g wants to merge 12 commits into
mainfrom
jason/simulate-run-json
Open

feat(simulate): export a run as JSON with --export#925
u9g wants to merge 12 commits into
mainfrom
jason/simulate-run-json

Conversation

@u9g

@u9g u9g commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Adds --export RUN_ID to lk agent simulate: prints an existing SimulationRun to stdout as JSON, so a run can be replayed or diffed programmatically.

lk agent simulate --export run_123 > run_123.json
  • One fetch, nothing else: no agent is spawned, no run is created, and the run is never polled. A run that has not finished is an error, an unknown ID surfaces the API's not-found error, and stdout carries the full export or nothing. Flags that shape or follow a run (--view, --scenarios, --audio, -n, --concurrency, --agent-name) are rejected rather than silently dropped; --quiet and --yes still work, since the export goes to stdout and only status output is silenced.
  • The run and its summary are emitted as verbatim protojson under a {version, run, summary} wrapper, so new proto fields reach the export on a protocol bump alone, with no change here. Fields the compiled protocol does not know are still dropped — protojson does not emit unknown fields — so an old lk against a newer server exports less than the wire carried. summary_zstd is dropped since the decoded summary is already included, and a summary that fails to decode fails the export instead of silently vanishing.
  • Chat contexts live in the summary, as summary.chat_history keyed by job ID, in proto form: oneof-wrapped items, SCREAMING_CASE enums, RFC3339 timestamps. That is not ChatContext.to_dict() shape, so a replay harness needs a translation step on the way in.
  • Both live runs and --view print the export hint. In --view the re-open hint is suppressed — it would just echo the command the user ran.

u9g added 6 commits July 29, 2026 13:46
The hand-written export structs mirrored the proto by hand and would drift
on every proto change. Emit the SimulationRun and decoded SimulationRunSummary
verbatim via protojson (proto field names) under a thin version wrapper.
protojson round-trip is the library's invariant, not ours; the test no
longer covered code this package owns.
It printed back the command the user had just typed.
@u9g u9g changed the title feat(simulate): export replayable run JSON feat(simulate): export a run as JSON with --run-json Aug 4, 2026
Comment thread cmd/lk/simulate.go Outdated
u9g added 2 commits August 5, 2026 13:49
--run-json rode along with a live run or a --view poll, so exporting a
finished run's JSON meant waiting on machinery that had nothing to do
with the export. --dump-json takes the run ID directly and does one
fetch: an unfinished run is an error, an unknown ID is the API's
not-found error, and stdout carries the JSON or nothing.
@u9g u9g changed the title feat(simulate): export a run as JSON with --run-json feat(simulate): export a run as JSON with --dump-json Aug 5, 2026
@u9g u9g changed the title feat(simulate): export a run as JSON with --dump-json feat(simulate): export a run as JSON with --export Aug 6, 2026
u9g added 3 commits August 6, 2026 09:03
A proto3 implicit-presence bool is indistinguishable from unset once
protojson omits it, so a consumer reading a dropped is_error has to guess.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants