thesys|
OpenUI

@openuidev/lang-react

API reference for the documented Generative UI runtime and library APIs.

Use this package for Generative UI authoring and rendering.

Import

import {
  createLibrary,
  Renderer,
  BuiltinActionType,
  createParser,
  createStreamingParser,
} from "@openuidev/lang-react";

createLibrary(input)

Creates a Library from component definitions.

function createLibrary(input: LibraryDefinition): Library;

Core types used in docs:

interface LibraryDefinition {
  components: Record<string, ComponentDefinition>;
  componentGroups?: ComponentGroup[];
  root?: string;
}

interface ComponentDefinition<T extends z.ZodObject<any> = z.ZodObject<any>> {
  props: T;
  description: string;
  component: ComponentRenderer<z.infer<T>>;
}

interface Library {
  components: Record<string, ComponentDefinition>;
  componentGroups?: ComponentGroup[];
  root?: string;
  prompt(options?: PromptOptions): string;
  toJSONSchemas(): Record<string, object>;
}

<Renderer />

Parses GenUI Lang text and renders nodes with your Library.

interface RendererProps {
  text: string | null;
  library: Library;
  isStreaming?: boolean;
  onAction?: (event: ActionEvent) => void;
  updateMessage?: (message: string) => void;
  fallback?: ComponentRenderer;
  placeholder?: React.ReactNode;
  nodePlaceholder?: React.ReactNode;
  onParseResult?: (result: ParseResult | null) => void;
}

Actions

enum BuiltinActionType {
  ContinueConversation = "continue_conversation",
  OpenUrl = "open_url",
}

interface ActionEvent {
  type: string;
  params: Record<string, any>;
  humanFriendlyMessage: string;
  llmFriendlyMessage: string;
}

Parser APIs

function createParser(library: Library): {
  parse(input: string): ParseResult;
};

function createStreamingParser(library: Library): {
  push(chunk: string): ParseResult;
  getResult(): ParseResult;
};

Core parsed types referenced in docs:

interface ElementNode {
  type: "element";
  typeName: string;
  props: Record<string, unknown>;
  partial: boolean;
}

interface ParseResult {
  root: ElementNode | null;
  meta: {
    incomplete: boolean;
    unresolved: string[];
    statementCount: number;
    validationErrors: ValidationError[];
  };
}

Context hooks (inside renderer components)

function useRenderNode(): (value: unknown) => React.ReactNode;
function useTriggerAction(): (
  userMessage: string,
  actionContext: string,
  formName?: string,
  action?: { type?: string; params?: Record<string, any> },
) => void;
function useIsStreaming(): boolean;
function useGetFieldValue(): (formName: string | undefined, name: string) => any;
function useSetFieldValue(): (
  formName: string | undefined,
  componentType: string | undefined,
  name: string,
  value: any,
  shouldTriggerSaveCallback?: boolean,
) => void;
function useFormName(): string | undefined;
function useSetDefaultValue(options: {
  formName?: string;
  componentType: string;
  name: string;
  existingValue: any;
  defaultValue: any;
  shouldTriggerSaveCallback?: boolean;
}): void;

Form validation APIs

interface FormValidationContextValue {
  errors: Record<string, string | undefined>;
  validateField: (name: string, value: unknown, rules: ParsedRule[]) => boolean;
  registerField: (name: string, rules: ParsedRule[], getValue: () => unknown) => void;
  unregisterField: (name: string) => void;
  validateForm: () => boolean;
  clearFieldError: (name: string) => void;
}

function useFormValidation(): FormValidationContextValue | null;
function validate(
  value: unknown,
  rules: ParsedRule[],
  customValidators?: Record<string, ValidatorFn>,
): string | undefined;
const builtInValidators: Record<string, ValidatorFn>;

Message/context utilities

function wrapContent(text: string): string;
function wrapContext(json: string): string;
function separateContentAndContext(raw: string): {
  content: string;
  contextString: string | null;
};

On this page