Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a6e3af9
refactor(openui-cloud): slim template onto shared @openuidev packages
AbhinRustagi Jul 28, 2026
61d12fc
Update package.json
AbhinRustagi Jul 28, 2026
0eb3a63
refactor(openui-cloud): use the useFetchLLM hook for the chat LLM
AbhinRustagi Jul 28, 2026
7519733
Merge branch 'abhin/template-cleanup' of github.com:thesysdev/openui …
AbhinRustagi Jul 28, 2026
73f7336
refactor(openui-self-hosted): use fetchLLM; drop react-headless/react…
AbhinRustagi Jul 28, 2026
ff8362b
refactor(openui-cloud): drop thread-header CSS overrides now in react-ui
AbhinRustagi Jul 28, 2026
fd00247
refactor(openui-cloud): adopt ref-commit simplifications
AbhinRustagi Jul 28, 2026
4c9dba3
chore(templates): align to react-ui 0.14 / react-headless 0.10; add d…
AbhinRustagi Jul 28, 2026
135c014
docs(templates): refresh READMEs for the slimmed starters
AbhinRustagi Jul 28, 2026
d2594e6
refactor(openui-self-hosted): forward raw SSE via .asResponse() + ope…
AbhinRustagi Jul 28, 2026
e03d451
chore(cli): bump to 0.3.0 for the slimmed templates
AbhinRustagi Jul 28, 2026
6bffb3e
refactor(openui-cloud): consolidate react-ui imports, extract starter…
AbhinRustagi Jul 28, 2026
6277db3
fix(openui-self-hosted): base sans font on body (Tailwind preflight u…
AbhinRustagi Jul 28, 2026
f137d97
feat(openui-self-hosted): load Inter via next/font like the cloud tem…
AbhinRustagi Jul 28, 2026
4e0a59e
fix: update docs and match latest changes
AbhinRustagi Jul 29, 2026
bf17646
fix: update readme
AbhinRustagi Jul 29, 2026
62de451
fix: add favicon
AbhinRustagi Jul 29, 2026
ad9ec64
fix: version match
AbhinRustagi Jul 29, 2026
1e03e61
fix: format
AbhinRustagi Jul 29, 2026
309fca6
fix: styles
AbhinRustagi Jul 29, 2026
e2f1c20
fix: remove credits modal
AbhinRustagi Jul 29, 2026
bfeeb2b
Merge branch 'main' of github.com:thesysdev/openui into abhin/templat…
AbhinRustagi Jul 29, 2026
40cd3fc
Merge branch 'main' of github.com:thesysdev/openui into abhin/templat…
AbhinRustagi Jul 29, 2026
1de32b5
Merge branch 'main' of github.com:thesysdev/openui into abhin/templat…
AbhinRustagi Jul 29, 2026
57be390
Merge branch 'main' of github.com:thesysdev/openui into abhin/templat…
AbhinRustagi Jul 29, 2026
43430e4
fix: update lockfiles
AbhinRustagi Jul 29, 2026
e21cdd3
Merge branch 'main' of github.com:thesysdev/openui into abhin/templat…
AbhinRustagi Jul 29, 2026
b47c976
update lock files
AbhinRustagi Jul 29, 2026
e2e7d14
Update self-hosting.mdx
AbhinRustagi Jul 30, 2026
ed94af7
Update SKILL.md
AbhinRustagi Jul 30, 2026
3dc5103
fix: update minimumReleaseAge rule
AbhinRustagi Jul 30, 2026
012ca1a
Merge branch 'abhin/template-cleanup' of github.com:thesysdev/openui …
AbhinRustagi Jul 30, 2026
4e76ee2
fix: lockfiles
AbhinRustagi Jul 30, 2026
4ba6717
fix: naming refactor
AbhinRustagi Jul 30, 2026
971e19a
Merge branch 'main' of github.com:thesysdev/openui into abhin/templat…
AbhinRustagi Jul 30, 2026
0cecba7
rm pnpm-lock
AbhinRustagi Jul 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/content/docs/agent/getting-started/openui-cloud.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ OpenUI Cloud is the managed backend for Agent Interface. It is built on the open
- **`llm`** points at a thin `/api/chat` route in your app that proxies to Cloud's Responses endpoint. Your `THESYS_API_KEY` stays on that route and never reaches the browser. On the client it uses `openAIResponsesAdapter()` with `openAIConversationMessageFormat`.
- **`storage`** is `useOpenuiCloudStorage()` from `@openuidev/thesys`. It reads conversations and artifacts from Cloud directly, authenticated by a short-lived frontend token your app mints from a `/api/frontend-token` route (so the server key never reaches the browser).

The component set (`chatLibrary`), artifact renderers, and categories also come from `@openuidev/thesys`.
The component set (`chatLibrary`), artifact renderers, and categories also come from `@openuidev/thesys`. The model catalog and allowlist remain app-owned; the reusable `ModelSwitcher` comes from `@openuidev/react-ui`.

Add your server-side key:

Expand Down
38 changes: 19 additions & 19 deletions docs/content/docs/agent/reference/self-hosting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ They are configured separately. You can run a real `llm` with ephemeral (in-memo

The `llm` channel is two halves of one loop:

- **Browser half** — `fetchLLM({ url, streamAdapter, messageFormat })` POSTs `{ threadId, messages }` to your route and parses the streamed reply.
- **Server half** — a route handler that receives `{ threadId, messages }`, calls your provider with streaming on, and returns the stream.
- **Browser half** — `fetchLLM({ url, streamAdapter, messageFormat })` POSTs an AG-UI-shaped body (`threadId`, `runId`, formatted `messages`, plus any extra `body` fields) to your route and parses the streamed reply.
- **Server half** — a route handler that reads what it needs from that body, calls your provider with streaming on, and returns the stream.

```tsx
import { AgentInterface, fetchLLM, openAIReadableStreamAdapter, openAIMessageFormat } from "@openuidev/react-ui";
import { AgentInterface, fetchLLM, openAIAdapter, openAIMessageFormat } from "@openuidev/react-ui";

const llm = fetchLLM({
url: "/api/chat", // your route handler
streamAdapter: openAIReadableStreamAdapter(), // how to parse the streamed response
messageFormat: openAIMessageFormat, // how to shape outgoing messages
url: "/api/chat", // your route handler
streamAdapter: openAIAdapter(), // parses the SDK's raw SSE response
messageFormat: openAIMessageFormat, // how to shape outgoing messages
});

export default function App() {
Expand Down Expand Up @@ -55,7 +55,7 @@ The full catalogue and the precise wire format each adapter expects are in [Adap

### Recipe: OpenAI

With `openAIMessageFormat` on the client, `messages` already arrives in OpenAI's chat shape, so you forward it straight to the SDK. `stream.toReadableStream()` emits NDJSON, which `openAIReadableStreamAdapter()` parses on the client.
With `openAIMessageFormat` on the client, `messages` already arrives in OpenAI's chat shape, so you forward it straight to the SDK. `.asResponse()` preserves the SDK's SSE response without re-encoding it, and `openAIAdapter()` parses that stream on the client.

```ts
// app/api/chat/route.ts
Expand All @@ -64,22 +64,22 @@ import OpenAI from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); // server-side only

export async function POST(req: Request) {
const { threadId, messages } = await req.json();

const stream = await openai.chat.completions.create({
model: "gpt-4o",
stream: true, // ← the part that makes it stream
messages, // already OpenAI-shaped via openAIMessageFormat
});
const { messages } = await req.json();

// openAIReadableStreamAdapter() parses exactly this NDJSON output.
return new Response(stream.toReadableStream(), {
headers: { "Content-Type": "text/event-stream" },
});
return await openai.chat.completions
.create(
{
model: "gpt-4o",
stream: true, // ← the part that makes it stream
messages, // already OpenAI-shaped via openAIMessageFormat
},
{ signal: req.signal }, // propagate browser aborts
)
.asResponse();
}
```

**Variant — forward raw SSE.** If you proxy another OpenAI-compatible service that emits SSE, return the SSE bytes unchanged and switch the client to `openAIAdapter()`:
**Variant — direct fetch.** If you proxy another OpenAI-compatible service without its SDK, return the SSE bytes unchanged and keep `openAIAdapter()`:

```ts
export async function POST(req: Request) {
Expand Down
2 changes: 1 addition & 1 deletion packages/openui-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openuidev/cli",
"version": "0.2.1",
"version": "0.2.2",
"description": "CLI for OpenUI — scaffold generative UI chat apps and generate LLM system prompts from component libraries",
"bin": {
"openui": "dist/index.js"
Expand Down
27 changes: 7 additions & 20 deletions packages/openui-cli/src/templates/openui-cloud/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,39 @@ cp .env.example .env.local # fill THESYS_API_KEY and point the base URLs at yo

Required env: `THESYS_API_KEY`, `DEMO_USER_ID`.

Optional env: `OPENUI_MODEL` sets the server-side fallback model used before a user picks a model
in the app.

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `src/app/api/route.ts` and improving your agent
You can start editing the page by modifying `src/app/api/chat/route.ts` and improving your agent
by adding system prompts or tools.

## Switching Models

Use the model switcher in the chat header to choose a model for new messages. The starter keeps a
small curated model list in the frontend and sends the selected `provider/model` id to `/api/chat`.
The built-in list includes Gemini, GPT, Claude Sonnet, and Claude Opus options; free Gemini
variants are marked with a `Free` badge.
small curated model list in `src/lib/models.tsx` and sends the selected `provider/model` id to
`/api/chat`, which validates it against the same list. The built-in list includes Gemini, GPT,
Claude Sonnet, and Claude Opus options; free Gemini variants are marked with a `Free` badge.

The built-in model ids are available on [models.dev's OpenRouter provider
list](https://models.dev/providers/openrouter/).

To set the initial server fallback, add `OPENUI_MODEL` to your `.env` file:

```bash
OPENUI_MODEL=google/gemini-3.6-flash-free
```

## SDK packages

- `@openuidev/thesys-server` — the server SDK (`artifactTool`,
`generateSystemPrompt`) used by the `/api/chat` route.
- `@openuidev/thesys` — the React component library (`chatLibrary`, `Presentation`,
`Report`) used by the client page and artifact renderers.
- `@openuidev/react-headless` / `@openuidev/react-ui` — the chat UI runtime
(`AgentInterface`, storage/stream contracts, `defineArtifactRenderer`).
(`AgentInterface`, `fetchLLM`, `ModelSwitcher`, storage/stream contracts).
- `@openuidev/devtools` — dev-only widget surfacing errors and the credits notice
(rendered only in development).

## Learn More

Expand Down
Loading
Loading