Generative UI Example (Tool UI)

Live demo of toolkit Tool UI patterns — charts, date pickers, contact forms, and maps. For the GenerativeUI JSON-spec primitive, see /gui-chat and /primitive in the same example app.

Overview

The main route (examples/with-generative-ui) demonstrates Tool UI patterns using toolkit render entries — not the MessagePrimitive.GenerativeUI JSON-spec primitive.

  • Chart Generation — AI returns structured data, rendered as bar/line/pie charts via Recharts
  • Date Picker — AI requests a date selection, user picks via native input, result sent back with addResult
  • Contact Form — AI collects name, email, and phone through an interactive form tool
  • Location Map — AI shows a place on an embedded OpenStreetMap
RouteWhat it demonstrates
/Tool UI (Tools({ toolkit })) — interactive widgets
/primitiveStatic GenerativeUIRender with a hand-written spec
/gui-chatEnd-to-end chat with render_gui tool → MessagePrimitive.GenerativeUI bridge

See the Generative UI primitive guide for opt-in wiring and pattern comparison.

Patterns Demonstrated

Backend-Rendered Tools (Chart, Location)

These tools have backend execute functions and frontend toolkit renderers. The AI generates the data, the backend confirms, and the frontend renders rich UI from args:

const toolkit = defineToolkit({
  generate_chart: {
    type: "backend",
    render: ({ args, status }) => {
    const { title, type, data, xKey, dataKeys } = args;
    // Render a Recharts BarChart/LineChart/PieChart based on args
    return <ChartContainer config={buildChartConfig(dataKeys)}>...</ChartContainer>;
  },
  },
});

Frontend-Only Tools (Date Picker, Contact Form)

These tools have no backend execute — the AI triggers the tool call, and the user completes it through interactive UI. The addResult callback sends the user's input back to the AI:

const toolkit = defineToolkit({
  select_date: {
    type: "human",
    render: ({ args, result, addResult }) => {
    if (result) return <div>Selected: {result.date}</div>;

    return (
      <div>
        <p>{args.prompt}</p>
        <input type="date" onChange={(e) => setValue(e.target.value)} />
        <button onClick={() => addResult({ date: value })}>Confirm</button>
      </div>
    );
  },
  },
});

Key Concepts

ConceptUsed InDescription
Tools({ toolkit })All 4 toolsRegister a React renderer for a specific tool call
addResultDate Picker, Contact FormSend user input back to the AI as the tool result
status.typeChart, LocationShow loading states while the AI streams tool arguments
args streamingChartRender partial UI as tool arguments stream in

Source

View full source on GitHub