Skip to main content

Generative UI

Diminuendo’s agent can produce rich, interactive user interfaces directly within the chat message stream. Instead of relying solely on text and markdown, the agent generates structured UI specs that the client renders as interactive React components — dashboards, forms, charts, data tables, quizzes, and more.
Generative UI is powered by the json-render SpecStream format. The agent emits JSONL patches inside ```spec fenced blocks, which the gateway parses and streams to clients as ui.spec_* events.

How It Works

User Prompt  →  Agent  →  Text + ```spec blocks  →  Gateway  →  ui.spec_* events  →  Client  →  Rendered UI
1

User sends a prompt

The user asks for data, comparisons, forms, or any content that benefits from visual presentation.
2

Agent generates UI specs

The agent writes normal conversational text and embeds spec fenced blocks containing JSONL patches. Each patch incrementally builds a UI spec.
3

Gateway parses spec fences

The SpecFenceParser detects ```spec fences in the agent’s output, strips them from the text stream, and emits ui.spec_start, ui.spec_delta, and ui.spec_complete events.
4

Client renders progressively

The client applies patches incrementally, rendering a partial UI during streaming. When ui.spec_complete arrives, the final compiled spec replaces the partial.
5

User interacts

Users can fill forms, click buttons, switch tabs, and select options. Local state changes happen instantly. Submissions route back to the agent via the sendMessage action.

Available Components

The agent has access to 27 components organized into six categories:

Layout

Stack · Card · Grid · Separator · Accordion · Tabs · TabContent · Timeline

Text & Emphasis

Heading · Text · Link · Badge · Alert · Callout

Data

Metric · Table · CodeBlock · Progress · Image

Charts

BarChart · LineChart · PieChart

Input

TextInput · SelectInput · RadioGroup · Button

Actions

setState · pushState · removeState · sendMessage · openUrl · copyToClipboard

Data Binding & Interactivity

The agent places data in the spec’s /state and references it in component props using expressions:
ExpressionPurposeExample
{ "$state": "/path" }Read a value from state"value": { "$state": "/metrics/revenue" }
{ "$bindState": "/path" }Two-way binding (forms)"value": { "$bindState": "/form/name" }
{ "$cond": ..., "$then": ..., "$else": ... }Conditional valueShow “Yes” or “No” based on a flag
{ "$template": "Hello ${/user/name}" }String interpolationBuild dynamic text from state
{ "$computed": "fn", "args": {...} }Call registered functionFormat currency, compute totals

Visibility Conditions

Components can be conditionally shown or hidden:
"visible": { "$state": "/form/submitted" }
"visible": { "$state": "/status", "eq": "active" }
"visible": [{ "$state": "/checked" }, { "$state": "/answer", "eq": "b" }]

Actions

Buttons and interactive elements trigger actions:
"on": {
  "press": {
    "action": "setState",
    "params": { "statePath": "/tab", "value": "details" }
  }
}
ActionDescription
setStateSet a value at a state path
pushStateAppend to an array
removeStateRemove from an array by index
sendMessageSend text back to the agent (form submission)
openUrlOpen a URL in the browser
copyToClipboardCopy text to clipboard

Sample Prompts

Try these prompts to exercise different aspects of the generative UI system. Each prompt is designed to trigger a specific UI pattern.

Prompt 1: Project Metrics Dashboard

Show me a dashboard of my project metrics: 1,247 commits this quarter,
89 open PRs, 34 issues. Include a weekly activity trend chart and a
table of recent PRs.
Expected UI: Card with Grid of 3 Metrics (with trend indicators), a LineChart showing weekly activity, and a Table of recent PRs.What to verify:
  • Metrics display with trend arrows (up/down/neutral)
  • LineChart renders with labeled axes
  • Table renders with sortable columns

Prompt 2: Sales Analytics

Create an analytics dashboard showing monthly revenue ($12K, $15K, $13.5K
for Jan-Mar), sales by category (Electronics 45K, Clothing 32K, Food 28K),
and daily visitor counts (Mon 1200, Tue 1800, Wed 1500).
Expected UI: Stack with Heading, Grid containing a LineChart (revenue), PieChart (categories), and BarChart (visitors), plus a Callout with a key insight.What to verify:
  • All three chart types render (LineChart, PieChart, BarChart)
  • PieChart has color-coded legend
  • Data binds correctly from state

Prompt 3: Project Setup Form

I need to set up a new project. Create a form where I can enter a project
name, select a framework (React, Vue, or Svelte), and click Submit. Show
a confirmation message after submission.
Expected UI: Card with TextInput, SelectInput, and Button. After clicking Submit, the button hides and a Callout (“Submitted”) appears.What to verify:
  • TextInput accepts user input
  • SelectInput dropdown works
  • Button triggers setState (hides itself) and sendMessage (sends data back)
  • Visibility conditions toggle correctly

Prompt 4: Contact Form with Validation

Build a contact form with fields for name, email, and a message textarea.
Include a submit button that sends the form data back to me.
Expected UI: Card with Stack of TextInputs and a Button with sendMessage action.What to verify:
  • Multiple TextInputs with different types (text, email)
  • Form data binds to state via $bindState
  • Submit button sends interpolated message via $template

Prompt 5: Multiple-Choice Quiz

Test my understanding of algorithms. Ask me: "What is the time complexity
of binary search?" with options O(n), O(log n), O(n log n), O(1). Show
whether I got it right after I click Check.
Expected UI: Card with Text question, RadioGroup with 4 options, Button (“Check Answer”), and two Callouts (correct/wrong) with visibility conditions.What to verify:
  • RadioGroup allows selection with $bindState
  • Button triggers setState to show feedback
  • Correct Callout appears only when answer = “b” AND checked = true
  • Wrong Callout appears for any other answer when checked

Prompt 6: Survey with Multiple Questions

Create a quick survey: (1) How satisfied are you? (Very/Somewhat/Not at all),
(2) Would you recommend us? (Yes/No/Maybe), (3) Any comments? (free text).
Add a Submit button that sends the responses.
Expected UI: Card with multiple RadioGroups and a TextInput, plus a Button.What to verify:
  • Multiple RadioGroups with independent $bindState paths
  • TextInput for free-text entry
  • Submit button sends all state values via sendMessage

Prompt 7: Framework Comparison

Compare React, Vue, and Svelte side by side. Show GitHub stars, bundle size,
and learning curve for each. Use tabs so I can switch between them.
Expected UI: Tabs component with 3 TabContents, each containing a Grid of Metrics with $state bindings.What to verify:
  • Tab switching works (click each tab)
  • Each tab shows different data from state
  • Metrics display correctly with state bindings

Prompt 8: Pricing Tier Comparison

Show a pricing comparison: Free (0/mo, 5 projects, community support),
Pro ($20/mo, unlimited projects, priority support), Enterprise (custom,
unlimited, dedicated support). Use a grid layout.
Expected UI: Grid with 3 Cards, each containing Heading, Metrics, and a list of features.What to verify:
  • Grid layout with 3 columns
  • Cards with titles and structured content
  • Metrics for pricing

Prompt 9: Migration Plan Timeline

Create a migration plan timeline with 4 phases: Phase 1 Audit (Week 1,
completed), Phase 2 Refactor (Week 2-3, in progress), Phase 3 Testing
(Week 4, upcoming), Phase 4 Deploy (Week 5, upcoming). Add a status note.
Expected UI: Card with a Timeline component showing 4 steps with status-based dot coloring, plus a Callout noting current phase.What to verify:
  • Timeline renders with vertical dots and connecting lines
  • Completed phase has solid dot
  • Current phase has highlighted dot
  • Upcoming phases have muted dots

Prompt 10: API Documentation

Show me REST API docs for a users endpoint: GET /users (list all),
POST /users (create), DELETE /users/:id (delete). Use an accordion so
I can expand each one. Include a code example for POST.
Expected UI: Stack with Heading, Accordion (3 expandable sections), and a CodeBlock with a curl example.What to verify:
  • Accordion sections expand/collapse
  • CodeBlock renders with syntax class
  • All three endpoints have distinct content

Prompt 11: Code Review Summary

Show a code review summary: 5 files changed, 120 additions, 45 deletions.
Include a table of changed files with their status (modified/added/deleted)
and a code block showing the key diff.
Expected UI: Card with Grid of Metrics (files, additions, deletions), Table of changed files, and a CodeBlock.What to verify:
  • Metrics with appropriate trend indicators
  • Table with file status data
  • CodeBlock with diff content

Prompt 12: Large Dashboard with Many Components

Build a comprehensive project dashboard with: 5 key metrics (commits,
PRs, issues, deployments, uptime), a weekly activity line chart, a
language distribution pie chart, a recent activity table with 5 entries,
and a callout with the top insight. Use cards and grids.
Expected UI: Stack with multiple Cards containing Grids, Charts, Tables — 20+ elements total.What to verify:
  • All components render without errors
  • Large spec compiles correctly
  • No missing elements or broken references
  • Progressive rendering shows partial UI during streaming

Protocol Events

Generative UI uses four protocol events:
EventPersistenceDescription
ui.spec_startEphemeralSignals the beginning of a new UI spec block
ui.spec_deltaEphemeralOne RFC 6902 JSON Patch operation
ui.spec_completePersistedFinal compiled spec, stored in message metadata
ui.spec_errorEphemeralParse or validation error
For full event documentation, see Server Events → Generative UI.

History Persistence

Completed UI specs are stored in assistant message metadata. When a session is reloaded, the client reconstructs the UI blocks from metadata.uiBlocks and metadata.parts, preserving the inline position of UI relative to text.

Stream Snapshots

Late-joining clients receive in-flight UI specs via the stream_snapshot event’s uiSpecs array, enabling them to see the current state of any spec being built.

Theming

Generated UI components inherit the application theme automatically. All components use Tailwind CSS custom properties (--background, --foreground, --primary, --border, etc.) that cascade from the app shell. Dark mode, accent colors, and font sizes are applied consistently.

Spec Diffing

The agent can update a previously rendered UI block by emitting a new ```spec block that targets an existing uiId. Instead of creating a new UI block, patches are applied to the existing spec, enabling iterative dashboard refinement across turns.

Architecture

Gateway: SpecFenceParser

Detects ```spec fences in agent text output, extracts JSONL patches, compiles final specs, and emits ui.spec_* events. Stateful per-session with automatic flush on turn completion.

Client: SpecRendererProvider

React context providing the renderSpec function. The self-contained renderer walks the spec tree, resolves expressions, manages local state, and renders 27 component types with theme-aware styling.

Store: Parts Array

The zustand chat store maintains an ordered parts[] array on ActiveTurn — interleaved text and UI blocks preserving inline position. Microtask batching collapses rapid patch events into single state updates.

Agent: Prompt Addendum

A comprehensive prompt addendum teaches the agent when to use generative UI, the output format, available components, data binding, interactivity patterns, and includes worked examples.