I build Rust infrastructure for the agent internet — the stack that lets AI agents reach the web and each other the way people reach websites over HTTP.
aginxbrowser — web access for AI agents: one MCP server, one Rust binary. Fetch live pages as markdown, render JS/SPAs on a built-in V8, screenshot without Chromium, five-engine meta-search, interactive login sessions with replayable action logs. Apache-2.0 — self-host it, or point your client at the hosted instance.
In our benchmark (bench/), a tiered auto-fetch answers in 532 ms where a Chrome-class round trip takes 4053 ms, at ~227 MB vs ~2.1 GB per page. Pages that only need the HTML layer never pay for a browser.
aginx — the Agent Protocol: route messages to agents as easily as HTTP routes them to servers. A pure server — which models an agent runs is the agent's own business.
opencarrier — an open-source agent OS in Rust: WeChat / Feishu / DingTalk / WeCom access, pluggable tools, 24/7 autonomous scheduling.
Also: model-router (protocol-translating model proxy with failover), ProxyMaster (auto-rule Chrome proxy manager), UPnPCast (modern DLNA/UPnP casting for Android).
When something breaks, I fix it in our tree first, verify the fix against a repro, and then hand the root cause and the patch data back upstream. Every claim below links a commit and a test.
- obscura#807 — Playwright
fill/clickover CDP hung forever whileevaluateworked. On our tree the elements weren't flaky: unstyled<input>/<textarea>laid out at full-width × 0 height, and Playwright's visible check needs a non-empty box. Controls now get Chrome-shaped defaults (177×22 text input, 13×13 checkbox, 177×38 textarea) and join text lines as inline atoms, baseline-aligned; the same sequence went 30s timeout → 66ms (3031b28), with the two red herrings (rAF pump,getBoxModelfallback quad) ruled out in the write-up. - obscura#817 — webpack style-loader died with "Couldn't find a style target". Pinned the chain in their own source: the aliased interface constructors made
head instanceof HTMLIFrameElementtrue for every element (wrappers shareElement.prototype), so the style target went down the iframe branch and came backundefined. Rebuilt the constructors withSymbol.hasInstancekeyed on tag name, prototype sharing intact — bilibili's 2MB player core now boots past it (f709e17), diagnosis posted with the end-to-end trace. - obscura#751 —
URL.createObjectURLmintedblob:obscura/<token>: any page could fingerprint the engine with onestartsWith, and non-Blob input was accepted without a word. Reported with the one-line check; our side now throws the Chrome TypeErrors and mints origin-bearing v4 UUIDs (4860141) — the first report where two contributors raced to the fix, #804 merged and closed it. - obscura#791 — CDP response-body retention keyed base64 off the content-type alone, so a GBK
text/htmlbody (text by header, not UTF-8 by bytes) came back fromNetwork.getResponseBodyas U+FFFD. Both stores — document and script-initiated fetch — now keep base64 unless the bytes are exact UTF-8, and the GBK round-trip is byte-exact; same convergence data posted on their PR (99a28f9). - servo#41512 — Servo renders a space between a float and the text after it, because block-leading collapsible whitespace survives float extraction. Our engine drops whitespace-only leaves at a run's edges before layout, so the same repro measures a 0px float-to-text gap (a 4px control proves one real space would show); no patch needed, our side already behaves (d4906aa).
- servo#38320 — Servo collapses a
min-contentflex container holding floats. They need to know what to copy from Chrome; our item-level measurement gives exactly 200px — both 100px floats contribute side by side, unfragmented. The probe also surfaced a gap in our engine (nowidthsizing keywords), which shipped the same day (7a51551); the follow-up closes the loop with container-level numbers: we land at 100px (taffy's widest-item wrap min-content), same as blitz, vs Chrome's 200px — the divergence lives below us, in taffy itself. - obscura#767 — a flex deferral cycle could sample a
calc()width twice and ship the wrong number. We built calc as parse-time folding (pure-px collapses immediately, the exact case their instrumentation exposed) plus one post-layout repair pass that resolves the mixed form against the settled containing block and replaces it — no expression left to re-evaluate, so the double-sampling state cannot exist (d4906aa). - obscura#764 — a floated dropdown came out over-wide. Our matrix split the symptom in two: hidden content was innocent, source indentation whitespace was not. The fix drops whitespace-only leaves at a run's edges before shrink-to-fit measures it; whitespace-source and compact markup now measure identically, closing both the +15 delta and the +7 adjacency residual (d4906aa).
- obscura#777 — CDP
setUserAgentOverrideparsed auserAgentbut silently droppedacceptLanguage, so a locale override could never reach the wire header ornavigator.language. Both CDP spellings now apply each sent field independently (locale-only leaves the UA alone), moving both HTTP transports and the live persona — while never re-pinning the process-global ICU default, which stays at isolate creation to avoid cross-isolate contamination (a15f7a0). - obscura#769 — rustls ships zero TLS 1.2 CBC cipher suites, so CBC-only legacy servers die at ClientHello while every browser connects fine. Reproduced on
cbc.badssl.com; our robots.txt gate now takes one final ride on the BoringSSL transport — same honest User-Agent, different cipher shelf (62ad068). - obscura#779 — CDP
RemoteObjectcontradicted itself for primitives:valuewas a string copy ofdescription,undefinedcollapsed intonull, and handles were minted for everything. Fixed all four shapes with CDP-level tests — and the tighter contract flushed out a latent bug where the handle path read its metadata from the wrong value (1b864eb). - obscura#541 — number RemoteObjects now spell like Chrome (
2, not2.0) (4760524). - modelcontextprotocol#3305 — the browser-automation capability contract discussion; our evidence-first
session_clickresponse (8712c14) came out of that thread. - blitz#750 — inline baseline alignment; we port the same semantics as a post-layout per-line shift — a different architecture reaching the same rendering.
Every issue I report, I arrive with a repro and a fix already running in our build.
