simulate: Node agent support, --view mode, and TUI/start UX fixes#878
Merged
Conversation
theomonnom
approved these changes
Jun 24, 2026
74d461e to
11e7c80
Compare
The `lk agent session` daemon could previously only spawn Python agents; Node/JS projects were rejected at detection time. This wires up the Node path so a JS/TS agent can be driven over the same text-mode console protocol as Python. - agent_utils.go: stop gating `detectProject` on Python-only. Accept Node projects too (DetectProjectRoot already recognizes them via package.json) and update the error to reflect both supported runtimes. - simulate_subprocess.go: extract interpreter/argv resolution into `buildAgentCommand`, branching on project type. Python keeps `<python> <entry> <args>` (uv prefixes `run python`); Node runs `node [--experimental-strip-types] <entry> <args>`. Add `findNodeBinary` (resolves `node` from PATH) and `isTypeScriptEntry` so a `.ts`/`.mts`/ `.cts` entrypoint runs directly via the type-stripping loader with no build step. - session_daemon.go: drop the stale TODO; the daemon now spawns either runtime via `buildConsoleArgs` (`console --connect-addr <addr>`). Verified end-to-end: `lk agent session start examples/src/console_text_agent.ts` spawns the JS agent, connects to the Go TCP console server, completes the text-mode handshake, and round-trips multi-turn `say` requests including a function-tool call. Co-authored-by: Cursor <cursoragent@cursor.com>
* feat(agent): support Node.js agents in lk agent dev/start/console Builds on the Node project detection and spawn helpers from the session daemon work (#861) to wire the remaining agent run commands for Node: - `lk agent dev`/`start`: spawn the agents-js `dev` subcommand (Python keeps `start --dev`), normalize --log-level casing per runtime (agents-js only accepts lowercase, Python expects uppercase), and make the reload-server handshake (--reload-addr) Python-only — Node reloads are a plain kill+respawn since agents-js has no job-restore protocol. - Entrypoint discovery: probe per-runtime candidate lists (agent.ts, agent.js, src/agent.{ts,js} for Node; agent.py, src/agent.py for Python) instead of a single root default, and make the not-found message runtime-aware. - Probe `node --version` before running a TypeScript entrypoint and fail with a clear message on Node < 22.6 (no --experimental-strip-types). - resolveCredentials: ignore the global --url flag's default value so the project config (--project) can supply the URL; previously the spawned agent was always pointed at http://localhost:7880 unless --url or LIVEKIT_URL was set explicitly. `lk agent console` needed no changes beyond #861 — the spawn path was already runtime-agnostic. Tested end to end against agents-js' console CLI branch (#1706): console text mode, audio mode (mic/speaker + playback-finished handshake), ctrl-T mode toggle, --record output, dev worker registration, file-watch reload, and clean shutdown. * feat(agent): load discovered .env files into Node agents via --env-file Node agents spawned by lk agent dev/start/console inherited only the shell environment, so credentials in a project .env file were never seen (Python agents conventionally load_dotenv() themselves). Discover a known env file in the project dir and pass it to Node's built-in dotenv with --env-file. The flag requires Node >= 20.6, so the type-stripping version check is refactored into a shared nodeVersion probe and the flag is skipped on older Nodes. Shell-exported variables still take precedence over file values. * feat(console): fail fast when the agent job crashes before connecting A pre-connect job crash (e.g. missing API key in the entrypoint) leaves the worker process alive, so lk agent console sat on the spinner for the full 60s connect timeout before surfacing the traceback. Scan agent output for crash markers (Python's "job crashed" shutdown reason, agents-js's FATAL "console mode failed:") via a new FailSignals option on AgentStartConfig, and abort the connect wait immediately with the recent logs. The session daemon's wait gets the same treatment, reporting the log path through the ready pipe. Verified against agents @ a61578853: a missing .env now fails in ~4s with the full traceback instead of timing out at 60s. * Revert "feat(agent): load discovered .env files into Node agents via --env-file" This reverts commit 2430a24. Per PR review, agent code is expected to load its own env; auto-loading a discovered .env file second-guesses that. Arbitrary arg forwarding (e.g. a -- separator) is the preferred ease-of-use mechanism instead. * feat(agent): forward runtime args after -- to node/python Per PR review, replace the reverted .env auto-loading with explicit arg forwarding: everything after a -- separator is passed to the runtime interpreter ahead of the entrypoint in lk agent dev/start/console and the session daemon, so `lk agent console agent.ts -- --env-file=.env` runs `node --env-file=.env agent.ts console ...`. urfave/cli strips the -- and folds the trailing args into the positionals, so splitForwardedArgs recovers the split from os.Args; detectProject uses it so a forwarded flag with no entrypoint argument isn't mistaken for one. The detached session daemon receives the args JSON-encoded via LK_SESSION_FWD. * test(agent): trim agent run tests to the fail-signal case Remove the log-level, entrypoint-resolution, arg-splitting, and command- building unit tests along with the session forwarded-args round-trip test, keeping TestAgentProcessFailSignal.
Ports our simulate work onto the Node-support branch: - Node agent start: normalizeLogLevel, --log-format only for Python, main.ts/main.js entrypoints, and refuse entrypoint discovery when package.json defines a build task; drop the Python-only guard. - `lk agent simulate --view <runID>`: open a pre-existing simulation and print the reopen command on close. - TUI: ←/→ arrow navigation in/out of simulation detail, richer agent-exit errors (start command + recent output), and quit when the agent fails to register.
…ately The local-run version gate ran main's file-based CheckSDKVersion for Node too, which (a) couldn't find @livekit/agents in monorepo/workspace layouts where the dep is a `workspace:*` symlink rather than a versioned entry, and (b) gated on the Python thin-CLI baseline (1.6.0), the wrong floor for the Node SDK. Resolve the installed @livekit/agents via Node's own module resolution (embedded node_resolve_version.js), starting from the entrypoint's directory so pnpm/workspace symlinks and hoisting resolve exactly as they will at runtime, and gate Node on its own nodeAgentMinVersion. Python keeps the existing CheckSDKVersion path. Export IsVersionSatisfied for the reused comparison.
11e7c80 to
f321ff9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports our simulate work onto the Node-support branch (
brian/agent-session-node-support). These changes originated on an older fork of the simulate TUI, so they're re-applied as fresh edits rather than cherry-picks.Agent start / Node support
normalizeLogLevelfor the agent's--log-level.--log-format coloredfor Python (the Node CLI rejects it).main.ts/src/main.js(andsrc/fallbacks).package.jsondefines abuildtask and no entrypoint was given (build output paths are nontrivial).lk agent simulate --view <runID>--viewflag /modeViewto open a pre-existing simulation.lk agent simulate --view <runID>) when the TUI closes.TUI UX
→/enterto open a simulation's detail;←/esc/backspaceto go back (hints updated).Intentionally not ported (already present in a different form on this branch): the
exit()/confirmQuitrefactor and thessave-scenario key — this branch has its own save overlay and quit handling.Builds clean with
go buildandgo vet -tags console.