@dudousxd/nestjs-agent-react 0.34.4 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{generative-ui-DdUZPCXX.d.ts → generative-ui-ClYT7OgL.d.cts} +32 -5
- package/dist/{generative-ui-CyHY8Lh1.d.cts → generative-ui-D1efzu_K.d.ts} +32 -5
- package/dist/genui-json-render.cjs +34 -6
- package/dist/genui-json-render.cjs.map +1 -1
- package/dist/genui-json-render.d.cts +2 -2
- package/dist/genui-json-render.d.ts +2 -2
- package/dist/genui-json-render.js +34 -6
- package/dist/genui-json-render.js.map +1 -1
- package/dist/genui-server-playwright.d.cts +2 -2
- package/dist/genui-server-playwright.d.ts +2 -2
- package/dist/genui-server.d.cts +3 -3
- package/dist/genui-server.d.ts +3 -3
- package/dist/genui.cjs +37 -5
- package/dist/genui.cjs.map +1 -1
- package/dist/genui.d.cts +4 -4
- package/dist/genui.d.ts +4 -4
- package/dist/genui.js +36 -5
- package/dist/genui.js.map +1 -1
- package/dist/index.cjs +47 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +47 -7
- package/dist/index.js.map +1 -1
- package/dist/{react-registry-z9GFbTm9.d.ts → react-registry-CC84Jm3U.d.ts} +1 -1
- package/dist/{react-registry-Di4IVrw-.d.cts → react-registry-R0eFtDCG.d.cts} +1 -1
- package/dist/{types-DZtFsWec.d.cts → types-COuArD3c.d.cts} +34 -1
- package/dist/{types-DZtFsWec.d.ts → types-COuArD3c.d.ts} +34 -1
- package/package.json +2 -2
|
@@ -49,7 +49,8 @@ function toGenerativeUIItem(part) {
|
|
|
49
49
|
...typeof source.fallbackText === "string" ? { fallbackText: source.fallbackText } : {},
|
|
50
50
|
props: isRecord(source.props) ? source.props : {},
|
|
51
51
|
version: typeof source.version === "number" ? source.version : null,
|
|
52
|
-
toolCallId: typeof source.toolCallId === "string" ? source.toolCallId : null
|
|
52
|
+
toolCallId: typeof source.toolCallId === "string" ? source.toolCallId : null,
|
|
53
|
+
...source.partial === true ? { partial: true } : {}
|
|
53
54
|
};
|
|
54
55
|
}
|
|
55
56
|
var resolverCaches = /* @__PURE__ */ new WeakMap();
|
|
@@ -168,6 +169,7 @@ function useGenerativeUIState(part, options, fallbackTree) {
|
|
|
168
169
|
item?.props ?? empty
|
|
169
170
|
);
|
|
170
171
|
if (item === null) return null;
|
|
172
|
+
if (item.partial === true && Object.keys(item.props).length === 0) return null;
|
|
171
173
|
if (name === GENUI_TREE_COMPONENT && item.fallbackText !== void 0 && (!isRecord(item.props.root) || typeof item.props.root.type !== "string"))
|
|
172
174
|
return {
|
|
173
175
|
status: "problem",
|
|
@@ -190,6 +192,14 @@ function useGenerativeUIState(part, options, fallbackTree) {
|
|
|
190
192
|
// src/genui/generative-ui.tsx
|
|
191
193
|
import { jsx } from "react/jsx-runtime";
|
|
192
194
|
var TreeScopeContext = createContext2(null);
|
|
195
|
+
var GenuiNodeContext = sharedContext(
|
|
196
|
+
"@dudousxd/nestjs-agent-react:genui-node"
|
|
197
|
+
);
|
|
198
|
+
function renderPlaceholder(scope, node) {
|
|
199
|
+
const { placeholder } = scope;
|
|
200
|
+
if (typeof placeholder === "function") return placeholder(node);
|
|
201
|
+
return placeholder !== void 0 ? placeholder : scope.loading;
|
|
202
|
+
}
|
|
193
203
|
function renderFallback(fallback, problem) {
|
|
194
204
|
if (typeof fallback === "function") return fallback(problem);
|
|
195
205
|
if (fallback !== void 0) return fallback;
|
|
@@ -225,6 +235,12 @@ function nodeItem(node, id) {
|
|
|
225
235
|
function TreeNode({ node, id }) {
|
|
226
236
|
const scope = useContext2(TreeScopeContext);
|
|
227
237
|
const item = useMemo2(() => nodeItem(node, id), [node, id]);
|
|
238
|
+
const incomplete = node.incomplete === true;
|
|
239
|
+
const held = node.held === true;
|
|
240
|
+
const state = useMemo2(
|
|
241
|
+
() => ({ id, type: node.type, incomplete, held }),
|
|
242
|
+
[id, node.type, incomplete, held]
|
|
243
|
+
);
|
|
228
244
|
const storedVersion = scope?.componentVersions?.[node.type];
|
|
229
245
|
const definition = scope?.options.catalog?.get?.(node.type);
|
|
230
246
|
const incompatible = storedVersion !== void 0 && definition !== void 0 && storedVersion !== (definition.version ?? 1);
|
|
@@ -235,11 +251,14 @@ function TreeNode({ node, id }) {
|
|
|
235
251
|
scope?.options.resolveComponent
|
|
236
252
|
);
|
|
237
253
|
const validation = useValidatedProps(
|
|
238
|
-
incompatible ? void 0 : scope?.options.catalog,
|
|
254
|
+
incompatible || incomplete ? void 0 : scope?.options.catalog,
|
|
239
255
|
node.type,
|
|
240
256
|
item.props
|
|
241
257
|
);
|
|
242
258
|
if (scope === null) return null;
|
|
259
|
+
if (held) {
|
|
260
|
+
return /* @__PURE__ */ jsx(GenuiNodeContext.Provider, { value: state, children: renderPlaceholder(scope, state) });
|
|
261
|
+
}
|
|
243
262
|
if (resolution.status === "loading" || validation.status === "pending") return scope.loading;
|
|
244
263
|
if (resolution.status === "unknown") {
|
|
245
264
|
if (scope.fallback === void 0 && scope.fallbackText !== void 0)
|
|
@@ -257,7 +276,7 @@ function TreeNode({ node, id }) {
|
|
|
257
276
|
}
|
|
258
277
|
const Renderer2 = resolution.Component;
|
|
259
278
|
const children = Array.isArray(node.children) ? node.children : [];
|
|
260
|
-
return /* @__PURE__ */ jsx(Renderer2, { ...validation.props, children: children.length > 0 ? children.map((child, index) => {
|
|
279
|
+
return /* @__PURE__ */ jsx(GenuiNodeContext.Provider, { value: state, children: /* @__PURE__ */ jsx(Renderer2, { ...validation.props, children: children.length > 0 ? children.map((child, index) => {
|
|
261
280
|
const childId = `${id}.${index}`;
|
|
262
281
|
if (scope.fallback === void 0 && scope.fallbackText !== void 0)
|
|
263
282
|
return /* @__PURE__ */ jsx(TreeNode, { node: child, id: childId }, childId);
|
|
@@ -271,7 +290,7 @@ function TreeNode({ node, id }) {
|
|
|
271
290
|
},
|
|
272
291
|
childId
|
|
273
292
|
);
|
|
274
|
-
}) : void 0 });
|
|
293
|
+
}) : void 0 }) });
|
|
275
294
|
}
|
|
276
295
|
function GenuiTree({ root }) {
|
|
277
296
|
if (root === void 0 || root === null || typeof root.type !== "string") return null;
|
|
@@ -285,6 +304,7 @@ function GenerativeUIScope({
|
|
|
285
304
|
fallbackText,
|
|
286
305
|
componentVersions,
|
|
287
306
|
loading = null,
|
|
307
|
+
placeholder,
|
|
288
308
|
onError,
|
|
289
309
|
children
|
|
290
310
|
}) {
|
|
@@ -299,6 +319,7 @@ function GenerativeUIScope({
|
|
|
299
319
|
...componentVersions !== void 0 ? { componentVersions } : {},
|
|
300
320
|
...fallbackText !== void 0 ? { fallbackText } : {},
|
|
301
321
|
loading,
|
|
322
|
+
placeholder,
|
|
302
323
|
onError
|
|
303
324
|
}),
|
|
304
325
|
[
|
|
@@ -309,6 +330,7 @@ function GenerativeUIScope({
|
|
|
309
330
|
fallbackText,
|
|
310
331
|
componentVersions,
|
|
311
332
|
loading,
|
|
333
|
+
placeholder,
|
|
312
334
|
onError
|
|
313
335
|
]
|
|
314
336
|
);
|
|
@@ -324,6 +346,7 @@ function GenuiProvider({
|
|
|
324
346
|
treeRenderer,
|
|
325
347
|
fallback,
|
|
326
348
|
loading,
|
|
349
|
+
placeholder,
|
|
327
350
|
onError,
|
|
328
351
|
children
|
|
329
352
|
}) {
|
|
@@ -335,9 +358,10 @@ function GenuiProvider({
|
|
|
335
358
|
...treeRenderer !== void 0 ? { treeRenderer } : {},
|
|
336
359
|
...fallback !== void 0 ? { fallback } : {},
|
|
337
360
|
...loading !== void 0 ? { loading } : {},
|
|
361
|
+
...placeholder !== void 0 ? { placeholder } : {},
|
|
338
362
|
...onError !== void 0 ? { onError } : {}
|
|
339
363
|
}),
|
|
340
|
-
[registry, catalog, resolveComponent, treeRenderer, fallback, loading, onError]
|
|
364
|
+
[registry, catalog, resolveComponent, treeRenderer, fallback, loading, placeholder, onError]
|
|
341
365
|
);
|
|
342
366
|
const renderUi = useCallback((block) => /* @__PURE__ */ jsx(GenerativeUI, { part: block }), []);
|
|
343
367
|
return /* @__PURE__ */ jsx(GenuiContext.Provider, { value, children: /* @__PURE__ */ jsx(AmbientRenderUiContext.Provider, { value: renderUi, children }) });
|
|
@@ -367,11 +391,13 @@ function GenerativeUI({
|
|
|
367
391
|
treeRenderer,
|
|
368
392
|
fallback: ownFallback,
|
|
369
393
|
loading: ownLoading,
|
|
394
|
+
placeholder: ownPlaceholder,
|
|
370
395
|
onError: ownOnError
|
|
371
396
|
}) {
|
|
372
397
|
const provided = useContext2(GenuiContext);
|
|
373
398
|
const fallback = ownFallback !== void 0 ? ownFallback : provided?.fallback;
|
|
374
399
|
const loading = ownLoading ?? provided?.loading ?? null;
|
|
400
|
+
const placeholder = ownPlaceholder !== void 0 ? ownPlaceholder : provided?.placeholder;
|
|
375
401
|
const onError = ownOnError ?? provided?.onError;
|
|
376
402
|
const options = useMergedOptions({
|
|
377
403
|
...registry !== void 0 ? { registry } : {},
|
|
@@ -399,6 +425,7 @@ function GenerativeUI({
|
|
|
399
425
|
...state.item.fallbackText !== void 0 ? { fallbackText: state.item.fallbackText } : {},
|
|
400
426
|
fallback,
|
|
401
427
|
loading,
|
|
428
|
+
...placeholder !== void 0 ? { placeholder } : {},
|
|
402
429
|
...onError !== void 0 ? { onError } : {},
|
|
403
430
|
children: /* @__PURE__ */ jsx(ItemBoundary, { item: state.item, fallback, onError, children: /* @__PURE__ */ jsx(Renderer2, { ...state.props }) })
|
|
404
431
|
}
|
|
@@ -414,7 +441,8 @@ function treeToJsonRenderSpec(root) {
|
|
|
414
441
|
const id = `el-${next++}`;
|
|
415
442
|
const entry = { type: node.type, props: node.props ?? {}, children: [] };
|
|
416
443
|
elements[id] = entry;
|
|
417
|
-
for (const child of node.children ?? [])
|
|
444
|
+
for (const child of node.children ?? [])
|
|
445
|
+
if (child.held !== true) entry.children.push(visit(child));
|
|
418
446
|
return id;
|
|
419
447
|
};
|
|
420
448
|
return { root: visit(root), elements };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/genui/json-render.tsx","../src/genui/generative-ui.tsx","../src/components/ambient-ui.ts","../src/genui/use-generative-ui.ts","../src/genui/types.ts"],"sourcesContent":["/**\n * Optional json-render adapter for tree frames (`@dudousxd/nestjs-agent-react/genui/json-render`).\n * Needs the optional peer `@json-render/react` (>= 0.21). Use it when your app already renders\n * json-render specs and wants tree frames to go through the same `Renderer` (its state, actions and\n * visibility machinery); otherwise `<GenerativeUI>` renders trees natively.\n *\n * ```tsx\n * import { GenuiProvider } from '@dudousxd/nestjs-agent-react/genui/json-render';\n *\n * <GenuiProvider registry={registry} catalog={catalog} jsonRender>…</GenuiProvider>\n * ```\n */\nimport { type ComponentRegistry, JSONUIProvider, Renderer } from '@json-render/react';\nimport { type ReactNode, useMemo } from 'react';\nimport {\n GenuiProvider as BaseGenuiProvider,\n type GenuiProviderProps as BaseGenuiProviderProps,\n} from './generative-ui.js';\nimport type { GenerativeUIElement, GenuiRegistry, GenuiRenderer } from './types.js';\n\n/** A json-render flat spec: `{ root, elements: { [id]: { type, props, children } } }`. */\nexport interface JsonRenderFlatSpec {\n root: string;\n elements: Record<string, { type: string; props: Record<string, unknown>; children: string[] }>;\n}\n\n/** A tree frame's `root` as a json-render flat spec (ids `el-0`, `el-1`, … depth first). */\nexport function treeToJsonRenderSpec(root: GenerativeUIElement): JsonRenderFlatSpec {\n const elements: JsonRenderFlatSpec['elements'] = {};\n let next = 0;\n const visit = (node: GenerativeUIElement): string => {\n const id = `el-${next++}`;\n const entry = { type: node.type, props: node.props ?? {}, children: [] as string[] };\n elements[id] = entry;\n for (const child of node.children ?? []) entry.children.push(visit(child));\n return id;\n };\n return { root: visit(root), elements };\n}\n\n/**\n * Adapt a genui registry (renderers taking props + `children`) to a json-render registry (renderers\n * taking `{ element, children }`), so one set of components serves both.\n */\nexport function toJsonRenderRegistry(registry: GenuiRegistry): ComponentRegistry {\n return Object.fromEntries(\n Object.entries(registry).map(([name, Renderer]) => [\n name,\n ({ element, children }: { element: { props?: unknown }; children?: ReactNode }) => (\n <Renderer {...((element.props ?? {}) as Record<string, unknown>)}>{children}</Renderer>\n ),\n ]),\n );\n}\n\nexport interface JsonRenderTreeProps {\n root?: GenerativeUIElement;\n registry: ComponentRegistry;\n /** json-render state the spec's `$state` expressions read. */\n initialState?: Record<string, unknown>;\n}\n\n/** Render a tree frame's `root` with json-render. */\nexport function JsonRenderTree({ root, registry, initialState }: JsonRenderTreeProps) {\n const spec = useMemo(() => (root === undefined ? null : treeToJsonRenderSpec(root)), [root]);\n if (spec === null) return null;\n return (\n <JSONUIProvider registry={registry} {...(initialState !== undefined ? { initialState } : {})}>\n <Renderer spec={spec as never} registry={registry} />\n </JSONUIProvider>\n );\n}\n\n/** A registry entry for `genui:tree` that renders through json-render with `registry`. */\nexport function jsonRenderTree(registry: ComponentRegistry): GenuiRenderer<{\n root?: GenerativeUIElement;\n}> {\n return function JsonRenderTreeFrame({ root }: { root?: GenerativeUIElement }) {\n return <JsonRenderTree registry={registry} {...(root !== undefined ? { root } : {})} />;\n };\n}\n\nexport interface GenuiProviderProps extends BaseGenuiProviderProps {\n /**\n * Draw composed tree frames through json-render: pass your json-render registry, or `true` to\n * derive one from `registry` ({@link toJsonRenderRegistry}). Omitted → trees render natively.\n * An explicit `treeRenderer` wins over it.\n */\n jsonRender?: ComponentRegistry | true;\n}\n\n/** `GenuiProvider` from `/genui`, plus the {@link GenuiProviderProps.jsonRender} option. */\nexport function GenuiProvider({ jsonRender, treeRenderer, registry, ...rest }: GenuiProviderProps) {\n const derived = useMemo(() => {\n if (jsonRender === undefined) return undefined;\n return jsonRenderTree(jsonRender === true ? toJsonRenderRegistry(registry ?? {}) : jsonRender);\n }, [jsonRender, registry]);\n const tree = treeRenderer ?? derived;\n return (\n <BaseGenuiProvider\n {...rest}\n {...(registry !== undefined ? { registry } : {})}\n {...(tree !== undefined ? { treeRenderer: tree } : {})}\n />\n );\n}\n","import {\n Component,\n type Context,\n type ErrorInfo,\n type ReactNode,\n createContext,\n useCallback,\n useContext,\n useMemo,\n} from 'react';\nimport { AmbientRenderUiContext, sharedContext } from '../components/ambient-ui.js';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\nimport type {\n GenerativeUIElement,\n GenerativeUIItem,\n GenerativeUIOptions,\n GenerativeUIProblem,\n GenerativeUIState,\n GenuiRegistry,\n GenuiRenderer,\n} from './types.js';\nimport {\n useGenerativeUIState,\n useResolvedComponent,\n useValidatedProps,\n} from './use-generative-ui.js';\n\n/** What to draw instead of a component that did not render. Default: nothing. */\nexport type GenerativeUIFallback = ReactNode | ((problem: GenerativeUIProblem) => ReactNode);\n\ninterface TreeScope {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n options: GenerativeUIOptions;\n fallback: GenerativeUIFallback | undefined;\n loading: ReactNode;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n}\n\nconst TreeScopeContext = createContext<TreeScope | null>(null);\n\nfunction renderFallback(fallback: GenerativeUIFallback | undefined, problem: GenerativeUIProblem) {\n if (typeof fallback === 'function') return fallback(problem);\n if (fallback !== undefined) return fallback;\n return problem.item.fallbackText !== undefined ? (\n <span style={{ whiteSpace: 'pre-wrap' }}>{problem.item.fallbackText}</span>\n ) : null;\n}\n\ninterface BoundaryProps {\n item: GenerativeUIItem;\n fallback: GenerativeUIFallback | undefined;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n children: ReactNode;\n}\n\n/** One failing renderer takes down its own item, never the message around it. */\nclass ItemBoundary extends Component<BoundaryProps, { error: unknown; failed: boolean }> {\n override state = { error: undefined as unknown, failed: false };\n\n static getDerivedStateFromError(error: unknown) {\n return { error, failed: true };\n }\n\n override componentDidCatch(error: unknown, _info: ErrorInfo) {\n this.props.onError?.(error, this.props.item);\n }\n\n override componentDidUpdate(previous: BoundaryProps) {\n // New props for the same item (a streamed update) get a fresh chance to render.\n if (this.state.failed && previous.item !== this.props.item) {\n this.setState({ error: undefined, failed: false });\n }\n }\n\n override render() {\n if (this.state.failed) {\n return renderFallback(this.props.fallback, {\n reason: 'error',\n item: this.props.item,\n error: this.state.error,\n });\n }\n return this.props.children;\n }\n}\n\nfunction nodeItem(node: GenerativeUIElement, id: string): GenerativeUIItem {\n return { id, component: node.type, props: node.props ?? {}, version: null, toolCallId: null };\n}\n\n/** One tree node: resolved and validated like a top-level item, children rendered as its `children`. */\nfunction TreeNode({ node, id }: { node: GenerativeUIElement; id: string }) {\n const scope = useContext(TreeScopeContext);\n const item = useMemo(() => nodeItem(node, id), [node, id]);\n const storedVersion = scope?.componentVersions?.[node.type];\n const definition = scope?.options.catalog?.get?.(node.type);\n const incompatible =\n storedVersion !== undefined &&\n definition !== undefined &&\n storedVersion !== (definition.version ?? 1);\n const resolution = useResolvedComponent(\n node.type,\n storedVersion ?? null,\n incompatible ? {} : (scope?.options.registry ?? {}),\n scope?.options.resolveComponent,\n );\n const validation = useValidatedProps(\n incompatible ? undefined : scope?.options.catalog,\n node.type,\n item.props,\n );\n if (scope === null) return null;\n if (resolution.status === 'loading' || validation.status === 'pending') return scope.loading;\n if (resolution.status === 'unknown') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n throw new Error('Unknown tree component');\n return renderFallback(scope.fallback, { reason: 'unknown', item });\n }\n if (resolution.status === 'error') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined) throw resolution.error;\n return renderFallback(scope.fallback, { reason: 'error', item, error: resolution.error });\n }\n if (validation.status === 'invalid') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n throw new Error('Invalid tree component');\n return renderFallback(scope.fallback, { reason: 'invalid', item, issues: validation.issues });\n }\n const Renderer = resolution.Component;\n const children = Array.isArray(node.children) ? node.children : [];\n return (\n <Renderer {...validation.props}>\n {children.length > 0\n ? children.map((child, index) => {\n const childId = `${id}.${index}`;\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n return <TreeNode key={childId} node={child} id={childId} />;\n return (\n <ItemBoundary\n key={childId}\n item={nodeItem(child, childId)}\n fallback={scope.fallback}\n onError={scope.onError}\n >\n <TreeNode node={child} id={childId} />\n </ItemBoundary>\n );\n })\n : undefined}\n </Renderer>\n );\n}\n\n/**\n * Renders a `genui:tree` frame's `{ root }` node by node through the same registry, catalog and\n * resolver as top-level components. Used automatically for tree frames unless a `treeRenderer`\n * (e.g. the json-render one) or a registry entry for `genui:tree` takes over.\n */\nexport function GenuiTree({ root }: { root?: GenerativeUIElement }) {\n if (root === undefined || root === null || typeof root.type !== 'string') return null;\n return <TreeNode node={root} id=\"root\" />;\n}\n\nexport interface GenerativeUIScopeProps extends GenerativeUIOptions {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n children?: ReactNode;\n}\n\n/**\n * The registry, catalog and fallbacks tree nodes render with. `<GenerativeUI>` provides it; wrap\n * your own chrome in it when you draw `useGenerativeUI`'s `Component` yourself and it may be a tree.\n */\nexport function GenerativeUIScope({\n registry,\n catalog,\n resolveComponent,\n fallback,\n fallbackText,\n componentVersions,\n loading = null,\n onError,\n children,\n}: GenerativeUIScopeProps) {\n const scope = useMemo<TreeScope>(\n () => ({\n options: {\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n },\n fallback,\n ...(componentVersions !== undefined ? { componentVersions } : {}),\n ...(fallbackText !== undefined ? { fallbackText } : {}),\n loading,\n onError,\n }),\n [\n registry,\n catalog,\n resolveComponent,\n fallback,\n fallbackText,\n componentVersions,\n loading,\n onError,\n ],\n );\n return <TreeScopeContext.Provider value={scope}>{children}</TreeScopeContext.Provider>;\n}\n\n/** What `<GenuiProvider>` hands every `<GenerativeUI>` / `useGenerativeUI` below it. */\nexport interface GenuiProviderValue extends Partial<GenerativeUIOptions> {\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n// Shared by key: `/genui` and `/genui/json-render` are separate bundles, and a provider from one\n// must reach a `<GenerativeUI>` from the other.\nconst GenuiContext: Context<GenuiProviderValue | null> = sharedContext<GenuiProviderValue>(\n '@dudousxd/nestjs-agent-react:genui-provider',\n);\n\n/** The enclosing `<GenuiProvider>`'s settings, or `null` outside one. */\nexport function useGenuiProvider(): GenuiProviderValue | null {\n return useContext(GenuiContext);\n}\n\nexport interface GenuiProviderProps extends GenuiProviderValue {\n children?: ReactNode;\n}\n\n/**\n * Set generative UI up once, at the app root: the registry of your renderers, the catalog to\n * validate against, a resolver for components the registry lacks, and what to draw when one does\n * not render. Every `<GenerativeUI>` below reads it (its own props still win), and `MessageItem` /\n * `MessageList` draw pushed components with it — no `renderUi` per message.\n *\n * ```tsx\n * <GenuiProvider registry={registry} catalog={catalog} fallback={({ item }) => <Unknown name={item.component} />}>\n * <App />\n * </GenuiProvider>\n * ```\n */\nexport function GenuiProvider({\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback,\n loading,\n onError,\n children,\n}: GenuiProviderProps) {\n const value = useMemo<GenuiProviderValue>(\n () => ({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n ...(fallback !== undefined ? { fallback } : {}),\n ...(loading !== undefined ? { loading } : {}),\n ...(onError !== undefined ? { onError } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer, fallback, loading, onError],\n );\n const renderUi = useCallback((block: TranscriptUiBlock) => <GenerativeUI part={block} />, []);\n return (\n <GenuiContext.Provider value={value}>\n <AmbientRenderUiContext.Provider value={renderUi}>{children}</AmbientRenderUiContext.Provider>\n </GenuiContext.Provider>\n );\n}\n\nconst NO_REGISTRY: GenuiRegistry = {};\n\n/** Provider settings overlaid with explicit ones (explicit wins), memoized on their parts. */\nfunction useMergedOptions(own: Partial<GenerativeUIOptions>): GenerativeUIOptions {\n const provided = useContext(GenuiContext);\n const registry = own.registry ?? provided?.registry ?? NO_REGISTRY;\n const catalog = own.catalog ?? provided?.catalog;\n const resolveComponent = own.resolveComponent ?? provided?.resolveComponent;\n const treeRenderer = own.treeRenderer ?? provided?.treeRenderer;\n return useMemo(\n () => ({\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer],\n );\n}\n\n/**\n * The headless half of {@link GenerativeUI}: what to draw for one pushed component, or `null` when\n * `part` is not one. Options default to the enclosing `<GenuiProvider>`'s.\n */\nexport function useGenerativeUI(\n part: unknown,\n options: Partial<GenerativeUIOptions> = {},\n): GenerativeUIState | null {\n const merged = useMergedOptions(options);\n return useGenerativeUIState(part, merged, merged.treeRenderer ?? (GenuiTree as GenuiRenderer));\n}\n\nexport interface GenerativeUIProps extends Partial<GenerativeUIOptions> {\n /** A transcript `ui` block, a `data-ui` message part, or a stored `{ id, component, props, version? }`. */\n part: TranscriptUiBlock | GenerativeUIItem | unknown;\n /** Drawn for an unknown component, invalid props, or a renderer that threw. Default: the provider's, then the item's persisted text. */\n fallback?: GenerativeUIFallback;\n /** Drawn while a resolver or an async validation is pending. Default: the provider's, else nothing. */\n loading?: ReactNode;\n /** A renderer threw (the item shows `fallback`). */\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n/**\n * Draws one server-pushed component with the app's own renderer. Headless: it adds no element and\n * no style of its own — only what the registry's component renders (and whatever `fallback` /\n * `loading` you pass). Everything but `part` defaults to the enclosing `<GenuiProvider>`.\n *\n * ```tsx\n * <GenerativeUI part={block} />\n * ```\n */\nexport function GenerativeUI({\n part,\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback: ownFallback,\n loading: ownLoading,\n onError: ownOnError,\n}: GenerativeUIProps) {\n const provided = useContext(GenuiContext);\n const fallback = ownFallback !== undefined ? ownFallback : provided?.fallback;\n const loading = ownLoading ?? provided?.loading ?? null;\n const onError = ownOnError ?? provided?.onError;\n const options = useMergedOptions({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n });\n const state = useGenerativeUIState(\n part,\n options,\n options.treeRenderer ?? (GenuiTree as GenuiRenderer),\n );\n if (state === null) return null;\n if (state.status === 'loading') return loading;\n if (state.status === 'problem') {\n const { status: _status, ...problem } = state;\n return renderFallback(fallback, problem);\n }\n const Renderer = state.Component;\n return (\n <GenerativeUIScope\n {...options}\n {...(state.item.componentVersions !== undefined\n ? { componentVersions: state.item.componentVersions }\n : {})}\n {...(state.item.fallbackText !== undefined ? { fallbackText: state.item.fallbackText } : {})}\n fallback={fallback}\n loading={loading}\n {...(onError !== undefined ? { onError } : {})}\n >\n <ItemBoundary item={state.item} fallback={fallback} onError={onError}>\n <Renderer {...state.props} />\n </ItemBoundary>\n </GenerativeUIScope>\n );\n}\n","import { type Context, type ReactNode, createContext, useContext } from 'react';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\n\n/** Draws a server-pushed component block. */\nexport type AmbientRenderUi = (block: TranscriptUiBlock) => ReactNode;\n\n/**\n * A context stored on `globalThis` under a registered symbol. Each entry point (`.`, `/genui`,\n * `/genui/json-render`) is its own bundle with its own copy of every module, so a context one entry\n * provides and another reads has to be found by key, not by module identity.\n */\nexport function sharedContext<T>(key: string): Context<T | null> {\n const symbol = Symbol.for(key);\n const holder = globalThis as Record<symbol, Context<T | null> | undefined>;\n const existing = holder[symbol];\n if (existing !== undefined) return existing;\n const created = createContext<T | null>(null);\n holder[symbol] = created;\n return created;\n}\n\n/**\n * How pushed components are drawn when no `renderUi` is passed — set by `<GenuiProvider>` (the\n * `/genui` subpath) and read by `MessageItem`.\n */\nexport const AmbientRenderUiContext: Context<AmbientRenderUi | null> =\n sharedContext<AmbientRenderUi>('@dudousxd/nestjs-agent-react:ambient-render-ui');\n\n/**\n * The renderer `<GenuiProvider>` installed for pushed components, or `null` outside one. For a\n * custom transcript built on `useTranscriptItem`: draw a `ui` block with it and you get what\n * `MessageItem` draws.\n */\nexport function useAmbientRenderUi(): AmbientRenderUi | null {\n return useContext(AmbientRenderUiContext);\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n GENUI_TREE_COMPONENT,\n type GenerativeUIItem,\n type GenerativeUIOptions,\n type GenerativeUIState,\n type GenuiCatalogLike,\n type GenuiIssueLike,\n type GenuiRegistry,\n type GenuiRenderer,\n type ResolveComponent,\n} from './types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Normalize whatever carries a pushed component: a transcript `ui` block, a `data-ui` message part\n * (`{ type: 'data-ui', id, data }`), a stored `{ id, component, props, version? }` entry. `null` for\n * anything else.\n */\nexport function toGenerativeUIItem(part: unknown): GenerativeUIItem | null {\n if (!isRecord(part)) return null;\n const source = part.type === 'data-ui' && isRecord(part.data) ? part.data : part;\n if (typeof source.component !== 'string') return null;\n const id =\n typeof source.id === 'string' ? source.id : typeof part.id === 'string' ? part.id : null;\n if (id === null) return null;\n return {\n id,\n component: source.component,\n ...(isRecord(source.componentVersions) &&\n Object.values(source.componentVersions).every(\n (version) => typeof version === 'number' && Number.isSafeInteger(version) && version > 0,\n )\n ? { componentVersions: { ...source.componentVersions } as Record<string, number> }\n : {}),\n ...(typeof source.fallbackText === 'string' ? { fallbackText: source.fallbackText } : {}),\n props: isRecord(source.props) ? source.props : {},\n version: typeof source.version === 'number' ? source.version : null,\n toolCallId: typeof source.toolCallId === 'string' ? source.toolCallId : null,\n };\n}\n\ntype Resolution =\n | { status: 'ready'; Component: GenuiRenderer }\n | { status: 'loading' }\n | { status: 'unknown' }\n | { status: 'error'; error: unknown };\n\ninterface CacheEntry {\n resolution: Resolution;\n settled: Promise<void> | null;\n}\n\nconst resolverCaches = new WeakMap<ResolveComponent, Map<string, CacheEntry>>();\n\nfunction resolveCached(\n resolve: ResolveComponent,\n name: string,\n version: number | null,\n): CacheEntry {\n let cache = resolverCaches.get(resolve);\n if (cache === undefined) {\n cache = new Map();\n resolverCaches.set(resolve, cache);\n }\n const key = `${name}@${version ?? ''}`;\n const hit = cache.get(key);\n if (hit !== undefined) return hit;\n let entry: CacheEntry;\n try {\n const result = resolve(name, version);\n if (result instanceof Promise) {\n entry = { resolution: { status: 'loading' }, settled: null };\n entry.settled = result.then(\n (Component) => {\n entry.resolution = Component ? { status: 'ready', Component } : { status: 'unknown' };\n },\n (error: unknown) => {\n entry.resolution = { status: 'error', error };\n },\n );\n } else {\n entry = {\n resolution: result ? { status: 'ready', Component: result } : { status: 'unknown' },\n settled: null,\n };\n }\n } catch (error) {\n entry = { resolution: { status: 'error', error }, settled: null };\n }\n cache.set(key, entry);\n return entry;\n}\n\n/**\n * Which renderer draws `name`: the registry first, then `resolveComponent` (cached; async results\n * re-render the caller when they land). `fallbackTree` answers the tree component when the\n * registry does not override it.\n */\nexport function useResolvedComponent(\n name: string,\n version: number | null,\n registry: GenuiRegistry,\n resolve: ResolveComponent | undefined,\n fallbackTree?: GenuiRenderer,\n): Resolution {\n const [, setTick] = useState(0);\n const own = registry[name];\n const entry =\n own !== undefined || resolve === undefined ? null : resolveCached(resolve, name, version);\n const pending = entry?.resolution.status === 'loading' ? entry.settled : null;\n useEffect(() => {\n if (pending === null) return;\n let live = true;\n void pending.then(() => {\n if (live) setTick((tick) => tick + 1);\n });\n return () => {\n live = false;\n };\n }, [pending]);\n if (own !== undefined) return { status: 'ready', Component: own };\n if (entry !== null && entry.resolution.status !== 'unknown') return entry.resolution;\n if (name === GENUI_TREE_COMPONENT && fallbackTree !== undefined) {\n return { status: 'ready', Component: fallbackTree };\n }\n return { status: 'unknown' };\n}\n\ntype Validation =\n | { status: 'ok'; props: Record<string, unknown> }\n | { status: 'pending' }\n | { status: 'invalid'; issues: GenuiIssueLike[] };\n\n/**\n * Props checked against the catalog: synchronously when the catalog can (`validateSync`), else\n * after the async check settles. A component the catalog does not know passes through unchecked.\n */\nexport function useValidatedProps(\n catalog: GenuiCatalogLike | undefined,\n name: string,\n props: Record<string, unknown>,\n): Validation {\n const checked = catalog?.has(name) === true;\n const immediate = useMemo<Validation | null>(() => {\n if (!checked || catalog === undefined) return { status: 'ok', props };\n const result = catalog.validateSync?.(name, props);\n if (result === undefined) return null;\n return result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues };\n }, [checked, catalog, name, props]);\n const [late, setLate] = useState<{ props: Record<string, unknown>; result: Validation } | null>(\n null,\n );\n useEffect(() => {\n if (immediate !== null || catalog === undefined) return;\n let live = true;\n catalog.validate(name, props).then(\n (result) => {\n if (!live) return;\n setLate({\n props,\n result: result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues },\n });\n },\n (error: unknown) => {\n if (!live) return;\n setLate({\n props,\n result: {\n status: 'invalid',\n issues: [{ path: [], message: error instanceof Error ? error.message : String(error) }],\n },\n });\n },\n );\n return () => {\n live = false;\n };\n }, [immediate, catalog, name, props]);\n if (immediate !== null) return immediate;\n return late !== null && late.props === props ? late.result : { status: 'pending' };\n}\n\n/** {@link import('./generative-ui.js').useGenerativeUI}, with the tree renderer handed in (avoids an import cycle). */\nexport function useGenerativeUIState(\n part: unknown,\n options: GenerativeUIOptions,\n fallbackTree: GenuiRenderer | undefined,\n): GenerativeUIState | null {\n const item = useMemo(() => toGenerativeUIItem(part), [part]);\n const name = item?.component ?? '';\n const definition = options.catalog?.get?.(name);\n const incompatible =\n item?.fallbackText !== undefined &&\n item.version !== null &&\n definition !== undefined &&\n item.version !== (definition.version ?? 1);\n const resolution = useResolvedComponent(\n name,\n item?.version ?? null,\n incompatible ? {} : options.registry,\n item === null ? undefined : options.resolveComponent,\n fallbackTree,\n );\n const empty = useMemo<Record<string, unknown>>(() => ({}), []);\n // A tree is validated node by node as it renders, not as one component.\n const validation = useValidatedProps(\n item === null || name === GENUI_TREE_COMPONENT || incompatible ? undefined : options.catalog,\n name,\n item?.props ?? empty,\n );\n if (item === null) return null;\n if (\n name === GENUI_TREE_COMPONENT &&\n item.fallbackText !== undefined &&\n (!isRecord(item.props.root) || typeof item.props.root.type !== 'string')\n )\n return {\n status: 'problem',\n reason: 'invalid',\n item,\n issues: [{ path: ['root'], message: 'Invalid UI tree root' }],\n };\n if (resolution.status === 'loading') return { status: 'loading', item };\n if (resolution.status === 'unknown') return { status: 'problem', reason: 'unknown', item };\n if (resolution.status === 'error') {\n return { status: 'problem', reason: 'error', item, error: resolution.error };\n }\n if (validation.status === 'pending') return { status: 'loading', item };\n if (validation.status === 'invalid') {\n return { status: 'problem', reason: 'invalid', item, issues: validation.issues };\n }\n return { status: 'ready', item, Component: resolution.Component, props: validation.props };\n}\n","import type { ComponentType, ReactNode } from 'react';\n\n/** The `ui` frame component a composed tree is pushed under (`GENUI_TREE_COMPONENT` of `@dudousxd/nestjs-agent-core/genui`). */\nexport const GENUI_TREE_COMPONENT = 'genui:tree';\n\n/** One pushed component, normalized from whatever carried it (a transcript block, a `data-ui` part, a stored entry). */\nexport interface GenerativeUIItem {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n id: string;\n component: string;\n props: Record<string, unknown>;\n version: number | null;\n toolCallId: string | null;\n}\n\n/** A node of a composed tree (`genui:tree` frames): `{ type, props, children? }`. */\nexport interface GenerativeUIElement {\n type: string;\n props: Record<string, unknown>;\n children?: GenerativeUIElement[];\n}\n\n/**\n * An app's renderer for one component: it receives the component's props spread, plus `children`\n * when it is a layout node in a tree. Any React component — the library never styles anything.\n */\nexport type GenuiRenderer<P = any> = ComponentType<P & { children?: ReactNode }>;\n\n/** Component name → the app's renderer. */\nexport type GenuiRegistry = Record<string, GenuiRenderer>;\n\n/**\n * Resolve a component the registry does not have — typically a tenant's own component, fetched for\n * the exact `version` a message was rendered with. Return `null`/`undefined` for \"no such\n * component\". May be async; results are cached per resolver, name and version.\n */\nexport type ResolveComponent = (\n name: string,\n version: number | null,\n) => GenuiRenderer | null | undefined | Promise<GenuiRenderer | null | undefined>;\n\nexport interface GenuiIssueLike {\n path: (string | number)[];\n message: string;\n}\n\ntype ValidationLike =\n | { ok: true; value: Record<string, unknown> }\n | { ok: false; issues: GenuiIssueLike[] };\n\n/**\n * What the renderer needs from a catalog to validate props before drawing them. A `Catalog` from\n * `@dudousxd/nestjs-agent-core/genui` satisfies it; declared structurally so any catalog-shaped\n * object does too.\n */\nexport interface GenuiCatalogLike {\n get?(name: string): { version?: number } | undefined;\n has(name: string): boolean;\n validate(name: string, props: unknown): Promise<ValidationLike>;\n validateSync?(name: string, props: unknown): ValidationLike | undefined;\n}\n\nexport interface GenerativeUIOptions {\n registry: GenuiRegistry;\n /** Validate props against it before rendering. Components the catalog does not know render unvalidated. */\n catalog?: GenuiCatalogLike;\n resolveComponent?: ResolveComponent;\n /**\n * Draws a composed tree frame (`genui:tree`) whole — e.g. through json-render (see the\n * `/genui/json-render` subpath's `GenuiProvider`). Omitted → trees render node by node through\n * `registry`.\n */\n treeRenderer?: GenuiRenderer<{ root?: GenerativeUIElement }>;\n}\n\n/** Why an item did not render. */\nexport type GenerativeUIProblem =\n | { reason: 'unknown'; item: GenerativeUIItem }\n | { reason: 'invalid'; item: GenerativeUIItem; issues: GenuiIssueLike[] }\n | { reason: 'error'; item: GenerativeUIItem; error: unknown };\n\nexport type GenerativeUIState =\n | {\n status: 'ready';\n item: GenerativeUIItem;\n Component: GenuiRenderer;\n props: Record<string, unknown>;\n }\n | { status: 'loading'; item: GenerativeUIItem }\n | ({ status: 'problem' } & GenerativeUIProblem);\n"],"mappings":"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","names":["useMemo","createContext","useContext","useMemo","Component","createContext","useContext","useMemo","Renderer","useMemo","useContext","useContext","Renderer","jsx","Renderer","useMemo","GenuiProvider"]}
|
|
1
|
+
{"version":3,"sources":["../src/genui/json-render.tsx","../src/genui/generative-ui.tsx","../src/components/ambient-ui.ts","../src/genui/use-generative-ui.ts","../src/genui/types.ts"],"sourcesContent":["/**\n * Optional json-render adapter for tree frames (`@dudousxd/nestjs-agent-react/genui/json-render`).\n * Needs the optional peer `@json-render/react` (>= 0.21). Use it when your app already renders\n * json-render specs and wants tree frames to go through the same `Renderer` (its state, actions and\n * visibility machinery); otherwise `<GenerativeUI>` renders trees natively.\n *\n * ```tsx\n * import { GenuiProvider } from '@dudousxd/nestjs-agent-react/genui/json-render';\n *\n * <GenuiProvider registry={registry} catalog={catalog} jsonRender>…</GenuiProvider>\n * ```\n */\nimport { type ComponentRegistry, JSONUIProvider, Renderer } from '@json-render/react';\nimport { type ReactNode, useMemo } from 'react';\nimport {\n GenuiProvider as BaseGenuiProvider,\n type GenuiProviderProps as BaseGenuiProviderProps,\n} from './generative-ui.js';\nimport type { GenerativeUIElement, GenuiRegistry, GenuiRenderer } from './types.js';\n\n/** A json-render flat spec: `{ root, elements: { [id]: { type, props, children } } }`. */\nexport interface JsonRenderFlatSpec {\n root: string;\n elements: Record<string, { type: string; props: Record<string, unknown>; children: string[] }>;\n}\n\n/** A tree frame's `root` as a json-render flat spec (ids `el-0`, `el-1`, … depth first). */\nexport function treeToJsonRenderSpec(root: GenerativeUIElement): JsonRenderFlatSpec {\n const elements: JsonRenderFlatSpec['elements'] = {};\n let next = 0;\n const visit = (node: GenerativeUIElement): string => {\n const id = `el-${next++}`;\n const entry = { type: node.type, props: node.props ?? {}, children: [] as string[] };\n elements[id] = entry;\n // A node held back while the model writes it (`streaming: 'complete'`) has no props to draw yet.\n for (const child of node.children ?? [])\n if (child.held !== true) entry.children.push(visit(child));\n return id;\n };\n return { root: visit(root), elements };\n}\n\n/**\n * Adapt a genui registry (renderers taking props + `children`) to a json-render registry (renderers\n * taking `{ element, children }`), so one set of components serves both.\n */\nexport function toJsonRenderRegistry(registry: GenuiRegistry): ComponentRegistry {\n return Object.fromEntries(\n Object.entries(registry).map(([name, Renderer]) => [\n name,\n ({ element, children }: { element: { props?: unknown }; children?: ReactNode }) => (\n <Renderer {...((element.props ?? {}) as Record<string, unknown>)}>{children}</Renderer>\n ),\n ]),\n );\n}\n\nexport interface JsonRenderTreeProps {\n root?: GenerativeUIElement;\n registry: ComponentRegistry;\n /** json-render state the spec's `$state` expressions read. */\n initialState?: Record<string, unknown>;\n}\n\n/** Render a tree frame's `root` with json-render. */\nexport function JsonRenderTree({ root, registry, initialState }: JsonRenderTreeProps) {\n const spec = useMemo(() => (root === undefined ? null : treeToJsonRenderSpec(root)), [root]);\n if (spec === null) return null;\n return (\n <JSONUIProvider registry={registry} {...(initialState !== undefined ? { initialState } : {})}>\n <Renderer spec={spec as never} registry={registry} />\n </JSONUIProvider>\n );\n}\n\n/** A registry entry for `genui:tree` that renders through json-render with `registry`. */\nexport function jsonRenderTree(registry: ComponentRegistry): GenuiRenderer<{\n root?: GenerativeUIElement;\n}> {\n return function JsonRenderTreeFrame({ root }: { root?: GenerativeUIElement }) {\n return <JsonRenderTree registry={registry} {...(root !== undefined ? { root } : {})} />;\n };\n}\n\nexport interface GenuiProviderProps extends BaseGenuiProviderProps {\n /**\n * Draw composed tree frames through json-render: pass your json-render registry, or `true` to\n * derive one from `registry` ({@link toJsonRenderRegistry}). Omitted → trees render natively.\n * An explicit `treeRenderer` wins over it.\n */\n jsonRender?: ComponentRegistry | true;\n}\n\n/** `GenuiProvider` from `/genui`, plus the {@link GenuiProviderProps.jsonRender} option. */\nexport function GenuiProvider({ jsonRender, treeRenderer, registry, ...rest }: GenuiProviderProps) {\n const derived = useMemo(() => {\n if (jsonRender === undefined) return undefined;\n return jsonRenderTree(jsonRender === true ? toJsonRenderRegistry(registry ?? {}) : jsonRender);\n }, [jsonRender, registry]);\n const tree = treeRenderer ?? derived;\n return (\n <BaseGenuiProvider\n {...rest}\n {...(registry !== undefined ? { registry } : {})}\n {...(tree !== undefined ? { treeRenderer: tree } : {})}\n />\n );\n}\n","import {\n Component,\n type Context,\n type ErrorInfo,\n type ReactNode,\n createContext,\n useCallback,\n useContext,\n useMemo,\n} from 'react';\nimport { AmbientRenderUiContext, sharedContext } from '../components/ambient-ui.js';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\nimport type {\n GenerativeUIElement,\n GenerativeUIItem,\n GenerativeUIOptions,\n GenerativeUIProblem,\n GenerativeUIState,\n GenuiNodeState,\n GenuiPlaceholder,\n GenuiRegistry,\n GenuiRenderer,\n} from './types.js';\nimport {\n useGenerativeUIState,\n useResolvedComponent,\n useValidatedProps,\n} from './use-generative-ui.js';\n\n/** What to draw instead of a component that did not render. Default: nothing. */\nexport type GenerativeUIFallback = ReactNode | ((problem: GenerativeUIProblem) => ReactNode);\n\ninterface TreeScope {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n options: GenerativeUIOptions;\n fallback: GenerativeUIFallback | undefined;\n loading: ReactNode;\n placeholder: GenuiPlaceholder | undefined;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n}\n\nconst TreeScopeContext = createContext<TreeScope | null>(null);\n\n// Shared by key, like the provider's: a renderer imports the hook from `/genui` while the tree may\n// be drawn by the `/genui/json-render` bundle's copy of this module.\nconst GenuiNodeContext: Context<GenuiNodeState | null> = sharedContext<GenuiNodeState>(\n '@dudousxd/nestjs-agent-react:genui-node',\n);\n\n/**\n * The tree node being rendered — read it in a renderer to draw a skeleton while the model is still\n * writing the node (`incomplete`), e.g. a chart's axes before its data. `null` outside a tree.\n *\n * ```tsx\n * function Chart(props: ChartProps) {\n * const node = useGenuiNode();\n * if (node?.incomplete && !props.data?.length) return <ChartSkeleton title={props.title} />;\n * return <BarChart {...props} />;\n * }\n * ```\n */\nexport function useGenuiNode(): GenuiNodeState | null {\n return useContext(GenuiNodeContext);\n}\n\nfunction renderPlaceholder(scope: TreeScope, node: GenuiNodeState): ReactNode {\n const { placeholder } = scope;\n if (typeof placeholder === 'function') return placeholder(node);\n return placeholder !== undefined ? placeholder : scope.loading;\n}\n\nfunction renderFallback(fallback: GenerativeUIFallback | undefined, problem: GenerativeUIProblem) {\n if (typeof fallback === 'function') return fallback(problem);\n if (fallback !== undefined) return fallback;\n return problem.item.fallbackText !== undefined ? (\n <span style={{ whiteSpace: 'pre-wrap' }}>{problem.item.fallbackText}</span>\n ) : null;\n}\n\ninterface BoundaryProps {\n item: GenerativeUIItem;\n fallback: GenerativeUIFallback | undefined;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n children: ReactNode;\n}\n\n/** One failing renderer takes down its own item, never the message around it. */\nclass ItemBoundary extends Component<BoundaryProps, { error: unknown; failed: boolean }> {\n override state = { error: undefined as unknown, failed: false };\n\n static getDerivedStateFromError(error: unknown) {\n return { error, failed: true };\n }\n\n override componentDidCatch(error: unknown, _info: ErrorInfo) {\n this.props.onError?.(error, this.props.item);\n }\n\n override componentDidUpdate(previous: BoundaryProps) {\n // New props for the same item (a streamed update) get a fresh chance to render.\n if (this.state.failed && previous.item !== this.props.item) {\n this.setState({ error: undefined, failed: false });\n }\n }\n\n override render() {\n if (this.state.failed) {\n return renderFallback(this.props.fallback, {\n reason: 'error',\n item: this.props.item,\n error: this.state.error,\n });\n }\n return this.props.children;\n }\n}\n\nfunction nodeItem(node: GenerativeUIElement, id: string): GenerativeUIItem {\n return { id, component: node.type, props: node.props ?? {}, version: null, toolCallId: null };\n}\n\n/** One tree node: resolved and validated like a top-level item, children rendered as its `children`. */\nfunction TreeNode({ node, id }: { node: GenerativeUIElement; id: string }) {\n const scope = useContext(TreeScopeContext);\n const item = useMemo(() => nodeItem(node, id), [node, id]);\n // A node of a preview the model is still writing: its props are half there, so they are not\n // validated (the final frame is) — the renderer is told instead, through `useGenuiNode`.\n const incomplete = node.incomplete === true;\n const held = node.held === true;\n const state = useMemo<GenuiNodeState>(\n () => ({ id, type: node.type, incomplete, held }),\n [id, node.type, incomplete, held],\n );\n const storedVersion = scope?.componentVersions?.[node.type];\n const definition = scope?.options.catalog?.get?.(node.type);\n const incompatible =\n storedVersion !== undefined &&\n definition !== undefined &&\n storedVersion !== (definition.version ?? 1);\n const resolution = useResolvedComponent(\n node.type,\n storedVersion ?? null,\n incompatible ? {} : (scope?.options.registry ?? {}),\n scope?.options.resolveComponent,\n );\n const validation = useValidatedProps(\n incompatible || incomplete ? undefined : scope?.options.catalog,\n node.type,\n item.props,\n );\n if (scope === null) return null;\n if (held) {\n return (\n <GenuiNodeContext.Provider value={state}>\n {renderPlaceholder(scope, state)}\n </GenuiNodeContext.Provider>\n );\n }\n if (resolution.status === 'loading' || validation.status === 'pending') return scope.loading;\n if (resolution.status === 'unknown') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n throw new Error('Unknown tree component');\n return renderFallback(scope.fallback, { reason: 'unknown', item });\n }\n if (resolution.status === 'error') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined) throw resolution.error;\n return renderFallback(scope.fallback, { reason: 'error', item, error: resolution.error });\n }\n if (validation.status === 'invalid') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n throw new Error('Invalid tree component');\n return renderFallback(scope.fallback, { reason: 'invalid', item, issues: validation.issues });\n }\n const Renderer = resolution.Component;\n const children = Array.isArray(node.children) ? node.children : [];\n return (\n <GenuiNodeContext.Provider value={state}>\n <Renderer {...validation.props}>\n {children.length > 0\n ? children.map((child, index) => {\n const childId = `${id}.${index}`;\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n return <TreeNode key={childId} node={child} id={childId} />;\n return (\n <ItemBoundary\n key={childId}\n item={nodeItem(child, childId)}\n fallback={scope.fallback}\n onError={scope.onError}\n >\n <TreeNode node={child} id={childId} />\n </ItemBoundary>\n );\n })\n : undefined}\n </Renderer>\n </GenuiNodeContext.Provider>\n );\n}\n\n/**\n * Renders a `genui:tree` frame's `{ root }` node by node through the same registry, catalog and\n * resolver as top-level components. Used automatically for tree frames unless a `treeRenderer`\n * (e.g. the json-render one) or a registry entry for `genui:tree` takes over.\n */\nexport function GenuiTree({ root }: { root?: GenerativeUIElement }) {\n if (root === undefined || root === null || typeof root.type !== 'string') return null;\n return <TreeNode node={root} id=\"root\" />;\n}\n\nexport interface GenerativeUIScopeProps extends GenerativeUIOptions {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n /** Drawn for a tree node held back while the model writes it. Default: `loading`. */\n placeholder?: GenuiPlaceholder;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n children?: ReactNode;\n}\n\n/**\n * The registry, catalog and fallbacks tree nodes render with. `<GenerativeUI>` provides it; wrap\n * your own chrome in it when you draw `useGenerativeUI`'s `Component` yourself and it may be a tree.\n */\nexport function GenerativeUIScope({\n registry,\n catalog,\n resolveComponent,\n fallback,\n fallbackText,\n componentVersions,\n loading = null,\n placeholder,\n onError,\n children,\n}: GenerativeUIScopeProps) {\n const scope = useMemo<TreeScope>(\n () => ({\n options: {\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n },\n fallback,\n ...(componentVersions !== undefined ? { componentVersions } : {}),\n ...(fallbackText !== undefined ? { fallbackText } : {}),\n loading,\n placeholder,\n onError,\n }),\n [\n registry,\n catalog,\n resolveComponent,\n fallback,\n fallbackText,\n componentVersions,\n loading,\n placeholder,\n onError,\n ],\n );\n return <TreeScopeContext.Provider value={scope}>{children}</TreeScopeContext.Provider>;\n}\n\n/** What `<GenuiProvider>` hands every `<GenerativeUI>` / `useGenerativeUI` below it. */\nexport interface GenuiProviderValue extends Partial<GenerativeUIOptions> {\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n /** Drawn for a tree node held back while the model writes it (`streaming: 'complete'`). */\n placeholder?: GenuiPlaceholder;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n// Shared by key: `/genui` and `/genui/json-render` are separate bundles, and a provider from one\n// must reach a `<GenerativeUI>` from the other.\nconst GenuiContext: Context<GenuiProviderValue | null> = sharedContext<GenuiProviderValue>(\n '@dudousxd/nestjs-agent-react:genui-provider',\n);\n\n/** The enclosing `<GenuiProvider>`'s settings, or `null` outside one. */\nexport function useGenuiProvider(): GenuiProviderValue | null {\n return useContext(GenuiContext);\n}\n\nexport interface GenuiProviderProps extends GenuiProviderValue {\n children?: ReactNode;\n}\n\n/**\n * Set generative UI up once, at the app root: the registry of your renderers, the catalog to\n * validate against, a resolver for components the registry lacks, and what to draw when one does\n * not render. Every `<GenerativeUI>` below reads it (its own props still win), and `MessageItem` /\n * `MessageList` draw pushed components with it — no `renderUi` per message.\n *\n * ```tsx\n * <GenuiProvider registry={registry} catalog={catalog} fallback={({ item }) => <Unknown name={item.component} />}>\n * <App />\n * </GenuiProvider>\n * ```\n */\nexport function GenuiProvider({\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback,\n loading,\n placeholder,\n onError,\n children,\n}: GenuiProviderProps) {\n const value = useMemo<GenuiProviderValue>(\n () => ({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n ...(fallback !== undefined ? { fallback } : {}),\n ...(loading !== undefined ? { loading } : {}),\n ...(placeholder !== undefined ? { placeholder } : {}),\n ...(onError !== undefined ? { onError } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer, fallback, loading, placeholder, onError],\n );\n const renderUi = useCallback((block: TranscriptUiBlock) => <GenerativeUI part={block} />, []);\n return (\n <GenuiContext.Provider value={value}>\n <AmbientRenderUiContext.Provider value={renderUi}>{children}</AmbientRenderUiContext.Provider>\n </GenuiContext.Provider>\n );\n}\n\nconst NO_REGISTRY: GenuiRegistry = {};\n\n/** Provider settings overlaid with explicit ones (explicit wins), memoized on their parts. */\nfunction useMergedOptions(own: Partial<GenerativeUIOptions>): GenerativeUIOptions {\n const provided = useContext(GenuiContext);\n const registry = own.registry ?? provided?.registry ?? NO_REGISTRY;\n const catalog = own.catalog ?? provided?.catalog;\n const resolveComponent = own.resolveComponent ?? provided?.resolveComponent;\n const treeRenderer = own.treeRenderer ?? provided?.treeRenderer;\n return useMemo(\n () => ({\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer],\n );\n}\n\n/**\n * The headless half of {@link GenerativeUI}: what to draw for one pushed component, or `null` when\n * `part` is not one. Options default to the enclosing `<GenuiProvider>`'s.\n */\nexport function useGenerativeUI(\n part: unknown,\n options: Partial<GenerativeUIOptions> = {},\n): GenerativeUIState | null {\n const merged = useMergedOptions(options);\n return useGenerativeUIState(part, merged, merged.treeRenderer ?? (GenuiTree as GenuiRenderer));\n}\n\nexport interface GenerativeUIProps extends Partial<GenerativeUIOptions> {\n /** A transcript `ui` block, a `data-ui` message part, or a stored `{ id, component, props, version? }`. */\n part: TranscriptUiBlock | GenerativeUIItem | unknown;\n /** Drawn for an unknown component, invalid props, or a renderer that threw. Default: the provider's, then the item's persisted text. */\n fallback?: GenerativeUIFallback;\n /** Drawn while a resolver or an async validation is pending. Default: the provider's, else nothing. */\n loading?: ReactNode;\n /**\n * Drawn for a tree node held back while the model writes it (its component streams `complete`).\n * Default: the provider's, else `loading`.\n */\n placeholder?: GenuiPlaceholder;\n /** A renderer threw (the item shows `fallback`). */\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n/**\n * Draws one server-pushed component with the app's own renderer. Headless: it adds no element and\n * no style of its own — only what the registry's component renders (and whatever `fallback` /\n * `loading` you pass). Everything but `part` defaults to the enclosing `<GenuiProvider>`.\n *\n * ```tsx\n * <GenerativeUI part={block} />\n * ```\n */\nexport function GenerativeUI({\n part,\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback: ownFallback,\n loading: ownLoading,\n placeholder: ownPlaceholder,\n onError: ownOnError,\n}: GenerativeUIProps) {\n const provided = useContext(GenuiContext);\n const fallback = ownFallback !== undefined ? ownFallback : provided?.fallback;\n const loading = ownLoading ?? provided?.loading ?? null;\n const placeholder = ownPlaceholder !== undefined ? ownPlaceholder : provided?.placeholder;\n const onError = ownOnError ?? provided?.onError;\n const options = useMergedOptions({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n });\n const state = useGenerativeUIState(\n part,\n options,\n options.treeRenderer ?? (GenuiTree as GenuiRenderer),\n );\n if (state === null) return null;\n if (state.status === 'loading') return loading;\n if (state.status === 'problem') {\n const { status: _status, ...problem } = state;\n return renderFallback(fallback, problem);\n }\n const Renderer = state.Component;\n return (\n <GenerativeUIScope\n {...options}\n {...(state.item.componentVersions !== undefined\n ? { componentVersions: state.item.componentVersions }\n : {})}\n {...(state.item.fallbackText !== undefined ? { fallbackText: state.item.fallbackText } : {})}\n fallback={fallback}\n loading={loading}\n {...(placeholder !== undefined ? { placeholder } : {})}\n {...(onError !== undefined ? { onError } : {})}\n >\n <ItemBoundary item={state.item} fallback={fallback} onError={onError}>\n <Renderer {...state.props} />\n </ItemBoundary>\n </GenerativeUIScope>\n );\n}\n","import { type Context, type ReactNode, createContext, useContext } from 'react';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\n\n/** Draws a server-pushed component block. */\nexport type AmbientRenderUi = (block: TranscriptUiBlock) => ReactNode;\n\n/**\n * A context stored on `globalThis` under a registered symbol. Each entry point (`.`, `/genui`,\n * `/genui/json-render`) is its own bundle with its own copy of every module, so a context one entry\n * provides and another reads has to be found by key, not by module identity.\n */\nexport function sharedContext<T>(key: string): Context<T | null> {\n const symbol = Symbol.for(key);\n const holder = globalThis as Record<symbol, Context<T | null> | undefined>;\n const existing = holder[symbol];\n if (existing !== undefined) return existing;\n const created = createContext<T | null>(null);\n holder[symbol] = created;\n return created;\n}\n\n/**\n * How pushed components are drawn when no `renderUi` is passed — set by `<GenuiProvider>` (the\n * `/genui` subpath) and read by `MessageItem`.\n */\nexport const AmbientRenderUiContext: Context<AmbientRenderUi | null> =\n sharedContext<AmbientRenderUi>('@dudousxd/nestjs-agent-react:ambient-render-ui');\n\n/**\n * The renderer `<GenuiProvider>` installed for pushed components, or `null` outside one. For a\n * custom transcript built on `useTranscriptItem`: draw a `ui` block with it and you get what\n * `MessageItem` draws.\n */\nexport function useAmbientRenderUi(): AmbientRenderUi | null {\n return useContext(AmbientRenderUiContext);\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n GENUI_TREE_COMPONENT,\n type GenerativeUIItem,\n type GenerativeUIOptions,\n type GenerativeUIState,\n type GenuiCatalogLike,\n type GenuiIssueLike,\n type GenuiRegistry,\n type GenuiRenderer,\n type ResolveComponent,\n} from './types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Normalize whatever carries a pushed component: a transcript `ui` block, a `data-ui` message part\n * (`{ type: 'data-ui', id, data }`), a stored `{ id, component, props, version? }` entry. `null` for\n * anything else.\n */\nexport function toGenerativeUIItem(part: unknown): GenerativeUIItem | null {\n if (!isRecord(part)) return null;\n const source = part.type === 'data-ui' && isRecord(part.data) ? part.data : part;\n if (typeof source.component !== 'string') return null;\n const id =\n typeof source.id === 'string' ? source.id : typeof part.id === 'string' ? part.id : null;\n if (id === null) return null;\n return {\n id,\n component: source.component,\n ...(isRecord(source.componentVersions) &&\n Object.values(source.componentVersions).every(\n (version) => typeof version === 'number' && Number.isSafeInteger(version) && version > 0,\n )\n ? { componentVersions: { ...source.componentVersions } as Record<string, number> }\n : {}),\n ...(typeof source.fallbackText === 'string' ? { fallbackText: source.fallbackText } : {}),\n props: isRecord(source.props) ? source.props : {},\n version: typeof source.version === 'number' ? source.version : null,\n toolCallId: typeof source.toolCallId === 'string' ? source.toolCallId : null,\n ...(source.partial === true ? { partial: true as const } : {}),\n };\n}\n\ntype Resolution =\n | { status: 'ready'; Component: GenuiRenderer }\n | { status: 'loading' }\n | { status: 'unknown' }\n | { status: 'error'; error: unknown };\n\ninterface CacheEntry {\n resolution: Resolution;\n settled: Promise<void> | null;\n}\n\nconst resolverCaches = new WeakMap<ResolveComponent, Map<string, CacheEntry>>();\n\nfunction resolveCached(\n resolve: ResolveComponent,\n name: string,\n version: number | null,\n): CacheEntry {\n let cache = resolverCaches.get(resolve);\n if (cache === undefined) {\n cache = new Map();\n resolverCaches.set(resolve, cache);\n }\n const key = `${name}@${version ?? ''}`;\n const hit = cache.get(key);\n if (hit !== undefined) return hit;\n let entry: CacheEntry;\n try {\n const result = resolve(name, version);\n if (result instanceof Promise) {\n entry = { resolution: { status: 'loading' }, settled: null };\n entry.settled = result.then(\n (Component) => {\n entry.resolution = Component ? { status: 'ready', Component } : { status: 'unknown' };\n },\n (error: unknown) => {\n entry.resolution = { status: 'error', error };\n },\n );\n } else {\n entry = {\n resolution: result ? { status: 'ready', Component: result } : { status: 'unknown' },\n settled: null,\n };\n }\n } catch (error) {\n entry = { resolution: { status: 'error', error }, settled: null };\n }\n cache.set(key, entry);\n return entry;\n}\n\n/**\n * Which renderer draws `name`: the registry first, then `resolveComponent` (cached; async results\n * re-render the caller when they land). `fallbackTree` answers the tree component when the\n * registry does not override it.\n */\nexport function useResolvedComponent(\n name: string,\n version: number | null,\n registry: GenuiRegistry,\n resolve: ResolveComponent | undefined,\n fallbackTree?: GenuiRenderer,\n): Resolution {\n const [, setTick] = useState(0);\n const own = registry[name];\n const entry =\n own !== undefined || resolve === undefined ? null : resolveCached(resolve, name, version);\n const pending = entry?.resolution.status === 'loading' ? entry.settled : null;\n useEffect(() => {\n if (pending === null) return;\n let live = true;\n void pending.then(() => {\n if (live) setTick((tick) => tick + 1);\n });\n return () => {\n live = false;\n };\n }, [pending]);\n if (own !== undefined) return { status: 'ready', Component: own };\n if (entry !== null && entry.resolution.status !== 'unknown') return entry.resolution;\n if (name === GENUI_TREE_COMPONENT && fallbackTree !== undefined) {\n return { status: 'ready', Component: fallbackTree };\n }\n return { status: 'unknown' };\n}\n\ntype Validation =\n | { status: 'ok'; props: Record<string, unknown> }\n | { status: 'pending' }\n | { status: 'invalid'; issues: GenuiIssueLike[] };\n\n/**\n * Props checked against the catalog: synchronously when the catalog can (`validateSync`), else\n * after the async check settles. A component the catalog does not know passes through unchecked.\n */\nexport function useValidatedProps(\n catalog: GenuiCatalogLike | undefined,\n name: string,\n props: Record<string, unknown>,\n): Validation {\n const checked = catalog?.has(name) === true;\n const immediate = useMemo<Validation | null>(() => {\n if (!checked || catalog === undefined) return { status: 'ok', props };\n const result = catalog.validateSync?.(name, props);\n if (result === undefined) return null;\n return result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues };\n }, [checked, catalog, name, props]);\n const [late, setLate] = useState<{ props: Record<string, unknown>; result: Validation } | null>(\n null,\n );\n useEffect(() => {\n if (immediate !== null || catalog === undefined) return;\n let live = true;\n catalog.validate(name, props).then(\n (result) => {\n if (!live) return;\n setLate({\n props,\n result: result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues },\n });\n },\n (error: unknown) => {\n if (!live) return;\n setLate({\n props,\n result: {\n status: 'invalid',\n issues: [{ path: [], message: error instanceof Error ? error.message : String(error) }],\n },\n });\n },\n );\n return () => {\n live = false;\n };\n }, [immediate, catalog, name, props]);\n if (immediate !== null) return immediate;\n return late !== null && late.props === props ? late.result : { status: 'pending' };\n}\n\n/** {@link import('./generative-ui.js').useGenerativeUI}, with the tree renderer handed in (avoids an import cycle). */\nexport function useGenerativeUIState(\n part: unknown,\n options: GenerativeUIOptions,\n fallbackTree: GenuiRenderer | undefined,\n): GenerativeUIState | null {\n const item = useMemo(() => toGenerativeUIItem(part), [part]);\n const name = item?.component ?? '';\n const definition = options.catalog?.get?.(name);\n const incompatible =\n item?.fallbackText !== undefined &&\n item.version !== null &&\n definition !== undefined &&\n item.version !== (definition.version ?? 1);\n const resolution = useResolvedComponent(\n name,\n item?.version ?? null,\n incompatible ? {} : options.registry,\n item === null ? undefined : options.resolveComponent,\n fallbackTree,\n );\n const empty = useMemo<Record<string, unknown>>(() => ({}), []);\n // A tree is validated node by node as it renders, not as one component.\n const validation = useValidatedProps(\n item === null || name === GENUI_TREE_COMPONENT || incompatible ? undefined : options.catalog,\n name,\n item?.props ?? empty,\n );\n if (item === null) return null;\n // A withdrawn preview (partial, nothing to draw): the call will not replace it.\n if (item.partial === true && Object.keys(item.props).length === 0) return null;\n if (\n name === GENUI_TREE_COMPONENT &&\n item.fallbackText !== undefined &&\n (!isRecord(item.props.root) || typeof item.props.root.type !== 'string')\n )\n return {\n status: 'problem',\n reason: 'invalid',\n item,\n issues: [{ path: ['root'], message: 'Invalid UI tree root' }],\n };\n if (resolution.status === 'loading') return { status: 'loading', item };\n if (resolution.status === 'unknown') return { status: 'problem', reason: 'unknown', item };\n if (resolution.status === 'error') {\n return { status: 'problem', reason: 'error', item, error: resolution.error };\n }\n if (validation.status === 'pending') return { status: 'loading', item };\n if (validation.status === 'invalid') {\n return { status: 'problem', reason: 'invalid', item, issues: validation.issues };\n }\n return { status: 'ready', item, Component: resolution.Component, props: validation.props };\n}\n","import type { ComponentType, ReactNode } from 'react';\n\n/** The `ui` frame component a composed tree is pushed under (`GENUI_TREE_COMPONENT` of `@dudousxd/nestjs-agent-core/genui`). */\nexport const GENUI_TREE_COMPONENT = 'genui:tree';\n\n/** One pushed component, normalized from whatever carried it (a transcript block, a `data-ui` part, a stored entry). */\nexport interface GenerativeUIItem {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n id: string;\n component: string;\n props: Record<string, unknown>;\n version: number | null;\n toolCallId: string | null;\n /**\n * A preview drawn while the model is still writing the call (genui `streaming: 'partial'`):\n * unvalidated, and replaced in place by the final frame under the same `id`.\n */\n partial?: true;\n}\n\n/** A node of a composed tree (`genui:tree` frames): `{ type, props, children? }`. */\nexport interface GenerativeUIElement {\n type: string;\n props: Record<string, unknown>;\n children?: GenerativeUIElement[];\n /**\n * The node's position (`root`, `root.0`, `root.0.2`), carried by partial frames. Stable as the\n * tree grows, and the same rule names the final tree's nodes.\n */\n id?: string;\n /** Partial frames only: the model has not finished writing this node. */\n incomplete?: true;\n /** Partial frames only: a `streaming: 'complete'` component held back until it closes (no props). */\n held?: true;\n}\n\n/**\n * What a tree node's renderer can learn about its node ({@link useGenuiNode}): which node it is,\n * and whether the model is still writing it. Room is left for more states (data a node is bound\n * to, loading) as separate fields — `incomplete` only ever means \"still being written\".\n */\nexport interface GenuiNodeState {\n /** The node's position id (`root`, `root.1.0`): stable from the first preview to the final frame. */\n id: string;\n type: string;\n /** The model has not finished writing this node: props (and children) may still grow. */\n incomplete: boolean;\n /** The node is a placeholder for a component that is only drawn whole (`streaming: 'complete'`). */\n held: boolean;\n}\n\n/**\n * An app's renderer for one component: it receives the component's props spread, plus `children`\n * when it is a layout node in a tree. Any React component — the library never styles anything.\n */\nexport type GenuiRenderer<P = any> = ComponentType<P & { children?: ReactNode }>;\n\n/** Component name → the app's renderer. */\nexport type GenuiRegistry = Record<string, GenuiRenderer>;\n\n/**\n * Resolve a component the registry does not have — typically a tenant's own component, fetched for\n * the exact `version` a message was rendered with. Return `null`/`undefined` for \"no such\n * component\". May be async; results are cached per resolver, name and version.\n */\nexport type ResolveComponent = (\n name: string,\n version: number | null,\n) => GenuiRenderer | null | undefined | Promise<GenuiRenderer | null | undefined>;\n\nexport interface GenuiIssueLike {\n path: (string | number)[];\n message: string;\n}\n\ntype ValidationLike =\n | { ok: true; value: Record<string, unknown> }\n | { ok: false; issues: GenuiIssueLike[] };\n\n/**\n * What the renderer needs from a catalog to validate props before drawing them. A `Catalog` from\n * `@dudousxd/nestjs-agent-core/genui` satisfies it; declared structurally so any catalog-shaped\n * object does too.\n */\nexport interface GenuiCatalogLike {\n get?(name: string): { version?: number } | undefined;\n has(name: string): boolean;\n validate(name: string, props: unknown): Promise<ValidationLike>;\n validateSync?(name: string, props: unknown): ValidationLike | undefined;\n}\n\nexport interface GenerativeUIOptions {\n registry: GenuiRegistry;\n /** Validate props against it before rendering. Components the catalog does not know render unvalidated. */\n catalog?: GenuiCatalogLike;\n resolveComponent?: ResolveComponent;\n /**\n * Draws a composed tree frame (`genui:tree`) whole — e.g. through json-render (see the\n * `/genui/json-render` subpath's `GenuiProvider`). Omitted → trees render node by node through\n * `registry`.\n */\n treeRenderer?: GenuiRenderer<{ root?: GenerativeUIElement }>;\n}\n\n/**\n * Drawn in place of a tree node that is not drawable yet — a `held` node (its component streams\n * `complete`) while the model writes it. Default: the `loading` element.\n */\nexport type GenuiPlaceholder = ReactNode | ((node: GenuiNodeState) => ReactNode);\n\n/** Why an item did not render. */\nexport type GenerativeUIProblem =\n | { reason: 'unknown'; item: GenerativeUIItem }\n | { reason: 'invalid'; item: GenerativeUIItem; issues: GenuiIssueLike[] }\n | { reason: 'error'; item: GenerativeUIItem; error: unknown };\n\nexport type GenerativeUIState =\n | {\n status: 'ready';\n item: GenerativeUIItem;\n Component: GenuiRenderer;\n props: Record<string, unknown>;\n }\n | { status: 'loading'; item: GenerativeUIItem }\n | ({ status: 'problem' } & GenerativeUIProblem);\n"],"mappings":"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","names":["useMemo","createContext","useContext","useMemo","Component","createContext","useContext","useMemo","Renderer","useMemo","useContext","useContext","Renderer","jsx","Renderer","useMemo","GenuiProvider"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Browser, LaunchOptions } from 'playwright-core';
|
|
2
2
|
import { CaptureAdapter } from './genui-server.cjs';
|
|
3
3
|
import '@dudousxd/nestjs-agent-core/genui';
|
|
4
|
-
import './react-registry-
|
|
4
|
+
import './react-registry-R0eFtDCG.cjs';
|
|
5
5
|
import 'react';
|
|
6
|
-
import './types-
|
|
6
|
+
import './types-COuArD3c.cjs';
|
|
7
7
|
|
|
8
8
|
interface PlaywrightCaptureOptions {
|
|
9
9
|
/** Caller-owned browser; the adapter closes only its own contexts and pages. */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Browser, LaunchOptions } from 'playwright-core';
|
|
2
2
|
import { CaptureAdapter } from './genui-server.js';
|
|
3
3
|
import '@dudousxd/nestjs-agent-core/genui';
|
|
4
|
-
import './react-registry-
|
|
4
|
+
import './react-registry-CC84Jm3U.js';
|
|
5
5
|
import 'react';
|
|
6
|
-
import './types-
|
|
6
|
+
import './types-COuArD3c.js';
|
|
7
7
|
|
|
8
8
|
interface PlaywrightCaptureOptions {
|
|
9
9
|
/** Caller-owned browser; the adapter closes only its own contexts and pages. */
|
package/dist/genui-server.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ComponentPresentation } from '@dudousxd/nestjs-agent-core/genui';
|
|
2
|
-
import { R as ReactComponentRegistry } from './react-registry-
|
|
3
|
-
export { c as createReactComponentRegistry } from './react-registry-
|
|
2
|
+
import { R as ReactComponentRegistry } from './react-registry-R0eFtDCG.cjs';
|
|
3
|
+
export { c as createReactComponentRegistry } from './react-registry-R0eFtDCG.cjs';
|
|
4
4
|
import 'react';
|
|
5
|
-
import './types-
|
|
5
|
+
import './types-COuArD3c.cjs';
|
|
6
6
|
|
|
7
7
|
interface CaptureOptions {
|
|
8
8
|
width?: number;
|
package/dist/genui-server.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ComponentPresentation } from '@dudousxd/nestjs-agent-core/genui';
|
|
2
|
-
import { R as ReactComponentRegistry } from './react-registry-
|
|
3
|
-
export { c as createReactComponentRegistry } from './react-registry-
|
|
2
|
+
import { R as ReactComponentRegistry } from './react-registry-CC84Jm3U.js';
|
|
3
|
+
export { c as createReactComponentRegistry } from './react-registry-CC84Jm3U.js';
|
|
4
4
|
import 'react';
|
|
5
|
-
import './types-
|
|
5
|
+
import './types-COuArD3c.js';
|
|
6
6
|
|
|
7
7
|
interface CaptureOptions {
|
|
8
8
|
width?: number;
|
package/dist/genui.cjs
CHANGED
|
@@ -28,6 +28,7 @@ __export(genui_exports, {
|
|
|
28
28
|
createReactComponentRegistry: () => createReactComponentRegistry,
|
|
29
29
|
toGenerativeUIItem: () => toGenerativeUIItem,
|
|
30
30
|
useGenerativeUI: () => useGenerativeUI,
|
|
31
|
+
useGenuiNode: () => useGenuiNode,
|
|
31
32
|
useGenuiProvider: () => useGenuiProvider
|
|
32
33
|
});
|
|
33
34
|
module.exports = __toCommonJS(genui_exports);
|
|
@@ -73,7 +74,8 @@ function toGenerativeUIItem(part) {
|
|
|
73
74
|
...typeof source.fallbackText === "string" ? { fallbackText: source.fallbackText } : {},
|
|
74
75
|
props: isRecord(source.props) ? source.props : {},
|
|
75
76
|
version: typeof source.version === "number" ? source.version : null,
|
|
76
|
-
toolCallId: typeof source.toolCallId === "string" ? source.toolCallId : null
|
|
77
|
+
toolCallId: typeof source.toolCallId === "string" ? source.toolCallId : null,
|
|
78
|
+
...source.partial === true ? { partial: true } : {}
|
|
77
79
|
};
|
|
78
80
|
}
|
|
79
81
|
var resolverCaches = /* @__PURE__ */ new WeakMap();
|
|
@@ -192,6 +194,7 @@ function useGenerativeUIState(part, options, fallbackTree) {
|
|
|
192
194
|
item?.props ?? empty
|
|
193
195
|
);
|
|
194
196
|
if (item === null) return null;
|
|
197
|
+
if (item.partial === true && Object.keys(item.props).length === 0) return null;
|
|
195
198
|
if (name === GENUI_TREE_COMPONENT && item.fallbackText !== void 0 && (!isRecord(item.props.root) || typeof item.props.root.type !== "string"))
|
|
196
199
|
return {
|
|
197
200
|
status: "problem",
|
|
@@ -214,6 +217,17 @@ function useGenerativeUIState(part, options, fallbackTree) {
|
|
|
214
217
|
// src/genui/generative-ui.tsx
|
|
215
218
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
216
219
|
var TreeScopeContext = (0, import_react3.createContext)(null);
|
|
220
|
+
var GenuiNodeContext = sharedContext(
|
|
221
|
+
"@dudousxd/nestjs-agent-react:genui-node"
|
|
222
|
+
);
|
|
223
|
+
function useGenuiNode() {
|
|
224
|
+
return (0, import_react3.useContext)(GenuiNodeContext);
|
|
225
|
+
}
|
|
226
|
+
function renderPlaceholder(scope, node) {
|
|
227
|
+
const { placeholder } = scope;
|
|
228
|
+
if (typeof placeholder === "function") return placeholder(node);
|
|
229
|
+
return placeholder !== void 0 ? placeholder : scope.loading;
|
|
230
|
+
}
|
|
217
231
|
function renderFallback(fallback, problem) {
|
|
218
232
|
if (typeof fallback === "function") return fallback(problem);
|
|
219
233
|
if (fallback !== void 0) return fallback;
|
|
@@ -249,6 +263,12 @@ function nodeItem(node, id) {
|
|
|
249
263
|
function TreeNode({ node, id }) {
|
|
250
264
|
const scope = (0, import_react3.useContext)(TreeScopeContext);
|
|
251
265
|
const item = (0, import_react3.useMemo)(() => nodeItem(node, id), [node, id]);
|
|
266
|
+
const incomplete = node.incomplete === true;
|
|
267
|
+
const held = node.held === true;
|
|
268
|
+
const state = (0, import_react3.useMemo)(
|
|
269
|
+
() => ({ id, type: node.type, incomplete, held }),
|
|
270
|
+
[id, node.type, incomplete, held]
|
|
271
|
+
);
|
|
252
272
|
const storedVersion = scope?.componentVersions?.[node.type];
|
|
253
273
|
const definition = scope?.options.catalog?.get?.(node.type);
|
|
254
274
|
const incompatible = storedVersion !== void 0 && definition !== void 0 && storedVersion !== (definition.version ?? 1);
|
|
@@ -259,11 +279,14 @@ function TreeNode({ node, id }) {
|
|
|
259
279
|
scope?.options.resolveComponent
|
|
260
280
|
);
|
|
261
281
|
const validation = useValidatedProps(
|
|
262
|
-
incompatible ? void 0 : scope?.options.catalog,
|
|
282
|
+
incompatible || incomplete ? void 0 : scope?.options.catalog,
|
|
263
283
|
node.type,
|
|
264
284
|
item.props
|
|
265
285
|
);
|
|
266
286
|
if (scope === null) return null;
|
|
287
|
+
if (held) {
|
|
288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GenuiNodeContext.Provider, { value: state, children: renderPlaceholder(scope, state) });
|
|
289
|
+
}
|
|
267
290
|
if (resolution.status === "loading" || validation.status === "pending") return scope.loading;
|
|
268
291
|
if (resolution.status === "unknown") {
|
|
269
292
|
if (scope.fallback === void 0 && scope.fallbackText !== void 0)
|
|
@@ -281,7 +304,7 @@ function TreeNode({ node, id }) {
|
|
|
281
304
|
}
|
|
282
305
|
const Renderer = resolution.Component;
|
|
283
306
|
const children = Array.isArray(node.children) ? node.children : [];
|
|
284
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Renderer, { ...validation.props, children: children.length > 0 ? children.map((child, index) => {
|
|
307
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GenuiNodeContext.Provider, { value: state, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Renderer, { ...validation.props, children: children.length > 0 ? children.map((child, index) => {
|
|
285
308
|
const childId = `${id}.${index}`;
|
|
286
309
|
if (scope.fallback === void 0 && scope.fallbackText !== void 0)
|
|
287
310
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TreeNode, { node: child, id: childId }, childId);
|
|
@@ -295,7 +318,7 @@ function TreeNode({ node, id }) {
|
|
|
295
318
|
},
|
|
296
319
|
childId
|
|
297
320
|
);
|
|
298
|
-
}) : void 0 });
|
|
321
|
+
}) : void 0 }) });
|
|
299
322
|
}
|
|
300
323
|
function GenuiTree({ root }) {
|
|
301
324
|
if (root === void 0 || root === null || typeof root.type !== "string") return null;
|
|
@@ -309,6 +332,7 @@ function GenerativeUIScope({
|
|
|
309
332
|
fallbackText,
|
|
310
333
|
componentVersions,
|
|
311
334
|
loading = null,
|
|
335
|
+
placeholder,
|
|
312
336
|
onError,
|
|
313
337
|
children
|
|
314
338
|
}) {
|
|
@@ -323,6 +347,7 @@ function GenerativeUIScope({
|
|
|
323
347
|
...componentVersions !== void 0 ? { componentVersions } : {},
|
|
324
348
|
...fallbackText !== void 0 ? { fallbackText } : {},
|
|
325
349
|
loading,
|
|
350
|
+
placeholder,
|
|
326
351
|
onError
|
|
327
352
|
}),
|
|
328
353
|
[
|
|
@@ -333,6 +358,7 @@ function GenerativeUIScope({
|
|
|
333
358
|
fallbackText,
|
|
334
359
|
componentVersions,
|
|
335
360
|
loading,
|
|
361
|
+
placeholder,
|
|
336
362
|
onError
|
|
337
363
|
]
|
|
338
364
|
);
|
|
@@ -351,6 +377,7 @@ function GenuiProvider({
|
|
|
351
377
|
treeRenderer,
|
|
352
378
|
fallback,
|
|
353
379
|
loading,
|
|
380
|
+
placeholder,
|
|
354
381
|
onError,
|
|
355
382
|
children
|
|
356
383
|
}) {
|
|
@@ -362,9 +389,10 @@ function GenuiProvider({
|
|
|
362
389
|
...treeRenderer !== void 0 ? { treeRenderer } : {},
|
|
363
390
|
...fallback !== void 0 ? { fallback } : {},
|
|
364
391
|
...loading !== void 0 ? { loading } : {},
|
|
392
|
+
...placeholder !== void 0 ? { placeholder } : {},
|
|
365
393
|
...onError !== void 0 ? { onError } : {}
|
|
366
394
|
}),
|
|
367
|
-
[registry, catalog, resolveComponent, treeRenderer, fallback, loading, onError]
|
|
395
|
+
[registry, catalog, resolveComponent, treeRenderer, fallback, loading, placeholder, onError]
|
|
368
396
|
);
|
|
369
397
|
const renderUi = (0, import_react3.useCallback)((block) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GenerativeUI, { part: block }), []);
|
|
370
398
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GenuiContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AmbientRenderUiContext.Provider, { value: renderUi, children }) });
|
|
@@ -398,11 +426,13 @@ function GenerativeUI({
|
|
|
398
426
|
treeRenderer,
|
|
399
427
|
fallback: ownFallback,
|
|
400
428
|
loading: ownLoading,
|
|
429
|
+
placeholder: ownPlaceholder,
|
|
401
430
|
onError: ownOnError
|
|
402
431
|
}) {
|
|
403
432
|
const provided = (0, import_react3.useContext)(GenuiContext);
|
|
404
433
|
const fallback = ownFallback !== void 0 ? ownFallback : provided?.fallback;
|
|
405
434
|
const loading = ownLoading ?? provided?.loading ?? null;
|
|
435
|
+
const placeholder = ownPlaceholder !== void 0 ? ownPlaceholder : provided?.placeholder;
|
|
406
436
|
const onError = ownOnError ?? provided?.onError;
|
|
407
437
|
const options = useMergedOptions({
|
|
408
438
|
...registry !== void 0 ? { registry } : {},
|
|
@@ -430,6 +460,7 @@ function GenerativeUI({
|
|
|
430
460
|
...state.item.fallbackText !== void 0 ? { fallbackText: state.item.fallbackText } : {},
|
|
431
461
|
fallback,
|
|
432
462
|
loading,
|
|
463
|
+
...placeholder !== void 0 ? { placeholder } : {},
|
|
433
464
|
...onError !== void 0 ? { onError } : {},
|
|
434
465
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ItemBoundary, { item: state.item, fallback, onError, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Renderer, { ...state.props }) })
|
|
435
466
|
}
|
|
@@ -519,6 +550,7 @@ function createReactComponentRegistry(options) {
|
|
|
519
550
|
createReactComponentRegistry,
|
|
520
551
|
toGenerativeUIItem,
|
|
521
552
|
useGenerativeUI,
|
|
553
|
+
useGenuiNode,
|
|
522
554
|
useGenuiProvider
|
|
523
555
|
});
|
|
524
556
|
//# sourceMappingURL=genui.cjs.map
|