본문으로 건너뛰기
cccskills
무료GitHub에 공개

openui-forge-anthropic

OpenUI generative UI with Anthropic Claude SDK backend. Stream conversion to OpenAI NDJSON format.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

연동 도구OpenAI
설치 방법 보기

포함된 파일(1)

  • SKILL.md5.9 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

OpenUI Forge — Anthropic

Build generative UI apps with OpenUI + Anthropic Claude. Converts Anthropic streaming events to OpenAI-compatible NDJSON.

Activation Triggers

  • "openui anthropic", "openui claude", "openui sonnet"
  • "generative ui claude", "claude streaming ui"

Prerequisites

  • Node.js >= 22 (24 LTS recommended), React >= 18.3.1 (19+ recommended)
  • ANTHROPIC_API_KEY environment variable set
  • Next.js project (App Router recommended)

Quick Start

  1. Install dependencies:
npm install @openuidev/react-ui @openuidev/react-headless @openuidev/react-lang lucide-react zod @anthropic-ai/sdk
  1. Add the CSS import to app/layout.tsx:
import "@openuidev/react-ui/components.css";
  1. Create the API route and frontend page below
  2. Run npm run dev and test

Full Code

Backend: app/api/chat/route.ts

The backend streams from Anthropic and converts each event into OpenAI-compatible SSE chunks that openAIAdapter() expects (data: {json}\n\n lines, terminated by data: [DONE]).

import { openuiChatLibrary } from "@openuidev/react-ui/genui-lib";
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

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

  const systemPrompt = openuiChatLibrary.prompt({
    preamble: "You are a helpful assistant that generates interactive UIs.",
    additionalRules: ["Always use Stack as root when combining multiple components."],
  });

  // ANTHROPIC_MODEL alternatives: claude-opus-4-8, claude-haiku-4-5, claude-fable-5
  const stream = client.messages.stream({
    model: process.env.ANTHROPIC_MODEL ?? "claude-sonnet-4-6",
    max_tokens: 4096,
    system: systemPrompt,
    messages,
  });

  const encoder = new TextEncoder();
  const readableStream = new ReadableStream({
    async start(controller) {
      const id = `chatcmpl-${Date.now()}`;
      for await (const event of stream) {
        if (
          event.type === "content_block_delta" &&
          event.delta.type === "text_delta"
        ) {
          const chunk = {
            id,
            object: "chat.completion.chunk",
            choices: [
              {
                index: 0,
                delta: { content: event.delta.text },
                finish_reason: null,
              },
            ],
          };
          controller.enqueue(
            encoder.encode(`data: ${JSON.stringify(chunk)}\n\n`)
          );
        }
      }
      const done = {
        id,
        object: "chat.completion.chunk",
        choices: [{ index: 0, delta: {}, finish_reason: "stop" }],
      };
      controller.enqueue(encoder.encode(`data: ${JSON.stringify(done)}\n\n`));
      controller.enqueue(encoder.encode("data: [DONE]\n\n"));
      controller.close();
    },
  });

  return new Response(readableStream, {
    headers: { "Content-Type": "text/event-stream" },
  });
}

Frontend: app/chat/page.tsx

"use client";
import { FullScreen } from "@openuidev/react-ui";
import { openuiChatLibrary } from "@openuidev/react-ui/genui-lib";
import {
  openAIAdapter,
  openAIMessageFormat,
} from "@openuidev/react-headless";

export default function ChatPage() {
  return (
    <FullScreen
      componentLibrary={openuiChatLibrary}
      streamProtocol={openAIAdapter()}
      messageFormat={openAIMessageFormat}
      apiUrl="/api/chat"
    />
  );
}

The backend emits SSE (data: {json}\n\n). Pair it with openAIAdapter() on the frontend — openAIReadableStreamAdapter() is for NDJSON (no data: prefix) and will silently produce no output here.

Component Creation

import { defineComponent } from "@openuidev/react-lang";
import { z } from "zod";

export const StatusCard = defineComponent({
  name: "StatusCard",
  description: "Displays a status with label and color indicator",
  props: z.object({
    label: z.string().describe("Status label text"),
    status: z.enum(["ok", "warning", "error"]).describe("Current status level"),
  }),
  component: ({ props }) => {
    const colors = { ok: "#22c55e", warning: "#eab308", error: "#ef4444" };
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
        <span style={{ width: 10, height: 10, borderRadius: "50%", background: colors[props.status] }} />
        <span>{props.label}</span>
      </div>
    );
  },
});

System Prompt Generation

npx @openuidev/cli generate ./src/lib/library.ts --out src/generated/system-prompt.txt

Or at runtime: openuiChatLibrary.prompt({ preamble: "...", additionalRules: [...] }).

Validation Checklist

  • ANTHROPIC_API_KEY is set in .env.local
  • CSS import present in root layout
  • Backend converts Anthropic content_block_delta events to OpenAI-compatible SSE chunks
  • Final chunk has finish_reason: "stop" and ends with data: [DONE]
  • Frontend uses streamProtocol={openAIAdapter()} and openAIMessageFormat
  • componentLibrary={openuiChatLibrary} prop passed to FullScreen

Error Patterns

ErrorCauseFix
401 from AnthropicMissing or invalid API keySet ANTHROPIC_API_KEY in .env.local
Stream hangsMissing [DONE] sentinel or controller.close()Ensure final chunk and [DONE] are sent
Garbled outputNot wrapping in data: ... SSE formatEach chunk must be data: {json}\n\n
Components render as textLibrary not passed to FullScreenAdd componentLibrary={openuiChatLibrary} prop
Nothing renders, no errorUsed openAIReadableStreamAdapter() (NDJSON) on SSE stream, or adapter= prop (silently ignored)Use streamProtocol={openAIAdapter()}
max_tokens requiredAnthropic API requires explicit max_tokensAlways set max_tokens (e.g., 4096)

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Build generative UI with OpenUI — any LLM provider, any backend language. Scaffold, integrate, validate.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OthmanAdi/openui-forge222026년 8월 3일 업데이트

OpenUI generative UI with C# ASP.NET Core Minimal API backend. Direct OpenAI API SSE streaming via HttpClient on .NET 10.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OthmanAdi/openui-forge222026년 8월 3일 업데이트

OpenUI generative UI with Elixir Phoenix backend. Chunked SSE streaming via Plug.Conn and Req.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OthmanAdi/openui-forge222026년 8월 3일 업데이트

OpenUI generative UI with Go (net/http) backend. Direct OpenAI API streaming via HTTP.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OthmanAdi/openui-forge222026년 8월 3일 업데이트

OpenUI generative UI with a Java Spring Boot (WebFlux) backend. Streams the OpenAI API directly via WebClient as SSE.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OthmanAdi/openui-forge222026년 8월 3일 업데이트

OpenUI generative UI with LangChain/LangGraph backend. Supports ChatOpenAI and ChatAnthropic.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OthmanAdi/openui-forge222026년 8월 3일 업데이트

OthmanAdi의 스킬 모두 보기

이 스킬의 문제 신고