Public API

Typed AI tools

from v_ase import FunctionTools provides model-independent tool definitions and execution. Use FunctionTools(command_url, artifact_dir="figures", timeout=300) as a context manager. definitions(names=None) returns MCP-shaped schemas; function_tools(names=None, strict=True) returns native function definitions. Execute with call(name, arguments) or call_function(name, arguments, strict=True), respectively.

Version 0.3.3 adds initial_definitions() for a small starting catalog and deferred_function_tools(namespace="vase", strict=True) for a host with deferred tool search. See scene workflows for the new snapshot, transaction, guide and image-inspection tools.

See MCP/native setup for lifecycle, strict optional/map semantics, resources and recovery, and tools by feature for the complete generated catalog. The CLI fallback is documented separately in CLI/HTTP collaboration.

Python

view

from v_ase.visualize import view

viewer_result = view(
    atoms_or_frames,
    *,
    notebook=None,
    block=True,
    port=None,
    show_cell=True,
    show_axes=True,
    show_bonds=True,
    respect_constraints=True,
    allow_relax=True,
    viz_only=True,
    theme="auto",
    return_mode="atoms",
    trajectory_source=None,
    initial_frame=0,
    initial_design_settings=None,
    document_name=None,
    close_on_disconnect=True,
    open_browser=True,
    stream_trajectory=False,
    volumetric_datasets=None,
    volumetric_precision="fp32",
)

Accepted input:

  • one ASE Atoms;

  • a sequence of Atoms frames;

  • a supported structure or trajectory path;

  • a .vase or project-embedded HTML path; or

  • a supported CHG/CHGCAR, PARCHG, LOCPOT, ELFCAR, Cube, or XSF path.

Important options:

  • notebook=None follows the process-local %v_ase display preference, then detects an active Jupyter kernel when that preference is auto. Use %v_ase inline, %v_ase browser, or %v_ase auto to switch subsequent view() calls without restarting the kernel. Pass True / "inline" or False / "browser" to override the preference for one call. Inline mode returns a view-only iframe below the cell; browser mode opens the complete external interface. Call display(editor) explicitly after assigning an inline handle.

  • viz_only=True uses the lightweight viewer and does not attach the fallback calculator.

  • theme="auto" and theme="system" follow the local browser/OS color preference. theme="light" and theme="dark" request an explicit initial interface theme unless that browser already has a user-selected preference.

  • viz_only=False enables atom editing, constraints editing, history, copy/paste, deletion, creation, and relaxation.

  • The browser’s top-bar View / Edit switch can change this capability during the same session. Entering Edit materializes lazy trajectory frames before editing is enabled.

  • block=True waits until the browser document closes or the local API finalizes the session.

  • block=False returns an ASEEditor handle.

  • return_mode is atoms, positions, or none.

  • respect_constraints=True commits coordinates through ASE constraint logic.

  • close_on_disconnect=True lets a closed browser document release a blocking Python or CLI call.

  • close_on_disconnect=False keeps the API session and its local server alive across workspace-tab disconnects until the session is finalized explicitly.

  • show_bonds=True is the default; pass False for an atom-only initial view.

  • open_browser=False keeps the loopback session available without invoking the operating-system browser launcher.

  • stream_trajectory=True requests per-frame browser transfer rather than a complete inline coordinate cache.

  • volumetric_precision is fp32 (the lower-memory default) or fp64.

The caller’s input object is copied and is never mutated.

Compatibility Alias

from v_ase import view_edit

edited = view_edit(atoms)

view_edit() is retained for compatibility and is equivalent to view(atoms, viz_only=False, ...). New code should use view().

view_file

from v_ase import view_file

view_file("trajectory.extxyz")
view_file("saved_project.vase")

view_file() forwards to view() and uses the canonical v_ase input pipeline. Supported large numeric LAMMPS dumps receive the virtual, byte-indexed trajectory path automatically.

ASEEditor

Returned by view(..., block=False).

editor.url
editor.get_atoms()
editor.get_positions()
editor.set_atoms(atoms)
editor.export_poscar("POSCAR")
editor.export_pickle("atoms.pkl")
editor.close()

get_atoms() returns a detached copy. close() releases the session, temporary files, workspace documents, and the managed local server when it is the final owner.

view(..., open_browser=False) suppresses automatic browser launch. With block=False, inspect ASEEditor.url; with blocking CLI use, v_ase prints the URL before waiting for the browser document to close. The server remains bound to 127.0.0.1. The CLI’s HOST:/path form creates and manages the SSH forwarding connection automatically; custom Python deployments remain responsible for their own transport.

CLI

v_ase gui
v_ase gui FILE
v_ase gui HOST:/REMOTE/FILE
v_ase gui FILE --interactive
v_ase gui FILE --cli
v_ase gui AMBIGUOUS --format FORMAT
v_ase gui FILE --no-browser

The default is View mode. --interactive starts in Edit mode. The top-bar switch can change mode after startup without reopening the file. HOST:/REMOTE/FILE is an scp-style remote target. The local v_ase process selects both loopback endpoints, then starts the remote backend and forwarding listener on one SSH connection. This keeps both endpoints on the same login node when a cluster alias is load balanced. The launcher opens the browser and tears the connection down after the browser closes:

v_ase gui physics:/data/trajectory.lammpstrj

The file reader, ASE objects, session state, trajectory cache, volumetric processing, and backend scientific operations remain on the remote host. The original file is never copied to the local computer. The browser performs UI interaction and WebGL rendering. Remote trajectories disable inline and whole-trajectory browser caches; frame changes request only the needed frame through the encrypted tunnel.

--no-browser is still available for headless local sessions. --stream-frames applies the same per-frame transfer policy to a local trajectory. --port remains an advanced override for a predetermined local integration endpoint; neither option is required for HOST:/REMOTE/FILE.

--cli is a terminal-oriented local API mode, not an embedded AI model. An automation agent invokes it itself. It suppresses automatic browser launch, prints one JSON handshake as the first stdout line, then streams committed workspace changes as NDJSON. Its semantic state and browser control schema avoid pixel-based structure inspection; the reported human_url opens the same live document for normal use and human refinement.

The CLI does not accept natural language or commands from stdin. Its first stdout line is discovery metadata, later stdout lines are v_ase.collaboration.v1 events, and status is written to stderr. The controlling external agent opens human_url and sends structured HTTP JSON through command_url, normally with v_ase api. The handshake explicitly reports command_transport="http-json-bridge", accepts_natural_language=false, and stdin_commands=false, plus events_url, event_protocol, event_delivery, and event_scope.

The terminal client uses progressive discovery and compact responses by default:

v_ase api "$COMMAND_URL" schema
v_ase api "$COMMAND_URL" schema --operation-schema compose-view \
  --operation-schema style-atoms --operation-schema configure-bonds
v_ase api "$COMMAND_URL" describe --profile summary
v_ase api "$COMMAND_URL" describe --profile structure --include-positions
v_ase api "$COMMAND_URL" describe --profile render
v_ase api "$COMMAND_URL" apply --params-file command.json
v_ase api "$COMMAND_URL" render --params-file render.json --save result.png

Bare schema returns an operation/export index; --full-schema is reserved for integration auditing. State profiles are summary, structure, appearance, bonding, render, analysis, and full. CLI apply adds a summary response unless --response-profile requests another profile, and reports exact mutation.changedPaths. Render results report effectiveRender.source and the exact camera used. This keeps inactive bond tables, complete per-atom arrays, and Base64 image data out of an agent’s context unless they are explicitly needed.

ASE Bulk Builder

The installed ASE compatibility catalog and nonmutating preview are available inside each live session:

GET  /api/build/bulk/catalog/{session_id}
POST /api/build/bulk/preview/{session_id}
POST /api/build/bulk/apply/{session_id}

The catalog identifies working reference materials, prototypes, cell modes, and conditional arguments. Preview returns either the exact generated cell and atom count or a structured missing_fields list. Apply is Edit-only and replaces the active structure with one periodic frame. A nonempty document requires replace_existing: true; clients must obtain user confirmation first.

The semantic equivalent is a revision-guarded build-bulk operation:

{
  "expectedRevision": 12,
  "mode": "edit",
  "operation": {
    "name": "build-bulk",
    "formula": "CuO",
    "crystalStructure": "rocksalt",
    "cellMode": "cubic",
    "a": 4.27,
    "confirmReplace": true
  }
}

Optional fields are b, c, alpha, covera, u, and an N x 3 fractional basis. c and covera are mutually exclusive. Read capabilities().bulkBuilder.catalogUrl, preview the exact request, and do not guess reference lattice data.

Edit-mode random insertion is available to external agents through the same live document and revision contract:

v_ase api "$COMMAND_URL" apply --params '{
  "expectedRevision": 12,
  "mode": "edit",
  "operation": {
    "name": "scatter-atoms",
    "entries": [
      {"element": "Li", "label": "Li_mobile", "count": 12},
      {"element": "H", "label": "H_probe", "count": 8}
    ],
    "regionMode": "regions",
    "regionMic": true,
    "regions": [
      {"id": "left", "role": "allow", "bounds": [1, 4, 0.5, 7.5, 0, 12]},
      {"id": "right", "role": "allow", "bounds": [5, 8, 0.5, 7.5, 0, 12]},
      {"id": "core", "role": "reject", "bounds": [3.5, 5.5, 3, 5, 2, 10]}
    ],
    "constrainToDomain": false,
    "seed": 2021,
    "freezeExisting": true,
    "cutoffBasis": "covalent",
    "cutoffScale": 1.0
  }
}'
v_ase api "$COMMAND_URL" apply --params '{
  "expectedRevision": 13,
  "operation": {
    "name": "relax-added-atoms",
    "strength": 2.5,
    "fmax": 0.01,
    "steps": 180,
    "constrainToDomain": false
  }
}'
v_ase api "$COMMAND_URL" apply --params '{
  "expectedRevision": 14,
  "operation": {"name": "finish-add-atoms"}
}'

The revision numbers above are illustrative. Call describe after each mutation and use its latest collaboration.revision in the next expectedRevision; never assume sequential values in a shared GUI.

stop-added-atoms interrupts the optimizer but leaves the insertion workspace open. cancel-add-atoms removes every inserted atom and restores the exact pre-session structure. A multi-region request supplies stable region IDs, Allow/Reject roles, and Cartesian xmin/xmax/ymin/ymax/zmin/zmax bounds. The exact domain is the finite cell intersected with the Allow union, or the full cell when no Allow exists, minus the Reject union. regionMic maps wrapped images through the complete triclinic lattice. Without a finite cell, at least one Allow region is required. constrainToDomain defaults to false because regions define initial scattering; true keeps every staged atom inside the Allow union and outside every Reject region during repulsive placement. Rigid molecules use their ASE template origin for this efficient domain constraint. Legacy allowEscape is the inverse compatibility field. update-add-atoms-region accepts a complete region array or one stable ID without moving staged atoms. The GUI maps multi-selected region translation to G and rejects R. Molecule requests additionally support quantityMode:"density" plus targetDensityGcm3; Count values then define an integer composition ratio, which is reduced to its primitive ratio before a complete batch is chosen. State reports target/actual density from exact accessible volume. update-add-atoms-region can also change regionMic; the same value immediately controls wrapped previews and optional confinement. schema is authoritative for all parameter names and allowed ranges.

v_ase api "$COMMAND_URL" describe --profile summary
v_ase api "$COMMAND_URL" apply --params-file command.json
v_ase api "$COMMAND_URL" render --params-file render.json --save figure.png

The terminal client redacts render/export dataUrl values unless --print-data-url is explicitly requested. Prefer --save so encoded pixels never enter an AI context.

The browser Open dialog can replace the active document, append selected frames to its trajectory, or open an independent workspace tab. .vase settings are restored for replace/new-tab operations and intentionally ignored for trajectory append.

Common format aliases:

Alias

Reader

POSCAR, CONTCAR, vasp

VASP structure

XDATCAR

VASP trajectory

vasprun.xml, vasp-xml

VASP XML

lammpstrj

LAMMPS text dump

data

LAMMPS data

xyz, extxyz

XYZ/extended XYZ

traj

ASE trajectory

vase

v_ase project

--index : loads all frames, --index -1 loads the last frame, and an integer loads one frame.

LAMMPS integer types remain distinct GUI labels. Valid integer values are used as atomic numbers for initial element defaults; invalid values use internal hydrogen while preserving the raw label. Custom extxyz labels such as H_type5 are mapped to ASE-valid chemical symbols without losing the label.

Calculator

User-supplied ASE calculators are preserved. Interactive mode attaches the built-in soft repulsion calculator only when the input has no calculator. Visualization mode does not attach it.

from v_ase.calculators import RepulsionCalculator
from v_ase.io import set_atom_labels

labels = [f"{symbol}_{index}" for index, symbol in enumerate(atoms.get_chemical_symbols())]
set_atom_labels(atoms, labels)
atoms.calc = RepulsionCalculator(
    device="cpu",
    cpu_threads=4,
    cutoff_mode="absolute",
    cutoff_basis="covalent",
    pair_cutoffs={"|".join(sorted((labels[0], labels[1]))): 2.00},
    k_repulsion=1.0,
)
energy = atoms.get_potential_energy()
forces = atoms.get_forces()

Torch is optional. The calculator uses NumPy when torch is absent and can use torch CPU or CUDA when available. Browser DEVICE/CPU controls apply only to this built-in calculator. Repulsion distances are independent from visual bonds. In the default cutoff_mode="absolute", each pair_cutoffs value is the physical onset for that unordered label pair in angstrom; zero disables the pair. Omitting the table generates values from ASE covalent-radius sums, or van der Waals sums with cutoff_basis="vdw". To scale all supplied reference distances together, use cutoff_mode="scaled" and set the dimensionless cutoff_scale. A single global onset is also accepted:

atoms.calc = RepulsionCalculator(
    cutoff_mode="absolute",
    cutoff_distance=1.50,  # Angstrom
    k_repulsion=1.0,
)

For r < r_cut, both modes use E_pair = 0.5 * k_repulsion * (r_cut - r)**2; at and beyond r_cut, pair energy and force are exactly zero. r_cut is therefore an onset distance, not a hard minimum-separation constraint. All settings are editable under Structure > Relaxation and persist with supported calculator state.

Compatibility imports remain available from v_ase, v_ase.calculator, and v_ase.repulsion. Conditioner is an alias for the same class.

Save Formats

ASE Pickle

Current-frame Python interchange. It retains:

  • coordinates, chemical symbols, labels, cell, and PBC;

  • ASE constraints and portable arrays;

  • valid cached SinglePointCalculator results.

It excludes visual settings, other trajectory frames, and arbitrary executable calculator implementations.

Visual Settings JSON

Reusable presentation preset containing:

  • label appearance and visibility;

  • bond configuration;

  • camera, projection, and atomic scale;

  • lighting, quality, and overlays;

  • display supercell and absolute Cartesian/fractional visual translation.

Coordinates are never included. Loading reconciles label-specific values with the new structure, ignores absent labels, and creates defaults for new labels and pairs.

Personal Visual Defaults

The GUI stores an optional per-OS-user startup style outside projects and structure files. It includes reusable appearance, bonds, lighting, viewport, display replication, visual translation, render quality, and image-export choices. It excludes atom coordinates, trajectory frames, cell contents, absolute camera placement, and per-atom overrides.

Use Export > Visual Settings > Set Current as Default to save it. Restore the built-in values with Restore App Defaults; the confirmation dialog deletes the saved preference only after Proceed. Portable Visual Settings JSON remains a separate file-based interchange format.

.vase

Self-contained project archive containing:

  • all trajectory frames and the active frame;

  • edited coordinates, cells/PBC, constraints, labels, safe arrays, and metadata;

  • cached standard calculator results and supported built-in calculator config;

  • complete visual settings.

The archive is ZIP-based, validated before extraction, and does not unpickle executable Python objects.

Standalone HTML View

One view-only browser document containing:

  • inlined Three.js, renderer code, styles, scene data, and trajectory frames;

  • the saved camera, display, bonds, constraints, analysis overlays, supercell, and visual translation;

  • optionally, the complete validated .vase archive as Base64 metadata.

It opens from file:// without a server or network request and supports only camera navigation and trajectory playback. embed_project defaults to false for a smaller view-only handoff. Set it to true for a downloadable .vase and lossless reopening through v_ase gui FILE.html. In the human Save Project dialog, enabling Include interactive rendered view changes the output to HTML and always embeds the complete project.

HTML, image, and video share the same Preview Area camera crop and aspect ratio. HTML dimensions are inherited from Preview Area and are not exposed as a second independent resolution control. HTML defaults to grid off, axes on, and unit cell on. An optimized high-resolution copy of the exact rendered frame is embedded so macOS Finder/Quick Look can display only the structure frame without executing JavaScript. In a browser, the full-frame poster and the adaptive device-pixel-ratio WebGL canvas occupy the same integer-sized rectangle; the first completed live frame automatically cross-fades over the poster before camera input begins, without moving or resizing the scene. View-only controls appear after activity and do not occupy layout space.

The generated project tag uses bounded Base64 decoding and the extracted ZIP passes the same path, schema, size, and integrity checks as a direct .vase file. HTML is larger than .vase because browser-ready scene data and runtime code are included; project embedding adds the Base64 archive.

Local Application API

The browser communicates only with a FastAPI server bound to 127.0.0.1. Endpoint groups:

  • session and workspace lifecycle;

  • structure load/append, frame switching, wrap, reset, history, copy/paste, add/delete;

  • coordinate commit and constraint editing;

  • calculator and relaxation control;

  • POSCAR, ASE Pickle, lossless WebP/optimized PNG image support, video support, Blender, 3DM, OBJ, and standalone HTML export;

  • visual-settings and .vase save/load;

  • binary current-frame and full-trajectory coordinate transfer.

  • semantic AI schema, operation/export parameter discovery, skill guide, and current-frame state.

Mutable structure requests and structure/3D-scene exports carry frame_index. The server switches to that frame before applying browser coordinates or producing output, preventing a fast scrub from leaking the previous frame’s cell, constraints, or coordinates into the operation.

Canonical atom identity update:

POST /api/atom-identity/{session_id}

Uploaded structures are appended without replacing visual state through:

POST /api/file/append/{session_id}

Large compatible trajectories expose contiguous float32 coordinates through:

GET /api/trajectory/positions/{session_id}
GET /api/frame/positions/{session_id}/{frame}

Trajectory displacement analysis is available through:

POST /api/analysis/displacement/{session_id}

The payload selects the current/reference frames and MIC policy. Common unique particle-ID arrays are preferred; equal-size frames fall back to atom index. Different-size frames without IDs return a physical-mapping error. Returned vectors retain physical values. The renderer anchors them at current visible atom positions, repeats them over display supercells, and applies visual translation equally to both endpoints.

One-atom Measure detail is available lazily through:

GET /api/analysis/atom-properties/{session_id}/{atom_index}?frame_index=N

The response contains standard ASE atom attributes, every stored per-atom Atoms.arrays entry, and every already stored per-atom calculator result for the requested frame. It does not evaluate the attached calculator. A selected display-supercell replica uses this base-index payload while the browser keeps the replica’s displayed Cartesian and fractional position.

Volumetric data is loaded through the ordinary file/path open or append pipeline. VASP scalar grids, Cube, and XSF are detected before ASE structure dispatch. Browser file/path endpoints accept volumetric_precision as float32 or float64; the semantic load-volumetric operation accepts precision as FP32/FP64 aliases. Dataset descriptors report precision and backend memory bytes. The newest nonconstant grid is selected and displayed at an in-range default isovalue immediately. Surface color and opacity changes restyle the current browser mesh without requesting marching cubes again. The current document then exposes:

view("CHGCAR", volumetric_precision="fp64") applies the same selection to Python path-based loading and records it as the next-import precision in the live GUI.

POST /api/volumetric/difference/{session_id}
POST /api/volumetric/isosurface/{session_id}
POST /api/volumetric/delete/{session_id}

The difference endpoint accepts stable dataset IDs and finite coefficients and requires matching dimensions, cell, origin, PBC, endpoint convention, and units. The isosurface payload accepts optional smearing_sigma in grid voxels from 0 through 8, plus smoothing_iterations from 0 through 30. Smearing uses wrapped boundaries on periodic axes and reflected boundaries on nonperiodic axes. It filters a display copy without modifying the stored FP32 or FP64 field. Mesh smoothing is applied after marching cubes and fixes cell-boundary vertices. The endpoint returns indexed vertices and faces with the applied refinement values in its binary header; the complete source grid remains backend-owned. Physical diagonal supercell application repeats every stored grid and records it in the same undo entry as atoms and trajectory frames.

The semantic show-volumetric operation validates the same ranges instead of silently clamping values. Signed mode uses +abs(level) and -abs(level), requires a nonzero level, and may retain only one sign if smearing moves the other sign outside the displayed scalar range. describe() exposes the resulting mesh counts, rendered levels, post-smearing range, and refinement settings under analysis.volumetricSurface; it does not transmit source grid arrays.

RDF endpoints are:

POST /api/analysis/rdf/{session_id}
POST /api/analysis/rdf-csv/{session_id}

Payload fields are cutoff, bins, pairMode, and activePairs. pairMode accepts active, selected, all, or none; the browser resolves selected to label pairs from active bonds whose endpoints are both selected and sends those pairs through activePairs. Full 3D PBC produces bulk g(r), while a finite no-PBC structure produces an unordered-pair probability density. The response includes the retained requested/effective cutoff, unique-MIC reference, actual periodic-image extent/span, warnings, total curve, and concentration-weighted partial curves. CSV uses the same calculation path. The Plotly drawer adds a g(r) = 1 bulk-limit reference for periodic RDF; the periodic amorphous regression checks that the long-range curve remains flat around that reference.

Agent discovery and semantic state are available through:

GET /api/ai/schema
GET /api/ai/skill
GET /api/ai/state/{session_id}
POST /api/ai/events/{session_id}
GET /api/ai/events/{session_id}?after={revision}&timeout={seconds}
GET /api/ai/workspace-events/{workspace_id}?after={revision}&timeout={seconds}

Browser-originated events are compact notifications, not state patches. They contain source, categories, changed paths, document/frame context, and a monotonic revision. Workspace events also contain the affected session_id and document_revision. Position arrays are intentionally omitted; agents must activate the affected document and call describe().

Image encoding is available through:

POST /api/export/image/{session_id}?format=webp
POST /api/export/image/{session_id}?format=png
POST /api/export/image/{session_id}?format=jpg
POST /api/export/image/{session_id}?format=pdf

The endpoint accepts the exact browser-rendered PNG bytes. WebP conversion is lossless; PNG conversion is a lossless IDAT recompression. JPEG and PDF flatten transparency onto white. Every response keeps the original pixel dimensions. PNG is the browser UI and semantic API default.

The human image-export workflow selects its destination before rendering and uses one monotonic progress sequence across browser render, pixel capture, upload, server encoding, response download, and destination write. Estimated remaining time is derived from completed pipeline work; 100% is emitted once, after the output file is complete.

The command bridge exposes schema, ready, capabilities, describe, apply, render, and export; workspace scope also exposes documents, activate, and newDocument. The optional document-level window.v_aseAI object mirrors the live document methods, including focused schema(options) discovery. Use the separate v_ase api client for ordinary agent work so the integration does not depend on page-main-world JavaScript. capabilities() advertises expectedRevision in its apply fields, and describe() reports the current document collaboration revision. apply() accepts that revision as an optimistic-concurrency guard and rejects stale commands before they can overwrite a newer human GUI edit. It covers frame and mode changes, quality, display and camera state, selection, constrained transforms, identity and constraint edits, wrapping, physical translation, atom creation/deletion, batch atom scattering and its region, supercells, history, reset, structure relaxation, rigid periodic-plane translation, and displacement analysis. Visual translation and display supercells are ordinary display settings available in View and Edit. rotate-selection accepts pivot: "active"; the last explicit atom index is the fixed rotation pivot. Reference-figure composition is exposed through set-visual-label, style-atoms, configure-bonds, and compose-view. These operations separate index/layer roles without changing ASE elements, apply final rendered radii, define an intentional visual-label policy or exact index-edge list, and align a centered periodic motif using explicit cellOffset references and centered display replication. configure-bonds accepts an empty pair list with disableUnspecified:true as the explicit no-bond state. clearEndpointOverrides:true makes requested pair appearance authoritative over stale atom-level bond styling. compose-view can use fit:"references" with exact atom/replica references to match a bounded panel’s visible motif count without modifying or hiding the remaining structure. configure-bonds.indexPairs selects exact zero-based visual atom edges for a figure that highlights only one chain or local motif while preserving every label-pair cutoff, range, and appearance setting when sent without pairs. For crop-only refinement, preserveOrientation:true retains the current camera direction and roll. atomDisplayMode:"2d" switches the complete composition to flat, unlit 2D geometry; "3d" restores material-aware geometry. It also covers commensurate search/materialization, optional (hkl) translation maps, volumetric loading, compatible-grid combinations, isosurface settings/removal, and RDF calculation. describe().analysis returns commensurate and registry mode state, volumetric dataset descriptors, and the current RDF summary without serializing large numerical fields into agent context. export() covers image, video, POSCAR, ASE Pickle, Blender, Rhino 3DM, OBJ, standalone HTML, .vase, and visual settings, plus RDF, commensurate, and registry CSV. Rendering and image export use the same capture path as the human Export workspace.

describe() is the primary machine-readable output and includes document, mode, frame, atom identity, positions when requested, cell/PBC, constraints, properties, selection, measurement, display, camera, and image-export state. It also includes volumetric dataset metadata and RDF curve names, cutoff metadata, warnings, and frame. apply() returns the updated semantic state and revision. Human and agent mutations are classified separately, coalesced after committed UI changes, published to the document and workspace streams, and retained in bounded history. render() and export() return data URLs plus filename, MIME type, byte count, format, and dimensions where applicable.

WebSockets stream relaxation updates and own browser-document/workspace lifetime. Closing the last connected browser document finalizes blocking calls after a short reconnect grace period.