Blackreach

A browser agent that can explain why it stopped, keep its place, and check the files it collects.

I build Blackreach to work through browser tasks from a natural-language goal. It observes the page, chooses an action, and carries progress between steps. The difficult part is knowing what actually happened when a run goes wrong.

This case study follows one concrete failure: a browser opened to a blank page and the terminal ended with Incomplete. That message didn't tell me whether navigation failed, the model was unavailable, or the task ran out of steps.

Version and scopePublished October 9, 2026: the Python engine update is now in the public repository. The evidence below records the October 8 engine work; the published version also updates the HTTP dependency. This work covers the existing agent engine and terminal interface.

One goal through three documentation sites

I asked Blackreach to compare Playwright, Puppeteer and Selenium using their official documentation. The configured OpenAI model chose the actions in this run. It reached all three requested sources and returned a comparison with links.

October 8, 2026 · 30-second motion edit of an 83.9-second run. Actual CLI output is re-set for readability; this is not continuous screen footage.
Original runtime
83.9 sec
Model decisions
6
Browser actions
4
Reported failures
2

The path wasn't clean. A comma attached to the first URL produced a 404, and the run also visited GitHub before reaching Selenium. The final status reported completion after six page visits. Keeping those details matters: this is one observed task, not a benchmark success rate.

Read the transcript and edit notes
  1. 0:00–0:03: Blackreach's cyan ASCII logo and terminal prompt. The candidate is version 5.0.0-beta.3, using OpenAI's configured gpt-5.6-luna model.
  2. 0:03–0:07: A shortened prompt asks for a comparison of Playwright, Puppeteer and Selenium using official documentation and source links.
  3. 0:07–0:11: The first Playwright address returns HTTP 404 because of a trailing comma. A later excerpt shows Puppeteer being observed, followed by navigation to the corrected Playwright address.
  4. 0:11–0:18: Excerpts show the Playwright language page and Selenium WebDriver documentation, with the actual step numbers and observation counts.
  5. 0:18–0:26: An editorial recap compares the three tools. Playwright covers Chromium, Firefox and WebKit, with JavaScript/TypeScript, Python, Java and .NET. Puppeteer supports Chrome and Firefox through its JavaScript/TypeScript library. Selenium provides WebDriver support across Chrome, Edge, Firefox and Safari, with Java, Python, C#, Ruby and JavaScript bindings; Kotlin uses the Java bindings.
  6. 0:26–0:30: The terminal reports the goal complete: six decisions, four actions, six pages and two failures.

The edit keeps the original logo pixels and re-sets captured CLI text into a cleaner layout. Higgsfield generated the background motion. The task wording is shortened; the final comparison is an independently checked editorial recap. Neither the generated visuals nor the edited timing are evidence of browser actions.

The original answer listed Kotlin alongside Selenium's language bindings. The recap groups it with Java to make that distinction clear. Source documentation: Playwright languages, Playwright browsers, Puppeteer and Selenium WebDriver.

Inspect the recorded run and edit receipt · Open the full-size video

Keep the page at its real address

A lightweight route fetched HTML and inserted it into a browser page. The markup looked like progress, but the browser could still be at about:blank. Relative links and scripts then had the wrong origin.

The interactive path now navigates to the source URL. A real Chromium test serves a local page with a relative script and link, checks their resolved origin, and follows the link. A page with no navigated source stops before another model decision.

Make the stopping point explicit

The runtime now returns a status, stop reason, error, and whether a usable checkpoint exists. The terminal separates decisions from browser actions. A model can finish after reading the first page: that's one decision and zero actions.

SituationWhat the engine reports
The decision budget runs outStep limit reached, with a resume command if progress was saved.
A provider rejects accessA specific failure; permanent errors stop without repeating the request every step.
The user interrupts a runCheckpoint handling runs before exit; a failed save cannot claim to be resumable.

The same outcome is carried through the command-line, interactive and API paths. Provider settings include an explicit output budget and transport timeout. Incomplete model output is rejected before it can become a browser action.

A recovery proof you can inspect

The controlled walkthrough uses a local fixture site, real Chromium, and SQLite. Its decisions are scripted so the test isolates the engine.

  1. Open the fixture and follow its report link.
  2. Stop at the one-decision limit and save the current report page.
  3. Create a new agent and browser, then load that checkpoint.
  4. Read the report reference and finish with two cumulative decisions and one browser action.
First run   max_steps   decisions=1   actions=1   resumable=true
New agent   success     decisions=2   actions=1   result=BR-LOCAL-42
Rejection   error       decisions=1   provider calls=1

The separate rejection case injects a provider-access error and checks that it appears in the final result and session-end log. Read the controlled proof receipt.

Check the downloaded artifact too

The public baseline already includes a download-verification example. It rejects HTML, a wrong-format archive, and missing files when a PDF was requested. A file's name is not enough to accept it. These format checks still don't prove that the PDF contains the document the user wanted.

Inspect the public download example ↗

A separate smoke test with local Qwen 2.5 7B reached the report page, then exhausted a three-decision budget after an invalid click. That failure is retained in the evaluation notes. Better engine diagnostics do not automatically make model planning reliable.

Earlier browser demonstration

July 2026, public commit 8a6a8c7. A real browser follows a scripted Wikipedia workflow. This predates the October engine update.

What this evidence doesn't establish

These checks prove specific navigation, failure and recovery behavior. They do not establish an autonomous success rate across websites, live access to every listed model, or reliable completion of arbitrary tasks. Checkpoints preserve task progress, not browser login cookies. An interrupted external action can still have an uncertain result and needs verification before retrying.

I use Codex and Claude Code heavily in this work. My part is choosing the problem, directing the changes, reviewing the behavior and testing what the result can actually support.


Read the debugging story · Public source · About me and roles