Glossary
Load-bearing terms used throughout AgentCanvas, grouped by subsystem.
Β§1Canvas & Editor
The visual editor β canvas surface, node catalog sidebar, toolbar, graph-save/load surface. One editor, one registry, one catalog at every graph level (ADR-canvas-002).
| Flat Workspace | ComfyUI-style canvas where all node types coexist on one surface β no outer/inner layer split (see ADR-canvas-001) |
| Canvas Stack | Navigation stack for entering/exiting composite node subgraphs; replaces the binary layer toggle (see ADR-dataflow-001) |
| Root Canvas | The top-level graph (replaces "outer graph" in the recursive model) |
| Subgraph | The graph inside any composite node (replaces "inner graph" as the general term) |
| UnifiedGraphEditor | Dual-mode React Flow editor: root mode reads from Zustand store, subgraph mode uses local state with save-back (see ADR-canvas-002) |
| Unified Node Registry | Single map (unifiedNodeTypes.ts) with 2 custom components (compositeNode, stateContainer) + _generic Proxy fallback to GenericBlockRenderer. All other node types (14 built-in + NodeSet tools) are rendered via the Proxy β no explicit entry needed |
| NodeSet Manager | Dedicated UI page for managing NodeSets, server-mode nodesets, and environments β separate from the canvas (see ADR-canvas-001) |
| ExecutionToolbar | Standalone Play/Pause/Stop/Step/Reset toolbar at page level (see ADR-canvas-002) |
| SaveGraphDialog | Modal dialog for saving the current canvas graph with a user-defined name to workspace/graphs/ |
| Source tab | Bottom-panel tab (between Logs and Report) that edits the selected node's slice of its NodeSet source β module-level globals, the functions its class transitively references, and the class itself β spliced back by line range via PUT /api/components/nodesets/{name}/source/scoped; local NodeSets hot-reload via the nodeset watcher, server-mode ones are flagged stale until restarted |
getGraphForExecution() | Zustand store method that serializes the root canvas as a GraphDefinition, filtering out the frontend-only stateContainer node type (FRONTEND_ONLY_TYPES; containers travel as graph.containers + access_grants, not nodes). Output viewers are real backend nodes and are sent along |
Β§2Graph Data Model
The pure-data JSON schema that travels over the wire and sits in workspace/graphs/. Framework doesn't read domain data here β only topology + configuration.
| GraphDefinition | Universal graph type (replaces AgentLoopDefinition) β recursive: contains NodeDef[] which may themselves contain subgraphs (see ADR-dataflow-001) |
| NodeDef | Universal node type used at every nesting depth (replaces InnerNode) β may contain optional subgraph for composites |
| EdgeDef | Universal edge type used at every nesting depth (replaces InnerEdge) |
| Composite Node | A node that contains a subgraph (GraphDefinition). Any group of nodes can become a composite with defined I/O via graphIn/graphOut |
| graphIn | Boundary node inside a composite that defines an input on the parent composite node β the composite's parameter slot (class GraphInNode; formerly PortIn) |
| graphOut (boundary) | Boundary node inside a composite that defines an output on the parent composite node β the composite's return slot (class GraphOutNode; formerly PortOut). The same node type doubles as the WebSocket sink (Β§9) |
| Flatten | Recursive expansion of composite nodes into a flat graph before execution β backend never sees nesting |
| FlattenMap | Mapping from flattened node IDs to their original composite path, used for error tracing |
| kind (GraphDefinition) | Field distinguishing graph types: "graph" (editable template, opens in tab) vs "node" (frozen composite, draggable). Default "graph", backward compatible (see ADR-canvas-003) |
| Graph Node | A saved graph archived as a frozen reusable composite (kind="node"). Stored in workspace/graph_nodes/, draggable onto any canvas. Uses snapshot semantics β copies by value, no reference to source |
Β§3Component System
The extension surface β base classes authors subclass in workspace/, auto-discovered by WorkspaceComponentRegistry at startup and hot-reload.
| BaseCanvasNode | Universal base class for all canvas nodes with forward() method, ui_config (NodeUIConfig) for Python-driven rendering, typed port declarations, and voluntary logging via _self_log() / log() |
| BaseNodeSet | Base class for atomic tool groups that load/unload together β managed on the NodeSet Manager page |
| Component Registry | Runtime system that auto-discovers Python classes in workspace/ and bridges them into the platform |
| NodeUIConfig | ClassVar on BaseCanvasNode declaring visual properties (color, layout, width, min_height, rounding), config_fields (user-editable inline widgets), and display_fields (read-only runtime data widgets). Layout values: block, strip, viewer, note, imageGrid. Enables Python-driven node UI β one Python class = one canvas node, no .tsx needed |
| ConfigField | Dataclass declaring an inline user-editable config control on a canvas node. 7 widget types: label, slider, text, select, toggle, textarea, port_list |
| DisplayField | Dataclass declaring a read-only runtime data display widget on a canvas node. 4 display types: image_viewer (base64 β img), log_list (scrollable entry list), metric_table (key-value metrics), text_viewer (scrollable text block) |
| GenericBlockRenderer | Universal frontend React component that renders any BaseCanvasNode from its ui_config. Thin dispatcher delegating to layout components: BlockLayout, StripLayout, ViewerLayout |
| ports_mode | Class-level field on BaseCanvasNode controlling how config.ports is mapped onto input/output schemas: "sink" (input-only), "source" (output-only), "input" (inputs from config), "mirror" (both sides mirror config) |
| batched / batch_dim | ClassVars on BaseCanvasNode opting a node into the batched-inference tier. batched: bool = False (default). When True, batch_dim: str must name an actual input port β that port carries the per-sample slot the server stacks across K callers (see ADR-eval-002) |
| parallelism | ClassVar on BaseNodeSet declaring deployment topology under eval worker_count>1 (see ADR-server-003). Values: "shared" (default β 1 instance; K callers coalesce through the already-hosted BatchedInferenceServer) or "replicated" (stateful env nodesets opt in β N independent tagged copies, one per worker). worker_count=1 is bit-identical in both modes |
Β§4Wire & Dataflow
Typed edges between ports β how data moves between nodes, per-firing. Separate from state containers (Β§5).
| Wire Type | Typed data carried by data wires. Current set (9): IMAGE, DEPTH, POSE, DISCRETE_ACTION, CONTROL, TEXT, BOOL, METRICS, ANY (standard/wire_types.py). Any inner type T may be wrapped as LIST[T]; each current type has one canonical on-wire format in WIRE_FORMAT_SPEC. POSE was renamed from STATE in ADR-dataflow-004 so that "state" can refer exclusively to stored memory slots |
| DISCRETE_ACTION | int | str β index or id into the env's declared valid action set. Replaces the retired VLN-only ACTION type (fixed 0β3): no fixed range, the env nodeset declares the space. The VLN 0β3 space (Β§10) is one instance |
| CONTROL | Continuous control command for VLA / manipulation: dict{pos:[3], rot:[3] axis-angle rad, gripper: floatβ[-1,1] (+1=open), joint_position?:[N]}. Split from the old single ACTION type together with DISCRETE_ACTION so the catalog spans VLN / VLA / manipulation |
| Deprecated wire types | ACTION (alias of DISCRETE_ACTION), OBSERVATION, STEP_RESULT β kept registered only so legacy graphs/nodesets load until the migration sweep; do not use in new graphs. OBSERVATION lost to flat rgb/depth ports; STEP_RESULT lost to the gym-style tuple |
| LIST[T] | Wire-type modifier (ADR-dataflow-005). Any wire type T may be wrapped as LIST[T] to make a port carry list[T]. Producers emit scalar T; consumer ports declared LIST[T] always see a list β the executor wraps single values to [value] and concatenates fan-in in edge declaration order at one port-binding seam. Enables multi-image LLM calls, multi-LLM debate, search-operator population fan-in. Nested LIST[LIST[T]] is not supported in v1 |
| Data Edge | Directional wire carrying typed data between node ports β the primary data transport. Solid animated line, colored by wire type |
Β§5State Containers
Visible shared state β distinct from wires because they carry no data and do not trigger firing. Multi-writer, cross-iteration, checkpointable.
| StateContainer | A dict of named BaseState entries, rendered as a visible canvas element. Holds agent memory β multi-writer, cross-iteration, checkpointable, read does not trigger firing |
| BaseState | Abstract base for a single named state entry. Parameterized by reducer type (accumulator, lastWrite, counter), a value type (TEXT, POSE, POINTCLOUD, β¦), and a reset_on list expanded from lifetime. Default on_signal clears to initial_value when a subscribed signal fires |
| AccumulatorState | BaseState reducer that appends each write to a list. Config: max_size trims oldest |
| LastWriteState | BaseState reducer that keeps only the most recent value |
| CounterState | BaseState reducer that sums numeric writes |
| Lifetime | State-clearing axis orthogonal to the reducer. Values: forever (default), step, episode, run, custom. At build time, each lifetime expands into a reset_on signal list the state subscribes to via on_signal |
| Signal | Named framework event delivered to states via broadcast_signal(name, payload). The executor emits run_start, step_start, step_end (at each IterOut boundary), and run_end; episode_reset is emitted by env panels (an action returning side_effect="signal"), not the executor. A state's lifetime expands to a reset_on signal list; the default on_signal clears the state to initial_value when a subscribed signal fires |
| Access Grant | Authorisation for a node to read() / write() a StateContainer. Not a wire: carries no data, does not trigger firing. Rendered as a dashed violet line. Renamed from "State Edge" in ADR-dataflow-004 |
| State Value Type | Narrow registry for memory slot shapes (ADR-dataflow-004): TEXT, BOOL, METRICS, POSE, POINTCLOUD, OCCUPANCY_MAP, EMBEDDING, EPISODE_CONTEXT, ANY. Raw wire payloads rejected by build_container |
| StateDef | Graph definition entry for a single named state: reducer type + value type + lifetime + config |
| ContainerDef | Graph definition entry for a state container: id, label, position, dict of StateDefs |
| AccessGrantDef | Graph definition entry authorising a node to read/write a container: {id, node_id, container_id}. Lives in graph.access_grants. Renamed from StateEdgeDef in ADR-dataflow-004 |
| __state__ port | Hidden bottom-center handle on every node for attaching access grants. Visible only when the access-grant toggle is on (CSS-controlled) |
| graph_state | Well-known container id "graph_state" β a regular ContainerDef in graph.containers that plays the role of the graph-level blackboard. Every node that wants access must hold an explicit AccessGrantDef to it. Nodes with the grant get a convenience binding ctx._graph_state |
| Nodeset-owned container | A container owned by a BaseNodeSet via get_containers() rather than declared in graph JSON β may hold opaque (non-JSON-safe) values via allow_opaque and supports per-key eviction so worker-parallel eval can isolate per-episode entries. Lives in the nodeset's home process; a shared server nodeset owning mutable containers draws a load-time warning (roadmap #68) |
Β§6Execution Engine
The runtime that turns a GraphDefinition into a live agent run β node scheduling, iteration gates, termination.
| Graph Executor | Data-driven executor β nodes fire when inputs arrive. Handles both DAG workflows (single forward pass) and cyclic agent loops (via IterIn/IterOut). No separate DAG executor exists |
| Entry node | A node the executor queues at run-start, discovered automatically (no author marking) by three structural conditions: not an iterIn, no incoming edges, no required input ports. Entry nodes fire first and feed the rest of the graph; a loop starts when an entry nodeβs output reaches the iterInβs init_* handles. Formerly called βseed nodeβ (renamed 2026-06-11 β βseedβ collided with RNG seeds and AAS seed data) |
| Loop Runner | Singleton that wraps the executor and manages pause/stop/resume lifecycle |
| Initialize | Removed (2026-06-10, follow-through of ADR-dataflow-008): its run-start collection role lives on iterIn's left/input side (declared via iterIn.config.initPorts). The node type is no longer registered; validate_graph_connectivity rejects graphs that still carry one, with a migration hint. Historic (ADR-dataflow-006): a run-start pivot (node_type="initialize", ports_mode="sink") that collected step-0 state and handed it to the paired iterIn via executor-internal pairedWith transfer |
| initPorts | Config list on a two-sided iterIn (ADR-dataflow-008) declaring its run-start left/input ports β [{name, wire_type, persist}]. _synthesize_iterin_ports reads these as init_-origin slots (the former initialize node's role, removed 2026-06-10). Named to avoid the rejected legacy init_ports key |
| IterIn / IterOut | Iteration boundary pivots. Since ADR-dataflow-008 iterIn is two-sided: its left input ports (declared in initPorts) receive run-start values captured once into init_ slots, and its right output ports expose the loop-carry bundle. Loop-carry values arrive via executor transfer from iterOut (per-iteration); init values arrive as ordinary incoming edges routed into port_slots. |
| port_slots | Field on NodeInstance (iterIn only). One slot per synthesised port, keyed by the prefixed handle (init_<X> / iterout_<X>); written by run-start init edges and the iterOut transfer, read on every iterIn fire. Replaces the former init_port_cache + pending_inputs split |
| pairedWith | Config field on iterOut storing the id of the paired iterIn. Drives the executor-internal transfer that delivers values into iterIn's port_slots without a canvas edge |
| validate_graph_connectivity | Load-time validator in graph_def.py. Rejects any graph that contains a node with a required input port lacking an incoming edge, raising ValueError translated to HTTP 400 at the run/eval API boundaries |
| Termination Node | Removed (2026-06-11): its halt role lives on the loop iterOut's stop input port, checked once per iteration by the engine's Decide phase; validate_graph_connectivity rejects graphs that still carry one, with a migration hint. Historic: a node that ended the agent loop when done=true, bound to its innermost containing scope (ADR-dataflow-007) |
| stop port | Class-level BOOL input on iterOut β the loop's halt signal. Wired from the done/is_stop producer; read by the iterOut-boundary Decide check exactly once per iteration. Unwired = budget-only loop. A bare stop with no loop-carry value does not fire the boundary. Excluded from the loop-carry transfer and the final mirror |
| Final side | iterOut's right/output side: one final_<name> handle per loop-carry port plus the constant final_stop (True once at termination β the canonical after-loop trigger). Emits exactly once when the scope terminates (stop, budget exhaust, or best-effort on the error path), carrying the terminal iteration's values. Edges from iterOut may use only these handles |
| After-loop band | The downstream closure of the root iterOut's final-side edges β the verdict stage (evaluate β graphOut chains), fed exactly once at termination and drained by _after_loop_pass. Purity rule: band nodes take inputs only from the final side or from other band nodes ("verdict inputs ride the pivot"). Replaces the removed config.post_loop flag β membership is derivable from topology |
| execution_id | UUID generated per run, tags all WebSocket events to route them to the correct output nodes |
| Scope | One (iterIn, iterOut) pair plus its body, IO interface (graphIn/graphOut), and per-scope config β the unit of iteration cadence in a graph (ADR-dataflow-007). The scope's canonical id is its iter_in node id |
| Scope Forest | Computed by analyze_scopes() in agent_loop/scope_analysis.py. The set of all scopes in a graph plus their parent/child topology |
| Inner Scope / Outer Scope | Relative terms in a nested scope tree. An inner scope's iter_in and iter_out both lie in an outer scope's BFS-reachable interior. Inner scopes are bounded by mandatory graphIn (parameter slots) and graphOut (return slots) |
| Outermost Scope | The root of the scope forest (no parent). Its iterOut's stop (or budget exhaust) ends the entire run |
| graphOut latch | When a graphOut node lives inside a non-graph scope, it BUFFERS its incoming value into state["latched_value"] instead of propagating immediately. On the owning scope's termination, the buffered value is flushed to outer-scope downstream (formerly "portOut latch") |
| Scope re-entry | When an outer scope's iter brings the inner scope's iter_in back into the ready queue, the executor resets the inner _ScopeState (terminated=False, step_counter=0). Makes inner scopes function-call-shaped |
| FireSpec | One captured child firing inside a FireList (ADR-executor-004). Carries node_type + inputs + per-call config + optional label + optional capture_outputs whitelist. The engine resolves node_type through NODE_HANDLERS and fires the corresponding class as an ephemeral child |
| FireList | Sentinel return type from a DynamicFireListNode's forward(). Holds specs: list[FireSpec] + spawner_outputs: dict (direct spawner outputs that flow alongside the children) + aggregator: dict (declarative collapse recipe). The engine recognises isinstance(result, FireList) and dispatches each spec sequentially (ADR-executor-004) |
| DynamicFireListNode | BaseCanvasNode subclass whose forward() returns a FireList instead of an output dict. aggregate(child_results) β dict collapses children's outputs back into the spawner's declared ports β required for local spawners; server-mode proxies use the declarative FireList.aggregator recipe instead |
| Dynamic Fire-List dispatch | Engine path inside _fire_node: when a spawner returns FireList, _fire_dynamic_children fires each spec sequentially as an ephemeral NodeInstance (id {spawner.id}::dyn{i}) that is NOT in self.nodes/adjacency/scope_forest. Children's outputs collected explicitly, then collapsed via aggregator and merged with spawner_outputs for downstream propagation (ADR-executor-004) |
| Declarative aggregator | JSON-safe recipe on FireList.aggregator telling the engine how to collapse children into the spawner's outputs without calling aggregate(). Supported kinds: passthrough_last, passthrough_index, merge_all, rename. Required when the spawner is a server-mode proxy class (which doesn't inherit the spawner's Python aggregate() method) |
| Ephemeral child | A NodeInstance created at run-time by the dynamic fire-list dispatcher for one FireSpec. NOT registered in self.nodes/adjacency/scope_forest/ready_queue; cannot be a loop pivot, a final-side member, or any structural / boundary type. Identified by id {spawner.id}::dyn{i}; logged with parent_node_id + dynamic_index provenance |
| parent_node_id / dynamic_index | Optional fields on NodeLogEntry (default None, backward-compatible) carrying provenance from a dynamic-firelist spawner to its child firings. Lets downstream consumers (eval analysis, replay) group children by spawner without re-running it (ADR-executor-004) |
Β§7Server Mode
Running a BaseNodeSet in its own interpreter via HTTP subprocess β the mechanism that lets Habitat-Sim (Python 3.8) coexist with the modern agentcanvas env.
| AutoServerApp | A ServerApp subclass that auto-generates server functions from any BaseNodeSet by introspecting tool ports β no manual PortSchema declaration needed (see ADR-server-001) |
| auto_host | CLI entry point (python -m app.server.auto_host) that launches any BaseNodeSet as a server-mode subprocess |
| server_python | Optional ClassVar on BaseNodeSet specifying the Python interpreter for server mode; defaults to sys.executable |
| BatchedInferenceServer | In-process rendezvous tier hosted by an AutoServerApp subprocess. Holds one _BatchQueue per (function_name, config_hash); collects K parallel callers' submissions, calls the underlying handler once with stacked inputs, scatters outputs to K awaiting futures |
| BatchedClient | The submitter side of the batched-inference rendezvous: per-call await server.submit(function_name, inputs, config) returns the slice for this caller |
Β§8Evaluation
Batch evaluation harness β each run is its own Python subprocess spawned by JobScheduler, with EnvWorkerPool fan-out inside each subprocess for parallel env workers.
| ExecutionGuard / ExecutionMode | Thread-safe mutex in app/state.py making canvas Play and batch eval mutually exclusive β ExecutionMode is idle / canvas / eval; acquire() succeeds only from idle. Subprocess eval jobs don't hold the guard β the JobScheduler's admission gate simply refuses to admit while the canvas lock is held (the eval mode is acquired only by the legacy in-process path). Env-panel POSTs are guarded by it too |
| JobScheduler | Backend service managing admission control + a FIFO queue of eval jobs across all Claude sessions hitting one backend. Lives at app/services/job_scheduler.py; tick loop runs every 1s admitting queued jobs through a per-resource measured gate β calibrated estimate vs measured free (VRAM + RAM) minus standing reservations (see ADR-eval-003 and the JobScheduler design doc) |
| run subprocess | Independent Python process (python -m app.eval_subprocess_main --run-dir ...) that runs one eval. Reads spec.json + shared_urls.json from the run dir, registers parent backend's shared singletons via WorkspaceComponentRegistry.register_remote_nodeset, runs BatchEvalRunner.execute() unmodified. PR_SET_PDEATHSIG-tied to backend |
| marginal_vram_mb | Per-job VRAM declaration in spec.scheduling β since 2026-07 the fallback admission rung: the measured gate charges calibrated per-resource estimates when coverage exists, the declaration when not (RAM rides ungated on that rung). Submit rejects declarations beyond the machine ceiling |
| register_remote_nodeset | WorkspaceComponentRegistry method letting a run subprocess attach to a parent-owned shared singleton without spawning a duplicate. Fetches the auto_host manifest, generates proxy nodes, registers a RemoteEnvPanelProxy |
_DONE marker | Empty file at outputs/eval_runs/{run_id}/_DONE written by the run subprocess on clean exit. Presence β run finalized; absence + dead PID = aborted |
| shared_urls.json | File at outputs/eval_runs/{run_id}/shared_urls.json mapping shared nodeset name β auto_host URL. Run subprocess reads it on startup to attach to parent's singletons rather than loading its own copy |
env panel (BaseEnvPanel) | Per-nodeset control-plane panel for env-side runtime knobs only (suite / split / episode, play / pause / stop / reset) β model/ckpt/adapter belong on node configs. Declared via the BaseNodeSet.env_panel ClassVar; served at /api/env-panels/*; bridged into server-mode subprocesses by RemoteEnvPanelProxy over /env-panel/*. Renamed from "controller" (2026-06-11) to disambiguate from robotics and MVC controllers |
| EnvWorkerPool | N-worker pool driving env subprocesses for batch eval. Async context manager β __aenter__ populates worker_count WorkerHandles, acquire() leases one per episode, __aexit__ unloads tagged subprocesses (see ADR-eval-002) |
| WorkerHandle | One slot in the EnvWorkerPool. Carries env_panel_overrides and server_url_overrides β populated with the tagged copies at worker_count>1 so the leased LoopRunner routes set-episode/play to its own subprocess |
| env_panel_overrides | Per-LoopRunner dict {nodeset_name: BaseEnvPanel} consulted by executor.get_env_panel(name). Empty at canvas Play / single-worker eval; populated by EnvWorkerPool at worker_count>1 |
| server_url_overrides | Per-LoopRunner dict {nodeset_name: server_url} consulted by executor.get_server_url(name); the proxy node's forward() swaps in the override at call time |
| default_per_step_budget_sec | ClassVar[float] on BaseNodeSet (default 30.0 β set generously so shared-singleton VLM contention under high worker_count doesn't burn the wall-clock; override on nodesets whose step latency diverges). Per-episode timeout in batch eval is max_steps Γ per_step_budget_sec |
Β§9Observability & Logs
Real-time streaming (viewer_data / nav_step over WebSocket) and post-hoc execution logs (JSONL under outputs/).
| GraphOut | Sink node (type graphOut, class GraphOutNode) that buffers its input into state["_last_inputs"] for the WebSocket broadcast at each iteration boundary (when IterOut fires); _broadcast_step consolidates these into the nav_step event. (Formerly named outputPort.) |
| ExecutionLogger | Per-run logger that captures structured NodeLogEntry records (port I/O, timing, voluntary inner log). Ring buffer in memory + JSONL file on disk in outputs/ (see ADR-observability-003) |
| NodeLogEntry | Pydantic model for one node firing: timestamp, execution_id, step, node_id/type/label, duration_ms, inputs, outputs, inner_log, port_wire_types, error |
| _self_log | Instance method on BaseCanvasNode β nodes call self._self_log(key, value) inside forward() to record domain-specific internals (e.g. assembled LLM prompts, API responses, token counts) |
| log_serialize | Recursive serializer that truncates large values for JSONL storage: strings >1KB β summary, numpy arrays β shape+dtype, bytes β length |
| exec_log | WebSocket event type broadcast per node firing during canvas execution. Contains summary: step, node_id, node_type, duration_ms, error. Full data available via REST /api/logs/{id} |
| ErrorBus | Singleton in-process pub/sub at app/errors.py that every backend producer publishes to. Maintains a 200-entry ring buffer + 500-deep async dispatch queue (see ADR-observability-004) |
| ErrorEnvelope | Canonical schema published by ErrorBus. Fields: id, ts, severity, source, code, title, message, scope, details, hint. scope carries node_id / node_type / origin / step / execution_id / endpoint / method |
| error_event | WebSocket event type broadcast for every published ErrorEnvelope. Routed by store.ts into useErrorStore; on (re)connect the frontend calls GET /api/errors to backfill envelopes published while disconnected |
| Report tab | Fourth tab in the bottom-panel OutputDrawer. Time-ordered list of envelopes with severity filter chips, source pill, click-to-expand. Companion floating ErrorToast layer pops error/warning envelopes top-right |
| LogBridgeHandler | logging.Handler subclass installed on the root logger at INFO+ that converts every Python log record into an ErrorEnvelope with source="log". Skips loops/noise sources |
Β§10VLN Domain
Task-side vocabulary β datasets, action space, metrics. Independent of the architecture above; swapping to a non-VLN benchmark would replace this section but leave Β§Β§1β9 intact.
| Episode | A single navigation task: start position + natural language instruction + goal |
| Split | Dataset partition: train, val_seen, val_unseen, test |
| Action | Discrete navigation command (standard/actions.py): 0=STOP, 1=FORWARD, 2=TURN_LEFT, 3=TURN_RIGHT. One instance of the generalized DISCRETE_ACTION wire type (Β§4) |
| R2R | Room-to-Room β VLN dataset with natural language navigation instructions. Base schema for MP3D episodes |
| R4R | Room-for-Room β concatenated R2R paths (first + second path ids + 9 combined instructions) |
| RxR | Room-across-Room β multilingual (en / hi / te) VLN dataset with word-level timed instructions + optional dense camera pose traces. Both MP3D (discrete) and Habitat-CE (continuous) nodesets surface val_unseen_* splits via the same language-suffix convention |
| RxR-CE | RxR continuous-environment variant used on the Habitat nodeset. Data: data/habitat/datasets/RxR_VLNCE_v0/{split}/{split}_guide.json.gz |
| REVERIE | Remote Embodied Visual referring Expression β VLN + object grounding with per-viewpoint 2D bounding boxes |
| CVDN / NDH | Cooperative Vision-and-Dialog Navigation β dialog-based navigation datasets where the instruction is a multi-turn Q&A |
| VLN-CE | Vision-and-Language Navigation in Continuous Environments β the benchmark |
| SPL | Success weighted by Path Length β primary VLN-CE metric |
| SR | Success Rate β fraction of episodes where agent stopped within 3m of goal |
| nDTW | Normalized Dynamic Time Warping β measures path fidelity to reference trajectory |
| SDTW | Success-weighted DTW β nDTW multiplied by success |