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

openui-forge-langchain

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

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

연동 도구OpenAI
설치 방법 보기

포함된 파일(1)

  • SKILL.md6.0 KB

SKILL.md(원문)

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

OpenUI Forge — LangChain

Build generative UI apps with OpenUI + LangChain. Stream from ChatOpenAI or ChatAnthropic, convert to OpenAI NDJSON.

Activation Triggers

  • "openui langchain", "openui langgraph", "openui langsmith"
  • "generative ui langchain", "langchain streaming ui"

Prerequisites

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

Quick Start

  1. Install dependencies (pick one or both LLM providers):
npm install @openuidev/react-ui @openuidev/react-headless @openuidev/react-lang lucide-react zod @langchain/openai @langchain/core
# For Anthropic: npm install @langchain/anthropic
  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 (OpenAI): app/api/chat/route.ts

import { openuiChatLibrary } from "@openuidev/react-ui/genui-lib";
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage, SystemMessage, AIMessage } from "@langchain/core/messages";

const model = new ChatOpenAI({ model: process.env.OPENAI_MODEL ?? "gpt-5.5", streaming: true });

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.",
  });

  const lcMessages = [
    new SystemMessage(systemPrompt),
    ...messages.map((m: { role: string; content: string }) =>
      m.role === "user" ? new HumanMessage(m.content) : new AIMessage(m.content)
    ),
  ];

  const stream = await model.stream(lcMessages);
  const encoder = new TextEncoder();
  const id = `chatcmpl-${Date.now()}`;

  const readableStream = new ReadableStream({
    async start(controller) {
      for await (const chunk of stream) {
        const text = typeof chunk.content === "string" ? chunk.content : "";
        if (!text) continue;
        const payload = {
          id,
          object: "chat.completion.chunk",
          choices: [{ index: 0, delta: { content: text }, finish_reason: null }],
        };
        controller.enqueue(encoder.encode(`data: ${JSON.stringify(payload)}\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" },
  });
}

Backend (Anthropic variant): app/api/chat/route.ts

Replace the model initialization and import:

import { ChatAnthropic } from "@langchain/anthropic";

const model = new ChatAnthropic({
  model: process.env.ANTHROPIC_MODEL ?? "claude-sonnet-4-6",
  maxTokens: 4096,
  streaming: true,
});

Everything else (message mapping, stream conversion, response) stays identical.

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. (langGraphAdapter is also exported from @openuidev/react-headless if you stream LangGraph events natively rather than converting to OpenAI shape.)

Component Creation

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

export const MetricCard = defineComponent({
  name: "MetricCard",
  description: "Displays a metric with label, value, and optional trend",
  props: z.object({
    label: z.string().describe("Metric name"),
    value: z.number().describe("Current metric value"),
    trend: z.enum(["up", "down", "flat"]).optional().describe("Trend direction"),
  }),
  component: ({ props }) => (
    <div style={{ padding: 16, border: "1px solid #e5e7eb", borderRadius: 8 }}>
      <div style={{ fontSize: 14, color: "#6b7280" }}>{props.label}</div>
      <div style={{ fontSize: 24, fontWeight: 700 }}>{props.value}</div>
      {props.trend && <span>{props.trend === "up" ? "+" : props.trend === "down" ? "-" : "="}</span>}
    </div>
  ),
});

System Prompt Generation

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

Validation Checklist

  • LLM provider API key is set
  • @langchain/openai or @langchain/anthropic installed
  • Messages correctly mapped to LangChain message types
  • Stream chunks converted to OpenAI-compatible SSE with data: prefix
  • Final chunk has finish_reason: "stop" and ends with data: [DONE]
  • Frontend uses streamProtocol={openAIAdapter()} and openAIMessageFormat
  • CSS import in root layout

Error Patterns

ErrorCauseFix
Empty chunks in streamLangChain AIMessageChunk content may be emptySkip chunks where text is empty
Type error on messagesWrong LangChain message classMap user to HumanMessage, assistant to AIMessage
Module not foundMissing LangChain provider packageInstall @langchain/openai or @langchain/anthropic
Stream hangsMissing [DONE] sentinelAlways send final stop chunk and [DONE]
CORS errorCross-origin frontendAdd CORS headers if frontend/backend are split

리뷰

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

댓글

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

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

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. 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 Anthropic Claude SDK backend. Stream conversion to OpenAI NDJSON format.

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

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일 업데이트

OthmanAdi의 스킬 모두 보기

이 스킬의 문제 신고