example/apps

Two runnable apps in examples/ drive the lash facade end to end: full hosts with a browser UI, real persistence, remote DTO streams, and optional durable execution, not toy snippets. agent-service is the focused starting point; agent-workbench adds background processes, triggers, and Restate-backed cron triggers while keeping the same session live replay pattern.

What's Here

Both run from the repo root and reach OpenRouter through the OpenAI-compatible provider. They choose concrete first-party adapters (SQLite, Restate, local files) to stay runnable; the runtime interfaces also support host-provided stores and workflow hosts. Each example has a full walkthrough; this page is the at-a-glance map.

agent service
Localhost SQLite chat app: the smallest realistic host. RLM mode, a typed session plugin, app-owned board tools, session observation live replay, per-chat model choice, and optional Restate-backed turns.
agent workbench
RLM chat workbench for durable background work: background processes, subagents, web tools, trigger buttons, a mock inbox that fires mail.received triggers, Restate-backed turns/cancellation, Restate-backed cron triggers, and cursor-based browser reconnect over /api/events. Restate is required and starts automatically in Docker.

Agent Service

A chat app that uses the first-party SQLite adapter to exercise the app-facing API in a realistic Axum host. Read it when checking whether an app wires the lash facade correctly.

RLM + typed plugin

Builds an RLM core via LashCore::rlm_builder(factory) and activates a DemoPlugin per chat through SessionBuilder::plugin::<DemoPlugin>(...).

App-owned tools

A tic-tac-toe board lives in the app's chat_boards table; the plugin's ToolProvider exposes board.read / board.play over it.

Session replay stream

The browser renders RemoteSessionObservationEvent rows from session.observe(), stores the opaque replay_cursor, and handles replay_gap with the public RemoteLiveReplayGap payload and RemoteSessionObservation snapshot. Product rows stay app-owned.

Optional Restate

Built with the restate feature and run with --durability restate (or AGENT_SERVICE_DURABILITY=restate), browser turns run through Restate ingress with a handler-scoped effect controller; board state stays app-owned. Durability defaults to local otherwise.

OPENROUTER_API_KEY=... cargo run -p agent-service
# then open http://127.0.0.1:3000

Full walkthrough of core wiring, the turn path, and Restate mode: agent service →

Agent Workbench

An RLM chat workbench built around durable background work and triggers. Restate is required; the bundled entrypoint starts it in Docker, registers the in-process endpoint, then opens the browser.

Background work

The model starts named Lashlang processes and spawns subagents; the right rail polls the process registry for live runs.

Trigger buttons

Red and blue buttons emit ui.button.pressed trigger occurrences that start processes for matching trigger registrations.

Session replay stream

The browser's /api/events stream merges host product rows with Lash session observation rows; reconnect passes the latest cursor and gap recovery reloads /api/state.

Restate control

User turns, queued refreshes, trigger deliveries, cron jobs, and session deletion submit through Restate ingress; the stop button sends an exact, replay-safe request through TurnWorkDriver.

Lashlang graph

The graph panel reads TraceLashlangGraphStore, a trace-derived view of foreground blocks, durable runs, and child links.

OPENROUTER_API_KEY=... just agent-workbench
# starts Restate in Docker, then opens http://127.0.0.1:3030

Full walkthrough of triggers, cron sync, and host wiring: agent workbench →

read on ·