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
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.
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.
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).
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.
Follow up to https://github.com/lightpanda-io/browser/pull/3130https://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).
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`.
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.
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.
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.
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.
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).
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).
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.
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.
When we know the precise final length, prefer ensureTotalCapacityPrecise over
ensureTotalCapacity. The latter goes through `growCapacity` which will allocate
~1.5x padding.
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.
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>