Commit Graph
5928 Commits
Author SHA1 Message Date
Adrià Arrufat e7cfc2f72a agent: avoid double Ollama probe at startup
Renames `wouldResolve` to `hasDetectableKey` and removes the Ollama
probe from it. Defers printing the welcome banner for Ollama-only
paths to prevent probing the local server twice. Also bumps zenai.
2026-06-15 22:56:20 +02:00
Adrià Arrufat 7a9924ab22 Agent: support HF_BILL_TO for Hugging Face
Passes the `HF_BILL_TO` environment variable to the ZenAI client
to route Hugging Face billing to an organization. Also updates
the `zenai` dependency.
2026-06-15 19:27:58 +02:00
Adrià Arrufat 3e5294318c Agent: add support for Huggingface inference
Updates the zenai dependency to the latest commit and adds HF_TOKEN to
the API keys hint.
2026-06-15 19:12:05 +02:00
Adrià Arrufat 2c35d760d8 Merge branch 'main' into agent 2026-06-15 15:21:54 +02:00
Adrià Arrufat e35c66c2a6 agent: reset save destination on /clear and /reset
clearConversation reset the recorded action buffer but left save_path
set, so after /clear or /reset a /save <newfile> was rejected with
"already saving to <oldfile>". Free and clear save_path alongside the
buffer so a cleared session can save to a fresh file.
2026-06-15 14:54:26 +02:00
Karl Seguin 15d4968cc8 Merge pull request #2745 from lightpanda-io/silence_a_test_log
dev: silence a test that uses/needs console
2026-06-15 17:16:08 +08:00
Karl Seguin 78d7793327 dev: silence a test that uses/needs console 2026-06-15 16:59:04 +08:00
Karl Seguin 98dcd12a82 Merge pull request #2735 from lightpanda-io/cdp_setExtraHTTPHeaders
Cdp set extra http headers
2026-06-15 16:21:20 +08:00
Karl Seguin 3984082c3b Merge pull request #2700 from navidemad/fix-b14-sequential-focus
webapi: run sequential focus navigation on Tab
2026-06-15 06:34:52 +08:00
Karl Seguin 9ace686d1e perf: avoid excessive tabIndex lookup/parse
Store tab index for current, edge, chosen in a local, and only get/parse it
once per candidate (vs twice).
2026-06-14 21:57:03 +08:00
Karl Seguin 02115bef72 Merge pull request #2682 from navidemad/agent-discovery-signals
Surface server-side agent-discovery signals: Link response header (RFC 8288) + robots.txt Content-Signal
2026-06-14 20:31:47 +08:00
Adrià Arrufat 4147274fa8 Merge branch 'main' into agent 2026-06-14 10:28:21 +02:00
Karl Seguin a4c5d09075 Merge pull request #2729 from navidemad/fix-a47-page-navigate-failed-response
cdp: answer Page.navigate with errorText when navigation fails
2026-06-14 13:39:43 +08:00
Karl Seguin ed5d9213fb Merge pull request #2736 from lightpanda-io/debug_assert
debug: Use normal crash report assertion in debug
2026-06-14 13:38:53 +08:00
Karl Seguin eec06238d0 nits: just personalizing the code as a means to understand it. 2026-06-14 10:17:39 +08:00
Navid EMAD a66c13ecf3 webapi: implement HTMLSelectElement.type and HTMLOptionElement.label
Both IDL attributes were unimplemented and evaluated to `undefined`.
`select.type` reflects the element's mode: "select-multiple" when the
`multiple` attribute is present, "select-one" otherwise (derived from the
existing `getMultiple()`). `option.label` returns the `label` content
attribute when present and non-empty, otherwise the value of the `text`
IDL attribute. Both match the HTML Living Standard.

Select-enhancement libraries branch on `select.type` to choose single- vs
multi-select code paths; reading `undefined` there made them take a dead
path and throw during initialization.

Closes #2738
2026-06-13 15:12:17 +02:00
Karl Seguin 4dbec74dfc debug: Use normal crash report assertion in debug
I don't know why I thought debug should `unreahcable` while release should
generate a crash report. The crash report always contains more info and whenever
I encounter a failed assertion in debug, the first thing I do is remove the
unreachable to get the more complete crash report.

(The crash report path skips sending the crash report in debug builds already)
2026-06-13 17:59:54 +08:00
Karl Seguin b957ad74c4 cdp, bot: Apply user-agent validation to CDP's setExtraHTTPHeaders
This is a change to https://github.com/lightpanda-io/browser/pull/2706 which
applies the Config.validateUserAgent to CDP's network.setExtraHTTPHeaders. This
makes the CDP method consistent with all other forms of user-agent setting, i.e
not allowing 'mozilla'-container values.
2026-06-13 15:43:38 +08:00
Adrià Arrufat 48025a371f Merge branch 'main' into agent 2026-06-13 08:17:31 +02:00
Karl Seguin ab53f92a11 Merge pull request #2731 from navidemad/fix-a48-console-log-warning-types
cdp: report console.log/console.warn with their own consoleAPICalled types
2026-06-13 12:22:34 +08:00
Navid EMAD b136b3a84d cdp: report console.log/console.warn with their own consoleAPICalled types
console.log and console.warn were both dispatched as .info, so
Runtime.consoleAPICalled (and Console.messageAdded) reported type
"info" for all three of log/info/warn — clients filtering console
output by severity saw them collapsed into one bucket.

Add log/warning members to ConsoleMessageType (the protocol's wire
values — "warning", not "warn") and map console.log -> log,
console.warn -> warning. info/error/debug/trace already matched.

Closes #2730
2026-06-12 19:22:24 +02:00
Navid EMAD c3afcc51dc cdp: answer Page.navigate with errorText when navigation fails
A root navigation that fails before any response headers arrive
(connection refused, DNS failure, TLS error) never answered the
Page.navigate command: the success reply is only sent from the
response-header path (frame_navigated), and frameErrorCallback dropped
the stored cdp_id along with the pending Page. The CDP client awaiting
the response was left hanging forever.

Dispatch a frame_navigate_failed notification from frameErrorCallback
when no response headers were processed (_http_status == null guards
against double-answering mid-body failures), and answer the pending
command with {frameId, loaderId, errorText} — matching Chrome, where
errorText is "present if and only if navigation has failed".

Closes #2728
2026-06-12 19:13:10 +02:00
Scott Taylor 723e7eb9d5 fix(cdp): validate User-Agent in Network.setExtraHTTPHeaders
A caller-supplied User-Agent overrides the built-in default and goes out
on the wire, so reject non-printable values the same way
Emulation.setUserAgentOverride and the --user-agent flag do.

We deliberately do NOT apply validateUserAgent's reserved (Mozilla)
check here: unlike the Emulation override (kept Lightpanda-branded to
keep go-rod working), setExtraHTTPHeaders is the intended,
Chrome-compatible escape hatch for setting a real browser-like
User-Agent, which by definition contains Mozilla.

Refs #2704
2026-06-12 12:28:19 -04:00
Navid EMAD 66bbce21e0 webapi: default navigator.globalPrivacyControl to false
Per https://w3c.github.io/gpc/#javascript-property the GPC signal
reflects an explicit user preference to opt out of tracking, and no
such preference is configured anywhere. Firefox defaults the property
to false; Chrome doesn't expose it at all. Returning true made
GPC-compliant consent managers treat every page load as an automated
reject-all and skip their consent UI entirely, diverging from every
default-config real browser.

Adds a value assertion next to the existing doNotTrack check in the
navigator fixture (the accessor-shape walk already covered the
property, but not its value).

Closes #2725
2026-06-12 17:46:18 +02:00
Adrià Arrufat a1bd1a4834 Merge pull request #2702 from lightpanda-io/save_system_prompt
agent: improve save system prompt
2026-06-12 16:01:37 +02:00
Adrià Arrufat 5eb8e3f8c3 Merge pull request #2705 from lightpanda-io/agent-feedback-fixes
Agent feedback fixes
2026-06-12 15:16:26 +02:00
Adrià Arrufat c98c762366 agent: add explicit update mode for script saving
Introduces an `update` save mode that allows the LLM to revise an
existing script. Distinguishes this from `append`, which now performs
a blind append. Updates the save prompts and system instructions
accordingly.
2026-06-12 13:39:22 +02:00
Karl SeguinandClaude Fable 5 67f947f606 Reflect source width/height as unsigned long per spec
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 18:29:46 +08:00
Adrià Arrufat 454594137b agent: revise the saved script on repeat /save
A second /save with nothing recorded and no prompt sent an empty user
message, which Anthropic rejects (HTTP 400: text content blocks must be
non-empty). Bail out early instead, telling the user to run commands or
give a prompt.

When a /save targets an existing script (a remembered save path, or
choosing append for an existing file), feed the file contents back to
the model and ask for the complete updated script, then overwrite. This
makes '/save fix X' actually fix the saved script — previously the
blind regeneration was appended after the buggy one. The --no-llm dump
path keeps its verbatim append semantics.
2026-06-12 11:57:40 +02:00
Adrià Arrufat 7f522e4f1a agent.welcome: correct logo color 2026-06-12 10:01:48 +02:00
Adrià Arrufat d9db947838 Merge branch 'main' into agent 2026-06-12 08:41:25 +02:00
Rohit 7835f133fe feat(webapi): reflect attributes on HTMLSourceElement
Add the reflected IDL attributes to the existing HTMLSourceElement,
which previously reflected none: src (resolved as a URL like
HTMLEmbedElement.src), srcset, sizes, media, type, width and height.

Mirrors the reflection idiom used by HTMLEmbedElement. width and height
are reflected as strings, matching the sibling HTMLEmbedElement
accessors. Adds element/html/source.html covering parse-from-markup,
property/attribute round-trips and src URL resolution.
2026-06-12 11:04:21 +05:30
Karl Seguin 70a70815e4 Merge pull request #2695 from lightpanda-io/offsetParent
webapi: Implement Element.offsetParent getter
2026-06-12 13:01:00 +08:00
Karl Seguin e1851309f0 Merge pull request #2714 from navidemad/fix-a43-redirect-no-location
http: deliver 3xx responses without a Location header as final responses
2026-06-12 12:44:15 +08:00
Karl Seguin 3686fd2600 Stricter redirect status code check
Single Location header lookup
2026-06-12 11:47:27 +08:00
Karl Seguin 9302b31f2d Merge pull request #2712 from navidemad/fix-b17-has-relative-selectors
selector: support relative :has() arguments (:has(> div), :has(~ p))
2026-06-12 11:30:02 +08:00
Karl Seguin 63665f8180 Merge pull request #2710 from navidemad/websocket-origin-header
websocket: send Origin header on upgrade requests
2026-06-12 11:02:30 +08:00
Karl Seguin 64238b3af4 Merge pull request #2708 from navidemad/fix-document-readystatechange
webapi: fire readystatechange at document on readiness changes
2026-06-12 10:48:11 +08:00
Karl Seguin e7e605b65b Merge pull request #2694 from rohitsux/feature/centralize-viewport-default
refactor(viewport): source hardcoded 1920x1080 from MediaQuery.Viewport.default
2026-06-12 09:51:37 +08:00
Karl Seguin 10a35af941 Merge pull request #2658 from lightpanda-io/nikneym/rust-url
`URL`: Rework URL web API with rust-url
2026-06-12 09:33:05 +08:00
Karl Seguin 2babfad486 minor: Create ViewPort type
Move logic that was added to MediaQuery into its own ViewPort.
2026-06-12 09:19:48 +08:00
Karl Seguin 01ff034bf4 minor: remove 'leak' word from test name
Keep ability to grep for 'leak' meaningful by not having it show up on success.
The assertion is redundant anyways, presumably no test leaks.
2026-06-12 08:58:19 +08:00
Navid EMAD 6665684abe http: deliver 3xx responses without a Location header as final responses
Every 300-399 status was routed into the redirect path, where the missing
Location header fails the transfer with error.LocationNotFound — the old
document is destroyed and nothing replaces it. Per the fetch standard's
HTTP-redirect fetch ("If locationURL is null, then return response") and
RFC 9110 §15.4, a 3xx without Location is a normal final response whose
body must be delivered. Guard both the redirect dispatch and the 3xx
skip-body branch on the header's presence so such responses fall through
to the regular completion path.

Closes #2713
2026-06-12 02:23:10 +02:00
Navid EMAD 25077d8ddc selector: support relative :has() arguments per Selectors Level 4
:has() arguments may start with an explicit combinator (":has(> div)",
":has(~ p)", ":has(+ span)") and are anchored at the element being
matched. Absolutize each argument at parse time by prepending a :scope
anchor segment, then match candidates with :scope bound to the element,
searching the parent's subtree for sibling-anchored arguments. This also
anchors plain arguments at the element, so ":has(span p)" no longer
false-positives when the span is an ancestor of the element.

Closes #2711
2026-06-12 00:57:57 +02:00
Navid EMAD 9b101a7009 websocket: send Origin header on upgrade requests
The WebSocket opening handshake must carry the document's origin in an
Origin header when initiated from a browser client (RFC 6455 §4.1), and
origin-checking endpoints (CSRF protection on WS servers) reject
upgrades that arrive without it. WebSocket.init already assembles extra
upgrade headers (Sec-WebSocket-Protocol, Cookie) but never added Origin.

Serialize the executing document's origin via URL.getOrigin next to the
existing header setup — "null" for opaque origins (about:blank, data:),
matching what Chrome sends. The TestWSServer captures the upgrade's
Origin header and exposes it via a new get-origin command; an
origin_on_upgrade fixture in websocket.html asserts the served page's
origin arrives on the upgrade.

Closes #2709
2026-06-12 00:27:25 +02:00
Navid EMAD 6b90a7be49 webapi: fire readystatechange at document on readiness changes
Per the HTML Standard's "update the current document readiness" steps,
every change to document.readyState must fire a readystatechange event
at the Document - twice during a normal load: when readiness becomes
interactive (before DOMContentLoaded) and when it becomes complete
(before the load event). The readiness flips in Frame.zig updated
_ready_state but never dispatched the event, so page scripts driving
their lifecycle off readystatechange never observed any transition.

Dispatch the event (non-bubbling, non-cancelable, trusted) right after
each flip, mirroring how DOMContentLoaded is emitted.

Closes #2707
2026-06-11 23:31:36 +02:00
Adrià Arrufat 538b560676 terminal: highlight JS globals in prompt
Adds syntax highlighting for common JS globals (like window, console,
and lp) in cyan, excluding property accesses.
2026-06-11 19:54:29 +02:00
Scott Taylor 79dfdf7465 fix(cdp): let setExtraHTTPHeaders override built-in headers like User-Agent
Network.setExtraHTTPHeaders applied caller headers with a plain
curl_slist append. Requests are seeded with a default `User-Agent:
Lightpanda/1.0`, so a caller-supplied User-Agent produced two
User-Agent entries; libcurl keeps the first and the override was
silently dropped (origins always saw `Lightpanda/1.0`). Other headers
worked because they had no default to collide with.

Add Headers.set, which replaces any existing header with the same
(case-insensitive) name before appending, and use it when applying the
CDP extra headers. This matches Chrome, where Network.setExtraHTTPHeaders
overrides default request headers.

Refs #2704
2026-06-11 12:31:14 -04:00
Adrià Arrufat aeba63427e script: enforce positional arguments come first
Returns a specific `PositionalMustComeFirst` error when a positional
argument is placed after key-value pairs.
2026-06-11 18:24:44 +02:00
Adrià Arrufat d292f2b342 agent: pump session during terminal idle
Updates isocline to support idle callbacks and registers a hook to
pump the session's curl multi while waiting for user input. This
prevents connection timeouts. Also refactors the idle pumping logic
into `Session.idleSlice` to share it with the MCP server.
2026-06-11 18:19:51 +02:00