From 2e0d9fbf864647add583bd2b70efb03a84bce6a0 Mon Sep 17 00:00:00 2001 From: Aditya-thesys Date: Tue, 8 Sep 2026 13:02:14 +0530 Subject: [PATCH 1/3] blog: Introducing OUI-1, the first open-weight model built for generative UI --- docs/components/charts/diffusion-charts.tsx | 288 ++++++++++++ .../charts/reliability-by-model.tsx | 1 + docs/content/blog/oui-1.mdx | 88 ++++ docs/lib/benchmark-data.ts | 9 + docs/lib/diffusion-blog-data.ts | 61 +++ docs/mdx-components.tsx | 14 + docs/public/blog/dg-reveal.html | 417 ++++++++++++++++++ 7 files changed, 878 insertions(+) create mode 100644 docs/components/charts/diffusion-charts.tsx create mode 100644 docs/content/blog/oui-1.mdx create mode 100644 docs/lib/diffusion-blog-data.ts create mode 100644 docs/public/blog/dg-reveal.html diff --git a/docs/components/charts/diffusion-charts.tsx b/docs/components/charts/diffusion-charts.tsx new file mode 100644 index 000000000..67ede2418 --- /dev/null +++ b/docs/components/charts/diffusion-charts.tsx @@ -0,0 +1,288 @@ +"use client"; + +// Charts for the OUI-1 post. Numbers live in lib/diffusion-blog-data.ts. + +import { useEffect, useRef, useState } from "react"; +import { BOARD_RUNS, CROSS_LIBRARY, FRONTIER_BAND, SCATTER, SPEED_ARC, STAGES } from "@/lib/diffusion-blog-data"; +import { Chart, ChartDataDisclosure, DataTable, Row, styles as s, slotClass } from "./primitives"; + +function useWidth(initial = 712) { + const holder = useRef(null); + const [w, setW] = useState(initial); + useEffect(() => { + const el = holder.current; + if (!el) return; + const ro = new ResizeObserver(([entry]) => setW(Math.max(320, Math.round(entry.contentRect.width)))); + ro.observe(el); + return () => ro.disconnect(); + }, []); + return { holder, w }; +} + +export function DgScoreboard() { + const { holder, w: W } = useWidth(); + const H = 430; + const PAD = { left: 46, right: 40, top: 34, bottom: 44 }; + const PW = W - PAD.left - PAD.right; + const PH = H - PAD.top - PAD.bottom; + + const X_MIN = Math.log10(2); + const X_MAX = Math.log10(45); + const x = (b: number) => PAD.left + (1 - (Math.log10(b) - X_MIN) / (X_MAX - X_MIN)) * PW; + const y = (v: number) => PAD.top + (1 - v / 100) * PH; + + const hero = SCATTER.find((p) => p.hero)!; + const ghost = SCATTER.find((p) => p.ghost)!; + + return ( + +
+ + + + {FRONTIER_BAND.label} · {FRONTIER_BAND.lo} to {FRONTIER_BAND.hi}% + + {[0, 20, 40, 60, 80, 100].map((t) => ( + + + {t} + + ))} + {[31, 14, 8, 4, 2].map((b) => ( + {b}B + ))} + + fewer active parameters → + + + + + + + + {SCATTER.map((p) => { + const HUE: Record = { + ours: "var(--pO, #a78bfa)", dgbase: "#3978e6", g31: "#3978e6", twin: "#3978e6", + phi4: "#2774c8", ministral: "#dc5a4f", granite: "#4d6fb8", lfm: "#c04f79", + "qwen38-27b": "#7c4dff", "qwen36-27b": "#7c4dff", "qwen36-a3b": "#7c4dff", + }; + const hue = HUE[p.id] ?? "var(--ink-muted)"; + const cx = x(p.params); + const cy = y(p.score); + if (p.hero) { + return ( + + + + + OUI-1 + + + {p.score}% · {(p.score / SCATTER.find((q) => q.ghost)!.score).toFixed(1)}x the base model + + + ); + } + const anchorRight = p.params === 8 || p.id === "lfm" || p.id === "qwen36-a3b"; + return ( + + + + {p.label} · {p.score}% + + + ); + })} + +
+ + + modelactive paramsOpenUI score + + {SCATTER.map((p) => ( + {p.label}{p.params}B{p.score}% + ))} + + + +
+ ); +} + +export function DgAnatomy() { + // wiring = undefined names + orphaned sections (see lib/diffusion-blog-data.ts) + const CLASSES = [ + { key: "schema" as const, label: "schema errors", slot: 1 as const }, + { key: "wiring" as const, label: "wiring errors: undefined names and orphaned sections", slot: 3 as const }, + ]; + const val = (st: (typeof STAGES)[number], k: "schema" | "wiring") => (k === "schema" ? st.schema : st.orphans + st.unresolved); + const total = (st: (typeof STAGES)[number]) => st.schema + st.orphans + st.unresolved; + const maxT = Math.max(...STAGES.map(total)); + const COLH = 250; + const reduction = (total(STAGES[0]) / total(STAGES[STAGES.length - 1])).toFixed(1); + return ( + ({ label: c.label, slot: c.slot }))} + > +
+ {STAGES.map((st, i) => { + const t = total(st); + const last = i === STAGES.length - 1; + const rate = ((t / st.statements) * 100).toFixed(1); + return ( +
+ + {t} + {last ? ( + + {reduction}× fewer + + ) : null} + +
+ {CLASSES.map((c) => ( + + ))} +
+ {st.label} + + {st.complete}/{BOARD_RUNS} runs complete +
+ {rate} defects per 100 statements +
+
+ ); + })} +
+
+ ); +} + +export function DgLoop() { + const BOXES = [ + { t: "generate", d: "the model writes a few hundred openui-lang programs" }, + { t: "verify", d: "the parser keeps the ones that pass clean; a judge checks each against its brief" }, + { t: "repair", d: "near-misses fixed by an LLM, listed defects only, rewrites rejected" }, + { t: "retrain", d: "the survivors become the next training set" }, + ]; + return ( + +
+
+ {BOXES.map((b, i) => ( +
+
+ + {i + 1} · {b.t} + + {b.d} +
+ {i < BOXES.length - 1 ? ( + + ) : null} +
+ ))} +
+ + + + + + + + + + each pass trains the model that writes the next batch + +
+
+ ); +} + +export function DgSpeedArc() { + const max = Math.max(...SPEED_ARC.map((r) => r.secPerScreen)); + return ( + +
+ {SPEED_ARC.map((r, i) => ( + + + {r.secPerScreen}s + + ))} +
+
+ ); +} + +export function DgCrossLibrary() { + const rows = [ + { id: "base", label: "DiffusionGemma", n: CROSS_LIBRARY.base, slot: 3 as const }, + { id: "ours", label: "OUI-1", n: CROSS_LIBRARY.ours, slot: 1 as const }, + ]; + return ( + +
+ {rows.map((r) => ( + + + {r.n} / {CROSS_LIBRARY.asks} + + ))} +
+
+ ); +} + +export function DgErrorExample() { + const LINES: Array<{ code: string; note?: string; kind?: "grammar" | "wiring" }> = [ + { code: 'header = CardHeader("Spending", "last 7 days")' }, + { code: 'total = Heading("$24,180", "h9")', note: "schema: h9 is not a heading level", kind: "grammar" }, + { code: 'chart = AreaChart(days, [spend], "wavy")', note: 'schema: "wavy" is not a curve type', kind: "grammar" }, + { code: 'footer = TextContent("Updated today")', note: "wiring: defined, never attached to root", kind: "wiring" }, + { code: "root = Card([header, total, chart, summary])", note: "wiring: summary is never defined", kind: "wiring" }, + ]; + const COLOR = { grammar: "#e5484d", wiring: "#d97706" } as const; + return ( +
+ {LINES.map((l) => ( +
+ {l.code} + {l.note ? {"// " + l.note} : null} +
+ ))} +
+ ); +} diff --git a/docs/components/charts/reliability-by-model.tsx b/docs/components/charts/reliability-by-model.tsx index 0515650e5..99b7487c1 100644 --- a/docs/components/charts/reliability-by-model.tsx +++ b/docs/components/charts/reliability-by-model.tsx @@ -48,6 +48,7 @@ const PROVIDER_HUE: Record = { IBM: "#4d6fb8", Liquid: "#c04f79", InclusionAI: "#7c6f64", + Thesys: "#a78bfa", }; const MODEL_NAME: Record = { sol: "GPT-5.6 Sol", diff --git a/docs/content/blog/oui-1.mdx b/docs/content/blog/oui-1.mdx new file mode 100644 index 000000000..ffc2af5f3 --- /dev/null +++ b/docs/content/blog/oui-1.mdx @@ -0,0 +1,88 @@ +--- +title: "Introducing OUI-1: the first open-weight model built for generative UI" +description: "A DiffusionGemma finetune at 71.7% on the Generative UI Benchmark, 5.5x its base." +date: "2026-09-08" +author: "Thesys Engineering Team" +featured: true +--- + +OUI-1 is a finetuned [DiffusionGemma](https://blog.google/innovation-and-ai/technology/developers-tools/diffusion-gemma-faster-text-generation/) model that writes user interfaces in [openui-lang](/docs). It is 26B parameters with 4B active, it runs on a single GPU (a consumer RTX 5090 included, at FP8), and the weights are on [Hugging Face](https://huggingface.co/thesysdev/OUI-1) under the Gemma Terms of Use. + +The best use for it is [appless](https://github.com/thesysdev/appless), a generative UI operating system where every UI is generated on the fly, and each tap becomes the model's context for the next one. That is what OUI-1 is optimised for. + +