@openuidev/server
v0.3.0
Published
Server utilities for OpenUI & OpenUI Gateway
Downloads
2,455
Readme
@openuidev/server
Server utilities for OpenUI & OpenUI Gateway.
Links: Package docs | Autofix API | GitHub repo
Autofix
Prefer this package over calling the endpoint yourself. Import createAutofix from @openuidev/server/openai for Chat Completions or @openuidev/server/vercel for the Vercel AI SDK. Use the spec from openui generate --spec for the same library as your renderer. Keep the API key on the server.
Configure once
import { createAutofix } from "@openuidev/server/openai";
import library from "./openui.spec.json";
export const autofix = createAutofix({
apiKey: process.env.THESYS_API_KEY!,
library,
});Fix a completed generation
import { autofix } from "./lib/autofix";
const result = await autofix.completions.fix({ generation, messages, signal });
if (result.status === "fix_failed") {
console.warn(result.unfixedErrors);
} else {
// Render or persist result.content.
}generation is the completed OpenUI text. Optional messages is the conversation before that generation.
Wrap a Chat Completions stream
import OpenAI from "openai";
import { autofix } from "../../../lib/autofix";
const model = new OpenAI();
export async function POST(request: Request) {
const { messages } = await request.json();
const source = await model.chat.completions.create(
{ model: "gpt-5.5", messages, stream: true },
{ signal: request.signal },
);
return autofix.completions
.stream({ stream: source, messages, signal: request.signal })
.toResponse();
}Return SSE for the frontend openAIAdapter(). autofix.responses is not supported yet.
Wrap a Vercel AI SDK stream
import { streamText, toUIMessageStream } from "ai";
import { createAutofix } from "@openuidev/server/vercel";
import library from "./openui.spec.json";
const autofix = createAutofix({
apiKey: process.env.THESYS_API_KEY!,
library,
});
const result = streamText({
model: "openai/gpt-5.5",
system: systemPrompt, // Generated from the same OpenUI component library.
prompt: "Show a greeting card",
abortSignal: signal,
});
return autofix.ai
.stream({
stream: toUIMessageStream({ stream: result.stream }),
signal,
})
.toResponse();Pass toUIMessageStream({ stream: result.stream }). toResponse() is the UI message SSE protocol used by useChat.
Consume the stream
Use either chunks or toResponse() once. result settles after that consumer finishes.
| Member | Purpose |
| -------------- | ------------------------------------------------------------------------ |
| chunks | Native SDK events, including any correction. |
| toResponse() | SSE Response for the matching frontend. |
| result | Settled Autofix result. Persist content when present, not joined text. |
result is null when Autofix did not run. A failed repair throws with code: "fix_failed". Use fix() on the same helper when you already have completed text.
apiBaseUrl overrides the Gateway origin. fetch supports custom transports or mocks.
Conversation history
Persist a Chat Completions turn as Conversations API items. Pass only the new turn —
last user message plus the assembled assistant reply — not the full messages array.
Use the master API key.
import { storeChatCompletionHistory } from "@openuidev/server/openai";
await storeChatCompletionHistory({
apiKey: process.env.THESYS_API_KEY!,
conversationId: threadId,
messages: [
{ role: "user", content: lastUserText },
{ role: "assistant", content: assistantText },
],
});Convert without posting:
import { chatCompletionMessagesToItems } from "@openuidev/server/openai";
chatCompletionMessagesToItems([
{ role: "user", content: "hello" },
{ role: "assistant", content: "hi" },
]);LangGraph
Import storeLangGraphHistory from @openuidev/server/langgraph. Pass completed
BaseMessage instances from @langchain/core/messages, the message types used
by LangGraph. This entry point requires the optional @langchain/core peer
dependency; other server entry points do not.
import { storeLangGraphHistory } from "@openuidev/server/langgraph";
await storeLangGraphHistory({
apiKey: process.env.THESYS_API_KEY!,
conversationId: threadId,
messages: newTurnMessages,
});Store only the new turn, including tool calls and results. Passing the full
replayed history or individual streaming chunks creates duplicate items.
The conversation must already exist. System/developer instructions are skipped;
text and user image_url blocks are supported. Use langGraphMessagesToItems
for conversion without a network request. apiBaseUrl and fetch work as in
storeChatCompletionHistory; storage failures reject the returned promise.
