Commit Graph

220 Commits

Author SHA1 Message Date
Adrià Arrufat
c92dad165f command: add /logout and refactor LLM commands 2026-05-30 22:03:46 +02:00
Adrià Arrufat
47072a82e6 repl: use explicit summaries for command help
Replaces the fragile `firstSentence` parser with an explicit `summary`
field on tool definitions. Also standardizes user-facing REPL
terminology to "command" instead of "slash command" or "tool".
2026-05-30 20:06:30 +02:00
Adrià Arrufat
1f85de3d3d agent: use ZON format for remembered config
Migrates the `.lp-agent` file to `.lp-agent.zon` and uses `std.zon`
for serialization and parsing.
2026-05-30 19:10:40 +02:00
Francis Bouvier
8052f0ad81 Agent model provider picker (#2581)
* agent: add a /model command to chnage current model

And remove the pick-model CLI option

* agent: add /provider to change the current provider

* agent: extract requireLlmNoArg helper

* agent: simplify provider detection

* repl: add tab completion for /model and /provider

Changes `/model` and `/provider` to accept an optional name argument
instead of prompting with a numbered list. Bare commands now print the
current selection, while Tab dynamically completes candidates. Model
lists are fetched and cached to prevent redundant network requests.

* agent: remember last selected provider and model

Persists the last selected AI provider and model in a local
`.lp-agent` file and resumes it on startup. Removes the
interactive provider picker in favor of deterministic auto-detection.

* agent: simplify requireLlm and model resolution

Changes `requireLlm` to return a boolean instead of credentials, and
cleans up the model initialization logic to use `resolved` directly.
Also removes unused user errors.

---------

Co-authored-by: Adrià Arrufat <adria.arrufat@gmail.com>
2026-05-30 19:02:44 +02:00
Adrià Arrufat
63bcba5eab agent: add verification guidelines to system prompt
Instructs the agent to cross-check ambiguous sources and commit to a
choice for multi-candidate questions instead of abstaining.
2026-05-29 17:21:39 +02:00
Adrià Arrufat
0a107e07a2 Merge pull request #2576 from lightpanda-io/agent_save_cmd
agent: add REPL /save command for recorded sessions
2026-05-29 15:55:49 +02:00
Adrià Arrufat
33b8af4eed agent: simplify default system prompt 2026-05-29 15:51:49 +02:00
Adrià Arrufat
135e7a0f9f Agent: simplify save handling and recorder logic
- Remove unused parameters from save helper functions.
- Inline and simplify save path duplication and file writing.
- Clean up optional unwrapping for the recorder.
2026-05-29 15:41:15 +02:00
Francis Bouvier
142c940b21 agent: add REPL /save command for recorded sessions
Add a REPL-only `/save [filename.lp]` command that persists the current
  interactive session as PandaScript without requiring the user to start the
  agent with `-i <script>`. The command records the same replayable actions as
  the existing script recorder, but keeps them in memory until the user chooses
  to save.

  Functional behavior:

  - During a REPL session, record replayable browser actions into an in-memory
    script buffer.
  - Manual slash commands are recorded through the same PandaScript formatting
    and filtering rules used by file recording.
  - Natural-language turns record their prompt as a `# ...` comment only when
    the LLM turn produces at least one successful replayable tool call.
  - Failed LLM tool calls are skipped, and repeated successful `/extract` calls
    keep only the last successful extract, matching the existing recorder logic.
  - `/save filename.lp` writes the current in-memory recording to that file.
  - Bare `/save` creates a random `session-<hex>.lp` file on first save.
  - If the first save targets an existing file, prompt with the existing numbered
    TTY picker and ask whether to replace or append.
  - After the first successful save, the REPL session is locked to that filename:
    later `/save` or `/save same-file.lp` appends to the same file without
    prompting, while `/save other-file.lp` is rejected.
  - After each successful save, reset the in-memory recorder so future saves only
    append actions entered since the previous save.
  - On any `/save` error or cancellation, keep the in-memory recorder intact so
    the user can retry without losing captured actions.
  - Restrict `/save` filenames to local file names, not paths, to keep behavior
    scoped to the current directory.

  Code changes:

  - Add `Recorder.Memory`, an in-memory recorder that shares the existing
    `Command.isRecorded`, `Command.format`, comment formatting, and `LP_*`
    reverse-substitution behavior with file recording.
  - Add `Recorder.Memory.reset()` so `/save` can clear only successfully saved
    deltas.
  - Add `/save` to the REPL meta command table and help/completion surface.
  - Add `save_buffer` and `save_path` state to `Agent`.
  - Feed manual REPL tool calls into `save_buffer` alongside the existing optional
    file recorder.
  - Extend LLM turn recording with a `capture_for_save` flag so natural-language
    REPL turns can be captured without affecting non-REPL script/self-heal paths.
  - Implement `/save` handling in `Agent`:
    - parse and validate the optional filename,
    - choose replace/append for existing first-save targets,
    - remember the first successful save path,
    - enforce the single-destination rule for the rest of the session,
    - append later deltas by default,
    - commit remembered path state only after a successful file write.
  - Add focused coverage for the memory recorder’s filtering and reset behavior.
2026-05-29 13:32:53 +02:00
Adrià Arrufat
ff95f83f74 agent: track and print token usage in one-shot mode
Updates zenai and aggregates token usage across all model calls.
Prints a `$usage` summary to stderr at the end of a task.
2026-05-29 12:44:20 +02:00
Adrià Arrufat
693db15281 browser: support markdown scoping and truncation
Adds `selector`, `backendNodeId`, and `maxBytes` options to the
`markdown` tool. This allows rendering specific subtrees and capping
large outputs. Also updates the agent guidance to prefer scoped reads.
2026-05-26 16:06:42 +02:00
Adrià Arrufat
8abbd6d9c0 Script: handle duplicate argument keys and URL query params 2026-05-25 19:25:58 +02:00
Adrià Arrufat
6e7a4420e3 terminal: deduplicate error and warning printing
Extracts the common printing logic from `printError` and `printWarning`
into a new `printSeverity` helper function.
2026-05-25 18:18:20 +02:00
Adrià Arrufat
4bc5baf7ee agent: improve command diagnostics and fix various bugs
- Add diagnostics to command parsing to report invalid field values.
- Fix UTF-8 truncation in spinner to avoid splitting codepoints.
- Fix swapped arguments in log error formatting.
- Distinguish "null" values from missing elements in verifier.
- Handle MCP tool cancellation and timeouts with specific error codes.
2026-05-25 17:51:46 +02:00
Adrià Arrufat
adc76d2cc1 agent: fix tool output capping and tokenizer escape handling
- Limit UTF-8 walkback in `capToolOutput` to 3 bytes to prevent
  excessive scanning on malformed input.
- Track consecutive backslashes in `tokenize` to correctly handle
  even-count backslashes before a closing quote.
2026-05-24 12:18:05 +02:00
Adrià Arrufat
634566f4b8 agent: truncate tool output at UTF-8 boundary 2026-05-24 11:48:22 +02:00
Adrià Arrufat
aed5bbf1b6 schema: reject backslash escapes in quoted values
Explicitly reject backslash-escaped quotes with a clear error
message, suggesting alternative quote styles or triple quotes.
Bare backslashes (e.g. in Windows paths) remain supported.
2026-05-24 11:35:07 +02:00
Adrià Arrufat
ddd9c84195 agent: update zenai and tune agent settings 2026-05-23 23:36:07 +02:00
Adrià Arrufat
6a0801a6f6 agent: add user turn before slash tool call
Gemini requires that a function call follow a user or function-response
turn. Record the user input before the synthetic assistant tool call.
2026-05-23 14:46:32 +02:00
Adrià Arrufat
4c06fe482f agent: record slash commands as tool calls
Mirrors user-typed slash commands into the message history as synthetic
tool calls. This ensures the LLM conversation remains in sync and the
next prompt can see the action's result.
2026-05-23 11:54:48 +02:00
Adrià Arrufat
0670823905 script: rename mcp_driver_guidance to driver_guidance
Rename the system prompt constant to reflect its broader usage.
Also add instructions to guide the agent on handling follow-up
questions after navigation.
2026-05-23 11:24:36 +02:00
Adrià Arrufat
f917a7adfc terminal: simplify print API and add printDimmed
Unifies printInfo/printInfoFmt and printError/printErrorFmt into
single functions accepting format arguments. Adds printDimmed for
dimmed output and supports highlighting quoted slash arguments.
2026-05-22 21:49:41 +02:00
Adrià Arrufat
4d283ae21c terminal: improve colors and help formatting
- Remove automatic dimming from `printInfoFmt`
- Add explicit ANSI formatting to slash command help
- Adjust syntax highlighting colors for terminal output
2026-05-22 20:56:35 +02:00
Adrià Arrufat
d4f4be704d repl: categorize help and centralize LLM checks
- Group `/help` output into Browser, LLM, and Meta commands.
- Only show LLM commands in help if an LLM client is configured.
- Centralize the check for commands requiring an LLM in the REPL loop.
- Add descriptions to meta and LLM commands.
2026-05-22 20:24:24 +02:00
Adrià Arrufat
0049480f04 Merge pull request #2528 from lightpanda-io/parseargs-error-detail
terminal: better error diagnostics
2026-05-22 20:10:07 +02:00
Adrià Arrufat
91916b7aae repl: sort slash commands alphabetically in help 2026-05-22 20:09:56 +02:00
Adrià Arrufat
c30ccae5fb terminal: improve log routing and navigation error reporting
- Route logs through a terminal sink to avoid trampling the spinner.
- Track and format the last navigation error in browser tools.
2026-05-22 19:58:02 +02:00
Adrià Arrufat
2669e3223f browser: add cooperative cancellation support
Allows SIGINT to abort in-flight browser operations and V8 execution.
2026-05-22 19:22:46 +02:00
Adrià Arrufat
f7a4d1f6e2 terminal: unify tool and action result printing
Replaces `printActionResult` and `printToolResult` with a single
`printToolOutcome` function. This unifies the output path and adds
red/green color coding for tool failures and successes.
2026-05-22 19:05:46 +02:00
Adrià Arrufat
1309407e01 script: unify heal formatting and move TTY helpers
- Merge `formatHealReplacement` and `formatHealReplacementLines` using
  a new `HealBody` union.
- Move `interactiveTty` and `promptNumberedChoice` to `Terminal.zig`.
- Relocate and consolidate tests for `canHeal` and `isRecorded`.
- Make internal `Schema` functions private.
2026-05-22 16:19:46 +02:00
Adrià Arrufat
486d0d53a9 agent: inline CommandRunner and simplify Command union 2026-05-22 15:50:36 +02:00
Adrià Arrufat
3a792c7c1c command: centralize slash command parsing and retry logic 2026-05-22 15:17:59 +02:00
Adrià Arrufat
8fb3c7baed tools: restructure browser tools and script schemas
- Replace `Action` enum with `Tool` enum using exhaustive switches
- Extract `ScriptIterator` to `Iterator.zig`
- Refactor `schema.zig` into `Schema.zig`
- Move string substitution logic into `tools.zig`
- Clean up `SlashCommand.zig` to only handle REPL meta-commands
2026-05-22 13:41:04 +02:00
Adrià Arrufat
a3eeec0b26 agent: use global tools and simplify meta commands
- Initialize tools once globally instead of allocating per-agent.
- Refactor meta commands to use an enum for cleaner dispatch.
- Remove unused `findSchemaCanonical` and simplify command parsing.
2026-05-21 23:24:21 +02:00
Adrià Arrufat
6177d51c4e agent: use action enum for tool calls and trim REPL input
- Update `buildToolCall` to use `browser_tools.Action` enum.
- Trim whitespace from REPL input in `Agent.zig`.
- Replace `expectEqualStrings` with `expectString` in tests.
2026-05-21 23:06:34 +02:00
Adrià Arrufat
e9943a3976 command: use Action enum for ToolCall name
Replaces the string `name` in `ToolCall` with `action: browser_tools.Action`.
This avoids repeated string-to-enum parsing and simplifies schema lookups.
Also updates `zenai` dependency to use its JSON duplication helper.
2026-05-21 22:51:52 +02:00
Adrià Arrufat
13ebb9e802 agent: simplify command, schema, and repl logic
- Remove `input_schema_raw` from `SchemaInfo` and use `parameters` directly
- Simplify JSON field extraction in `Verifier` to avoid `parseArgs`
- Refactor REPL command splitting and environment substitution
- Clean up and condense comments across the codebase
2026-05-21 22:39:58 +02:00
Adrià Arrufat
e89fb9b485 agent: simplify tool allocation and schema info
Remove `tool_schema_arena` from `Agent` and allocate the tools slice
directly using the general allocator.

Remove the pre-calculated `is_multiline_capable` field from
`SchemaInfo` and compute it dynamically in `isMultiLineCapable()`.
2026-05-21 22:24:27 +02:00
Adrià Arrufat
3b2956c400 schema: simplify initialization and parsing
- Use global schemas built once at startup instead of parsing on init.
- Simplify argument verification using `browser_tools.parseArgs`.
- Optimize `parseValue` with `std.ArrayList`.
- Panic on global schema parse failure since schemas are static.
2026-05-21 22:17:21 +02:00
Adrià Arrufat
8cf431b771 agent: remove ToolExecutor abstraction
Inlines the browser, session, and node registry management directly
into Agent. Updates CommandRunner to use Session and Registry directly,
and calls browser_tools.call without the ToolExecutor wrapper.
2026-05-21 22:02:27 +02:00
Adrià Arrufat
349b4ea798 agent: clean up dead code and optimize schema parsing
- Remove unused `callEval` and `extract` from `ToolExecutor`.
- Optimize `parseValue` in `schema.zig` to allocate directly instead of
  using `std.ArrayList` when filling missing defaults.
- Simplify redundant checks and clean up comments.
2026-05-21 21:41:28 +02:00
Adrià Arrufat
d16f8a032e script: support triple-quoted strings and optimize lookups
- Add support for triple-quoted strings (''' and """) in the tokenizer
  and quote stripper.
- Avoid allocations in `stripQuotes` by returning slices.
- Optimize schema lookups using O(1) enum-based canonical resolution.
- Skip env var substitution if "$LP_" is not present in the string.
2026-05-21 21:33:05 +02:00
Adrià Arrufat
7f60d73338 use global schemas and enum-based tool matching
- Use `SlashCommand.globalSchemas()` instead of passing schemas around.
- Use `browser_tools.Action` enums for tool matching in Agent and Verifier.
- Optimize string substitution and quote stripping with early exits.
2026-05-21 21:08:02 +02:00
Adrià Arrufat
0ce0d264a4 agent: prevent use-after-free in self-heal path 2026-05-21 20:45:03 +02:00
Adrià Arrufat
459893f414 script: unify PandaScript to slash commands
Unifies PandaScript syntax by replacing uppercase keywords with slash
commands (e.g., `/goto`, `/click`, `/fill`). Refactors the `Command`
representation to use a generic tool call structure backed by schemas.

BREAKING CHANGE: Uppercase PandaScript keywords (GOTO, CLICK, TYPE, etc.)
are no longer supported. All scripts must use slash commands.
2026-05-21 20:38:21 +02:00
Adrià Arrufat
88ac71a474 agent: remove no_llm field 2026-05-21 19:05:55 +02:00
Adrià Arrufat
19c361c2e8 agent: use zenai credentials detection 2026-05-21 19:03:48 +02:00
Adrià Arrufat
2bd24ba30e agent: use zenai envVarName helper 2026-05-21 18:55:50 +02:00
Adrià Arrufat
758d2c48fb agent: require --no-llm for basic REPL 2026-05-21 18:37:16 +02:00
Adrià Arrufat
ceb5f368f0 script: rename raw_line to opener_line 2026-05-21 18:01:46 +02:00