Skip to content

Let callers read a navigation's status off the result - #12

Merged
arrufat merged 2 commits into
mainfrom
page-result-status
Sep 30, 2026
Merged

arrufat merged 2 commits into
mainfrom
page-result-status

Conversation

@arrufat

@arrufat arrufat commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

Until now page.goto(...) answered Navigated successfully. whatever came back, so a 404 was indistinguishable from the page you wanted. lightpanda-io/browser#3691 put the status into that sentence, and lightpanda-io/browser#3694 sends the same facts as MCP structuredContent. This reads them.

r = page.goto(url="https://example.com/missing")
print(r)          # Navigated successfully. HTTP 404 Not Found.
r.http_status     # 404
r.url             # 'https://example.com/missing'
r.title           # 'Error response'

Why a str subclass and not a dict

Returning the parsed object would match what extract and links already do, and it was my first instinct. But the sentence carries things the fields don't — which element was clicked, and Opened a new window; tools now act on it. when a click took over a popup. Returning either one alone drops something, so PageResult is the sentence, with the fields as attributes. Printing it, comparing it and startswith are all unchanged.

That mirrors the reasoning on the browser side for leaving evaluate out of structuredContent: don't throw away the payload for the metadata.

Ordering

CI builds against browser nightly, which does not carry #3694 yet. A binary that sends no structuredContent falls through to the plain string exactly as before, and the new test skips rather than fails — so this is safe to merge first and starts exercising itself once #3694 lands.

The two commits

Regenerate _methods.py is pre-existing drift, not caused by this change: detectForms and interactiveElements now document their JSON shape, evaluate documents its script argument, scroll gained a selector, and goto's description changed in #3691. CI fails on that drift against nightly regardless. It is first on the branch so it can be split off if you would rather land it on its own — I checked that the generated file is byte-identical whether produced from a binary with or without #3694, so the new outputSchema does not reach _methods.py.

Catches up with browser changes already on main: detectForms and
interactiveElements now document their JSON shape, evaluate documents its
script argument, scroll takes a selector, and goto reports the HTTP status
(lightpanda-io/browser#3691).
`goto` used to answer "Navigated successfully." whatever came back, so a
404 was indistinguishable from content. lightpanda-io/browser#3691 put the
status in that sentence and #3694 sends the same facts as MCP
`structuredContent`, which is where this reads them.

`goto` and the actions now return a `PageResult`: the sentence, with `url`,
`http_status` and `title` as attributes. A str subclass rather than a dict
because the sentence carries what the fields don't -- which element was
clicked, whether a new window took over -- and returning either alone would
lose something.

Older binaries send no `structuredContent` and still fall through to the
plain string, so this is safe ahead of the browser release that carries
#3694; the new test skips against them.
@arrufat
arrufat merged commit 9f1d061 into main Sep 30, 2026
11 checks passed
@arrufat
arrufat deleted the page-result-status branch September 30, 2026 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant