Skip to content

Connect a model

GistUI needs a text stream and nothing else. How to wire the system prompt and the stream with OpenAI, Anthropic, the Vercel AI SDK, AI gateways and local models.

Updated View as Markdown

GistUI does not call a model for you and does not care which one you use. The contract has two halves:

  1. Give the model GistUI’s system prompt, where you call it.
  2. Send the model’s text to the browser, unchanged, as a stream.
import { prompt } from "@gistui/catalog";

const system = prompt().text;
// prompt()                    the whole reply is one UI
// prompt({ mode: "inline" })  chat text, with the UI in ```gistui fences
// prompt({ mode: "edit" })    the reply is a patch to a UI that is already shown

The prompt is byte-stable: the same options give the same bytes, so provider prompt caching hits.

Pick your setup

You use Page Text stream comes from
The Vercel AI SDK (ai) Vercel AI SDK result.toTextStreamResponse()
OpenAI’s API or SDK OpenAI textDeltas(res, "openai")
Anthropic’s API or SDK Anthropic textDeltas(res, "anthropic")
Vercel AI Gateway, OpenRouter, Groq, Together, Ollama, vLLM OpenAI-compatible APIs textDeltas(res, "openai")
Cloudflare Workers AI Cloudflare Workers AI the AI SDK provider, or the OpenAI-compatible endpoint
An AG-UI agent (LangGraph, CrewAI, Mastra…) AG-UI textDeltas(res, "agui")

Reading a provider’s stream

Providers send server-sent events, not plain text. @gistui/server turns them into text on any JavaScript runtime (Node, Bun, Deno, Edge, Workers).

npm i @gistui/server
import { textDeltas, toReadable } from "@gistui/server";

// textDeltas(response, format): an async iterable of text
// format: "openai" | "anthropic" | "ai-sdk" | "agui" | "text"
return new Response(toReadable(textDeltas(res, "openai")));

textDeltas throws when the provider reports an error (a non-ok response, or an error event in the stream), so a failed call is never an empty answer. Leaving the loop early cancels the upstream request.

Prompt options

Option Use
mode "full" (default), "inline" for chat, "edit" for patches
tools Describe the tools @query and @mutation may call: [{ name: "get_sales", args: "{range:str}" }]
groups Only some component groups, for a smaller prompt: ["Layout", "Content", "Data"]
preamble Text placed before everything else: your product, the assistant’s role
rules Extra rules appended to the built-in ones
examples "one" (default), "none", or your own example programs
guide false leaves the design guide out; a string replaces it
const system = prompt({
  mode: "inline",
  preamble: "You are the assistant inside Acme Analytics.",
  tools: [{ name: "get_sales", args: "{range:str}" }],
}).text;

Which models work well

Any model that follows a system prompt and can stream. On the public benchmark, gpt-oss-120b writes 88% of screens valid as written, and 100% after autofix. See Benchmarks for the numbers per model.

Small models make more mistakes on large screens. Autofix repairs them in code, and repairStream with a complete function can ask your model to fix what code could not: see Autofix and repair.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close