The AI document features got a run of upgrades: pluggable model providers, an instant Apply, a live‑streaming preview that no longer flickers, support for much larger documents, and a Docsmith chat that knows the house style and actually streams.
01 — the headline
The streaming preview used to re‑set the iframe’s srcDoc on every chunk — which fully reloads the iframe. That meant a white flash and a scroll reset several times a second, plus a stretch of raw ```html and unstyled text before anything looked right.
body.innerHTML updates as content grows.And before the document is renderable at all, you now get a skeleton placeholder instead of raw text — the leading markdown fence is stripped, and we wait until the model has emitted <head>/<style> and a <body> before swapping the skeleton for the live document.
02 — how streaming works
A new SSE route streams the generation; the dialog renders it live. The final done event carries the finalized HTML, so Apply stays instant — it persists that, no second generation.
03 — pluggable providers
A Model selector routes the request to one of three engines; OpenAI stays the default, so nothing changes unless you pick another.
OPENAI_API_KEYANTHROPIC_API_KEY@oi/beta · OPENINFER_API_KEY04 — fix
▸ Preview → full model run
▸ Apply → full model run again → “Applying…” hangs
▸ Preview → model run, HTML kept
▸ Apply → reuse the previewed HTML → near‑instant
The previewed HTML rides through to beautifyDocument(…, precomputedHtml), which persists it directly. The rollback snapshot still runs, so Version History is unchanged.
05 — bigger documents
Two limits were cutting large docs short: the input was capped low (long docs were rejected), and Claude’s output was capped (the beautified tail truncated mid‑document). Both are raised — safe, since our models have huge context windows and we stream.
06 — docsmith chat
The chat carries the same DESIGN_SYSTEM Beautify uses — it no longer asks you to “share your design principles.”
Insertable tags widened to div and table, so it can add styled containers and tables instead of coercing them to <p>.
Added X‑Accel‑Buffering: no + no‑transform so proxies stop holding the SSE reply and dumping it at once.
07 — timeline
API keys are server env vars (.env.local locally, Vercel settings in prod) — not stored in Supabase. Each provider reads only its own key.