Skip to content

Add agent mode: LLM-driven REPL, scripted replay, shared tools layer#2338

Draft
arrufat wants to merge 350 commits into
mainfrom
agent
Draft

Add agent mode: LLM-driven REPL, scripted replay, shared tools layer#2338
arrufat wants to merge 350 commits into
mainfrom
agent

Conversation

@arrufat
Copy link
Copy Markdown
Contributor

@arrufat arrufat commented Apr 30, 2026

Adds a new lightpanda agent command alongside serve, fetch, and mcp, with five operating modes that all share the same browser-tool surface.

Features

  • Interactive REPL, optionally backed by an LLM (Anthropic, OpenAI, Gemini, Ollama) via the zenai client. Without --provider, the REPL still runs as a "dumb" Pandascript-only shell.
  • Pandascript, a tiny line-oriented DSL for browser actions (GOTO, CLICK, TYPE, WAIT, SCROLL, HOVER, SELECT, CHECK, EXTRACT, EVAL, LOGIN, ACCEPT_COOKIES, TREE, MARKDOWN).
  • Recording and replay of .lp scripts. agent script.lp replays without any LLM call; agent -i script.lp replays then drops into the REPL, appending new commands to the file.
  • Self-healing replay (--self-heal): when a recorded command fails on a drifted page, a short LLM turn inspects the current state, emits a fixed command, and rewrites the script line in place.
  • One-shot mode (--task): a single user turn whose final answer goes to stdout, with progress and tool calls on stderr, so the result can be captured cleanly.
  • Slash commands in the REPL: /<tool> [args] invokes a browser tool directly without going through the LLM. /help lists tools, /quit exits the REPL.
  • Tab completion (case-insensitive) over PandaScript keywords and slash commands, with a dim ghost-suffix hint. Persistent history in .lp-history.

arrufat added 30 commits April 20, 2026 13:27
- Use `atomicFile` for script updates in `Agent.zig`.
- Ensure `ai_client` is properly deinitialized on `init` failure.
- Consolidate JSON quoting into `Command.buildJson`.
- Simplify `Recorder` and `ToolExecutor` implementations.
- Fix page scope access in `mcp/tools.zig`.
- Update `ToolExecutor.callEval` to return `EvalResult` for better error handling.
- Swap `ScriptIterator.init` arguments to follow the allocator-first convention.
- Use explicit type syntax for `.init` calls across the agent package.
- Remove redundant `isKnownTool` helper in favor of direct enum conversion.
Updates prompts to report access errors literally and forbids prior
knowledge fallback. Increases terminal tool result display limit.
@arrufat arrufat changed the title Add agent mode: LLM-driven REPL, scripted replay, MCP server, shared tools layer Add agent mode: LLM-driven REPL, scripted replay, shared tools layer May 18, 2026
arrufat added 23 commits May 19, 2026 10:09
Reorder defer statements in agentThread to ensure the signal bridge is
detached before the agent instance is deinitialized.
Sorts environment variables by value length descending to prevent
shorter values from clobbering longer ones during substitution.
Updates the `enabled` field in `Spinner` to use `std.atomic.Value(bool)`.
This prevents potential race conditions between the agent thread and
the spinner worker thread when checking or updating the state.
- Prevent UB in `applyReplacements` with pointer assertions.
- Reorder `writeAtomic` to build content before writing backup.
- Strip trailing `\r` in `ScriptIterator` for CRLF compatibility.
- Use shorter representation for `SCROLL` commands.
- Make `VerifyResult.failed` reason non-optional with an OOM fallback.
- Use `ElementProperty` enum for safer JS property injection.
- Ensure `Recorder` disables on all errors to prevent silent data loss.
- Add `CHECK` command round-trip test.
Explains that Ctrl-C is ignored during the synchronous model listing
call because it occurs before SigBridge.attach.
Adds the `-a` short flag, improves CLI validation for one-shot mode,
and ensures `--model` takes precedence over `--pick-model`.

BREAKING CHANGE: `--task-attachment` has been renamed to `--attach`.
- Replace `Self` with `Recorder` and `Verifier` for improved clarity.
- Add `Spinner.isEnabled()` to encapsulate atomic state access.
- Shorten and refine various comments across the codebase.
Unifies tool outcomes into a `ToolResult` struct, replacing `EvalResult`.
Renames `CommandExecutor` to `CommandRunner` and simplifies error handling.
Introduce an `Llm` struct to bundle the provider and API key together.
Add `UserError` to identify errors that have already printed human-
readable messages, preventing duplicate logging on exit.
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