API reference
September 21, 2026 ยท View on GitHub
SDK construction and lifecycle
new JevBrowser({ page, ...options }) borrows a Playwright Page. await JevBrowser.launch(options) launches or attaches. close() disposes only resources owned by the instance; async disposal is supported. Do not operate a Page concurrently from another core or external writer. Concurrent operations on one core return BUSY.
Options include:
- Provider:
apiKey,model,baseURL,fetchandtimeoutMs. Environment fallbacks areJEV_API_KEY/TYPESAFE_API_KEY,JEV_MODEL,JEV_BASE_URL. The hosted default requires an API key. A custombaseURLmay be keyless and must expose TypeSafe-compatiblePOST /v1/systemonerequest/response envelopes. - Observation:
maxElements(120),maxTexts(160),maxCandidates(250). Limits fail explicitly instead of silently excluding action candidates.scopenarrows a particular observation;recordsScopeidentifies repeated records but does not itself remove unrelated page text. - Launch:
browser(chromium,firefox,webkit; environmentJEV_BROWSER),headless,launchOptions,contextOptions,storageState,userDataDir,cdpEndpoint,wsEndpoint. Choose at most one profile/CDP/WebSocket mode. CDP requires Chromium; PDF requires Chromium. Context options include ordinary Playwright locale, viewport, device, permissions and HTTP credentials settings. - Files:
fileRoots,outputDir. Native uploads/artifacts use these boundaries. Explicit launch/profile paths are independently granted by the caller. - Guard callbacks:
allowAction(plan, operation)for Jev actions,allowCommand(command, operation)for native operations. Both require literaltrue.operationhassignaland remainingtimeoutMs. These callbacks do not restrict direct Page access or create a network sandbox. allowEvaluate: enables caller-authored page evaluation and init scripts. Disabled by default. No Node-side evaluation command exists.
Per-operation signal, timeoutMs and scope are available where relevant. The default operation budget is 30 seconds. Cancellation does not roll back completed effects. User-supplied callbacks and custom decision engines must honor the signal and remain bounded.
Main methods
| Method | Result and purpose |
|---|---|
goto(url, options?) | {url}; HTTP(S) navigation through the native dispatch |
snapshot(options?) | URL/title, elements, source texts, records, scroll and truncation metadata; no Jev call |
observe(instruction, {values?, ...options}?) | One ActionPlan or null; no mutation |
act(instructionOrPlan, options?) | executed or pending dialog, plan and URL |
extract(instruction, zodSchema, options?) | {data, evidence, snapshotId, decision?, decisions?} |
locateSemantic(description, options?) | SemanticTarget; grounded current ref + evidence + confidence, no generated selector |
compareSemantic(request, options?) | SemanticComparisonResult; deterministic short-circuit or confidence-aware semantic comparison |
compareSemanticBatch(requests, options?) | SemanticComparisonResult[]; independent source/comparison questions share decision frontiers |
assertSemantic(request, options?) | same result on pass; throws distinct failed/inconclusive semantic assertion errors |
run(instruction, {values?, expect?, until?, ...options}?) | {status, reason, steps, inputs, effects, usage, verification?, checkpoints?, continuation?}; verified multi-stage goal |
resume(continuationId, {values?, timeoutMs?, signal?}?) | Same-session continuation; unknown saves reconcile read-only before authorized later work |
agent(defaults?).execute(instructionOrOptions) | Same run result, same core loop |
native(command, options?) | Typed command union; mechanical operation without a model |
screenshot(options?) | Viewport PNG Buffer |
close() | Disposes references/listeners, closes owned resources |
observe plans are local and single-use. act(plan) and act({id: plan.id}) use the internally retained action, not fields supplied by the caller. A new AI observation, snapshot or navigation can invalidate a plan. Native snapshot refs may survive several operations as long as the original node and its meaning still match; a new snapshot replaces the reference set. Use a fresh snapshot after STALE_TARGET.
Single-action act/observe inputs can be explicit named string values, or quoted strings copied verbatim from the instruction. run additionally accepts nested JSON values and preserves JSON Pointer paths in input coverage. See goal-runtime.md for its separate data and completion contract. Explicit values take precedence; they are not generated by Jev. Current quote syntax is ASCII double quotes, Japanese corner quotes and curly double quotes. Use named values for complex escaping or secrets.
Extraction
Schemas can be scalar roots, objects with scalar fields, nested objects, or arrays of observed records. Scalar strings, numbers, booleans, compatible enums, optional and nullable scalar fields are supported. Arbitrary object unions, recursive schemas, dates, defaults, catch fallbacks, value-changing transforms and generated prose are not supported. Extract exact large integers as strings.
Use recordsScope for tables/cards with non-semantic markup. Nested record arrays follow actual nested DOM records. A value is copied from the selected source and validated; it is never freely generated. Each array item is restricted to one record's sources. For separate unrelated objects on the same page, narrow scope or make separate calls.
Evidence uses dotted object paths and zero-based record indices, such as invoices.0.total. Scalar roots use value. Scalar array items use 0.value. Evidence contains original text, surrounding context, frame, source ID and copied value; hrefs also identify the href attribute. A missing required source is EXTRACTION_MISSING. Data violating the final schema is EXTRACTION_SCHEMA. An empty record set is [] unless the schema requires a minimum count.
The CLI/MCP accepts exactly one of fields (simple scalar definitions) or schema (JSON Schema). SDK callers use Zod directly. The JSON Schema conversion follows the installed Zod implementation; unsupported constructs are rejected.
Semantic verification
Semantic verification is separate from native/Playwright assertions. Use exact assertions when the browser exposes exact truth; use semantic comparison when equivalence itself requires language understanding.
const result = await browser.compareSemantic({
actual: { description: 'Current plan' },
expected: 'Professional annual plan',
minConfidence: 0.8,
});
actual is either {description}, a current {ref}, a SemanticTarget returned by locateSemantic, or SDK-only {locator, property?, attribute?} using a real Playwright Locator. Description-based actuals are first bound to one grounded observed source. A definition-list term is treated as a field label, not the field value. No semantic comparison can use a model-generated selector or an unobserved source.
Results contain status (passed | failed | inconclusive), model choice (equivalent | different | insufficient_evidence), final comparison confidence, separate sourceConfidence, comparison threshold, sourceThreshold, grounded evidence, provenance source (deterministic | semantic), and semantic usage metrics. minConfidence defaults to 0.8; minSourceConfidence defaults to the effective comparison threshold. Both must be within [0,1]. A semantic assertion passes only when every model-dependent link needed for the assertion clears its own threshold: grounded-source selection and, when required, the semantic comparison. If source selection is already below sourceThreshold, comparison is skipped and the result is insufficient_evidence / inconclusive. Exact comparison itself is reported as deterministic and makes no second model call, while sourceConfidence still exposes source-selection uncertainty.
confidence is a Jev decision score, not a calibrated probability of correctness. assertSemantic throws SEMANTIC_ASSERTION_FAILED for a sufficiently confident different result and SEMANTIC_ASSERTION_INCONCLUSIVE for low confidence or insufficient evidence. An inconclusive result never passes.
compareSemanticBatch observes once when source discovery is needed. Independent source questions share one frontier and independent unresolved comparisons share the next. Usage reports requests, questions, serialDecisionDepth, token counts, providerMs, observationMs, and local verificationMs. Transport chunks forced by the 64-question / 128 KiB limits remain one dependency depth when they can run concurrently.
The same aggregate batch usage is attached to each item returned by compareSemanticBatch() for result-shape consistency; it must be counted once, not summed across items.
See semantic-verification.md for the verification model, privacy boundary, calibration discipline and examples.
Native command groups
All accept {command: name, ...args} in native(), --args JSON in CLI, and browser_<name> in MCP. A target is a snapshot ref or a caller-authored Playwright selector in target; frame is optional. element is an optional human-readable description, not a selector.
| Group | Commands |
|---|---|
| Navigation | navigate, navigate_back, navigate_forward, reload |
| Input | click, type, hover, drag, press_key, select_option, check, fill_form, mouse |
| Synchronization | wait_for, assert |
| Browser structure | tabs, frames, resize, handle_dialog |
| Files | file_upload, downloads, take_screenshot, pdf |
| Inspection | console_messages, network_requests, evaluate |
| State/test setup | storage, cookies, storage_state, trace, route, init_script |
Examples:
await browser.native({ command: 'type', target: 'input[name=email]', text: 'user@example.invalid' });
await browser.native({ command: 'select_option', target: 'select', values: ['pro'] });
await browser.native({ command: 'check', target: 'input[type=checkbox]', checked: true });
await browser.native({ command: 'wait_for', text: 'Saved' });
await browser.native({ command: 'assert', target: 'h1', property: 'text', expected: 'Saved' });
await browser.native({ command: 'tabs', action: 'new', url: 'https://example.com' });
await browser.native({ command: 'trace', action: 'start' });
await browser.native({ command: 'trace', action: 'stop', filename: 'trace.zip' });
Assertions support visible, hidden, enabled, text, value, checked, count, url, title. They poll within the operation budget, up to five seconds, and fail with ASSERTION_FAILED. Text assertions compare exact textContent. Native select_option replaces the selection set as Playwright does; AI select/deselect candidates preserve unrelated multiselect choices.
A dialog result must be handled with handle_dialog before other operations. downloads supports list, save, cancel; supply an index from the current list and a chosen output filename. File upload can use a file input target or a pending chooser. Screenshots support type, fullPage, target and output filename. Cookie/state/console/trace results may contain secrets.
Errors and automation
Stable codes distinguish configuration, unsupported schemas, missing candidates/evidence, stale refs/plans, cancelled or uncertain actions, failed assertions, denied capabilities, and session failures. CLI/MCP sanitize unexpected errors instead of returning provider response bodies. SDK caller code may still see Playwright errors and should treat them as local diagnostics.
A native/AI command returning executed means the operation ran, not that the business workflow succeeded. Goal execution can also establish UI readback by comparing a fresh result record with actual supplied values. Inspect the verification source and unobserved fields; this does not prove database durability. Never treat confidence or the absence of an exception as a passed E2E assertion.
Downloads are reported after the browser emits a download event. A click returning does not imply a download has started. In SDK workflows, register page.waitForEvent('download') before clicking; native clients can inspect the current download list in a later command. Whether a resource is rendered or downloaded depends on browser behavior and the response MIME/Content-Disposition headers.
Goal continuation
See goal-continuation.md for checkpoint evidence, final assertions, immutable inputs, same-Page/origin/scope ownership and unknown-effect reconciliation. SDK, persistent CLI resume and MCP browser_resume share one runner. A thrown BrowserError.partial may contain the continuation; inspect it rather than re-running the original task.
v0.7 semantic refinements
locateSemanticBatch(descriptions, options)returns reusable targets from one retained observation.assertSemanticBatch(requests, options)applies the same confidence policy as compare, then re-reads sources before returning. It rejects an empty assertion batch.compareSemantic*returns snapshot evidence;assertSemantic*returns only after a live re-read or throws with changed/inconclusive evidence.freshnessissnapshot,verifiedorchanged.- SDK Locator properties are
text(default),value,checked,attribute(explicit attribute name). The source must be uniquely visible within the current Page and optional scope. @tontoko/jev-browser/playwrightexportssemanticMatchers(core)for the caller's existingexpect.extend.- CLI/MCP batch commands are read-only.
semantic_compare_batch/semantic_assert_batchreturn{results,usage}and support global or per-item thresholds.semantic_locate_batchreturns{targets}. BrowserError.semanticpreserves{results,expected}through process boundaries; provider bodies and credentials are never attached. Resultmodelsretains named inference provenance;modelis omitted for incomplete/mixed attribution.
See semantic-verification.md for precise property, freshness, negation and data disclosure semantics.