UNPKG

@copilotkit/a2ui-renderer

Version:

A2UI Renderer for CopilotKit - render A2UI surfaces in React applications

1 lines 9.13 kB
{"version":3,"file":"create-catalog.cjs","names":["createReactComponent","Catalog","basicCatalog"],"sources":["../../src/react-renderer/create-catalog.tsx"],"sourcesContent":["import { z, type ZodObject, type ZodRawShape } from \"zod\";\nimport { Catalog } from \"@a2ui/web_core/v0_9\";\nimport { BASIC_FUNCTIONS } from \"@a2ui/web_core/v0_9/basic_catalog\";\nimport { basicCatalog, createReactComponent } from \"./a2ui-react\";\nimport type { ReactComponentImplementation } from \"./a2ui-react\";\nimport type { ComponentApi } from \"@a2ui/web_core/v0_9\";\n\n// ─── Catalog Definitions (platform-agnostic) ─────────────────────────\n\n/**\n * A single component definition — Zod props schema + optional description.\n * Platform-agnostic: no React or rendering details.\n */\nexport interface CatalogComponentDefinition<\n T extends ZodRawShape = ZodRawShape,\n> {\n /** Zod schema for component props */\n props: ZodObject<T>;\n /** Description for the AI agent */\n description?: string;\n}\n\n/**\n * A record mapping component names to their definitions.\n * This is the platform-agnostic \"contract\" that agents use.\n */\nexport type CatalogDefinitions = Record<\n string,\n CatalogComponentDefinition<any>\n>;\n\n/**\n * Infer the props type for a specific component in the definitions.\n */\nexport type PropsOf<D extends CatalogDefinitions, K extends keyof D> = z.infer<\n D[K][\"props\"]\n>;\n\n// ─── Catalog Renderers (platform-specific) ───────────────────────────\n\n/**\n * Props passed to a renderer function.\n */\nexport interface RendererProps<T = Record<string, unknown>> {\n /** Resolved prop values from the A2UI data model */\n props: T;\n /** Render a child component by ID */\n children: (id: string) => React.ReactNode;\n /** Dispatch an A2UI action from this component (e.g., on button click) */\n dispatch?: (action: any) => void;\n}\n\n/**\n * A renderer function for a component.\n */\nexport type ComponentRenderer<T = Record<string, unknown>> = React.FC<\n RendererProps<T>\n>;\n\n/**\n * A record mapping component names to React renderer functions.\n * Type-checked against the catalog definitions.\n */\nexport type CatalogRenderers<D extends CatalogDefinitions> = {\n [K in keyof D]: ComponentRenderer<z.infer<D[K][\"props\"]>>;\n};\n\n// ─── Create Catalog ──────────────────────────────────────────────────\n\n/**\n * Create an A2UI catalog from definitions and renderers.\n *\n * Definitions are platform-agnostic (Zod schemas + descriptions).\n * Renderers are platform-specific (React components).\n * TypeScript enforces that renderers match definitions exactly.\n *\n * @example\n * ```tsx\n * // schema.ts (platform-agnostic)\n * export const demoCatalogDefinitions = {\n * Card: {\n * description: \"A card container\",\n * props: z.object({ title: z.string(), child: z.string().optional() }),\n * },\n * } satisfies CatalogDefinitions;\n *\n * // catalog.tsx (React renderers)\n * export const demoCatalog = createCatalog(demoCatalogDefinitions, {\n * Card: ({ props, children }) => (\n * <div>{props.title}{props.child && children(props.child)}</div>\n * ),\n * });\n * ```\n */\nexport function createCatalog<D extends CatalogDefinitions>(\n definitions: D,\n renderers: CatalogRenderers<D>,\n options?: {\n /** Catalog ID. Defaults to a generated URI. */\n catalogId?: string;\n /** If true, merge the built-in basic catalog components (Text, Button, Row, etc.) into this catalog. Default: false */\n includeBasicCatalog?: boolean;\n },\n): Catalog<ReactComponentImplementation> {\n const catalogId = options?.catalogId ?? \"copilotkit://custom-catalog\";\n const includeBasic = options?.includeBasicCatalog === true;\n\n const customComponents: ReactComponentImplementation[] = [];\n\n for (const [name, def] of Object.entries(definitions)) {\n const api: ComponentApi = {\n name,\n schema: def.props,\n };\n\n const renderer = (renderers as Record<string, ComponentRenderer<any>>)[\n name\n ];\n const wrapped = createReactComponent(\n api,\n ({ props, buildChild, context }) => {\n const Render = renderer;\n const dispatch = (action: any) => context.dispatchAction(action);\n return (\n <Render props={props} children={buildChild} dispatch={dispatch} />\n );\n },\n );\n\n customComponents.push(wrapped);\n }\n\n const allComponents = includeBasic\n ? [...Array.from(basicCatalog.components.values()), ...customComponents]\n : customComponents;\n\n const functions = includeBasic\n ? Array.from(basicCatalog.functions.values())\n : [];\n\n return new Catalog<ReactComponentImplementation>(\n catalogId,\n allComponents,\n functions,\n );\n}\n\n// ─── Extract Schema (for runtime) ────────────────────────────────────\n\n/**\n * Extract a JSON-serializable schema from catalog definitions.\n * Suitable for passing to the runtime's `a2ui.schema` config.\n */\nexport function extractSchema(definitions: CatalogDefinitions): Array<{\n name: string;\n description?: string;\n props?: Record<string, unknown>;\n}> {\n return Object.entries(definitions).map(([name, def]) => ({\n name,\n description: def.description,\n props: zodSchemaToSimpleObject(def.props),\n }));\n}\n\nfunction zodSchemaToSimpleObject(\n schema: ZodObject<any>,\n): Record<string, unknown> {\n const shape = schema.shape;\n const properties: Record<string, { type: string; description?: string }> = {};\n for (const [key, value] of Object.entries(shape)) {\n const zodValue = value as any;\n properties[key] = {\n type: zodValue._def?.typeName ?? \"unknown\",\n ...(zodValue.description ? { description: zodValue.description } : {}),\n };\n }\n return { type: \"object\", properties };\n}\n\n// ─── Backward Compatibility ──────────────────────────────────────────\n\n// Old API — definitions + renderers combined in one object\nexport interface A2UIComponentDefinition<T extends ZodRawShape = ZodRawShape> {\n props: ZodObject<T>;\n description?: string;\n render: React.FC<RendererProps<z.infer<ZodObject<T>>>>;\n}\n\nexport type A2UIComponentMap = Record<string, A2UIComponentDefinition<any>>;\n\n/**\n * @deprecated Use `createCatalog(definitions, renderers)` instead.\n */\nexport function createA2UICatalog(\n components: A2UIComponentMap,\n options?: {\n catalogId?: string;\n includeBasicCatalog?: boolean;\n },\n): Catalog<ReactComponentImplementation> {\n const definitions: CatalogDefinitions = {};\n const renderers: Record<string, ComponentRenderer<any>> = {};\n\n for (const [name, def] of Object.entries(components)) {\n definitions[name] = { props: def.props, description: def.description };\n renderers[name] = def.render;\n }\n\n return createCatalog(definitions, renderers as any, options);\n}\n\n/**\n * @deprecated Use `extractSchema(definitions)` instead.\n */\nexport function extractA2UISchema(components: A2UIComponentMap): Array<{\n name: string;\n description?: string;\n props?: Record<string, unknown>;\n}> {\n const definitions: CatalogDefinitions = {};\n for (const [name, def] of Object.entries(components)) {\n definitions[name] = { props: def.props, description: def.description };\n }\n return extractSchema(definitions);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8FA,SAAgB,cACd,aACA,WACA,SAMuC;CACvC,MAAM,YAAY,SAAS,aAAa;CACxC,MAAM,eAAe,SAAS,wBAAwB;CAEtD,MAAM,mBAAmD,EAAE;AAE3D,MAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,YAAY,EAAE;EACrD,MAAM,MAAoB;GACxB;GACA,QAAQ,IAAI;GACb;EAED,MAAM,WAAY,UAChB;EAEF,MAAM,UAAUA,qCACd,MACC,EAAE,OAAO,YAAY,cAAc;GAClC,MAAM,SAAS;GACf,MAAM,YAAY,WAAgB,QAAQ,eAAe,OAAO;AAChE,UACE,2CAAC;IAAc;IAAO,UAAU;IAAsB;KAAY;IAGvE;AAED,mBAAiB,KAAK,QAAQ;;AAWhC,QAAO,IAAIC,4BACT,WAToB,eAClB,CAAC,GAAG,MAAM,KAAKC,2BAAa,WAAW,QAAQ,CAAC,EAAE,GAAG,iBAAiB,GACtE,kBAEc,eACd,MAAM,KAAKA,2BAAa,UAAU,QAAQ,CAAC,GAC3C,EAAE,CAML;;;;;;AASH,SAAgB,cAAc,aAI3B;AACD,QAAO,OAAO,QAAQ,YAAY,CAAC,KAAK,CAAC,MAAM,UAAU;EACvD;EACA,aAAa,IAAI;EACjB,OAAO,wBAAwB,IAAI,MAAM;EAC1C,EAAE;;AAGL,SAAS,wBACP,QACyB;CACzB,MAAM,QAAQ,OAAO;CACrB,MAAM,aAAqE,EAAE;AAC7E,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,EAAE;EAChD,MAAM,WAAW;AACjB,aAAW,OAAO;GAChB,MAAM,SAAS,MAAM,YAAY;GACjC,GAAI,SAAS,cAAc,EAAE,aAAa,SAAS,aAAa,GAAG,EAAE;GACtE;;AAEH,QAAO;EAAE,MAAM;EAAU;EAAY;;;;;AAiBvC,SAAgB,kBACd,YACA,SAIuC;CACvC,MAAM,cAAkC,EAAE;CAC1C,MAAM,YAAoD,EAAE;AAE5D,MAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,WAAW,EAAE;AACpD,cAAY,QAAQ;GAAE,OAAO,IAAI;GAAO,aAAa,IAAI;GAAa;AACtE,YAAU,QAAQ,IAAI;;AAGxB,QAAO,cAAc,aAAa,WAAkB,QAAQ;;;;;AAM9D,SAAgB,kBAAkB,YAI/B;CACD,MAAM,cAAkC,EAAE;AAC1C,MAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,WAAW,CAClD,aAAY,QAAQ;EAAE,OAAO,IAAI;EAAO,aAAa,IAAI;EAAa;AAExE,QAAO,cAAc,YAAY"}