/** * GuiDriver — the one abstraction. Template method pattern: this base class owns the * shared observation pipeline (rendering, change verdict, ref bookkeeping, standard * wording), subclasses supply platform primitives and declare their extras. Tools are * built once from any driver by the factories in tools/ — consistency across platforms * comes from that shared code, not from tests. * * A driver instance is created at bootstrap but must connect lazily: no browser/device * I/O until a primitive is first called. */ import type { ActResult, ContextPolicy, Snapshot, SnapshotCapture, Strategy, TargetInfo, ToolResult, VerbSpec } from "./types.ts"; /** Standard effect-evidence wording. Tuned against real failure modes; identical on * every platform so behavior learned on one transfers to another. */ export declare const FROZEN_NOTE: string; export declare abstract class GuiDriver { abstract readonly platform: string; abstract readonly strategies: Strategy[]; /** Read the current a11y state as a numbered element list. */ protected abstract snapshot(): Promise; abstract screenshot(): Promise; abstract readText(): Promise; abstract listTargets(): Promise; abstract focusTarget(id: string): Promise; /** Execute one act verb (universal or extra) with its raw arguments. */ abstract perform(kind: string, args: Record): Promise; abstract close(): Promise; /** Extra act verbs beyond the universal set (open_url, swipe, ax_action, ...). */ extraVerbs(_strategy: Strategy): VerbSpec[]; /** Grounding teaching appended to the base system prompt. */ abstract promptFragment(strategy: Strategy): string; /** Rebind to an environment a harness prepared for this session, from the env-var * params it published (browser reads PI_GUI_CDP_URL, android PI_GUI_ANDROID_SERIAL). * Optional — drivers without a rebinding notion simply omit it. */ retargetEnv?(params: Record): Promise; contextPolicy(strategy: Strategy): ContextPolicy; /** In hybrid mode, attach a screenshot when the tree has fewer elements than this. */ protected sparseThreshold: number; /** MIME type returned by screenshot(). Atomic captures may override per image. */ protected readonly screenshotMimeType: string; /** Default drivers collect structure first and pixels only when requested. Drivers * with an atomic structure+image API override this to keep both views coherent. */ protected captureSnapshot(): Promise; private prevSig; private refs; private lastImageHash; /** Is this ref from the latest observation? Refs die on every re-observe. */ knownRef(ref: string): boolean; /** * A one-shot fact the driver wants the next tool result to carry (e.g. "the browser had been * closed and a fresh one is up"). Overridden by drivers that have such facts; the base returns * nothing. It rides the OBSERVATION as well as the action, because a model that only observes * after a reopen would otherwise see a blank page with no explanation. */ protected takePendingNote(): string | null; /** Element observation: snapshot → verdict vs previous → rendered text (+ optional * screenshot fallback when the tree is sparse, for hybrid). */ observeElements(opts?: { prefix?: string; attachImageIfSparse?: boolean; forceImage?: boolean; }): Promise; /** Screenshot observation with an image-hash verdict (pixels strategy). */ observeImage(opts?: { prefix?: string; withVerdict?: boolean; }): Promise; observeFullText(): Promise; /** Snapshot → the compact text the model reads. Override for platform-specific layout. */ protected renderSnapshot(s: Snapshot, targets: TargetInfo[]): string; /** Change signature: refs stripped (re-minted each observe), form values included * (a fill changes values but not the element set). */ protected signature(s: Snapshot): string; }