Skip to main content

UOM Assistant Frontend: State Synchronization & LangGraph Runtime

This document explains the runtime state machine integration, event stream adapters, checkpoint backtracking logic, and manual checkpoint recovery routines utilized in the UOM Assistant frontend dashboard.

1. The Runtime Wrapper & Local State Machine

The interface communicates with the LangGraph backend via the useLangGraphRuntime hook, which is wrapped in a provider component to distribute state across the workspace: The wrapper maintains the local reactive state machine:
  • graphState: A Partial<BackendState> containing the active translation data, validation errors, and equivalence diff logs.
  • error and runError: Diagnostic models logging compilation failures and stream aborted triggers.
  • activeNode: Identifies the current executing python node in the backend (e.g., input extraction, schema inspection, compilation validation, equivalence checks, and evaluations).

2. Configurable Context Injection (stream)

When a user submits a query via the Composer input, the custom stream callback triggers. This method loads credentials and database configuration settings from localStorage under the "uom_translator_config" key and injects them as a structured payload into the run execution context. For more information on LanGraph SDK client methods/options (streamMode, streamSubgraphs, context), see the LangGraph SDK documentation.
Some payload parameters, come directly from assistant-ui runtime, which are passed through the config argument of the stream method:
  • abortSignal: An AbortController signal that can be triggered to cancel the stream.
  • command: An optional command object (e.g. { resume: ... }), used by the InterruptHandler component to resume a suspended graph. Its resume value is forwarded verbatim to the backend interrupt() call (see §6).
  • checkpointId: An optional string identifier for resuming from a specific checkpoint in the thread history.

2.1 LLM Backend Switcher

This injection logic allows users to swap models and providers on-the-fly:
  • Local Ollama Deployment: Directs requests to a local daemon (e.g., http://localhost:11434) running open-weights models like qwen2.5-coder.
  • Remote Metacentrum e-INFRA CZ: Routes calls through Metacentrum’s OpenAI-compatible APIs, providing access to larger models like einfra/kimi-k2.6 or einfra/deepseek-v4-pro-thinking.

3. Sub-graphs, Event Handlers, & Custom Telemetry

The runtime adapter processes LangGraph events to sync backend execution details with the UI.

3.1 Sub-graph State Merging

To track execution parameters inside nested validation or equivalence test subgraphs, the runtime processes sub-graph values and merges them into the main state object. See LangGraph Subgraph Docs how multi-agent orchestration works.

3.2 Custom Event Logs (onCustomEvent)

The Python orchestrator streams container log details and validation updates as custom events, which are processed by the runtime for debugging:

3.3 Noise Reduction Error Filtering

To prevent system warnings or connection resets from flooding the user console, the error handler implements a filtering system that ignores known harmless messages:

5. Thread List Synchronization (RemoteThreadListAdapter)

Note: The adapter definitions in this section are simplified conceptual representations of the actual implementation. The frontend maps UI actions (like creating or deleting threads) to the backend database using a thread list adapter:

5.1 Adapter Methods

  • list(): Queries the thread catalog using client.threads.search (returning up to 50 threads sorted by creation date descending):
  • rename(remoteId, newTitle): Updates metadata tags stored on the server:
  • delete(remoteId): Removes the thread from server persistence:
  • initialize(): Provisions a new thread identifier on the server, initialized with a timestamped title:
  • fetch(threadId): Retrieves the current state and messages for the selected thread:

6. Interrupt & User Decision Flow (InterruptHandler)

When the orchestrator reaches a manual validation gate, the backend human_intervention_node suspends execution using LangGraph’s native interrupt() API (not a tool call). The interrupt payload carries an instruction plus the current translation state:
The InterruptHandler reads this payload, renders the explanation and the query-equivalence deep diffs, and presents the Accept / Reject decision controls.

6.1 State Transitions during Suspends

The component uses hooks from @assistant-ui/react-langgraph to resume the graph:
  • useLangGraphInterruptState(): Accesses the active suspend payload via interrupt.value. The card renders whenever a payload is present.
    Do not gate on interrupt.resumable. That field is deprecated in @langchain/langgraph-sdk (≥ 1.x) and omitted by recent servers, so guarding on it hides the card entirely (both live and on reload).
  • useLangGraphSendCommand(): Resumes execution by posting the decision object back to the suspended node. The value becomes the return value of the backend interrupt() call and is validated against the HumanInterventionResponse Pydantic model, so both fields are required and it must be an object — not a bare string or a JSON-encoded string:

6.2 Persistence across reloads

Because the backend uses a native interrupt(), the suspension is part of the thread’s server-side checkpoint. The runtime’s load() callback returns it so the card reappears when an interrupted conversation is reopened from the thread list:
Why native interrupt() rather than the tool-message approval pattern? The assistant-ui Approval UI tutorial resumes by appending a ToolMessage (via addResult) to a pending tool call. That mechanism is incompatible with interrupt() + Command(resume): addResult sends new input rather than a resume command, and it would require the backend graph to be rebuilt around a pending tool call. The native interrupt keeps the human-in-the-loop gate as a first-class checkpoint that persists and restores cleanly.
For more information on interrupt handling and human-in-the-loop patterns, see the LangGraph Interrupts Documentation and the assistant-ui LangGraph Interrupts guide.