@dudousxd/nestjs-agent-react 0.18.0 → 0.19.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.
@@ -1,6 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { ComponentRegistry } from '@json-render/react';
3
- import { c as GenerativeUIElement, i as GenuiRenderer, h as GenuiRegistry } from './types-DFD-soWU.cjs';
3
+ import { n as GenuiProviderProps$1, c as GenerativeUIElement, q as GenuiRenderer, p as GenuiRegistry } from './generative-ui-C53b3FoA.cjs';
4
+ import './model-gHqjNjLJ.cjs';
5
+ import '@dudousxd/nestjs-agent-core';
6
+ import 'ai';
4
7
 
5
8
  /** A json-render flat spec: `{ root, elements: { [id]: { type, props, children } } }`. */
6
9
  interface JsonRenderFlatSpec {
@@ -30,5 +33,15 @@ declare function JsonRenderTree({ root, registry, initialState }: JsonRenderTree
30
33
  declare function jsonRenderTree(registry: ComponentRegistry): GenuiRenderer<{
31
34
  root?: GenerativeUIElement;
32
35
  }>;
36
+ interface GenuiProviderProps extends GenuiProviderProps$1 {
37
+ /**
38
+ * Draw composed tree frames through json-render: pass your json-render registry, or `true` to
39
+ * derive one from `registry` ({@link toJsonRenderRegistry}). Omitted → trees render natively.
40
+ * An explicit `treeRenderer` wins over it.
41
+ */
42
+ jsonRender?: ComponentRegistry | true;
43
+ }
44
+ /** `GenuiProvider` from `/genui`, plus the {@link GenuiProviderProps.jsonRender} option. */
45
+ declare function GenuiProvider({ jsonRender, treeRenderer, registry, ...rest }: GenuiProviderProps): React.JSX.Element;
33
46
 
34
- export { type JsonRenderFlatSpec, JsonRenderTree, type JsonRenderTreeProps, jsonRenderTree, toJsonRenderRegistry, treeToJsonRenderSpec };
47
+ export { GenuiProvider, type GenuiProviderProps, type JsonRenderFlatSpec, JsonRenderTree, type JsonRenderTreeProps, jsonRenderTree, toJsonRenderRegistry, treeToJsonRenderSpec };
@@ -1,6 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { ComponentRegistry } from '@json-render/react';
3
- import { c as GenerativeUIElement, i as GenuiRenderer, h as GenuiRegistry } from './types-DFD-soWU.js';
3
+ import { n as GenuiProviderProps$1, c as GenerativeUIElement, q as GenuiRenderer, p as GenuiRegistry } from './generative-ui-BhXFni8j.js';
4
+ import './model-gHqjNjLJ.js';
5
+ import '@dudousxd/nestjs-agent-core';
6
+ import 'ai';
4
7
 
5
8
  /** A json-render flat spec: `{ root, elements: { [id]: { type, props, children } } }`. */
6
9
  interface JsonRenderFlatSpec {
@@ -30,5 +33,15 @@ declare function JsonRenderTree({ root, registry, initialState }: JsonRenderTree
30
33
  declare function jsonRenderTree(registry: ComponentRegistry): GenuiRenderer<{
31
34
  root?: GenerativeUIElement;
32
35
  }>;
36
+ interface GenuiProviderProps extends GenuiProviderProps$1 {
37
+ /**
38
+ * Draw composed tree frames through json-render: pass your json-render registry, or `true` to
39
+ * derive one from `registry` ({@link toJsonRenderRegistry}). Omitted → trees render natively.
40
+ * An explicit `treeRenderer` wins over it.
41
+ */
42
+ jsonRender?: ComponentRegistry | true;
43
+ }
44
+ /** `GenuiProvider` from `/genui`, plus the {@link GenuiProviderProps.jsonRender} option. */
45
+ declare function GenuiProvider({ jsonRender, treeRenderer, registry, ...rest }: GenuiProviderProps): React.JSX.Element;
33
46
 
34
- export { type JsonRenderFlatSpec, JsonRenderTree, type JsonRenderTreeProps, jsonRenderTree, toJsonRenderRegistry, treeToJsonRenderSpec };
47
+ export { GenuiProvider, type GenuiProviderProps, type JsonRenderFlatSpec, JsonRenderTree, type JsonRenderTreeProps, jsonRenderTree, toJsonRenderRegistry, treeToJsonRenderSpec };
@@ -3,7 +3,502 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
3
3
 
4
4
  // src/genui/json-render.tsx
5
5
  import { JSONUIProvider, Renderer } from "@json-render/react";
6
- import { useMemo } from "react";
6
+ import { useMemo as useMemo3 } from "react";
7
+
8
+ // src/genui/generative-ui.tsx
9
+ import { Component, createContext as createContext2, useCallback, useContext as useContext2, useMemo as useMemo2 } from "react";
10
+
11
+ // src/components/ambient-ui.ts
12
+ import { createContext, useContext } from "react";
13
+ function sharedContext(key) {
14
+ const symbol = Symbol.for(key);
15
+ const holder = globalThis;
16
+ const existing = holder[symbol];
17
+ if (existing !== void 0) return existing;
18
+ const created = createContext(null);
19
+ holder[symbol] = created;
20
+ return created;
21
+ }
22
+ __name(sharedContext, "sharedContext");
23
+ var AmbientRenderUiContext = sharedContext("@dudousxd/nestjs-agent-react:ambient-render-ui");
24
+
25
+ // src/genui/use-generative-ui.ts
26
+ import { useEffect, useMemo, useState } from "react";
27
+
28
+ // src/genui/types.ts
29
+ var GENUI_TREE_COMPONENT = "genui:tree";
30
+
31
+ // src/genui/use-generative-ui.ts
32
+ function isRecord(value) {
33
+ return typeof value === "object" && value !== null && !Array.isArray(value);
34
+ }
35
+ __name(isRecord, "isRecord");
36
+ function toGenerativeUIItem(part) {
37
+ if (!isRecord(part)) return null;
38
+ const source = part.type === "data-ui" && isRecord(part.data) ? part.data : part;
39
+ if (typeof source.component !== "string") return null;
40
+ const id = typeof source.id === "string" ? source.id : typeof part.id === "string" ? part.id : null;
41
+ if (id === null) return null;
42
+ return {
43
+ id,
44
+ component: source.component,
45
+ props: isRecord(source.props) ? source.props : {},
46
+ version: typeof source.version === "number" ? source.version : null,
47
+ toolCallId: typeof source.toolCallId === "string" ? source.toolCallId : null
48
+ };
49
+ }
50
+ __name(toGenerativeUIItem, "toGenerativeUIItem");
51
+ var resolverCaches = /* @__PURE__ */ new WeakMap();
52
+ function resolveCached(resolve, name, version) {
53
+ let cache = resolverCaches.get(resolve);
54
+ if (cache === void 0) {
55
+ cache = /* @__PURE__ */ new Map();
56
+ resolverCaches.set(resolve, cache);
57
+ }
58
+ const key = `${name}@${version ?? ""}`;
59
+ const hit = cache.get(key);
60
+ if (hit !== void 0) return hit;
61
+ let entry;
62
+ try {
63
+ const result = resolve(name, version);
64
+ if (result instanceof Promise) {
65
+ entry = {
66
+ resolution: {
67
+ status: "loading"
68
+ },
69
+ settled: null
70
+ };
71
+ entry.settled = result.then((Component2) => {
72
+ entry.resolution = Component2 ? {
73
+ status: "ready",
74
+ Component: Component2
75
+ } : {
76
+ status: "unknown"
77
+ };
78
+ }, (error) => {
79
+ entry.resolution = {
80
+ status: "error",
81
+ error
82
+ };
83
+ });
84
+ } else {
85
+ entry = {
86
+ resolution: result ? {
87
+ status: "ready",
88
+ Component: result
89
+ } : {
90
+ status: "unknown"
91
+ },
92
+ settled: null
93
+ };
94
+ }
95
+ } catch (error) {
96
+ entry = {
97
+ resolution: {
98
+ status: "error",
99
+ error
100
+ },
101
+ settled: null
102
+ };
103
+ }
104
+ cache.set(key, entry);
105
+ return entry;
106
+ }
107
+ __name(resolveCached, "resolveCached");
108
+ function useResolvedComponent(name, version, registry, resolve, fallbackTree) {
109
+ const [, setTick] = useState(0);
110
+ const own = registry[name];
111
+ const entry = own !== void 0 || resolve === void 0 ? null : resolveCached(resolve, name, version);
112
+ const pending = entry?.resolution.status === "loading" ? entry.settled : null;
113
+ useEffect(() => {
114
+ if (pending === null) return;
115
+ let live = true;
116
+ void pending.then(() => {
117
+ if (live) setTick((tick) => tick + 1);
118
+ });
119
+ return () => {
120
+ live = false;
121
+ };
122
+ }, [
123
+ pending
124
+ ]);
125
+ if (own !== void 0) return {
126
+ status: "ready",
127
+ Component: own
128
+ };
129
+ if (entry !== null && entry.resolution.status !== "unknown") return entry.resolution;
130
+ if (name === GENUI_TREE_COMPONENT && fallbackTree !== void 0) {
131
+ return {
132
+ status: "ready",
133
+ Component: fallbackTree
134
+ };
135
+ }
136
+ return {
137
+ status: "unknown"
138
+ };
139
+ }
140
+ __name(useResolvedComponent, "useResolvedComponent");
141
+ function useValidatedProps(catalog, name, props) {
142
+ const checked = catalog?.has(name) === true;
143
+ const immediate = useMemo(() => {
144
+ if (!checked || catalog === void 0) return {
145
+ status: "ok",
146
+ props
147
+ };
148
+ const result = catalog.validateSync?.(name, props);
149
+ if (result === void 0) return null;
150
+ return result.ok ? {
151
+ status: "ok",
152
+ props: result.value
153
+ } : {
154
+ status: "invalid",
155
+ issues: result.issues
156
+ };
157
+ }, [
158
+ checked,
159
+ catalog,
160
+ name,
161
+ props
162
+ ]);
163
+ const [late, setLate] = useState(null);
164
+ useEffect(() => {
165
+ if (immediate !== null || catalog === void 0) return;
166
+ let live = true;
167
+ catalog.validate(name, props).then((result) => {
168
+ if (!live) return;
169
+ setLate({
170
+ props,
171
+ result: result.ok ? {
172
+ status: "ok",
173
+ props: result.value
174
+ } : {
175
+ status: "invalid",
176
+ issues: result.issues
177
+ }
178
+ });
179
+ }, (error) => {
180
+ if (!live) return;
181
+ setLate({
182
+ props,
183
+ result: {
184
+ status: "invalid",
185
+ issues: [
186
+ {
187
+ path: [],
188
+ message: error instanceof Error ? error.message : String(error)
189
+ }
190
+ ]
191
+ }
192
+ });
193
+ });
194
+ return () => {
195
+ live = false;
196
+ };
197
+ }, [
198
+ immediate,
199
+ catalog,
200
+ name,
201
+ props
202
+ ]);
203
+ if (immediate !== null) return immediate;
204
+ return late !== null && late.props === props ? late.result : {
205
+ status: "pending"
206
+ };
207
+ }
208
+ __name(useValidatedProps, "useValidatedProps");
209
+ function useGenerativeUIState(part, options, fallbackTree) {
210
+ const item = useMemo(() => toGenerativeUIItem(part), [
211
+ part
212
+ ]);
213
+ const name = item?.component ?? "";
214
+ const resolution = useResolvedComponent(name, item?.version ?? null, options.registry, item === null ? void 0 : options.resolveComponent, fallbackTree);
215
+ const empty = useMemo(() => ({}), []);
216
+ const validation = useValidatedProps(item === null || name === GENUI_TREE_COMPONENT ? void 0 : options.catalog, name, item?.props ?? empty);
217
+ if (item === null) return null;
218
+ if (resolution.status === "loading") return {
219
+ status: "loading",
220
+ item
221
+ };
222
+ if (resolution.status === "unknown") return {
223
+ status: "problem",
224
+ reason: "unknown",
225
+ item
226
+ };
227
+ if (resolution.status === "error") {
228
+ return {
229
+ status: "problem",
230
+ reason: "error",
231
+ item,
232
+ error: resolution.error
233
+ };
234
+ }
235
+ if (validation.status === "pending") return {
236
+ status: "loading",
237
+ item
238
+ };
239
+ if (validation.status === "invalid") {
240
+ return {
241
+ status: "problem",
242
+ reason: "invalid",
243
+ item,
244
+ issues: validation.issues
245
+ };
246
+ }
247
+ return {
248
+ status: "ready",
249
+ item,
250
+ Component: resolution.Component,
251
+ props: validation.props
252
+ };
253
+ }
254
+ __name(useGenerativeUIState, "useGenerativeUIState");
255
+
256
+ // src/genui/generative-ui.tsx
257
+ var TreeScopeContext = /* @__PURE__ */ createContext2(null);
258
+ function renderFallback(fallback, problem) {
259
+ if (typeof fallback === "function") return fallback(problem);
260
+ return fallback ?? null;
261
+ }
262
+ __name(renderFallback, "renderFallback");
263
+ var ItemBoundary = class ItemBoundary2 extends Component {
264
+ static {
265
+ __name(this, "ItemBoundary");
266
+ }
267
+ state = {
268
+ error: void 0,
269
+ failed: false
270
+ };
271
+ static getDerivedStateFromError(error) {
272
+ return {
273
+ error,
274
+ failed: true
275
+ };
276
+ }
277
+ componentDidCatch(error, _info) {
278
+ this.props.onError?.(error, this.props.item);
279
+ }
280
+ componentDidUpdate(previous) {
281
+ if (this.state.failed && previous.item !== this.props.item) {
282
+ this.setState({
283
+ error: void 0,
284
+ failed: false
285
+ });
286
+ }
287
+ }
288
+ render() {
289
+ if (this.state.failed) {
290
+ return renderFallback(this.props.fallback, {
291
+ reason: "error",
292
+ item: this.props.item,
293
+ error: this.state.error
294
+ });
295
+ }
296
+ return this.props.children;
297
+ }
298
+ };
299
+ function nodeItem(node, id) {
300
+ return {
301
+ id,
302
+ component: node.type,
303
+ props: node.props ?? {},
304
+ version: null,
305
+ toolCallId: null
306
+ };
307
+ }
308
+ __name(nodeItem, "nodeItem");
309
+ function TreeNode({ node, id }) {
310
+ const scope = useContext2(TreeScopeContext);
311
+ const item = useMemo2(() => nodeItem(node, id), [
312
+ node,
313
+ id
314
+ ]);
315
+ const resolution = useResolvedComponent(node.type, null, scope?.options.registry ?? {}, scope?.options.resolveComponent);
316
+ const validation = useValidatedProps(scope?.options.catalog, node.type, item.props);
317
+ if (scope === null) return null;
318
+ if (resolution.status === "loading" || validation.status === "pending") return scope.loading;
319
+ if (resolution.status === "unknown") {
320
+ return renderFallback(scope.fallback, {
321
+ reason: "unknown",
322
+ item
323
+ });
324
+ }
325
+ if (resolution.status === "error") {
326
+ return renderFallback(scope.fallback, {
327
+ reason: "error",
328
+ item,
329
+ error: resolution.error
330
+ });
331
+ }
332
+ if (validation.status === "invalid") {
333
+ return renderFallback(scope.fallback, {
334
+ reason: "invalid",
335
+ item,
336
+ issues: validation.issues
337
+ });
338
+ }
339
+ const Renderer2 = resolution.Component;
340
+ const children = Array.isArray(node.children) ? node.children : [];
341
+ return /* @__PURE__ */ React.createElement(Renderer2, validation.props, children.length > 0 ? children.map((child, index) => {
342
+ const childId = `${id}.${index}`;
343
+ return /* @__PURE__ */ React.createElement(ItemBoundary, {
344
+ key: childId,
345
+ item: nodeItem(child, childId),
346
+ fallback: scope.fallback,
347
+ onError: scope.onError
348
+ }, /* @__PURE__ */ React.createElement(TreeNode, {
349
+ node: child,
350
+ id: childId
351
+ }));
352
+ }) : void 0);
353
+ }
354
+ __name(TreeNode, "TreeNode");
355
+ function GenuiTree({ root }) {
356
+ if (root === void 0 || root === null || typeof root.type !== "string") return null;
357
+ return /* @__PURE__ */ React.createElement(TreeNode, {
358
+ node: root,
359
+ id: "root"
360
+ });
361
+ }
362
+ __name(GenuiTree, "GenuiTree");
363
+ function GenerativeUIScope({ registry, catalog, resolveComponent, fallback, loading = null, onError, children }) {
364
+ const scope = useMemo2(() => ({
365
+ options: {
366
+ registry,
367
+ ...catalog !== void 0 ? {
368
+ catalog
369
+ } : {},
370
+ ...resolveComponent !== void 0 ? {
371
+ resolveComponent
372
+ } : {}
373
+ },
374
+ fallback,
375
+ loading,
376
+ onError
377
+ }), [
378
+ registry,
379
+ catalog,
380
+ resolveComponent,
381
+ fallback,
382
+ loading,
383
+ onError
384
+ ]);
385
+ return /* @__PURE__ */ React.createElement(TreeScopeContext.Provider, {
386
+ value: scope
387
+ }, children);
388
+ }
389
+ __name(GenerativeUIScope, "GenerativeUIScope");
390
+ var GenuiContext = sharedContext("@dudousxd/nestjs-agent-react:genui-provider");
391
+ function GenuiProvider({ registry, catalog, resolveComponent, treeRenderer, fallback, loading, onError, children }) {
392
+ const value = useMemo2(() => ({
393
+ ...registry !== void 0 ? {
394
+ registry
395
+ } : {},
396
+ ...catalog !== void 0 ? {
397
+ catalog
398
+ } : {},
399
+ ...resolveComponent !== void 0 ? {
400
+ resolveComponent
401
+ } : {},
402
+ ...treeRenderer !== void 0 ? {
403
+ treeRenderer
404
+ } : {},
405
+ ...fallback !== void 0 ? {
406
+ fallback
407
+ } : {},
408
+ ...loading !== void 0 ? {
409
+ loading
410
+ } : {},
411
+ ...onError !== void 0 ? {
412
+ onError
413
+ } : {}
414
+ }), [
415
+ registry,
416
+ catalog,
417
+ resolveComponent,
418
+ treeRenderer,
419
+ fallback,
420
+ loading,
421
+ onError
422
+ ]);
423
+ const renderUi = useCallback((block) => /* @__PURE__ */ React.createElement(GenerativeUI, {
424
+ part: block
425
+ }), []);
426
+ return /* @__PURE__ */ React.createElement(GenuiContext.Provider, {
427
+ value
428
+ }, /* @__PURE__ */ React.createElement(AmbientRenderUiContext.Provider, {
429
+ value: renderUi
430
+ }, children));
431
+ }
432
+ __name(GenuiProvider, "GenuiProvider");
433
+ var NO_REGISTRY = {};
434
+ function useMergedOptions(own) {
435
+ const provided = useContext2(GenuiContext);
436
+ const registry = own.registry ?? provided?.registry ?? NO_REGISTRY;
437
+ const catalog = own.catalog ?? provided?.catalog;
438
+ const resolveComponent = own.resolveComponent ?? provided?.resolveComponent;
439
+ const treeRenderer = own.treeRenderer ?? provided?.treeRenderer;
440
+ return useMemo2(() => ({
441
+ registry,
442
+ ...catalog !== void 0 ? {
443
+ catalog
444
+ } : {},
445
+ ...resolveComponent !== void 0 ? {
446
+ resolveComponent
447
+ } : {},
448
+ ...treeRenderer !== void 0 ? {
449
+ treeRenderer
450
+ } : {}
451
+ }), [
452
+ registry,
453
+ catalog,
454
+ resolveComponent,
455
+ treeRenderer
456
+ ]);
457
+ }
458
+ __name(useMergedOptions, "useMergedOptions");
459
+ function GenerativeUI({ part, registry, catalog, resolveComponent, treeRenderer, fallback: ownFallback, loading: ownLoading, onError: ownOnError }) {
460
+ const provided = useContext2(GenuiContext);
461
+ const fallback = ownFallback ?? provided?.fallback;
462
+ const loading = ownLoading ?? provided?.loading ?? null;
463
+ const onError = ownOnError ?? provided?.onError;
464
+ const options = useMergedOptions({
465
+ ...registry !== void 0 ? {
466
+ registry
467
+ } : {},
468
+ ...catalog !== void 0 ? {
469
+ catalog
470
+ } : {},
471
+ ...resolveComponent !== void 0 ? {
472
+ resolveComponent
473
+ } : {},
474
+ ...treeRenderer !== void 0 ? {
475
+ treeRenderer
476
+ } : {}
477
+ });
478
+ const state = useGenerativeUIState(part, options, options.treeRenderer ?? GenuiTree);
479
+ if (state === null) return null;
480
+ if (state.status === "loading") return loading;
481
+ if (state.status === "problem") {
482
+ const { status: _status, ...problem } = state;
483
+ return renderFallback(fallback, problem);
484
+ }
485
+ const Renderer2 = state.Component;
486
+ return /* @__PURE__ */ React.createElement(GenerativeUIScope, {
487
+ ...options,
488
+ fallback,
489
+ loading,
490
+ ...onError !== void 0 ? {
491
+ onError
492
+ } : {}
493
+ }, /* @__PURE__ */ React.createElement(ItemBoundary, {
494
+ item: state.item,
495
+ fallback,
496
+ onError
497
+ }, /* @__PURE__ */ React.createElement(Renderer2, state.props)));
498
+ }
499
+ __name(GenerativeUI, "GenerativeUI");
500
+
501
+ // src/genui/json-render.tsx
7
502
  function treeToJsonRenderSpec(root) {
8
503
  const elements = {};
9
504
  let next = 0;
@@ -32,7 +527,7 @@ function toJsonRenderRegistry(registry) {
32
527
  }
33
528
  __name(toJsonRenderRegistry, "toJsonRenderRegistry");
34
529
  function JsonRenderTree({ root, registry, initialState }) {
35
- const spec = useMemo(() => root === void 0 ? null : treeToJsonRenderSpec(root), [
530
+ const spec = useMemo3(() => root === void 0 ? null : treeToJsonRenderSpec(root), [
36
531
  root
37
532
  ]);
38
533
  if (spec === null) return null;
@@ -58,7 +553,28 @@ function jsonRenderTree(registry) {
58
553
  }, "JsonRenderTreeFrame");
59
554
  }
60
555
  __name(jsonRenderTree, "jsonRenderTree");
556
+ function GenuiProvider2({ jsonRender, treeRenderer, registry, ...rest }) {
557
+ const derived = useMemo3(() => {
558
+ if (jsonRender === void 0) return void 0;
559
+ return jsonRenderTree(jsonRender === true ? toJsonRenderRegistry(registry ?? {}) : jsonRender);
560
+ }, [
561
+ jsonRender,
562
+ registry
563
+ ]);
564
+ const tree = treeRenderer ?? derived;
565
+ return /* @__PURE__ */ React.createElement(GenuiProvider, {
566
+ ...rest,
567
+ ...registry !== void 0 ? {
568
+ registry
569
+ } : {},
570
+ ...tree !== void 0 ? {
571
+ treeRenderer: tree
572
+ } : {}
573
+ });
574
+ }
575
+ __name(GenuiProvider2, "GenuiProvider");
61
576
  export {
577
+ GenuiProvider2 as GenuiProvider,
62
578
  JsonRenderTree,
63
579
  jsonRenderTree,
64
580
  toJsonRenderRegistry,