Guide

Generative UI inside your AI assistant

Your assistant shouldn't only describe data in text — it should *show* it. This guide covers turning a user's chat message into an inline, interactive component.

The pattern

1. User: "show me this month's revenue by product".
2. Your agent fetches the data.
3. Agent calls Morphis with the user's natural intent + data.
4. Morphis returns a sanitized component. The assistant renders a chart or table inline.

Implementation flow

chat-handler.js
async function onUserMessage(message, userContext) {
  // 1. Pull live data the user's message refers to
  const data = await db.query('revenue_by_product', { month: 'current' })

  // 2. Ask Morphis to render it as the user requested
  const res = await fetch('https://getmorphis.com/api/generate-ui', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      apiKey: process.env.MORPHIS_API_KEY,
      intent: message,                              // e.g. "revenue by product as a bar chart"
      contextData: data,
      theme: userContext.theme                      // 'light' | 'dark'
    })
  })

  const { html, metadata } = await res.json()
  return { html, model: metadata.model }
}

Rendering inside the chat UI

Before rendering, decide whether the intent is request-for-UI or conversational. A cheap heuristic is checking if the message mentions a visual artifact — "chart", "table", "dashboard", "form", "summary card".

  • For UI intents, stream a placeholder bubble, replace with iframe once Morphis responds.
  • For non-UI intents, keep your LLM's text response as-is.
  • Always propagate metadata.tokensUsed to your usage logger; chat-driven generation costs more than static pages.

What data to send

Pass only the specific fields the component needs, not a full user profile. If the assistant mentions an invoice, pull that invoice's fields. Bigger blobs dilute intent clarity.

Rewrite the intent before sending it. An assistant message like "here's your churn table" becomes "churn table for the last 30 days, sortable by customer, red badge for at-risk accounts."

Full example

chat-with-morphis.js
const isUiIntent = /chart|table|graph|dashboard|form|card|plot|map/i.test(message)

if (isUiIntent) {
  const res = await fetch('https://getmorphis.com/api/generate-ui', { ... })
  const { html } = await res.json()
  await chat.sendBubble({ type: 'component', html })
} else {
  await chat.sendBubble({ type: 'text', text: await llm.complete(message) })
}
User data authorization. The component shows whatever you put in contextData. Don't leak records the current user isn't entitled to see — Morphis never connects to your database, so the burden stays on you.