Skip to content

Python API

Mount Lens in a notebook cell. Connect to that instance from a live agent kernel call with marimo_lens.agent.connect().

TaskAPI
Add the notebook interfaceLens
Read selections, source, and imagesLens.context(), LensContext
Show agent work and return a resultstart_activity(), stop_activity(), reveal()
Move addressed requests to Historyresolve()
Connect an agent or capture current outputconnect(), MountedLens
Release a Lens instanceclose()

The two caller roles are:

  • Notebook authors construct Lens and keep it mounted with the notebook.
  • Code-mode agents call marimo_lens.agent.connect() and work through a MountedLens handle.

The two surfaces share context, activity, reveal, and resolution behavior. The agent handle adds stable reconnection identity and current cell-output capture.

Source version

This reference follows the repository's main branch. PyPI follows tagged releases. Read Compatibility when the installed signatures differ.

Notebook-author API

The top-level package exports:

python
from marimo_lens import (
    ActivityHandle,
    CellReference,
    Lens,
    LensContext,
    LensError,
    LensReferences,
    NotebookReference,
    SelectionReference,
    SelectionTargetReference,
    __version__,
)

__version__ comes from the installed marimo-lens distribution metadata.

Lens

python
Lens(*, dom_selector: str | None = None) -> Lens

Creates the Python widget and browser UI that own one Lens instance.

  • dom_selector: str | None adds configured DOM targets to the default notebook output targets. The string is stripped and accepts at most 1,024 UTF-16 code units.
  • Returns a renderable Lens instance.
  • Raises TypeError for a non-string selector.
  • Raises ValueError for an empty or oversized selector.
  • The browser reports invalid CSS syntax when the view mounts.
python
from marimo_lens import Lens

lens = Lens()
lens

Keep the value mounted while people create selections and agents call its methods. Read Targets before configuring host DOM targets.

Lens.context

lens.context() -> LensContext

Returns detached selection references, lazy graph-context text, available selection-image bytes, and the captured selection-state revision.

python
context = lens.context()
selection = context.current

The object does not update. Call context() again after notebook or Lens state changes. Existing contexts remain readable after lens.close().

Raises LensError(code="lens_closed") after the Lens closes.

Read the LensContext reference for every field and degradation rule.

Lens.start_activity

python
lens.start_activity(
    target: str | SelectionReference,
    *,
    expected_revision: int | None = None,
    duration_ms: int | None = None,
    label: str | None = None,
    message: str | None = None,
) -> ActivityHandle

Marks one selection or cell as the current work location and returns the opaque owner accepted by stop_activity().

python
context = lens.context()
selection = context.current

if selection is not None:
    activity = lens.start_activity(
        selection,
        expected_revision=context.revision,
        label="Updating selected result",
        message="Inspecting the target and its producing cells.",
    )

Pass a SelectionReference and its captured expected_revision to address the selected target. Pass a cell ID string for a notebook walkthrough. A cell address can omit expected_revision and must identify a current graph member.

duration_ms=None keeps activity visible until a matching stop, later attention, or teardown. A duration from 1 through 300,000 milliseconds clears it after that hold. label defaults to Working in the browser. Labels accept 40 UTF-16 code units and activity messages accept 240. Selection state does not change.

Raises LensError for a closed Lens, stale selection revision, missing selection, unavailable runtime, or missing cell. Invalid inputs raise TypeError or ValueError.

Lens.stop_activity

lens.stop_activity(activity) -> None

Stops activity when activity still owns the current presentation.

python
lens.stop_activity(activity)

ActivityHandle is a string-backed, JSON-safe opaque value. A stale handle has no effect. A non-string value raises TypeError. An empty or oversized value raises ValueError. A closed Lens raises LensError(code="lens_closed").

Lens.reveal

python
lens.reveal(
    target: str | SelectionReference,
    *,
    expected_revision: int | None = None,
    duration_ms: int,
    label: str | None = None,
    message: str | None = None,
) -> None

Brings one selection or cell into view for a required hold.

python
context = lens.context()
selection = context.current

if selection is not None:
    lens.reveal(
        selection,
        expected_revision=context.revision,
        duration_ms=8_000,
        label="Updated result",
        message="Verified the change and brought the selected target into view.",
    )

Target and revision rules match start_activity(). Reveal preserves selection state and keyboard focus. A later attention event replaces it. Wait for the hold before resolving when the resolution receipt should follow the revealed result.

duration_ms accepts 1 through 300,000 milliseconds. Labels accept 40 UTF-16 code units. Reveal messages accept 1,000. See Errors and limits for the complete validation contract.

Lens.resolve

python
lens.resolve(
    selection_ids: str | Sequence[str],
    *,
    expected_revision: int,
    summary: str | None = None,
) -> int

Moves one or more Open selections into History and returns the next selection-state revision.

python
context = lens.context()
selection_ids = [item["id"] for item in context.references["selections"]]

if selection_ids:
    revision = lens.resolve(
        selection_ids,
        expected_revision=context.revision,
        summary="Updated the result and verified the affected cells.",
    )

Pass one ID string or a sequence of up to 64 unique strings. Lens validates the entire batch before changing state. The resolved selections share one resulting revision and optional summary of up to 240 UTF-16 code units. Their selection-image bytes are released.

The state transition commits before Lens sends its best-effort resolution receipt. A receipt delivery failure does not roll back History. Expected errors are lens_closed, revision_conflict, selection_not_found, and selection_context_limit.

Lens.close

lens.close() -> None

Closes the Lens instance, cancels pending cell-output capture, and releases Open selections, History entries, and Lens-owned selection images. Repeated calls have no effect.

Later public operations raise LensError(code="lens_closed").

Agent adapter

Import the adapter inside the live notebook kernel:

python
import marimo_lens.agent as lens_agent

agent_plugin

agent_plugin() -> agent_plugins.Plugin

Returns the Agent Plugin resource bundle installed with the current marimo-lens distribution.

Raises agent_plugins.AgentPluginError when distribution metadata or the packaged plugin is unavailable. Reinstall the same marimo-lens version before retrying.

agent_skill

agent_skill() -> agent_plugins.Skill

Returns the packaged marimo-lens Agent Skill.

  • skill / "SKILL.md" gives the instruction path.
  • skill.body gives the Markdown instruction body.
  • skill.files gives the packaged resource inventory.

Raises agent_plugins.AgentPluginError when the plugin contains no Lens skill.

add_lens_cell

add_lens_cell(ctx) -> str

Returns the existing agent-managed Lens cell ID or queues one collapsed Lens cell and returns its new ID.

python
import marimo._code_mode as cm
import marimo_lens.agent as lens_agent

async with cm.get_context() as context:
    cell_id = lens_agent.add_lens_cell(context)

The code-mode context creates and runs a queued cell when its async context manager exits. Connect in a later kernel call after the browser renders Lens.

ctx must expose create_cell(), run_cell(), and cells.find(). Other objects raise TypeError. Several agent-managed Lens cells raise LensError(code="lens_ambiguous").

connect

connect(context=None, *, identity=None) -> MountedLens

Finds one live Lens and returns its agent-facing handle.

python
import marimo._code_mode as cm
import marimo_lens.agent as lens_agent

mounted = lens_agent.connect(cm.get_context())

context adds Lens objects found in code-mode globals to browser-ready Lens registrations. identity selects the same Lens in a later kernel call.

Raises LensError(code="lens_unavailable") when no matching Lens exists. Raises LensError(code="lens_ambiguous") when several candidates exist and no identity selects one. A context without a globals mapping or a non-string identity raises TypeError. An empty identity raises ValueError.

MountedLens

MountedLens remains attached to one live Lens instance. It can address any selection owned by that instance.

MemberContract
identityOpaque string for reconnecting across kernel calls.
context()Delegates to Lens.context().
cell_image(cell_id, *, expected_revision)Requests a fresh, unmarked cell-output PNG.
start_activity(...)Delegates to Lens.start_activity().
stop_activity(activity)Delegates to Lens.stop_activity().
reveal(...)Delegates to Lens.reveal().
resolve(...)Delegates to Lens.resolve().

mounted.cell_image(cell_id, *, expected_revision) -> bytes | None

The first call starts browser capture and returns None. End that kernel call, reconnect to the same Lens, and repeat the same cell ID and revision. The completed call returns and consumes the PNG bytes.

python
context = mounted.context()
selection = context.current

if selection is not None and selection["cells"]:
    cell_id = selection["cells"][0]["id"]
    png = mounted.cell_image(
        cell_id,
        expected_revision=context.revision,
    )

One capture can be pending per Lens. Finish it before requesting another cell. A stale revision raises revision_conflict. A different cell while capture is pending raises capture_busy. A terminal result consumes the capture slot, so another call starts a new capture. Browser capture has a 15-second deadline and the Python request expires after 20 seconds. The operation requires a current graph member and a browser-ready Lens view. Read Context and evidence for the difference between a selection image and a cell-output image.

LensError

LensError extends RuntimeError and exposes:

  • code: str, a stable machine-readable failure code.
  • revision: int | None, the current selection-state revision when available.

Read Errors and limits for every code, recovery action, argument rule, and bound. Read Connect an agent for the complete workflow.