Seven changes across the AI document features: pluggable model providers, a latency fix, a live‑streaming preview, and design‑system + streaming upgrades to the Docsmith chat.
TL;DR
Pick the inference engine: OpenAI (default), Claude (Anthropic Messages API), or OpenInfer (@oi/beta). One source of truth in lib/beautify-providers.ts.
The chat model list gained @oi/beta, routed through an OpenAI‑compatible client pointed at OpenInfer's Responses API.
Applying a preview re‑ran the whole model. Now it reuses the previewed HTML — Apply is a DB write, not a second generation.
Beautify now constructs the preview on screen as the model writes it, with a “Constructing…” spinner — instead of one long blank wait.
The chat now carries the same DESIGN_SYSTEM Beautify uses, and can insert div/table blocks for diagrams & tables.
Added no‑buffer headers so edge proxies stop holding the chat’s SSE stream and dumping it all at once.
01 · Pluggable providers
A new Model dropdown sits atop the Beautify dialog. The selection flows through the server action into a single dispatcher that fans out to the chosen provider. OpenAI stays the default, so nothing breaks for existing users.
OPENAI_API_KEYANTHROPIC_API_KEY · claude-opus-4-8OPENINFER_API_KEY · @oi/beta02 · Fix — the “Applying…” hang
After previewing, clicking Apply to Document called the model all over again (and re‑compiled Tailwind), discarding the HTML the preview had just produced. With a slow or streaming provider, that second pass made “Applying…” appear stuck.
The previewed HTML now rides through onTransform → beautifyDocument(…, precomputedHtml), which persists it directly. The rollback‑version snapshot still runs, so Version History is unchanged.
03 · Live‑streaming preview
The old preview was a single blocking call — a server action awaited the entire generation before returning, so you stared at a spinner the whole time. A new streaming route emits tokens as the model writes them, and the dialog renders the partial HTML live. Because the model emits the <style> in the <head> first, every element that follows streams in already‑styled.
done event carries the exact HTML that Apply persists, so accepting stays instant.New plain module (a route can’t import a 'use server' file). Holds the prompt builder, per‑provider streaming generators, finalize, and shared helpers. Design system stays single‑sourced via DESIGN_SYSTEM.
SSE route: streams delta chunks, then a done event with the finalized document.
Consumes the stream into a live iframe with a “Constructing…” spinner; Apply is gated until done; Cancel aborts.
The original previewBeautify server action and the Apply path are untouched, so the non‑streaming flow remains as a fallback.
04 · Docsmith chat
The chat system prompt now injects the same DESIGN_SYSTEM Beautify uses — with a block‑level adapter note (inline styles, build diagrams as inline <svg> / styled boxes). It no longer asks you to “share your design principles.”
Insertable block tags widened to include div and table (schema + ALLOWED_INSERT_TAGS), so it can add styled containers and tables instead of coercing them to <p>.
The chat SSE response now sends Cache‑Control: no‑transform and X‑Accel‑Buffering: no, matching the beautify route, so proxies stop buffering the whole reply.
The chat already streamed at the SDK layer, but the response carried no buffer‑control headers. Some edge proxies hold an SSE body until it closes and then deliver it in one shot — so the reply appeared all at once. The new headers tell the proxy to pass bytes straight through. If it still feels delayed on the default reasoning model, that’s the model thinking silently before its first visible token — a separate, opt‑in “show reasoning” improvement.
05 · Commit timeline
06 · Where things live
| Path | Role |
|---|---|
lib/beautify-providers.ts | Provider registry (id / label / default) — shared by dialog & server. |
lib/beautify-core.ts | New shared engine: prompt build, per‑provider streaming + accumulate, finalize, helpers. |
lib/actions/documents.ts | previewBeautify / beautifyDocument (+ precomputedHtml fast path); non‑streaming provider dispatch (fallback). |
app/api/beautify/preview/route.ts | Streaming SSE preview endpoint. |
components/beautify-document-dialog.tsx | Model dropdown + live streaming preview UI. |
app/api/chat/route.ts | Docsmith: OpenInfer routing, design‑system prompt, div/table tags, no‑buffer headers. |
lib/actions/chat.ts | ALLOWED_INSERT_TAGS widened (div, table). |
components/chat/chat-panel.tsx | OpenInfer in the model list. |
.env.example | Documents OPENAI_/ANTHROPIC_/OPENINFER_API_KEY. |
Keys are server env vars (.env.local locally, Vercel project settings in prod) — not stored in Supabase. Each provider reads only its own key.