Skip to content
Cascading Labs QScrape VoidCrawl Yosoi

A3Node

Experimental

DOMLoader drives a browser page to a stable state before Yosoi captures HTML. It clears common blockers, clicks content triggers, scrolls when needed, and waits for the DOM to settle.

A3Node caches that work. On later browser fetches, Yosoi can replay the stored actions before HTML capture and avoid the full behavior-tree search when replay works.

Enable A3Node

CLI:

uvx yosoi fetch https://example.com --a3node
uvx yosoi scrape https://example.com/products/sku-1 --contract @Product --a3node

Python:

from yosoi.core.fetcher import create_fetcher
async with create_fetcher('waterfall', experimental_a3node=True) as fetcher:
result = await fetcher.fetch('https://shop.example.com/catalog')

Recipe replay also enables A3Node automatically when the recipe carries a3nodes.

Scoped Replay

A3Node storage is no longer broad domain-only state. New scope keys include:

  • domain;
  • normalized route path;
  • query-key shape, excluding values;
  • replay intent, such as fetch or scrape/action/download shape;
  • browser/profile fingerprint, including tier, headless/headful state, identity id, locale, timezone, geo/proxy/user-agent hashes, and accept-language.

This prevents one page template, query surface, or browser identity from overwriting another just because they share a domain.

Storage lives in .yosoi/yosoi.sqlite3 in the a3nodes table. Legacy domain-only rows are treated as legacy scopes instead of broad reusable authority.

Fragment Bank

Yosoi can also learn small domain-free fragments for common obstacles:

  • cookie banners;
  • popups;
  • age gates.

Fragments are keyed by stable target structure, not source domain. Before scoped probing, Yosoi can try the best reusable fragments. A fragment miss is non-authoritative: if the target is absent or stale, it is skipped and normal scoped probing continues.

Replay Behavior

On each browser fetch with A3Node enabled:

  1. Yosoi builds the scoped key before navigation.
  2. It loads the scoped A3Node recipe from SQLite.
  3. It replays stored concrete targets only if they are present.
  4. It skips stale fragment or action targets instead of failing the whole fetch.
  5. It runs the normal DOMLoader probe when replay is absent or insufficient.
  6. Successful scoped acts are saved and reusable fragments are refreshed.

Replay avoids the full trigger search on the hot path when stored targets are available. It remains advisory: stale replay data cannot authorize serving data by itself.

Boundary With Portable Recipes

SystemJobStorage
A3NodeGet the page into a stable DOM state before HTML capture..yosoi/yosoi.sqlite3
Portable recipeShare contract, selectors, optional A3Node actions, and validation evidence..yosoi/recipes/*.json or remote JSON
DiscoveryLesson / ReplayPlanPreserve MCP-learned browser discovery behavior..yosoi/lessons/

Keep those boundaries separate. A3Node answers “how do I make this page loaded enough to scrape?” Portable recipes answer “what contract and selectors should be replayed?”

Inspecting State

from yosoi.storage.a3node import A3NodeScope, A3NodeStorage
storage = A3NodeStorage()
scope = A3NodeScope.for_url(
'https://shop.example.com/catalog?page=1',
domain='shop.example.com',
intent='fetch',
browser_fingerprint='default',
)
node = await storage.load(scope)
if node:
print(node.acts)
print(node.replay_count)

To force a fresh probe for a scope:

await A3NodeStorage().delete(scope)

FAQs

Is A3Node enabled by default?

No. It is experimental and opt-in through experimental_a3node=True or the CLI --a3node flag.

What does A3Node store?

It stores the ordered DOMLoader actions that made a scoped page stable, plus replay counters and timestamps. Empty recipes are stored too.

Does A3Node replay non-empty recipes?

Yes. It replays stored concrete targets when present, skips stale targets, and falls back to a fresh probe when replay falls short.

Is this the same as a portable Yosoi recipe?

No. A3Node stabilizes browser fetches. Portable recipes package contracts, selectors, optional A3Node actions, and validation evidence for sharing.