import type { ControlState } from "./index.js"; import type { SensitivityLevel } from "./index.js"; import type { PixelConsentState } from "./pixel-consent.js"; /** * Cloud-browser session info — populated by the surface that owns * the session lifecycle (web's `registerWebComputerTool`). * Surfaces without a virtual_browser embodiment (desktop_drive, * sandboxed) report `status: "closed"` always — those surfaces * don't expose `computer({navigate})` at all, so the AI shouldn't * be reasoning about a browser session there. */ export interface BrowserSessionInfo { /** * Whether motebit currently has an active virtual_browser * session. `closed` means no live screencast, no Chromium * process; the AI must call a tool to open one before * navigating / reading / screenshotting. */ readonly status: "closed" | "open"; /** * URL of the page motebit is currently looking at. Present * only when `status === "open"` AND the surface is tracking * navigation events. May be omitted (`undefined`) if the * surface hasn't wired URL tracking yet — absent means * "we don't know," not "no URL." */ readonly url?: string; /** * Co-browse control state — who's driving. Present when * `status === "open"` AND the session has a co-browse machine * (web). Absent on surfaces without co-browse (desktop_drive * v1). */ readonly control?: ControlState; } /** * Memory self-state — the typed truth about the motebit's own * memory store THIS turn, surfaced so the AI reads it instead of * inferring continuity from its architecture description. * * The hallucination this closes is the self-state sibling of the * browser-state one: asked "are you forming memories?", the AI * reads the `[INTERNAL REFERENCE]` line ("Memory graph: semantic * memory with decay, consolidation…") and confabulates "yes, I'm * forming memories" — even when zero formed this session and the * newest is days old. The capability description is true; the * runtime claim was not. The fix is the same as `BrowserSessionInfo`: * give the AI the typed runtime signal so the answer is grounded in * what the store actually holds, not what the architecture can do. * * Doctrine: `typed-truth-perception.md` — same four-part shape as * the browser line (wire field + runtime producer + prompt clause + * dispatch/test). The `[Now]` block is where the AI reads it. */ export interface MemorySelfState { /** Total non-tombstoned memory nodes this motebit currently holds. */ readonly total: number; /** * Age in ms of the most-recently-formed memory, or null when the * store is empty. Lets the AI answer "how fresh is my memory?" * from a number, not a guess ("9 days old", not "recently"). */ readonly newestAgeMs: number | null; /** * Memories formed since the current conversation began (the runtime * stamps this at boot and re-stamps it on each `resetConversation`, * so "this session" tracks what the user perceives when they ask * "are you remembering this?" — not runtime uptime). The * load-bearing field: a `0` here is the typed contradiction to * "yes, I'm forming memories" when nothing has been written. */ readonly formedThisSession: number; } /** * Full runtime session-state snapshot — composed by the runtime * from per-surface browser info plus its own sensitivity and * consent fields. Threaded through `MotebitLoopOptions` → * `ContextPack.sessionState` → the system prompt's dynamic * suffix as a `[Session]` block. * * v1 surface scope: web (cloud-browser embodiment). Desktop and * mobile surfaces will populate the same shape with their own * embodiment's state when the prompt-1 pattern lands there. */ export interface SessionStateSnapshot { /** Cloud-browser session info from the surface. */ readonly browser: BrowserSessionInfo; /** Effective session sensitivity tier — runtime-owned, applies to all AI calls. */ readonly sensitivity: SensitivityLevel; /** Per-session pixel-passthrough consent — runtime-owned. */ readonly pixelConsent: PixelConsentState; /** * Stale-omission signal — set when a prior tool result in this * conversation emitted `bytes_omitted_reason: ` but the gate * that fired `` is no longer firing under the current state. * Carries the prior reason so the prompt can teach the AI to * recover correctly (re-take, don't re-recommend an already- * granted affordance). * * The classic case: AI screenshot returns `bytes_omitted_reason: * "consent_required"`; user types `/vision grant`; AI's next turn * still references the historical omission and recommends * `/vision grant` to a user who already granted it. This signal is * the runtime telling the AI: "your prior omission is stale; the * gate has flipped." * * Absent (undefined) means either no omission has fired this * conversation OR the gate that fired is still firing (the * omission isn't stale). The PERCEPTION_DOCTRINE clause in * `@motebit/ai-core::prompt` teaches: if this field is present in * the [Now] block, re-take before answering and DO NOT re-recommend * the affordance for the stale reason. * * Doctrine: `motebit-computer.md` §"Typed truth on results" — same * shape as `frame_stale` and `not_in_control`. Typed wire field + * prompt clause + dispatch enforcement (the runtime computes the * staleness, the AI doesn't have to cross-reference history). */ readonly staleBytesOmissionReason?: import("./pixel-consent.js").PixelOmittedReason; /** * Substrate proprioception — the model this motebit is thinking * through THIS turn, read live from the provider (follows /model * switches; never a static string). Witnessed 2026-08-01 on * motebit.com: asked "what model are you running — this is a test", * the motebit honestly answered "I don't know" while the surface * chrome rendered `claude-opus-4-7` in the same frame. The runtime * knew; the interior wasn't told. With this facet, "swap the * substrate and I'd still be me" becomes a nameable fact instead of * an assertion — pluggability felt, not claimed. Absent when no * provider is wired. */ readonly substrate?: { readonly model: string; }; /** * Money acts settled THIS exchange — the streaming manager's own * ledger of completed paid delegations (same reset lifecycle as the * denial brake: the user's next message clears it). Witnessed * 2026-08-01: a completed \$0.25 hire the model then denied and tried * to re-buy. A hire listed here is DONE and paid — the [Now] clause * teaches: never deny it, never re-propose it. Produced by the * execution path, never model-authored. Absent/empty when nothing * settled this exchange. */ readonly settledDelegations?: ReadonlyArray<{ readonly capability: string; }>; /** * Memory self-state — runtime-owned. Present when the runtime has * a memory store wired (it always does in production; absent only * on surfaces/tests that construct a snapshot without one). When * present, the `[Now]` block emits a `Memory:` line the AI reads to * ground self-claims about its own memory instead of inferring them * from the architecture description. See {@link MemorySelfState}. */ readonly memory?: MemorySelfState; } //# sourceMappingURL=session-state.d.ts.map