[STG-2473] feat(cli): surface navigation httpStatus on browse open#2319
Draft
shrey150 wants to merge 1 commit into
Draft
[STG-2473] feat(cli): surface navigation httpStatus on browse open#2319shrey150 wants to merge 1 commit into
shrey150 wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: 02afd18 The changes in this PR will be included in the next version bump. This PR includes changesets to release 0 packagesWhen changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
shrey150
commented
Jul 6, 2026
shrey150
commented
Jul 6, 2026
b18c923 to
c1cce2d
Compare
shrey150
commented
Jul 6, 2026
| } | ||
|
|
||
| if (typeof httpStatus === "number" && httpStatus >= 400) { | ||
| result.hint = `Navigation returned ${httpStatus} — the page is unavailable; check the URL or use the site's own navigation before a web search.`; |
Contributor
Author
There was a problem hiding this comment.
instead of this hint, should we add it into skill.md? does this hint meaningfully improve agent task performance, or can we forgo it assuming that agents can figure out a 4xx / 5xx error is bad
browse open (and reload/back/forward) now includes the top-level document's httpStatus, so the driving agent can tell a real 200 page apart from a loaded 4xx/5xx error page instead of treating a rendered 404/403 as success. Additive and optional — a normal 200 page is unchanged, and a navigation with no captured response omits the field. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
c1cce2d to
02afd18
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
browse open(andreload/back/forward) now includes the HTTP status of the top-level document on its result — one optional field,httpStatus. That's the whole change. A normal200page is unchanged; a navigation with no captured response omits the field.Why it matters: today, when you
opena URL that returns a 404/403, the browser still "loads" something (often a rendered error page orchrome-error://), and an agent driving the CLI can't tell that apart from a real page — so it happily continues as if the nav succeeded. Surfacing the status gives the driver a fact it can act on.Heads up for the reviewer: I'm opening this as a draft on purpose. I ran a fairly serious A/B (details below) and the honest result is that this is a correct, harmless primitive that doesn't move the aggregate eval number at Haiku. I have a specific ask for you at the bottom — mainly should I keep pursuing this, and should I re-run the eval on Sonnet instead of Haiku?
Linear: STG-2473
Where this came from (a customer investigation)
An internal customer evaluation showed self-hosted Sonnet 4.5 + browse CLI underperforming our managed Agents product on multi-step travel/booking tasks. Digging in, the gap wasn't the model — it was scaffolding. Managed agent-runner re-observes and recovers after a bad step; a thin harness driving raw browse CLI didn't even know a step was bad, because a loaded 404 looks like success.
So the question this PR set out to answer: can we make browse "self-documenting" enough that a thin harness recovers like agent-runner does — and does that actually help, measured honestly?
Approaches considered
I prototyped three layers of "self-documentation" and tried to isolate each one:
browse snapshot, not nav. No clean signal in evals.hint: "Navigation returned 404 — the page is unavailable; check the URL…"httpStatusfactThe principle I landed on: facts belong in tool output, guidance belongs in SKILL.md / the harness prompt.
httpStatusis a fact. The hint was guidance-in-output, so it's out.The eval (this is the part I want your eyes on)
I built a proper A/B instead of eyeballing trajectories. Setup:
claude_codeeval path driving the real browse CLI, on Browserbase remote.gemini-2.5-flash.claude-haiku-4-5.max_turns = 60— this matters (see "validity" below).A= baseline (stock CLI) ·B=httpStatusonly ·C=httpStatus+ hint.Results
Significance (two-proportion z):
How to read this honestly
santorini_flightwent 3/8 → 0/8 (capped 2 → 0: it bailed instantly), andticketmaster_sportingwent 4/8 → 2/8 (the fact-only arm had lifted it to 7/8). The over-abandonment cancels the floor gains → net wash. The hint text is too blunt for a small model to apply judiciously.httpStatus-only has no regressions and is a correct primitive, which is why it's the safe thing to land.A validity note (why I trust this run and not my earlier ones)
An earlier factorial ran at
max_turns = 30and showed no signal anywhere. That was an artifact: 72% of runs hit the 30-turn cap, and a capped run passes ~2% — so it was measuring turn-budget, not the change. Atmax_turns = 60the cap rate drops to ~46% and, crucially, becomes correlated with genuine task difficulty (easy tasks cap 0%,kayakcaps 100% in both arms because it's just turn-starved) rather than a uniform guillotine. That's why this run's deltas are meaningful and the old one's weren't.What I actually want advice on
httpStatusis harmless and correct, but the eval doesn't prove it lifts task success at Haiku. Is "correct primitive with a real-but-small subgroup effect" a good enough reason to land, or should I hold it?Scope of this PR
Deliberately tiny — just the fact:
openResult()setshttpStatuswhen a navigation response was captured (session-manager.ts).response.status()fromopen/reload/back/forward(navigation.ts).OpenResult.httpStatus?: numbertype (types.ts).browsepatch).No candidate links, no hint string — both cut per the data above.
E2E Test Matrix
browse open https://httpbin.org/status/404 --remote(local build)"httpStatus": 404,url: "chrome-error://chromewebdata/", nohintfieldbrowse open https://example.com --remote(local build)"httpStatus": 200, nohintfieldvitest run tests/self-documenting.test.tsopenResultcontract.pnpm build(packages/cli)max_turns=60, V3Evaluator-scored, on Browserbase🤖 Generated with Claude Code