Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions docs/content/docs/openui-lang/examples/harnesses/pi.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: pi Agent Harness
description: Chat with the pi coding agent (a real read/bash/edit/write agent) and get its answers as live generative UI, bridged through the pi SDK over an OpenAI-compatible stream.
---

Anything that can stream text can drive OpenUI's renderer, including a full **coding agent**. This example connects [pi](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) (`@earendil-works/pi-coding-agent`), running its default `read` / `bash` / `edit` / `write` tools, to `<AgentInterface>`. Pi calls **OpenUI Cloud** Completions; `generateSystemPrompt()` is appended so it emits [OpenUI Lang](/docs/openui-lang/overview) for Cloud `chatLibrary` instead of markdown.
Anything that can stream text can drive OpenUI's renderer, including a full **coding agent**. This example connects [pi](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) (`@earendil-works/pi-coding-agent`), running its default `read` / `bash` / `edit` / `write` tools, to `<AgentInterface>`. Pi calls **OpenUI Cloud** Completions; `generateSystemPrompt({ cloud: true })` is appended so it emits [OpenUI Lang](/docs/openui-lang/overview) for Cloud `chatLibrary` instead of markdown.

Its mid-turn activity (reasoning and tool runs) surfaces as cards too.

Expand All @@ -28,7 +28,7 @@ Its mid-turn activity (reasoning and tool runs) surfaces as cards too.
| --- | --- | --- |
| Frontend | `src/app/page.tsx` | A single `<AgentInterface>` wired with `fetchLLM({ streamAdapter: openAIReadableStreamAdapter(), messageFormat: openAIMessageFormat })` and Cloud `chatLibrary`. |
| Bridge route | `src/app/api/chat/route.ts` | Drives a pi `AgentSession` against OpenUI Cloud Completions and re-emits its events as NDJSON OpenAI chunks (`delta.content` is OpenUI Lang). |
| Session registry | `src/lib/pi-session.ts` | One persistent `AgentSession` per chat thread, keyed by `threadId`. Injects `generateSystemPrompt()` and the Cloud model. |
| Session registry | `src/lib/pi-session.ts` | One persistent `AgentSession` per chat thread, keyed by `threadId`. Injects `generateSystemPrompt({ cloud: true })` and the Cloud model. |
| Agent | `@earendil-works/pi-coding-agent` | The pi coding agent: `read` / `bash` / `edit` / `write` on the workspace you choose at launch. |

Everything runs in **one Next.js process**: the App-Router route _is_ the backend. The pi SDK is embedded directly (no separate server), so there is no second service and no CORS. Each chat thread maps to one persistent pi `AgentSession`, so multi-turn context is preserved.
Expand Down Expand Up @@ -59,7 +59,7 @@ const llm = fetchLLM({
/>;
```

`generateSystemPrompt()` from `@openuidev/thesys-server` is the **same** Cloud chat-library sentinel Pi sends on Completions, so the model's markup matches `chatLibrary`.
`generateSystemPrompt({ cloud: true })` from `@openuidev/lang-core` is the **same** Cloud chat-library sentinel Pi sends on Completions, so the model's markup matches `chatLibrary`.

## The bridge route

Expand Down
2 changes: 1 addition & 1 deletion examples/agent-frameworks/google-adk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Open [http://localhost:3000](http://localhost:3000) and try a starter such as
## How it works

- `src/agent.ts` defines the `get_weather` tool and a `createAgent()` builder.
The instruction is Cloud's `generateSystemPrompt()`. The model is Cloud's
The instruction is Cloud's `generateSystemPrompt({ cloud: true })`. The model is Cloud's
Gemini (`google/gemini-3.6-flash-free`).
- `src/app/api/chat/route.ts` runs the agent with a `Runner` and keys ADK
sessions by chat `threadId` (so multi-turn history is preserved).
Expand Down
2 changes: 1 addition & 1 deletion examples/agent-frameworks/google-adk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
},
"dependencies": {
"@google/adk": "^1.2.0",
"@openuidev/lang-core": "0.2.17",
"@openuidev/react-headless": "0.9.13",
"@openuidev/react-lang": "0.2.15",
"@openuidev/react-ui": "0.13.10",
"@openuidev/thesys": "0.3.2",
"@openuidev/thesys-server": "0.1.3",
"adk-llm-bridge": "^0.5.3",
"next": "^16.3.3",
"react": "19.2.3",
Expand Down
4 changes: 2 additions & 2 deletions examples/agent-frameworks/google-adk/src/agent.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Agent, FunctionTool } from "@google/adk";
import { generateSystemPrompt } from "@openuidev/thesys-server";
import { generateSystemPrompt } from "@openuidev/lang-core";
import { Custom } from "adk-llm-bridge";
import { z } from "zod";

Expand Down Expand Up @@ -47,7 +47,7 @@ export function createAgent() {
baseURL: "https://api.thesys.dev/v1/embed",
apiKey,
}),
instruction: generateSystemPrompt(),
instruction: generateSystemPrompt({ cloud: true }),
tools: [getWeather],
});
}
2 changes: 1 addition & 1 deletion examples/agent-frameworks/langgraph-platform/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
"@langchain/langgraph": "^1.4.5",
"@langchain/langgraph-sdk": "^1.9.18",
"@langchain/openai": "^1.5.2",
"@openuidev/lang-core": "0.2.17",
"@openuidev/langchain": "0.0.3",
"@openuidev/react-headless": "0.9.13",
"@openuidev/react-lang": "0.2.15",
"@openuidev/react-ui": "0.13.10",
"@openuidev/thesys": "0.3.2",
"@openuidev/thesys-server": "0.1.3",
"deepagents": "^1.10.5",
"langchain": "^1.5.1",
"next": "16.1.6",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChatOpenAI } from "@langchain/openai";
import { openUIStreamTransformer } from "@openuidev/langchain/transformer";
import { generateSystemPrompt } from "@openuidev/thesys-server";
import { generateSystemPrompt } from "@openuidev/lang-core";
import { createDeepAgent } from "deepagents";

import { getStockPrice, getWeather, searchWeb } from "./tools";
Expand All @@ -19,6 +19,7 @@ export const graph = createDeepAgent({
model,
tools: [getWeather, getStockPrice, searchWeb],
systemPrompt: generateSystemPrompt({
cloud: true,
instructions: [
"You are an OpenUI assistant with weather, finance, and research tools.",
"Use the tools when they help answer the user's request, then answer only in OpenUI Lang.",
Expand Down
6 changes: 4 additions & 2 deletions examples/agent-frameworks/mastra/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
"@ag-ui/mastra": "1.1.1",
"@ai-sdk/openai-compatible": "^1.0.49",
"@mastra/core": "1.29.0",
"@openuidev/lang-core": "0.2.17",
"@openuidev/react-headless": "0.9.13",
"@openuidev/react-lang": "0.2.15",
"@openuidev/react-ui": "0.13.10",
"@openuidev/thesys": "0.3.2",
"@openuidev/thesys-server": "0.1.3",
"next": "16.2.6",
"react": "19.2.3",
"react-dom": "19.2.3",
Expand Down Expand Up @@ -46,7 +46,9 @@
"@ai-sdk/ui-utils@1.2.11>@ai-sdk/provider-utils": "2.2.8"
},
"peerDependencyRules": {
"ignoreMissing": ["@copilotkit/runtime"],
"ignoreMissing": [
"@copilotkit/runtime"
],
"allowedVersions": {
"zod": ">=3"
}
Expand Down
3 changes: 2 additions & 1 deletion examples/agent-frameworks/mastra/src/mastra.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Agent } from "@mastra/core/agent";
import { Mastra } from "@mastra/core";
import { generateSystemPrompt } from "@openuidev/thesys-server";
import { generateSystemPrompt } from "@openuidev/lang-core";
import { OpenUICloudGateway, openuiCloudModelId } from "@/openui-cloud-gateway";
import { getStockPrice, getWeather } from "@/tools";

export const openuiAgent = new Agent({
id: "openui-mastra-agent",
name: "OpenUI x Mastra Agent",
instructions: generateSystemPrompt({
cloud: true,
instructions:
"You are a helpful assistant. Use tools when relevant and help the user with their requests. Always format your responses cleanly.",
}),
Expand Down
2 changes: 1 addition & 1 deletion examples/agent-frameworks/vercel-ai-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Open [http://localhost:3000](http://localhost:3000) to see the chat interface.

## How it works

The server (`src/app/api/chat/route.ts`) uses `streamText` with Cloud Completions (`POST /v1/embed/chat/completions`), `generateSystemPrompt()`, and the tools in `src/lib/tools.ts`. It returns `toUIMessageStreamResponse()` — the Vercel AI SDK's native UIMessage stream.
The server (`src/app/api/chat/route.ts`) uses `streamText` with Cloud Completions (`POST /v1/embed/chat/completions`), `generateSystemPrompt({ cloud: true })`, and the tools in `src/lib/tools.ts`. It returns `toUIMessageStreamResponse()` — the Vercel AI SDK's native UIMessage stream.

The frontend (`src/app/page.tsx`) renders `<AgentInterface />` with `fetchLLM({ streamAdapter: vercelAIAdapter(), messageFormat: vercelAIMessageFormat })`. Storage is omitted, so AgentInterface uses its built-in in-memory default (wiped on reload).

Expand Down
2 changes: 1 addition & 1 deletion examples/agent-frameworks/vercel-ai-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
},
"dependencies": {
"@ai-sdk/openai": "^3.0.41",
"@openuidev/lang-core": "0.2.17",
"@openuidev/react-headless": "0.9.13",
"@openuidev/react-lang": "0.2.15",
"@openuidev/react-ui": "0.13.10",
"@openuidev/thesys": "0.3.2",
"@openuidev/thesys-server": "0.1.3",
"ai": "^6.0.116",
"next": "16.2.6",
"react": "19.2.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { tools } from "@/lib/tools";
import { createOpenAI } from "@ai-sdk/openai";
import { generateSystemPrompt } from "@openuidev/thesys-server";
import { generateSystemPrompt } from "@openuidev/lang-core";
import { convertToModelMessages, stepCountIs, streamText } from "ai";

const openai = createOpenAI({
Expand Down Expand Up @@ -52,7 +52,7 @@ export async function POST(req: Request) {

const result = streamText({
model: openai.chat("google/gemini-3.6-flash-free"),
system: generateSystemPrompt(),
system: generateSystemPrompt({ cloud: true }),
messages: modelMessages,
tools,
stopWhen: stepCountIs(5),
Expand Down
2 changes: 1 addition & 1 deletion examples/agent-frameworks/vercel-eve/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ export default defineAgent({
model,
modelContextWindowTokens: 1_048_576,
build: {
externalDependencies: ["@openuidev/thesys-server"],
externalDependencies: ["@openuidev/lang-core"],
},
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { generateSystemPrompt } from "@openuidev/thesys-server";
import { generateSystemPrompt } from "@openuidev/lang-core";
import { defineDynamic, defineInstructions } from "eve/instructions";

/**
Expand All @@ -9,7 +9,7 @@ export default defineDynamic({
events: {
"session.started": () =>
defineInstructions({
markdown: generateSystemPrompt(),
markdown: generateSystemPrompt({ cloud: true }),
}),
},
});
2 changes: 1 addition & 1 deletion examples/agent-frameworks/vercel-eve/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
},
"dependencies": {
"@ai-sdk/openai": "^3.0.41",
"@openuidev/lang-core": "0.2.17",
"@openuidev/react-headless": "0.9.13",
"@openuidev/react-lang": "0.2.15",
"@openuidev/react-ui": "0.13.10",
"@openuidev/thesys": "0.3.2",
"@openuidev/thesys-server": "0.1.3",
"@vercel/connect": "0.2.2",
"ai": "7.0.0-beta.178",
"eve": "^0.11.7",
Expand Down
2 changes: 1 addition & 1 deletion examples/app-frameworks/fastapi/backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
)
MODEL = os.environ.get("OPENUI_MODEL", "google/gemini-3.6-flash-free")

# Same payload as generateSystemPrompt() from @openuidev/thesys-server.
# Same payload as generateSystemPrompt({ cloud: true }) from @openuidev/lang-core.
CLOUD_SYSTEM_PROMPT = ']]>openui:config\n{"libraryVersion": "0.1.0"}'

app = FastAPI()
Expand Down
3 changes: 1 addition & 2 deletions examples/app-frameworks/react-native/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
"start": "next start"
},
"dependencies": {
"@openuidev/lang-core": "0.2.16",
"@openuidev/thesys-server": "0.1.3",
"@openuidev/lang-core": "0.2.17",
"next": "^15.2.3",
"openai": "^6.22.0",
"react": "^19.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { library, promptOptions } from "@/library";
import { generateSystemPrompt } from "@openuidev/thesys-server";
import { generateSystemPrompt } from "@openuidev/lang-core";
import { NextRequest } from "next/server";
import OpenAI from "openai";

const SYSTEM_PROMPT = generateSystemPrompt({
cloud: true,
library: library.toSpec(),
promptOptions: {
examples: promptOptions.examples,
Expand Down
2 changes: 1 addition & 1 deletion examples/app-frameworks/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"dependencies": {
"@ai-sdk/openai": "^3.0.41",
"@ai-sdk/svelte": "^4.0.191",
"@openuidev/lang-core": "0.2.17",
"@openuidev/svelte-lang": "0.1.2",
"@openuidev/thesys-server": "0.1.3",
"ai": "^6.0.116",
"chart.js": "^4.5.1",
"zod": "^4.3.6"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { env } from "$env/dynamic/private";
import { library, promptOptions } from "$lib/library";
import { tools } from "$lib/tools";
import { createOpenAI } from "@ai-sdk/openai";
import { generateSystemPrompt } from "@openuidev/thesys-server";
import { generateSystemPrompt } from "@openuidev/lang-core";
import { convertToModelMessages, smoothStream, stepCountIs, streamText } from "ai";

const openai = createOpenAI({
Expand All @@ -27,6 +27,7 @@ const openai = createOpenAI({
});

const systemPrompt = generateSystemPrompt({
cloud: true,
library: library.toSpec(),
promptOptions: {
examples: promptOptions.examples,
Expand Down
2 changes: 1 addition & 1 deletion examples/app-frameworks/svelte/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ import { defineConfig } from "vite";
export default defineConfig({
plugins: [tailwindcss(), sveltekit()],
ssr: {
noExternal: ["@openuidev/svelte-lang", "@openuidev/lang-core", "@openuidev/thesys-server"],
noExternal: ["@openuidev/svelte-lang", "@openuidev/lang-core"],
},
});
1 change: 0 additions & 1 deletion examples/app-frameworks/vue/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import tailwindcss from "@tailwindcss/vite";
const openuiDeps = [
"@openuidev/lang-core",
"@openuidev/vue-lang",
"@openuidev/thesys-server",
"zod",
];

Expand Down
2 changes: 1 addition & 1 deletion examples/app-frameworks/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"dependencies": {
"@ai-sdk/openai": "^3.0.41",
"@ai-sdk/vue": "^3.0.0",
"@openuidev/thesys-server": "0.1.3",
"@openuidev/lang-core": "0.2.17",
"@openuidev/vue-lang": "0.1.4",
"ai": "^6.0.116",
"chart.js": "^4.5.1",
Expand Down
3 changes: 2 additions & 1 deletion examples/app-frameworks/vue/server/api/chat.post.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createOpenAI } from "@ai-sdk/openai";
import { generateSystemPrompt } from "@openuidev/thesys-server";
import { generateSystemPrompt } from "@openuidev/lang-core";
import { convertToModelMessages, stepCountIs, streamText } from "ai";
import { createOpenUILibrary, promptOptions } from "~/lib/define-library";
import { tools } from "~/lib/tools";
Expand All @@ -12,6 +12,7 @@ const openai = createOpenAI({
const specLibrary = createOpenUILibrary();

const systemPrompt = generateSystemPrompt({
cloud: true,
library: specLibrary.toSpec(),
promptOptions: {
examples: promptOptions.examples,
Expand Down
2 changes: 1 addition & 1 deletion examples/design-systems/material-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
"@mui/icons-material": "^6.4.12",
"@mui/material": "^6.4.12",
"@mui/x-charts": "^7.29.1",
"@openuidev/lang-core": "0.2.17",
"@openuidev/react-headless": "0.9.13",
"@openuidev/react-lang": "0.2.15",
"@openuidev/react-ui": "0.13.10",
"@openuidev/thesys-server": "0.1.3",
"next": "16.2.7",
"openai": "^6.22.0",
"react": "19.2.3",
Expand Down
3 changes: 2 additions & 1 deletion examples/design-systems/material-ui/src/lib/cloud-prompt.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { generateSystemPrompt, type ChatLibrary } from "@openuidev/thesys-server";
import { generateSystemPrompt, type ChatLibrary } from "@openuidev/lang-core";
import { readFileSync } from "fs";
import { join } from "path";

Expand All @@ -8,6 +8,7 @@ export function cloudInstructions(extra?: string): string {
readFileSync(join(process.cwd(), "src/generated/spec.json"), "utf-8"),
) as ChatLibrary;
return generateSystemPrompt({
cloud: true,
library,
...(extra ? { instructions: extra } : {}),
});
Expand Down
4 changes: 2 additions & 2 deletions examples/design-systems/shadcn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ On the client, the `<AgentInterface />` component from `@openuidev/react-ui` han
### Request / Response Flow

1. User types a message. `<AgentInterface />` calls `llm.send`, which sends `POST /api/chat` with the full thread formatted via `openAIMessageFormat`.
2. The API route loads the generated library spec, wraps it with `generateSystemPrompt()`, and calls OpenUI Cloud's Chat Completions API with the full message history.
2. The API route loads the generated library spec, wraps it with `generateSystemPrompt({ cloud: true, library })`, and calls OpenUI Cloud's Chat Completions API with the full message history.
3. If the model calls an app-owned tool, `runChatToolLoop` executes it on this server and continues until the model returns a final answer.
4. The model streams OpenUI Lang as Chat Completions SSE events.
5. On the client, `openAIAdapter()` parses the events and hands the accumulated text to `<AgentInterface />`.
Expand Down Expand Up @@ -120,7 +120,7 @@ This runs `generate` first (compiles the component library → `src/generated/sp

### System Prompt Generation

The `src/lib/shadcn-genui/index.tsx` file defines the entire component library using `createLibrary()`. At dev time, the OpenUI CLI reads this library and writes `src/generated/spec.json`. Cloud's `generateSystemPrompt({ library })` turns that spec into the managed system prompt.
The `src/lib/shadcn-genui/index.tsx` file defines the entire component library using `createLibrary()`. At dev time, the OpenUI CLI reads this library and writes `src/generated/spec.json`. `generateSystemPrompt({ cloud: true, library })` turns that spec into Cloud's managed system prompt.

Re-run generation any time you change component definitions:

Expand Down
2 changes: 1 addition & 1 deletion examples/design-systems/shadcn/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
"lint": "eslint"
},
"dependencies": {
"@openuidev/lang-core": "0.2.17",
"@openuidev/react-headless": "0.9.13",
"@openuidev/react-lang": "0.2.15",
"@openuidev/react-ui": "0.13.10",
"@openuidev/thesys-server": "0.1.3",
"@radix-ui/react-accordion": "^1.2.3",
"@radix-ui/react-alert-dialog": "^1.1.15",
"@radix-ui/react-aspect-ratio": "^1.1.1",
Expand Down
3 changes: 2 additions & 1 deletion examples/design-systems/shadcn/src/lib/cloud-prompt.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { generateSystemPrompt, type ChatLibrary } from "@openuidev/thesys-server";
import { generateSystemPrompt, type ChatLibrary } from "@openuidev/lang-core";
import { readFileSync } from "fs";
import { join } from "path";

Expand All @@ -8,6 +8,7 @@ export function cloudInstructions(extra?: string): string {
readFileSync(join(process.cwd(), "src/generated/spec.json"), "utf-8"),
) as ChatLibrary;
return generateSystemPrompt({
cloud: true,
library,
...(extra ? { instructions: extra } : {}),
});
Expand Down
2 changes: 1 addition & 1 deletion examples/harnesses/grok-build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ explicitly instead of silently continuing with empty model context.

The system prompt and validation schema are derived directly from `src/library.ts` in memory.
`chatLibrary.prompt()` compiles Cloud's chat-library signatures locally — Grok Build is still the
model (xAI), so the Cloud `generateSystemPrompt()` sentinel is not used. The prompt is attached to
model (xAI), so the Cloud `generateSystemPrompt({ cloud: true })` sentinel is not used. The prompt is attached to
`session/new` as ACP `_meta.rules`; it teaches Grok to produce the OpenUI Lang understood by
`chatLibrary`. The schema lets the server verify that the final candidate has a renderable `Card`
root before any assistant text reaches the browser.
Expand Down
4 changes: 2 additions & 2 deletions examples/harnesses/grok-build/src/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Before sending the final response, verify that root is a Card and every referenc
};

// Grok Build talks to xAI, not OpenUI Cloud, so compile the Cloud chat library
// prompt locally. generateSystemPrompt() from @openuidev/thesys-server is a
// Cloud API sentinel and would not expand here.
// prompt locally. generateSystemPrompt({ cloud: true }) from @openuidev/lang-core
// is a Cloud API sentinel and would not expand here.
export const systemPrompt = library.prompt(promptOptions);
export const componentSpec = library.toJSONSchema();
Loading