Commit Graph

6342 Commits

Author SHA1 Message Date
Adrià Arrufat
ecfb404af4 agent: require ALL CAPS for commands 2026-05-11 11:41:04 +02:00
Adrià Arrufat
3273898e97 browser.tools: reduce eval branch quota in minify 2026-05-11 09:18:09 +02:00
Adrià Arrufat
0ffabdd278 browser.tools: simplify minify function logic 2026-05-11 09:13:55 +02:00
Adrià Arrufat
1423cbe1d1 refactor: optimize agent memory and browser tools
- Rebuild `message_arena` during self-heal to prevent memory accumulation.
- Optimize `minify` comptime performance by avoiding string concatenation.
- Update `extractText` to use `runEval` and sentinels for better reliability.
- Add logging for long environment variable names in `lookupLpEnv`.
2026-05-11 09:07:27 +02:00
Adrià Arrufat
0338bf71af refactor: simplify mcp communication and tool dispatching 2026-05-11 08:57:36 +02:00
Adrià Arrufat
ecc68f8780 Merge branch 'main' into agent 2026-05-11 08:03:35 +02:00
Karl Seguin
efbf1db87c Merge pull request #2410 from lightpanda-io/fix_merge
Try to fix a bad merge
2026-05-11 11:37:28 +08:00
Karl Seguin
0bbddb3179 Try to fix a bad merge
https://github.com/lightpanda-io/browser/pull/2289
and
https://github.com/lightpanda-io/browser/pull/2297
2026-05-11 11:25:40 +08:00
Karl Seguin
1bfefa3d58 Merge pull request #2289 from navidemad/fix-b2-page-navigation-history
page: implement Page.getNavigationHistory and Page.navigateToHistoryEntry
2026-05-11 09:29:43 +08:00
Adrià Arrufat
aae699e3b5 refactor: simplify MCP tool results and optimize slash command
Consolidates MCP tool listing and result sending. Optimizes buffer
allocation in SlashCommand.stripQuotes.
2026-05-10 17:22:33 +02:00
Adrià Arrufat
10f7478099 refactor: unify tool arg parsing and simplify string formatting 2026-05-10 17:07:57 +02:00
Karl Seguin
92d617d649 Merge pull request #2404 from navidemad/fix-fetch-double-free-on-sync-error
Fix double-free in fetch when http_client.request fails synchronously
2026-05-10 12:03:07 +08:00
Karl Seguin
520d968840 Merge pull request #2398 from staylor/fix/worker-importscripts-segfault
Defer page teardown while worker scripts are evaluating
2026-05-10 11:08:49 +08:00
Karl Seguin
261059acbe Merge pull request #2393 from lightpanda-io/scheduler_timeslice
Add timeslice to scheduler
2026-05-10 10:33:21 +08:00
Adrià Arrufat
e7d6597e08 refactor: unify URL handling and clean up agent logic 2026-05-10 00:04:51 +02:00
Scott Taylor
92607ad765 Defer page teardown while worker scripts are evaluating
Worker scripts can call importScripts(), which performs a synchronous
HTTP request via HttpClient.syncRequest. To stay responsive during a
long fetch, syncRequest pumps the CDP socket (cdp.blocking_read) while
waiting. If a CDP message such as Target.closeTarget arrives on that
socket mid-fetch, the previous code path tore down the page
immediately:

    Worker JS -> importScripts -> syncRequest -> blocking_read
      -> CDP dispatch -> Target.closeTarget
      -> Session.removePage -> Page.deinit -> Frame.deinit
      -> Worker.deinit (frees worker arena + identity_map)

When control unwound back into the worker's eval, the next operation
that hit ctx.identity.identity_map.getOrPut dereferenced the freed
metadata pointer and segfaulted (sometimes immediately, sometimes a
few connections later as the arena got recycled).

Reproducer: any URL that loads dedicated workers calling importScripts
during initial eval, driven via puppeteer-core's connectOverCDP. The
allbirds.com product page (which loads ~8 web-pixel workers each
calling importScripts) reliably triggered it within ~10 connections.

Session.removePage already deferred when the frame's own
ScriptManager.is_evaluating was set; that guard never tripped because
worker scripts don't go through the frame's ScriptManager. Fix:

  * Worker.loadInitialScript now sets the worker's own
    _worker_scope._script_manager.is_evaluating around the eval, with
    save/restore so nested worker evals compose correctly.

  * WorkerGlobalScope.importScript also sets its own
    _script_manager.is_evaluating around the syncRequest +
    runMacrotasks. The typical caller (Worker.loadInitialScript)
    already sets this around its outer eval, so the outer guard
    usually covers us; the inner mark is defense-in-depth for callers
    that reach importScripts() from a setTimeout / microtask outside
    the loadInitialScript scope.

  * New Frame.anyScriptEvaluating method walks the frame tree (frame
    ScriptManager + every worker's ScriptManager + child frames) and
    returns true if any is mid-eval. Session.removePage and
    CDP.disposeBrowserContext use this in place of the frame-only
    check, deferring teardown until all evals unwind. Final cleanup
    happens at CDP.deinit on connection close, matching the existing
    deferred-teardown contract.

Verified by running the puppeteer-core repro back-to-back against a
single Lightpanda serve; all returned 200 with the right title, no
UAF crashes (was previously crashing within 1-10 runs). All 521 unit
tests still pass.

Note: a separate, pre-existing latent V8 issue surfaces under stress
on this same code path. After many iterations a Runtime.evaluate
promise tracked by V8's inspector PromiseHandlerTracker is discarded
during garbage collection's first-pass weak callbacks; the discard
sends a failure response which triggers v8::String::NewFromOneByte,
hitting the debug-only assertion AllowHeapAllocation::IsAllowed() in
heap-allocator-inl.h:79 (no allocations allowed during weak callbacks).
This reproduces on a baseline build of this PR commit and on a
baseline build of just the original two-line is_evaluating fix \u2014
i.e. it is not introduced by the deferral logic. The deferral makes
it more visible because inspector callbacks now live longer before
teardown, so they are more likely to be alive during a GC. Tracking
this as a follow-up; the fix here still resolves the UAF that was
crashing the server immediately.
2026-05-09 17:26:41 -04:00
Adrià Arrufat
a5e7ec16be agent: unify interactive prompts and tool execution 2026-05-09 20:40:38 +02:00
Adrià Arrufat
1de98efbc4 agent: simplify model string ownership 2026-05-09 20:27:16 +02:00
Adrià Arrufat
5284abc3e7 agent: consolidate listModels logic into Agent.zig 2026-05-09 20:18:27 +02:00
Adrià Arrufat
938795ec8d agent: add --pick-model for interactive selection 2026-05-09 20:11:52 +02:00
Adrià Arrufat
16b83f5093 agent: add provider auto-detection and --no-llm flag 2026-05-09 19:52:42 +02:00
Adrià Arrufat
357033eb0c agent: add --list-models flag 2026-05-09 19:16:48 +02:00
Adrià Arrufat
5f2a46b311 browser: use explicit switch cases for tool actions 2026-05-09 18:27:51 +02:00
Adrià Arrufat
2b4e69b517 refactor: improve recorder and spinner state management
Moves recording state into Recorder and uses a tagged union for Spinner
state. Introduces TurnInput to simplify Agent turn processing.
2026-05-09 18:05:52 +02:00
Adrià Arrufat
7726ad4623 agent: avoid JSON round-trips in tool calls
Use `std.json.Value` directly for tool arguments instead of
stringifying and reparsing. This optimizes the hot replay path
in the agent and MCP server.
2026-05-09 17:53:41 +02:00
Adrià Arrufat
5b5e42cbaa refactor: optimize string building and unify text extraction 2026-05-09 17:47:28 +02:00
Navid EMAD
d7e283fed9 Don't propagate http_client.request errors from Fetch.init
When http_client.request fails synchronously (e.g. RobotsLayer returning
RobotsBlocked because robots.txt is already cached), Client.request
invokes our error_callback before returning the error. httpErrorCallback
rejects the promise and releases response._arena. Letting the error
propagate from Fetch.init also fires the `errdefer response.deinit`,
double-freeing the arena and corrupting the arena pool — eventually
surfacing as a malloc abort during teardown.

Fixes #2403.
2026-05-09 14:57:08 +02:00
Adrià Arrufat
372c0a12a2 agent: simplify logic and cleanup comments 2026-05-08 08:23:19 +02:00
Adrià Arrufat
8e1bf69b57 Merge branch 'main' into agent 2026-05-08 08:08:39 +02:00
Karl Seguin
c633617544 Add timeslice to scheduler
Give scheduler a 500ms timeslice to run per queue (high/low priority).

A site can load hundreds of timeouts to all execute at the same time. These
can be relatively expensive (e.g. lots of calls directly or indirectly to
getBoundingClientRect). As-is, the scheduler drains its queue to completion and
other timeouts, like --wait-ms can't do what they're meant to do. By adding
timeslice, we prevent many tasks all scheduled for the same time to go
unchecked.

I was initially planning on putting this higher in runMacrotasks, but that could
lead to starvation, i.e. if the first context used up all the time. Having it
per context is more fair, at the cost of running 500ms * context. But, (a) the
number of context we allow is fixed and (b) the reality is that most sites have
few contexts and normally only the first one is doing anything interesting.
2026-05-08 10:34:47 +08:00
Karl Seguin
6e9156a86f Merge pull request #2389 from lightpanda-io/interception-layer-on-serve
InterceptionLayer only on `.serve` mode
2026-05-08 06:51:03 +08:00
Karl Seguin
97f95a992e Merge pull request #2388 from lightpanda-io/cache-clear
Add Clear to Cache and FsCache
2026-05-08 06:50:35 +08:00
Karl Seguin
ffee9e67ce Merge pull request #2377 from lightpanda-io/page_dom_version
Track DOM version on the page
2026-05-08 06:45:16 +08:00
Karl Seguin
b8674cd252 Merge pull request #2379 from lightpanda-io/setter_and_static_arity
Give setters an arity of 1
2026-05-08 06:45:00 +08:00
Adrià Arrufat
77fc818976 refactor: optimize tool calls and improve script healing 2026-05-07 20:30:49 +02:00
Adrià Arrufat
622d408d03 mcp: add verification to script_step 2026-05-07 20:18:37 +02:00
Adrià Arrufat
c6ccd83ac4 mcp: add pandascript recording and self-healing tools
Adds tools to record sessions and heal scripts over MCP. Refactors
shared logic to `script.zig` and adds a TTY spinner for the agent.
2026-05-07 20:11:40 +02:00
Muki Kiboigo
66293ebc99 only enable InterceptionLayer on .serve mode 2026-05-07 09:03:40 -07:00
Muki Kiboigo
14e1f1bcf6 add clear fn to Cache and FsCache 2026-05-07 09:00:33 -07:00
Pierre Tachoire
1131cb09ff Merge pull request #2387 from lightpanda-io/zig-fmt-ci
Fix zig fmt step in CI
2026-05-07 17:49:15 +02:00
Adrià Arrufat
7bf69a9a34 agent: remove integrated mcp server
Removes the `--mcp` flag and the internal `task` tool from the agent.
Users should use `lightpanda mcp` for external agent integrations.
2026-05-07 17:12:46 +02:00
Muki Kiboigo
e5e5f78928 fix formatting on EventTarget.zig 2026-05-07 08:10:43 -07:00
Muki Kiboigo
f54ee13b32 fix zig fmt step in CI 2026-05-07 08:09:33 -07:00
Karl Seguin
fbb8126cc4 Merge pull request #2378 from lightpanda-io/blank_navigation
Protect assertion when reload from about:blank
2026-05-07 23:00:33 +08:00
Karl Seguin
823a7c480d Merge pull request #2380 from lightpanda-io/illegal_instructor_capture_name
On Illegal Constructor, try to capture name (for logs)
2026-05-07 23:00:13 +08:00
Adrià Arrufat
16e61e342e terminal: simplify spinner access and organize ansi codes 2026-05-07 16:38:11 +02:00
Adrià Arrufat
855ab768fa terminal: show tool execution trace in spinner mode 2026-05-07 16:28:16 +02:00
Karl Seguin
d4a210c5f1 Merge pull request #2385 from lightpanda-io/avoid_script_error_double_free
On error, don't free headers
2026-05-07 22:11:58 +08:00
Adrià Arrufat
a254e4041a agent: refine verbosity levels and tool output UI 2026-05-07 16:11:28 +02:00
Adrià Arrufat
54d873e007 agent: add proactive login and silence tool errors 2026-05-07 15:51:18 +02:00