/** * sim/operate.ts — the operate action handler + runtime assembly, ported from * mirofish `engine/runtime/operate.py` and `runtime/observe.py`. * * `operate` is the planner's one first-class world action. agent.execute * routes it here; runOperate delegates to the Executor seam (the TS * counterpart of `sandbox.exec()` — grounding, multi-step, screenshots all * live behind it) and returns text + a fresh screenshot as the next * observation. * * L0/L1 context-sharing, three channels (each fixed a real failure): * ① context — the executor remembers nothing between delegations, so the * engine auto-appends a rolling digest of recent delegation outcomes; * ② expect — the objective completion check the executor self-verifies; * ③ upward findings — the most informative substep results ride back into * the planner's observation (failures verbatim: the real diagnosis of a * Playwright failure sits ~430 chars in, so failed findings keep head+tail). */ import { type ExecSink, type Executor, type Part, type SimRuntime, type StepRecord, type SubStep, type Use } from "./models.ts"; /** * Clip one finding. Success clips from the head (readings front-load their * value); failures keep head + tail joined by …(略)… — error bodies are * boilerplate-first, diagnosis-last, and clipping from the head once turned * "modal intercepts pointer events" into "system stuck", burning whole cases. */ export declare function clipFinding(text: string, failed: boolean): string; /** Substep results worth carrying up to the planner: failures always, long * informative readings otherwise; newest first, capped, deduped vs summary. */ export declare function keyFindings(steps: SubStep[], summary: string): string[]; /** Executor failure summary → something a persona can feel (no executor jargon). */ export declare function humanizedFailure(command: string, summary: string, steps: SubStep[]): string; /** The observation body one operate reports back to the planner — shared by * the live path and history-reseeding, so injected and real records are * indistinguishable downstream. */ export declare function operateNote(command: string, ok: boolean, summary: string, steps: SubStep[], endType: string | null): string; /** Rebuild sink.thread (recent delegation outcomes) from history — used when * resuming (fromFrame); same projection as the live path. */ export declare function rebuildThread(history: StepRecord[]): string[]; /** Rebuild the in-flight observation after injecting history: the last step's * delegation reports, projected exactly like the live path. Screenshots are * live-device state and cannot be rebuilt (open() re-observes). */ export declare function seedFromHistory(history: StepRecord[], endType?: string | null): Part[]; /** Offline runtime whose planner vocabulary matches a real end of `kind` * exactly, with no device and no side effects — the porting-friendly seam for * predict mode and cross-implementation diffing. */ export declare function shapeRuntime(kind?: string | null, uses?: Use[]): SimRuntime; /** A screenshot Part of the current end state, or null (shell / no end / failed). */ export declare function shotPart(rt: SimRuntime): Promise; /** The planner's observation outlet: one line of text + a screenshot when the * end has one. Used by operate reports and the default init. */ export declare function observeNote(rt: SimRuntime, note: string): Promise; /** Light no-end observation: browser page title only (duck-typed state()). */ export declare function lightObserve(rt: SimRuntime): Promise; /** * The operate handler: hand the semantic intent to the executor, return the * observation. Wires the three context channels (thread bridge into context, * expect straight through, findings back up) and folds cost/opTrace/thread * into the sink for the agent to drain into the StepRecord. */ export declare function runOperate(rt: SimRuntime, args: Record): Promise; /** The shell built-in write_file: whole content lands in one call (bypassing * PTY heredoc). Content is authored by the planner; ≤ 200KB. */ export declare function runWriteFile(rt: SimRuntime, args: Record): Promise; /** Assemble an end-attached runtime: executor handle + default opening * observation + execution-layer uses + optional pre-wired sink (hosts pass one * to receive live substeps). The planner gets `operate` because the executor * is non-null; uses stay execution-layer tools and never reach the planner. */ export declare function endRuntime(executor: Executor, opts?: { init?: ((rt: SimRuntime) => Promise) | null; uses?: Use[]; sink?: ExecSink; }): SimRuntime;