@dudousxd/nestjs-agent-react 0.19.0 → 0.21.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.
@@ -0,0 +1,302 @@
1
+ import { ThreadSummary, ThreadDetail, MessageAttachment, ToolCatalogEntry, SkillCatalogEntry, QuotaView, QuotaReport, ModelCatalogView, AgentCatalogEntry, MessageFeedbackValue, MessageFeedback } from '@dudousxd/nestjs-agent-core';
2
+
3
+ /**
4
+ * Partial update accepted by `PATCH <base>/threads/:threadId`. `defaultAgent: null` clears a
5
+ * previously-set default back to the module's own default; omitting it leaves the thread's
6
+ * current default untouched.
7
+ */
8
+ interface ThreadPatch {
9
+ title?: string;
10
+ defaultAgent?: string | null;
11
+ /** Pin a catalog model on the thread; `null` unpins it. */
12
+ model?: string | null;
13
+ }
14
+ /** Starting a turn: the body `POST <base>/chat` takes (see docs/stream-protocol.md). */
15
+ interface ChatStreamRequest {
16
+ /** `{ message, threadId?, agent?, model?, attachments?, pageContext?, regenerate?, … }`. */
17
+ body: Record<string, unknown>;
18
+ /** Per-request headers the AI SDK was handed for this send. */
19
+ headers?: Record<string, string>;
20
+ /** Aborted when the user stops the turn. */
21
+ signal?: AbortSignal;
22
+ }
23
+ /** Attaching to a run that is already streaming: `GET <base>/chat/:runId/stream?after=<seq>`. */
24
+ interface ResumeStreamRequest {
25
+ runId: string;
26
+ /**
27
+ * The sequence number (SSE `id:`) of the last frame the client already has. Omitted → replay
28
+ * from the first frame. A backend that cannot skip may ignore it: the transport also drops frames
29
+ * at or below it.
30
+ */
31
+ after?: number;
32
+ headers?: Record<string, string>;
33
+ signal?: AbortSignal;
34
+ }
35
+ /**
36
+ * An open chat stream: the raw `text/event-stream` bytes in the stream-protocol framing, plus the
37
+ * identity a backend may learn before the first frame (the `X-Agent-Run-Id` / `X-Agent-Thread-Id`
38
+ * headers). The body's own `event: meta` frame supplies them otherwise.
39
+ */
40
+ interface ChatStreamResponse {
41
+ body: ReadableStream<Uint8Array>;
42
+ runId?: string;
43
+ threadId?: string;
44
+ }
45
+ /** What `POST <base>/messages/:id/feedback` takes. `value: null` clears the rating. */
46
+ interface MessageFeedbackInput {
47
+ value: MessageFeedbackValue | null;
48
+ comment?: string;
49
+ }
50
+ interface UploadAttachmentOptions {
51
+ signal?: AbortSignal;
52
+ /** Called with 0..1 as the upload progresses, when the backend can observe it. */
53
+ onProgress?: (fraction: number) => void;
54
+ }
55
+ /** How {@link AgentClient} reaches the server — handed to an {@link AttachmentUploadStrategy}. */
56
+ interface AgentConnection {
57
+ /** The server's origin, trailing slash removed (`''` for same-origin). */
58
+ baseUrl: string;
59
+ /** The agent's route prefix, normalized to a leading slash (`'/agent'`), or `''`. */
60
+ path: string;
61
+ /** The client's static + per-request headers, resolved now (auth, CSRF). */
62
+ headers: () => Promise<Record<string, string>>;
63
+ credentials?: RequestCredentials;
64
+ fetch: typeof fetch;
65
+ }
66
+ /**
67
+ * Replaces {@link AgentClient}'s own `uploadAttachment` (`POST <path>/attachments`) — e.g.
68
+ * `mediaAttachments()` from `@dudousxd/nestjs-agent-react/media`, or your own storage. Gets the
69
+ * client's connection so it needs no configuration of its own. Resolve with the attachment your
70
+ * server's `AGENT_ATTACHMENT_STAGING` recognises by `mediaId`.
71
+ */
72
+ type AttachmentUploadStrategy = (file: File, options: UploadAttachmentOptions, connection: AgentConnection) => Promise<MessageAttachment>;
73
+ /**
74
+ * Everything the React layer asks of a server — the seam between `useAgentChat` (and the other
75
+ * hooks) and whatever serves the agent. {@link AgentClient} is the default implementation, over the
76
+ * library's own REST routes with `fetch`. An app with its own client — a generated one, a different
77
+ * auth scheme (cookie session + CSRF header), a backend that is not this library at all but speaks
78
+ * docs/stream-protocol.md — implements this instead and passes it as `<AgentProvider backend>` (or
79
+ * per hook, `useAgentChat({ backend })`).
80
+ *
81
+ * The streaming, thread and cancel members are required: without them there is no chat. The rest
82
+ * are optional; a hook that needs one the backend does not have throws
83
+ * {@link AgentBackendUnsupportedError} when it is called, so a backend only implements what its
84
+ * server supports.
85
+ */
86
+ interface AgentBackend {
87
+ /** Start a turn and return its SSE stream. Throw on a non-2xx answer. */
88
+ openChatStream(request: ChatStreamRequest): Promise<ChatStreamResponse>;
89
+ /** Attach to a streaming run. Resolve `null` when nothing is streaming under that id (HTTP 404). */
90
+ resumeChatStream(request: ResumeStreamRequest): Promise<ChatStreamResponse | null>;
91
+ /** Hard-stop a run server-side. */
92
+ cancelStream(runId: string): Promise<unknown>;
93
+ listThreads(): Promise<ThreadSummary[]>;
94
+ getThread(id: string): Promise<ThreadDetail>;
95
+ updateThread(id: string, patch: ThreadPatch): Promise<unknown>;
96
+ deleteThread(id: string): Promise<unknown>;
97
+ forkFromMessage?(threadId: string, messageId: string): Promise<ThreadSummary>;
98
+ promoteThread?(id: string): Promise<unknown>;
99
+ truncateFromMessage?(threadId: string, messageId: string): Promise<unknown>;
100
+ approveToolCall?(input: {
101
+ toolCallId: string;
102
+ remember?: boolean;
103
+ via?: string;
104
+ }): Promise<unknown>;
105
+ rejectToolCall?(input: {
106
+ toolCallId: string;
107
+ reason?: string;
108
+ via?: string;
109
+ }): Promise<unknown>;
110
+ answerToolCall?(input: {
111
+ toolCallId: string;
112
+ answers?: Record<string, string[]>;
113
+ }): Promise<unknown>;
114
+ skipToolCall?(input: {
115
+ toolCallId: string;
116
+ }): Promise<unknown>;
117
+ uploadAttachment?(file: File, options?: UploadAttachmentOptions): Promise<MessageAttachment>;
118
+ listTools?(agent?: string): Promise<ToolCatalogEntry[]>;
119
+ listSkills?(threadId?: string): Promise<SkillCatalogEntry[]>;
120
+ getQuotaToday?(): Promise<QuotaView>;
121
+ /** `GET <base>/quota` — every budget window, and which one blocks sends, if any. */
122
+ getQuota?(): Promise<QuotaReport>;
123
+ /** `GET <base>/models?agent=` — what a model picker offers. */
124
+ listModels?(agent?: string): Promise<ModelCatalogView>;
125
+ /** `GET <base>/agents` — what an agent picker offers. */
126
+ listAgents?(): Promise<AgentCatalogEntry[]>;
127
+ setMessageFeedback?(messageId: string, input: MessageFeedbackInput): Promise<{
128
+ feedback: MessageFeedback | null;
129
+ }>;
130
+ }
131
+ /** An optional {@link AgentBackend} member the bound backend does not implement was called. */
132
+ declare class AgentBackendUnsupportedError extends Error {
133
+ readonly method: string;
134
+ constructor(method: string);
135
+ }
136
+ type OptionalMethod = {
137
+ [K in keyof AgentBackend]-?: undefined extends AgentBackend[K] ? K : never;
138
+ }[keyof AgentBackend];
139
+ /**
140
+ * The optional backend method `name`, bound — or a throw naming it. For hook code that has to call
141
+ * something a backend may not offer.
142
+ */
143
+ declare function requireBackendMethod<K extends OptionalMethod>(backend: AgentBackend, name: K): NonNullable<AgentBackend[K]>;
144
+
145
+ /**
146
+ * Thrown by {@link AgentClient} on a non-2xx response. Carries the HTTP `status` so callers can
147
+ * branch (e.g. 403 → "not your thread", 429 → quota) instead of string-matching a generic Error.
148
+ */
149
+ declare class AgentHttpError extends Error {
150
+ readonly status: number;
151
+ readonly method: string;
152
+ readonly path: string;
153
+ constructor(status: number, method: string, path: string, statusText: string);
154
+ }
155
+ /** The quota-today read-model: usage, the configured limit (null → unlimited), and USD spend. */
156
+ type QuotaToday = QuotaView;
157
+ interface CancelResult {
158
+ aborted: boolean;
159
+ }
160
+ interface OkResult {
161
+ ok: boolean;
162
+ }
163
+ interface AgentClientOptions {
164
+ /**
165
+ * The server's origin, e.g. `https://api.example.com`. Defaults to `''` (same origin). The
166
+ * agent's route prefix is {@link AgentClientOptions.path}, not part of this.
167
+ */
168
+ baseUrl?: string;
169
+ /**
170
+ * The agent's route prefix — `AgentModule`'s `path`, with any global prefix in front
171
+ * (`'api/agent'`). Leading/trailing slashes are optional. Defaults to `'agent'`.
172
+ */
173
+ path?: string;
174
+ /** Static headers merged into every request. */
175
+ headers?: Record<string, string>;
176
+ /**
177
+ * Resolved per request — for short-lived bearer tokens, or a CSRF header read from a cookie
178
+ * (`{ 'X-XSRF-TOKEN': readCookie('XSRF-TOKEN') }`), which has to be read at request time because
179
+ * the server may rotate it.
180
+ */
181
+ getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
182
+ /**
183
+ * Forwarded to fetch so cookie auth works. Same-origin requests send cookies by default; set
184
+ * `'include'` when the API lives on another origin (and have it answer with credentialed CORS).
185
+ */
186
+ credentials?: RequestCredentials;
187
+ /** Injectable for tests / non-browser runtimes. */
188
+ fetch?: typeof fetch;
189
+ /** Attachment uploads. */
190
+ attachments?: {
191
+ /**
192
+ * How `uploadAttachment` uploads. Omitted → `POST <path>/attachments` (multipart). Pass
193
+ * `mediaAttachments()` from `@dudousxd/nestjs-agent-react/media` for resumable uploads through
194
+ * nestjs-media, or your own {@link AttachmentUploadStrategy}.
195
+ */
196
+ upload?: AttachmentUploadStrategy;
197
+ };
198
+ }
199
+ /**
200
+ * Framework-agnostic REST client for the nestjs-agent endpoints — the default {@link AgentBackend}.
201
+ * Used by `useAgentChat`, but standalone-usable (vanilla fetch, no React).
202
+ */
203
+ declare class AgentClient implements AgentBackend {
204
+ private readonly options;
205
+ constructor(options?: AgentClientOptions);
206
+ /** `POST <path>/chat` → the turn's SSE stream. Throws {@link AgentHttpError} on a non-2xx. */
207
+ openChatStream(request: ChatStreamRequest): Promise<ChatStreamResponse>;
208
+ /**
209
+ * `GET <path>/chat/:runId/stream[?after=<seq>]` → the run's SSE stream, or `null` when nothing is
210
+ * streaming under that id (404).
211
+ */
212
+ resumeChatStream(request: ResumeStreamRequest): Promise<ChatStreamResponse | null>;
213
+ /**
214
+ * Rate a message (`'up'`/`'down'`, optional comment) or clear its rating (`value: null`). Answers
215
+ * the stored rating.
216
+ */
217
+ setMessageFeedback(messageId: string, input: MessageFeedbackInput): Promise<{
218
+ feedback: MessageFeedback | null;
219
+ }>;
220
+ listThreads(): Promise<ThreadSummary[]>;
221
+ /**
222
+ * The skills this caller can invoke right now, scope-resolved — the same list, built by the same
223
+ * call, that the model is offered, so what a user can type after a `/` and what the agent can
224
+ * reach cannot drift apart. `threadId` reaches the host's own resolver, which may scope a skill to
225
+ * one conversation; omitted, the server reads it as a brand-new thread.
226
+ */
227
+ listSkills(threadId?: string): Promise<SkillCatalogEntry[]>;
228
+ /**
229
+ * The tools this caller can reach through `agent` (the default agent when omitted), each with the
230
+ * server-declared `presentation` a chat narrates it by — the same list the model is offered.
231
+ * Prefer {@link useToolCatalog}, which fetches it once and shares it.
232
+ */
233
+ listTools(agent?: string): Promise<ToolCatalogEntry[]>;
234
+ getThread(id: string): Promise<ThreadDetail>;
235
+ deleteThread(id: string): Promise<void>;
236
+ forkFromMessage(threadId: string, messageId: string): Promise<ThreadSummary>;
237
+ renameThread(id: string, title: string): Promise<OkResult>;
238
+ /** General `PATCH <path>/threads/:threadId` — title and/or the thread's pinned default agent. */
239
+ updateThread(id: string, patch: ThreadPatch): Promise<OkResult>;
240
+ /**
241
+ * Uploads a file (image/PDF) for a vision-capable model turn. Multipart, field name `file` —
242
+ * mirrors the backend's `POST <path>/attachments`. The returned {@link MessageAttachment} is
243
+ * what a caller then rides on `sendMessage({ text }, { body: { attachments: [...] } })`.
244
+ */
245
+ uploadAttachment(file: File, options?: UploadAttachmentOptions): Promise<MessageAttachment>;
246
+ private uploadWithProgress;
247
+ promoteThread(id: string): Promise<OkResult>;
248
+ truncateFromMessage(threadId: string, messageId: string): Promise<OkResult>;
249
+ /** `GET <path>/models?agent=` — the models this caller may pick, grouped by provider. */
250
+ listModels(agent?: string): Promise<ModelCatalogView>;
251
+ /** `GET <path>/agents` — the registered agents, the default one flagged. */
252
+ listAgents(): Promise<AgentCatalogEntry[]>;
253
+ /** `GET <path>/quota` — the caller's budget windows and the one blocking sends, if any. */
254
+ getQuota(): Promise<QuotaReport>;
255
+ getQuotaToday(): Promise<QuotaToday>;
256
+ cancelStream(runId: string): Promise<CancelResult>;
257
+ /**
258
+ * `remember` approves later calls of the same tool in the same thread; `via` names the surface
259
+ * the decision came through (the server records `'web'` when omitted).
260
+ */
261
+ approveToolCall(input: {
262
+ toolCallId: string;
263
+ remember?: boolean;
264
+ via?: string;
265
+ }): Promise<void>;
266
+ rejectToolCall(input: {
267
+ toolCallId: string;
268
+ reason?: string;
269
+ via?: string;
270
+ }): Promise<void>;
271
+ /**
272
+ * Settle a parked question set. `answers` is questionId → chosen option values; a question left
273
+ * out takes the pre-picked default the request carried, resolved server-side against the request
274
+ * the run already holds. Omit the whole object and the user has confirmed every pre-picked
275
+ * answer — which is the point of the surface, so it is a valid submission rather than a blank.
276
+ */
277
+ answerToolCall(input: {
278
+ toolCallId: string;
279
+ answers?: Record<string, string[]>;
280
+ }): Promise<void>;
281
+ /**
282
+ * Decline to answer and let the agent proceed on its own pre-picked values. Lands on the same
283
+ * values a confirmation would, and persists differently on purpose — only one of them is
284
+ * evidence the user chose them.
285
+ */
286
+ skipToolCall(input: {
287
+ toolCallId: string;
288
+ }): Promise<void>;
289
+ private fetchImpl;
290
+ /** This client's connection, for an {@link AttachmentUploadStrategy}. */
291
+ private connection;
292
+ private baseUrl;
293
+ private agentPath;
294
+ /** Origin + agent path: what every route hangs off. */
295
+ private root;
296
+ private resolveHeaders;
297
+ private credentials;
298
+ private request;
299
+ private handleResponse;
300
+ }
301
+
302
+ export { type AgentBackend as A, type CancelResult as C, type MessageFeedbackInput as M, type QuotaToday as Q, type ResumeStreamRequest as R, type ThreadPatch as T, type UploadAttachmentOptions as U, type AttachmentUploadStrategy as a, AgentBackendUnsupportedError as b, AgentClient as c, type AgentClientOptions as d, type AgentConnection as e, AgentHttpError as f, type ChatStreamRequest as g, type ChatStreamResponse as h, requireBackendMethod as r };
@@ -1,3 +1,5 @@
1
+ import * as React from 'react';
2
+ import { ComponentType, ReactNode } from 'react';
1
3
  import { ElicitationQuestion, ElicitationInputType, ToolPresentation, ToolCatalogEntry, ToolResultField, ToolResultView, ToolPresentationTone, ElicitationInput } from '@dudousxd/nestjs-agent-core';
2
4
  import { ToolUIPart, DynamicToolUIPart, UIMessage } from 'ai';
3
5
 
@@ -558,4 +560,166 @@ declare function describeTimestamp(createdAt: string | null | undefined): Timest
558
560
  */
559
561
  declare function formatRelativeTime(date: Date): string;
560
562
 
561
- export { resolveResultView as $, type ApproveOptions as A, type BuildBlocksOptions as B, type ChatStatus as C, type DescribeToolCallOptions as D, type ElicitationBlockOptions as E, type TranscriptToolBlock as F, type GroupToolActivityOptions as G, type TranscriptToolCall as H, buildTranscriptBlocks as I, coerceAnswer as J, correctedCallIds as K, describeTimestamp as L, type MessageUsageInfo as M, describeToolCall as N, describeUsage as O, extractMessageText as P, fillTemplate as Q, type RawAnswer as R, type SettleAction as S, type TranscriptUiBlock as T, type UsageSummary as U, formatRelativeTime as V, groupToolActivity as W, inferResultView as X, isActionCall as Y, phraseFor as Z, readPath as _, type TranscriptBlock as a, toolCallState as a0, toolCatalogFrom as a1, type TimestampInfo as b, type ToolCatalog as c, type AnyToolUIPart as d, type TranscriptFile as e, type ApprovalBlockOptions as f, type CoercibleQuestion as g, type ResolvedReading as h, type ResolvedResultView as i, type RetrievedPassage as j, type ToolActivityGroup as k, type ToolCallDescription as l, type ToolCallState as m, type ToolCallStatus as n, type TranscriptApproval as o, type TranscriptApprovalStatus as p, type TranscriptElicitationBlock as q, type TranscriptElicitationOutcome as r, type TranscriptFilesBlock as s, type TranscriptQuestion as t, type TranscriptQuestionOption as u, type TranscriptReasoningBlock as v, type TranscriptSettleState as w, type TranscriptSource as x, type TranscriptSourcesBlock as y, type TranscriptTextBlock as z };
563
+ /** The `ui` frame component a composed tree is pushed under (`GENUI_TREE_COMPONENT` of `@dudousxd/nestjs-agent-core/genui`). */
564
+ declare const GENUI_TREE_COMPONENT = "genui:tree";
565
+ /** One pushed component, normalized from whatever carried it (a transcript block, a `data-ui` part, a stored entry). */
566
+ interface GenerativeUIItem {
567
+ id: string;
568
+ component: string;
569
+ props: Record<string, unknown>;
570
+ version: number | null;
571
+ toolCallId: string | null;
572
+ }
573
+ /** A node of a composed tree (`genui:tree` frames): `{ type, props, children? }`. */
574
+ interface GenerativeUIElement {
575
+ type: string;
576
+ props: Record<string, unknown>;
577
+ children?: GenerativeUIElement[];
578
+ }
579
+ /**
580
+ * An app's renderer for one component: it receives the component's props spread, plus `children`
581
+ * when it is a layout node in a tree. Any React component — the library never styles anything.
582
+ */
583
+ type GenuiRenderer<P = any> = ComponentType<P & {
584
+ children?: ReactNode;
585
+ }>;
586
+ /** Component name → the app's renderer. */
587
+ type GenuiRegistry = Record<string, GenuiRenderer>;
588
+ /**
589
+ * Resolve a component the registry does not have — typically a tenant's own component, fetched for
590
+ * the exact `version` a message was rendered with. Return `null`/`undefined` for "no such
591
+ * component". May be async; results are cached per resolver, name and version.
592
+ */
593
+ type ResolveComponent = (name: string, version: number | null) => GenuiRenderer | null | undefined | Promise<GenuiRenderer | null | undefined>;
594
+ interface GenuiIssueLike {
595
+ path: (string | number)[];
596
+ message: string;
597
+ }
598
+ type ValidationLike = {
599
+ ok: true;
600
+ value: Record<string, unknown>;
601
+ } | {
602
+ ok: false;
603
+ issues: GenuiIssueLike[];
604
+ };
605
+ /**
606
+ * What the renderer needs from a catalog to validate props before drawing them. A `Catalog` from
607
+ * `@dudousxd/nestjs-agent-core/genui` satisfies it; declared structurally so any catalog-shaped
608
+ * object does too.
609
+ */
610
+ interface GenuiCatalogLike {
611
+ has(name: string): boolean;
612
+ validate(name: string, props: unknown): Promise<ValidationLike>;
613
+ validateSync?(name: string, props: unknown): ValidationLike | undefined;
614
+ }
615
+ interface GenerativeUIOptions {
616
+ registry: GenuiRegistry;
617
+ /** Validate props against it before rendering. Components the catalog does not know render unvalidated. */
618
+ catalog?: GenuiCatalogLike;
619
+ resolveComponent?: ResolveComponent;
620
+ /**
621
+ * Draws a composed tree frame (`genui:tree`) whole — e.g. through json-render (see the
622
+ * `/genui/json-render` subpath's `GenuiProvider`). Omitted → trees render node by node through
623
+ * `registry`.
624
+ */
625
+ treeRenderer?: GenuiRenderer<{
626
+ root?: GenerativeUIElement;
627
+ }>;
628
+ }
629
+ /** Why an item did not render. */
630
+ type GenerativeUIProblem = {
631
+ reason: 'unknown';
632
+ item: GenerativeUIItem;
633
+ } | {
634
+ reason: 'invalid';
635
+ item: GenerativeUIItem;
636
+ issues: GenuiIssueLike[];
637
+ } | {
638
+ reason: 'error';
639
+ item: GenerativeUIItem;
640
+ error: unknown;
641
+ };
642
+ type GenerativeUIState = {
643
+ status: 'ready';
644
+ item: GenerativeUIItem;
645
+ Component: GenuiRenderer;
646
+ props: Record<string, unknown>;
647
+ } | {
648
+ status: 'loading';
649
+ item: GenerativeUIItem;
650
+ } | ({
651
+ status: 'problem';
652
+ } & GenerativeUIProblem);
653
+
654
+ /** What to draw instead of a component that did not render. Default: nothing. */
655
+ type GenerativeUIFallback = ReactNode | ((problem: GenerativeUIProblem) => ReactNode);
656
+ /**
657
+ * Renders a `genui:tree` frame's `{ root }` node by node through the same registry, catalog and
658
+ * resolver as top-level components. Used automatically for tree frames unless a `treeRenderer`
659
+ * (e.g. the json-render one) or a registry entry for `genui:tree` takes over.
660
+ */
661
+ declare function GenuiTree({ root }: {
662
+ root?: GenerativeUIElement;
663
+ }): React.JSX.Element | null;
664
+ interface GenerativeUIScopeProps extends GenerativeUIOptions {
665
+ fallback?: GenerativeUIFallback;
666
+ loading?: ReactNode;
667
+ onError?: (error: unknown, item: GenerativeUIItem) => void;
668
+ children?: ReactNode;
669
+ }
670
+ /**
671
+ * The registry, catalog and fallbacks tree nodes render with. `<GenerativeUI>` provides it; wrap
672
+ * your own chrome in it when you draw `useGenerativeUI`'s `Component` yourself and it may be a tree.
673
+ */
674
+ declare function GenerativeUIScope({ registry, catalog, resolveComponent, fallback, loading, onError, children, }: GenerativeUIScopeProps): React.JSX.Element;
675
+ /** What `<GenuiProvider>` hands every `<GenerativeUI>` / `useGenerativeUI` below it. */
676
+ interface GenuiProviderValue extends Partial<GenerativeUIOptions> {
677
+ fallback?: GenerativeUIFallback;
678
+ loading?: ReactNode;
679
+ onError?: (error: unknown, item: GenerativeUIItem) => void;
680
+ }
681
+ /** The enclosing `<GenuiProvider>`'s settings, or `null` outside one. */
682
+ declare function useGenuiProvider(): GenuiProviderValue | null;
683
+ interface GenuiProviderProps extends GenuiProviderValue {
684
+ children?: ReactNode;
685
+ }
686
+ /**
687
+ * Set generative UI up once, at the app root: the registry of your renderers, the catalog to
688
+ * validate against, a resolver for components the registry lacks, and what to draw when one does
689
+ * not render. Every `<GenerativeUI>` below reads it (its own props still win), and `MessageItem` /
690
+ * `MessageList` draw pushed components with it — no `renderUi` per message.
691
+ *
692
+ * ```tsx
693
+ * <GenuiProvider registry={registry} catalog={catalog} fallback={({ item }) => <Unknown name={item.component} />}>
694
+ * <App />
695
+ * </GenuiProvider>
696
+ * ```
697
+ */
698
+ declare function GenuiProvider({ registry, catalog, resolveComponent, treeRenderer, fallback, loading, onError, children, }: GenuiProviderProps): React.JSX.Element;
699
+ /**
700
+ * The headless half of {@link GenerativeUI}: what to draw for one pushed component, or `null` when
701
+ * `part` is not one. Options default to the enclosing `<GenuiProvider>`'s.
702
+ */
703
+ declare function useGenerativeUI(part: unknown, options?: Partial<GenerativeUIOptions>): GenerativeUIState | null;
704
+ interface GenerativeUIProps extends Partial<GenerativeUIOptions> {
705
+ /** A transcript `ui` block, a `data-ui` message part, or a stored `{ id, component, props, version? }`. */
706
+ part: TranscriptUiBlock | GenerativeUIItem | unknown;
707
+ /** Drawn for an unknown component, invalid props, or a renderer that threw. Default: the provider's, else nothing. */
708
+ fallback?: GenerativeUIFallback;
709
+ /** Drawn while a resolver or an async validation is pending. Default: the provider's, else nothing. */
710
+ loading?: ReactNode;
711
+ /** A renderer threw (the item shows `fallback`). */
712
+ onError?: (error: unknown, item: GenerativeUIItem) => void;
713
+ }
714
+ /**
715
+ * Draws one server-pushed component with the app's own renderer. Headless: it adds no element and
716
+ * no style of its own — only what the registry's component renders (and whatever `fallback` /
717
+ * `loading` you pass). Everything but `part` defaults to the enclosing `<GenuiProvider>`.
718
+ *
719
+ * ```tsx
720
+ * <GenerativeUI part={block} />
721
+ * ```
722
+ */
723
+ declare function GenerativeUI({ part, registry, catalog, resolveComponent, treeRenderer, fallback: ownFallback, loading: ownLoading, onError: ownOnError, }: GenerativeUIProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
724
+
725
+ export { type TranscriptQuestionOption as $, type ApproveOptions as A, type BuildBlocksOptions as B, type ChatStatus as C, type CoercibleQuestion as D, type DescribeToolCallOptions as E, type ElicitationBlockOptions as F, type GenerativeUIItem as G, type GroupToolActivityOptions as H, type RawAnswer as I, type ResolvedReading as J, type ResolvedResultView as K, type RetrievedPassage as L, type MessageUsageInfo as M, type ToolActivityGroup as N, type ToolCallDescription as O, type ToolCallState as P, type ToolCallStatus as Q, type ResolveComponent as R, type SettleAction as S, type TranscriptUiBlock as T, type UsageSummary as U, type TranscriptApproval as V, type TranscriptApprovalStatus as W, type TranscriptElicitationBlock as X, type TranscriptElicitationOutcome as Y, type TranscriptFilesBlock as Z, type TranscriptQuestion as _, GENUI_TREE_COMPONENT as a, type TranscriptReasoningBlock as a0, type TranscriptSettleState as a1, type TranscriptSource as a2, type TranscriptSourcesBlock as a3, type TranscriptTextBlock as a4, type TranscriptToolBlock as a5, type TranscriptToolCall as a6, buildTranscriptBlocks as a7, coerceAnswer as a8, correctedCallIds as a9, describeTimestamp as aa, describeToolCall as ab, describeUsage as ac, extractMessageText as ad, fillTemplate as ae, formatRelativeTime as af, groupToolActivity as ag, inferResultView as ah, isActionCall as ai, phraseFor as aj, readPath as ak, resolveResultView as al, toolCallState as am, toolCatalogFrom as an, GenerativeUI as b, type GenerativeUIElement as c, type GenerativeUIFallback as d, type GenerativeUIOptions as e, type GenerativeUIProblem as f, type GenerativeUIProps as g, GenerativeUIScope as h, type GenerativeUIScopeProps as i, type GenerativeUIState as j, type GenuiCatalogLike as k, type GenuiIssueLike as l, GenuiProvider as m, type GenuiProviderProps as n, type GenuiProviderValue as o, type GenuiRegistry as p, type GenuiRenderer as q, GenuiTree as r, useGenuiProvider as s, type TranscriptBlock as t, useGenerativeUI as u, type TimestampInfo as v, type ToolCatalog as w, type AnyToolUIPart as x, type TranscriptFile as y, type ApprovalBlockOptions as z };
@@ -1,3 +1,5 @@
1
+ import * as React from 'react';
2
+ import { ComponentType, ReactNode } from 'react';
1
3
  import { ElicitationQuestion, ElicitationInputType, ToolPresentation, ToolCatalogEntry, ToolResultField, ToolResultView, ToolPresentationTone, ElicitationInput } from '@dudousxd/nestjs-agent-core';
2
4
  import { ToolUIPart, DynamicToolUIPart, UIMessage } from 'ai';
3
5
 
@@ -558,4 +560,166 @@ declare function describeTimestamp(createdAt: string | null | undefined): Timest
558
560
  */
559
561
  declare function formatRelativeTime(date: Date): string;
560
562
 
561
- export { resolveResultView as $, type ApproveOptions as A, type BuildBlocksOptions as B, type ChatStatus as C, type DescribeToolCallOptions as D, type ElicitationBlockOptions as E, type TranscriptToolBlock as F, type GroupToolActivityOptions as G, type TranscriptToolCall as H, buildTranscriptBlocks as I, coerceAnswer as J, correctedCallIds as K, describeTimestamp as L, type MessageUsageInfo as M, describeToolCall as N, describeUsage as O, extractMessageText as P, fillTemplate as Q, type RawAnswer as R, type SettleAction as S, type TranscriptUiBlock as T, type UsageSummary as U, formatRelativeTime as V, groupToolActivity as W, inferResultView as X, isActionCall as Y, phraseFor as Z, readPath as _, type TranscriptBlock as a, toolCallState as a0, toolCatalogFrom as a1, type TimestampInfo as b, type ToolCatalog as c, type AnyToolUIPart as d, type TranscriptFile as e, type ApprovalBlockOptions as f, type CoercibleQuestion as g, type ResolvedReading as h, type ResolvedResultView as i, type RetrievedPassage as j, type ToolActivityGroup as k, type ToolCallDescription as l, type ToolCallState as m, type ToolCallStatus as n, type TranscriptApproval as o, type TranscriptApprovalStatus as p, type TranscriptElicitationBlock as q, type TranscriptElicitationOutcome as r, type TranscriptFilesBlock as s, type TranscriptQuestion as t, type TranscriptQuestionOption as u, type TranscriptReasoningBlock as v, type TranscriptSettleState as w, type TranscriptSource as x, type TranscriptSourcesBlock as y, type TranscriptTextBlock as z };
563
+ /** The `ui` frame component a composed tree is pushed under (`GENUI_TREE_COMPONENT` of `@dudousxd/nestjs-agent-core/genui`). */
564
+ declare const GENUI_TREE_COMPONENT = "genui:tree";
565
+ /** One pushed component, normalized from whatever carried it (a transcript block, a `data-ui` part, a stored entry). */
566
+ interface GenerativeUIItem {
567
+ id: string;
568
+ component: string;
569
+ props: Record<string, unknown>;
570
+ version: number | null;
571
+ toolCallId: string | null;
572
+ }
573
+ /** A node of a composed tree (`genui:tree` frames): `{ type, props, children? }`. */
574
+ interface GenerativeUIElement {
575
+ type: string;
576
+ props: Record<string, unknown>;
577
+ children?: GenerativeUIElement[];
578
+ }
579
+ /**
580
+ * An app's renderer for one component: it receives the component's props spread, plus `children`
581
+ * when it is a layout node in a tree. Any React component — the library never styles anything.
582
+ */
583
+ type GenuiRenderer<P = any> = ComponentType<P & {
584
+ children?: ReactNode;
585
+ }>;
586
+ /** Component name → the app's renderer. */
587
+ type GenuiRegistry = Record<string, GenuiRenderer>;
588
+ /**
589
+ * Resolve a component the registry does not have — typically a tenant's own component, fetched for
590
+ * the exact `version` a message was rendered with. Return `null`/`undefined` for "no such
591
+ * component". May be async; results are cached per resolver, name and version.
592
+ */
593
+ type ResolveComponent = (name: string, version: number | null) => GenuiRenderer | null | undefined | Promise<GenuiRenderer | null | undefined>;
594
+ interface GenuiIssueLike {
595
+ path: (string | number)[];
596
+ message: string;
597
+ }
598
+ type ValidationLike = {
599
+ ok: true;
600
+ value: Record<string, unknown>;
601
+ } | {
602
+ ok: false;
603
+ issues: GenuiIssueLike[];
604
+ };
605
+ /**
606
+ * What the renderer needs from a catalog to validate props before drawing them. A `Catalog` from
607
+ * `@dudousxd/nestjs-agent-core/genui` satisfies it; declared structurally so any catalog-shaped
608
+ * object does too.
609
+ */
610
+ interface GenuiCatalogLike {
611
+ has(name: string): boolean;
612
+ validate(name: string, props: unknown): Promise<ValidationLike>;
613
+ validateSync?(name: string, props: unknown): ValidationLike | undefined;
614
+ }
615
+ interface GenerativeUIOptions {
616
+ registry: GenuiRegistry;
617
+ /** Validate props against it before rendering. Components the catalog does not know render unvalidated. */
618
+ catalog?: GenuiCatalogLike;
619
+ resolveComponent?: ResolveComponent;
620
+ /**
621
+ * Draws a composed tree frame (`genui:tree`) whole — e.g. through json-render (see the
622
+ * `/genui/json-render` subpath's `GenuiProvider`). Omitted → trees render node by node through
623
+ * `registry`.
624
+ */
625
+ treeRenderer?: GenuiRenderer<{
626
+ root?: GenerativeUIElement;
627
+ }>;
628
+ }
629
+ /** Why an item did not render. */
630
+ type GenerativeUIProblem = {
631
+ reason: 'unknown';
632
+ item: GenerativeUIItem;
633
+ } | {
634
+ reason: 'invalid';
635
+ item: GenerativeUIItem;
636
+ issues: GenuiIssueLike[];
637
+ } | {
638
+ reason: 'error';
639
+ item: GenerativeUIItem;
640
+ error: unknown;
641
+ };
642
+ type GenerativeUIState = {
643
+ status: 'ready';
644
+ item: GenerativeUIItem;
645
+ Component: GenuiRenderer;
646
+ props: Record<string, unknown>;
647
+ } | {
648
+ status: 'loading';
649
+ item: GenerativeUIItem;
650
+ } | ({
651
+ status: 'problem';
652
+ } & GenerativeUIProblem);
653
+
654
+ /** What to draw instead of a component that did not render. Default: nothing. */
655
+ type GenerativeUIFallback = ReactNode | ((problem: GenerativeUIProblem) => ReactNode);
656
+ /**
657
+ * Renders a `genui:tree` frame's `{ root }` node by node through the same registry, catalog and
658
+ * resolver as top-level components. Used automatically for tree frames unless a `treeRenderer`
659
+ * (e.g. the json-render one) or a registry entry for `genui:tree` takes over.
660
+ */
661
+ declare function GenuiTree({ root }: {
662
+ root?: GenerativeUIElement;
663
+ }): React.JSX.Element | null;
664
+ interface GenerativeUIScopeProps extends GenerativeUIOptions {
665
+ fallback?: GenerativeUIFallback;
666
+ loading?: ReactNode;
667
+ onError?: (error: unknown, item: GenerativeUIItem) => void;
668
+ children?: ReactNode;
669
+ }
670
+ /**
671
+ * The registry, catalog and fallbacks tree nodes render with. `<GenerativeUI>` provides it; wrap
672
+ * your own chrome in it when you draw `useGenerativeUI`'s `Component` yourself and it may be a tree.
673
+ */
674
+ declare function GenerativeUIScope({ registry, catalog, resolveComponent, fallback, loading, onError, children, }: GenerativeUIScopeProps): React.JSX.Element;
675
+ /** What `<GenuiProvider>` hands every `<GenerativeUI>` / `useGenerativeUI` below it. */
676
+ interface GenuiProviderValue extends Partial<GenerativeUIOptions> {
677
+ fallback?: GenerativeUIFallback;
678
+ loading?: ReactNode;
679
+ onError?: (error: unknown, item: GenerativeUIItem) => void;
680
+ }
681
+ /** The enclosing `<GenuiProvider>`'s settings, or `null` outside one. */
682
+ declare function useGenuiProvider(): GenuiProviderValue | null;
683
+ interface GenuiProviderProps extends GenuiProviderValue {
684
+ children?: ReactNode;
685
+ }
686
+ /**
687
+ * Set generative UI up once, at the app root: the registry of your renderers, the catalog to
688
+ * validate against, a resolver for components the registry lacks, and what to draw when one does
689
+ * not render. Every `<GenerativeUI>` below reads it (its own props still win), and `MessageItem` /
690
+ * `MessageList` draw pushed components with it — no `renderUi` per message.
691
+ *
692
+ * ```tsx
693
+ * <GenuiProvider registry={registry} catalog={catalog} fallback={({ item }) => <Unknown name={item.component} />}>
694
+ * <App />
695
+ * </GenuiProvider>
696
+ * ```
697
+ */
698
+ declare function GenuiProvider({ registry, catalog, resolveComponent, treeRenderer, fallback, loading, onError, children, }: GenuiProviderProps): React.JSX.Element;
699
+ /**
700
+ * The headless half of {@link GenerativeUI}: what to draw for one pushed component, or `null` when
701
+ * `part` is not one. Options default to the enclosing `<GenuiProvider>`'s.
702
+ */
703
+ declare function useGenerativeUI(part: unknown, options?: Partial<GenerativeUIOptions>): GenerativeUIState | null;
704
+ interface GenerativeUIProps extends Partial<GenerativeUIOptions> {
705
+ /** A transcript `ui` block, a `data-ui` message part, or a stored `{ id, component, props, version? }`. */
706
+ part: TranscriptUiBlock | GenerativeUIItem | unknown;
707
+ /** Drawn for an unknown component, invalid props, or a renderer that threw. Default: the provider's, else nothing. */
708
+ fallback?: GenerativeUIFallback;
709
+ /** Drawn while a resolver or an async validation is pending. Default: the provider's, else nothing. */
710
+ loading?: ReactNode;
711
+ /** A renderer threw (the item shows `fallback`). */
712
+ onError?: (error: unknown, item: GenerativeUIItem) => void;
713
+ }
714
+ /**
715
+ * Draws one server-pushed component with the app's own renderer. Headless: it adds no element and
716
+ * no style of its own — only what the registry's component renders (and whatever `fallback` /
717
+ * `loading` you pass). Everything but `part` defaults to the enclosing `<GenuiProvider>`.
718
+ *
719
+ * ```tsx
720
+ * <GenerativeUI part={block} />
721
+ * ```
722
+ */
723
+ declare function GenerativeUI({ part, registry, catalog, resolveComponent, treeRenderer, fallback: ownFallback, loading: ownLoading, onError: ownOnError, }: GenerativeUIProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
724
+
725
+ export { type TranscriptQuestionOption as $, type ApproveOptions as A, type BuildBlocksOptions as B, type ChatStatus as C, type CoercibleQuestion as D, type DescribeToolCallOptions as E, type ElicitationBlockOptions as F, type GenerativeUIItem as G, type GroupToolActivityOptions as H, type RawAnswer as I, type ResolvedReading as J, type ResolvedResultView as K, type RetrievedPassage as L, type MessageUsageInfo as M, type ToolActivityGroup as N, type ToolCallDescription as O, type ToolCallState as P, type ToolCallStatus as Q, type ResolveComponent as R, type SettleAction as S, type TranscriptUiBlock as T, type UsageSummary as U, type TranscriptApproval as V, type TranscriptApprovalStatus as W, type TranscriptElicitationBlock as X, type TranscriptElicitationOutcome as Y, type TranscriptFilesBlock as Z, type TranscriptQuestion as _, GENUI_TREE_COMPONENT as a, type TranscriptReasoningBlock as a0, type TranscriptSettleState as a1, type TranscriptSource as a2, type TranscriptSourcesBlock as a3, type TranscriptTextBlock as a4, type TranscriptToolBlock as a5, type TranscriptToolCall as a6, buildTranscriptBlocks as a7, coerceAnswer as a8, correctedCallIds as a9, describeTimestamp as aa, describeToolCall as ab, describeUsage as ac, extractMessageText as ad, fillTemplate as ae, formatRelativeTime as af, groupToolActivity as ag, inferResultView as ah, isActionCall as ai, phraseFor as aj, readPath as ak, resolveResultView as al, toolCallState as am, toolCatalogFrom as an, GenerativeUI as b, type GenerativeUIElement as c, type GenerativeUIFallback as d, type GenerativeUIOptions as e, type GenerativeUIProblem as f, type GenerativeUIProps as g, GenerativeUIScope as h, type GenerativeUIScopeProps as i, type GenerativeUIState as j, type GenuiCatalogLike as k, type GenuiIssueLike as l, GenuiProvider as m, type GenuiProviderProps as n, type GenuiProviderValue as o, type GenuiRegistry as p, type GenuiRenderer as q, GenuiTree as r, useGenuiProvider as s, type TranscriptBlock as t, useGenerativeUI as u, type TimestampInfo as v, type ToolCatalog as w, type AnyToolUIPart as x, type TranscriptFile as y, type ApprovalBlockOptions as z };
@@ -1,7 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { ComponentRegistry } from '@json-render/react';
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';
3
+ import { n as GenuiProviderProps$1, c as GenerativeUIElement, q as GenuiRenderer, p as GenuiRegistry } from './generative-ui-9AJNVKBZ.cjs';
5
4
  import '@dudousxd/nestjs-agent-core';
6
5
  import 'ai';
7
6