Commit Graph
8555 Commits
Author SHA1 Message Date
Karl Seguin df084b2cab Merge pull request #3146 from lightpanda-io/style-width-children-aware
render: CSS width/height are now children-content aware
2026-08-07 07:15:23 +08:00
Karl Seguin deb4eb3eef Merge pull request #3155 from lightpanda-io/zenai-bump
build: update zenai dependency
2026-08-07 07:14:57 +08:00
Adrià Arrufat 8e3d6adeee build: update zenai dependency
Pulls in the latest three zenai commits:

- f721fd4 feat(retry): honor Retry-After hints on retryable responses
- 103f5e1 feat(retry): treat 408 request timeout as retryable
- 75597b3 feat(types): sync with upstream Go SDK releases
2026-08-06 14:24:11 +02:00
Adrià Arrufat ce36e3880e Merge pull request #3151 from lightpanda-io/run-subcommand-docs
docs: prefer `lightpanda run` for replaying scripts
2026-08-06 13:55:49 +02:00
Adrià Arrufat 23c8f04b1f Merge pull request #3149 from lightpanda-io/tools-unknown-name-in-band
tools: surface unknown tool names in-band
2026-08-06 13:02:37 +02:00
Adrià Arrufat 78f24b5da5 docs: prefer lightpanda run for replaying scripts
The `run` subcommand is the intended way to replay a recorded
PandaScript (`agent <script>.js` still works, but `run` carries no LLM
options and states the intent). Update the generated script-writing
skill, the recorder doc comment, and the README accordingly.
2026-08-06 13:02:17 +02:00
Adrià Arrufat aaa7a5434b tools: surface unknown tool names in-band
An LLM that invents a tool name (e.g. OpenAI's internal
multi_tool_use.parallel wrapper leaking through as a literal tool call)
previously got back "Error: InvalidParams" — the same message as
malformed arguments — so its natural correction was to retry the bogus
name with reshuffled args. Return an in-band "Unknown tool: <name>"
error result instead so the model learns the name itself is wrong.

The MCP and slash-command paths validate names before reaching call(),
so only the LLM tool-call path is affected.
2026-08-06 10:29:56 +02:00
Adrià Arrufat f55aa1a669 Merge pull request #3140 from lightpanda-io/goto-waituntil
goto: optional waitUntil + dcl-gated selector waits
2026-08-06 07:32:05 +02:00
Karl Seguin 9b05efd689 Merge pull request #3147 from lightpanda-io/silence-test-logs
chore: silence test logs for expected error case
2026-08-06 10:27:49 +08:00
Karl Seguin 7cd14cd114 zig fmt 2026-08-06 10:10:34 +08:00
Karl Seguin ef237a7e20 chore: silence test logs for expected error case 2026-08-06 10:08:37 +08:00
Karl Seguin 58cfe511ac render: CSS width/height are now children-content aware
This takes https://github.com/lightpanda-io/browser/pull/3137 and applies is to
the width/height CSS values (e.g. CSSStyleCSSStyle.getPropertyValue("width")) to
provide a consistent width/height view of an element.

Fixes slow rendering of https://inchurch.com.br
2026-08-06 09:59:19 +08:00
Karl Seguin 7a9460ff10 Merge pull request #3142 from lightpanda-io/fetch-redirect-interception
cdp: send request information (RI) notifications on redirect
2026-08-06 07:21:05 +08:00
Karl Seguin 7c89a462eb cdp: send request information (RI) notifications on redirect
Extracted from https://github.com/lightpanda-io/browser/pull/3122. Sends RI for
redirect. Also, on a continueRequest which does redirect, restores the original
headers (continueRequest's headers are only valid for a single request).

To make this work in all drivers, CDP now decouples the transfer_id from the
intercept_id. Each unique request gets a distinct intercept_id which is managed
in CDP (with a intercept_id -> transfer_id mapping).
2026-08-06 06:53:54 +08:00
Karl Seguin 6a080207e1 Merge pull request #3145 from lightpanda-io/getComputedStyle-pseudo-
webapi: Improve getComputedStyle with pseudo
2026-08-06 06:49:01 +08:00
Karl Seguin 835b3e1e01 Merge pull request #3144 from lightpanda-io/custom-element-creation
Custom element creation
2026-08-06 06:48:51 +08:00
Karl Seguin 390c5c0e2d Merge pull request #3122 from staylor/fix/playwright-cdp-session-routing
Fix Playwright auxiliary CDP session interception
2026-08-06 06:48:07 +08:00
Karl Seguin 13d08d394d webapi: Improve getComputedStyle with pseudo
1. Stop logging not_implemented for :before, :after - they are used a lot and
   the log is just noise

2. Change the computed style identity map key from element -> (element,
   pseudo_type). This ensures that the same element+pseudo correctly gets the
   same CSSStyleProperties, and it avoids needlessly creating more objects for
   a repeated element/pseudo pair.
2026-08-05 20:51:22 +08:00
Adrià Arrufat 17c30c3a52 Merge branch 'main' into goto-waituntil 2026-08-05 13:08:23 +02:00
Karl Seguin 966050aa59 webapi: fix custom-element creation logic
Follow up to https://github.com/lightpanda-io/browser/pull/3130

https://mf5ai1-cc.myshopify.com/products/ultimate-blue-raspberry-cyborg-ii-for-lefties-bundle?_fd=0

Loads with various errors, and hits an unreachable in debug mode. The core issue
is how we create already-defined custom-elements. We need to run the constructor
validate the state (a bunch of post-create conditions we need to check) and, on
failure, fallback to a simple HTMLUnknownElement. Without the validation, the
constructor can result in a state that we shouldn't allow, and html5ever ends up
spitting a result it promises not to (because we fed it an invalid sequence).
2026-08-05 18:15:39 +08:00
Karl Seguin 83db6a394d Simplify termination tracking, remove undefined.
1. Every `var caught: js.TryCatch.Caught = undefined;` is now defaulted to .{}.
   This eliminates a possible dirty read. Function tryCall (and its variants)
   were guarding against this, but newInstance wasn't.

2. Env.terminate() now immediately sets `terminate_requested` which means
   `isExecutionTerminating` is removed and only `terminatePending` exists, and
   it only needs to check `terminate_requested`.
2026-08-05 16:51:43 +08:00
Adrià Arrufat c793ea8c0f cdp: LP.waitForSelector shares the state-dependent wait default
Review flag: the dcl gating in actions.waitForSelector also changed the CDP
extension, which kept a flat 5s default. It now uses the same rule as the
tool layer (5s at load, 15s before), so a mid-navigation call keeps the wall
budget it had when the pre-wait ran to load. Explicit timeouts unchanged.
2026-08-05 09:11:08 +02:00
Adrià Arrufat 6c1a9a58ba tools: waits entered before load default to the nav budget too
Review feedback on the dcl gating: a selector that only appears after load
used to get goto's 10s plus the wait's 5s; after a domcontentloaded
navigation the same selector had only time-to-dcl + 5s. waitForSelector and
waitForScript now default to 15s when the page hasn't reached load, 5s once
it has (unchanged for every pre-existing flow). An explicit timeout always
wins.
2026-08-05 09:05:12 +02:00
Karl Seguin 33763f70ab Merge pull request #3143 from lightpanda-io/fix-webdriver-build
fix: Fix broken WPT build (-Dwpt_extensions)
2026-08-05 15:00:11 +08:00
Adrià Arrufat ffd293a18e goto: warn against 'done' in the waitUntil description
Review feedback: 'done' sounds like what people want and is the slowest
option. Same treatment as waitForState's description.
2026-08-05 08:59:28 +02:00
Karl Seguin 4e8533b040 fix: Fix broken WPT build (-Dwpt_extensions)
Broken by: https://github.com/lightpanda-io/browser/pull/3128
2026-08-05 14:41:17 +08:00
Karl Seguin f9071d1cf8 split PR, fix non-playwright drivers
As-is, this PR (3122) includes 2 distinct fixes:
1 - a Target.attachToTarget should create a distinct session_id
2 - http redirects with request interception (RI) should:
    a - not preserve the original RI headers, and
    b - should send their own RI request to the driver

This commit removes #2 so that it can be done in its own follow up. #2 is
relatively big. The commit also removes the integration test and CI changes.
These will be ported to the demo project to leverage the existing CI flow.

3122 breaks non-playwright drivers on both features. #2, will be addressed
in the follow up PR. For #1, when attachToTarget is called when bc.session_id
is null, then the existing behavior is maintained. This happens for example,
with chromedp which doesn't autoAttach.
2026-08-05 10:59:20 +08:00
Karl Seguin 8cdc8831c1 Merge pull request #3137 from lightpanda-io/client-width-content-width
render: Fallback to contentWidth when clientWidth isn't explicit
2026-08-05 08:45:02 +08:00
Karl Seguin 9767276ae3 Merge pull request #3136 from lightpanda-io/remove-test-log
chore: remove test error log from expected error
2026-08-05 08:44:47 +08:00
Karl Seguin b691603823 Merge pull request #3135 from lightpanda-io/ensureTotalCapacityPrecise
mem: prefer ensureTotalCapacityPrecise to reduce memory usage
2026-08-05 08:44:32 +08:00
Karl Seguin 3c3939b21d Merge pull request #3134 from lightpanda-io/https-truncation-redirect
http: redirect even on missing close_notify
2026-08-05 08:44:17 +08:00
Karl Seguin c8ff4ff71d Merge pull request #3133 from lightpanda-io/referrer-policy
http: start implementation correct referrer policy
2026-08-05 08:44:01 +08:00
Karl Seguin 850004d088 Merge pull request #3132 from lightpanda-io/dedupe-isolated-worlds
cdp: avoid creating duplicate isolated worlds
2026-08-05 08:43:37 +08:00
Karl Seguin df913ec8a5 Merge pull request #3131 from lightpanda-io/gc-hint-heuristics
perf: Reduce memory pressure notification to v8
2026-08-05 08:43:17 +08:00
Karl Seguin a7ea65e680 Merge pull request #3128 from lightpanda-io/element-bare-tag
mem: Switch Element's _type to a bare tag
2026-08-05 08:42:55 +08:00
Adrià Arrufat 4a49030af6 chore: trim narrative comments 2026-08-04 22:36:56 +02:00
Adrià Arrufat b85fb7c6be simplify: recorder rewind, Tool.waitsForReadiness, single goto default
Post-review cleanup of the goto-waituntil branch:
- Recorder: emit the plain goto immediately and keep only a rewind offset +
  pre-scrubbed dcl line; a readiness wait recorded next rewinds and swaps the
  line. bytes() is infallible again, isEmpty() is gone, and the Agent.zig
  save-path changes revert. Shared renderCall() replaces the duplicated
  await/page. prologue; ObjectMap.clone + @tagName replace the hand-rolled
  clone loop and string literal.
- tools: Tool.waitsForReadiness as an exhaustive predicate (waitForScript was
  silently missing from the recorder's inline set); GotoParams.waitUntil is
  non-optional with the default resolved once; performGoto takes an options
  struct instead of two trailing nullables; the goto schema enum comes from
  Config.tagJsonArray like waitForState's.
- actions: comment states the invariant (polling needs a parsed document)
  rather than the symptom.
2026-08-04 22:26:13 +02:00
Adrià Arrufat a73cd97502 agent: record goto as domcontentloaded when a wait follows
The recorder holds each goto one step: if the next recorded call is
waitForSelector/waitForState, the emitted line carries
waitUntil=domcontentloaded (the follow-up wait covers readiness); anything
else, including extract and comments, flushes the plain load-wait form. An
explicit waitUntil is never rewritten. bytes() flushes a trailing held goto
and became fallible; isEmpty() replaces the len check in synthesizeSave (#3138).
2026-08-04 22:06:46 +02:00
Adrià Arrufat 5097e23bcd actions: gate selector/script waits on domcontentloaded, not load
waitForSelector and waitForScript pre-waited for .load before polling, which
re-waited the late-script tail a waitUntil=domcontentloaded navigation
deliberately skipped. Parsing done is enough for the poll to start; the poll
itself keeps ticking the page. On an ad-heavy apnews article this is the
difference between the dcl goto helping (8.8s -> 3.4s debug build) and not
helping at all (#3138).
2026-08-04 22:06:46 +02:00
Adrià Arrufat cd8ff37882 tools: add waitUntil option to goto
Optional param on the goto tool (load | domcontentloaded | networkalmostidle |
networkidle), default unchanged (load). Threaded through performGoto, startGoto
and the script runtime's pending-goto driver, which previously hard-coded
.load. Closes half of #3138.
2026-08-04 22:06:46 +02:00
Karl Seguin 9e05cf37d1 render: Fallback to contentWidth when clientWidth isn't explicit
amivoice.com appends to a child until that child reports a specific clientWidth.
To be correct, we'd need to know the render mode of the node (e.g. flexbox modes
overflows, etc...). Without that, we have limited options. If the width is
explicitly set, we use that (as before), but if it isn't, rather than defaulting
we use the much more expensive contentWidth.  Also applies to height.
2026-08-04 18:50:22 +08:00
Karl Seguin b90515616f chore: remove test error log from expected error 2026-08-04 17:49:38 +08:00
Karl Seguin c86d969ce0 mem: prefer ensureTotalCapacityPrecise to reduce memory usage
When we know the precise final length, prefer ensureTotalCapacityPrecise over
ensureTotalCapacity. The latter goes through `growCapacity` which will allocate
~1.5x padding.
2026-08-04 17:44:05 +08:00
Karl Seguin d4642d8afc http: redirect even on missing close_notify
We already had special handling for BoringSSL's RecvError on improperly closed
TLS connection. This moves the handling up, so that redirect handling is
covered by it too.
2026-08-04 17:37:07 +08:00
Karl Seguin 714e6095ed lower gc limit just for the CI... 2026-08-04 17:13:03 +08:00
Karl Seguin a71bf101d6 http: start implementation correct referrer policy
Referrer header is now set based on the computation of the frame url, the
target url, and the referrer policy which is parsed from the response header
and/or a <meta name=referrer>
2026-08-04 17:09:05 +08:00
Karl Seguin 7840005916 lower gc limit just for the CI... 2026-08-04 15:06:17 +08:00
Karl Seguin a2c4aa0020 lower gc limit just for the CI... 2026-08-04 14:30:52 +08:00
Karl Seguin aa22b7feea cdp: avoid creating duplicate isolated worlds
If a driver asks to create an isolated world that already exists, don't create
it, return the existing one.
2026-08-04 14:27:15 +08:00
Karl Seguin 6e72c43fa2 remove dead context guard...trying to pass CI regression tests 2026-08-04 12:55:26 +08:00