@dudousxd/nestjs-agent-react 0.7.4 → 0.8.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/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as ai from 'ai';
2
- import { ChatTransport, UIMessage, UIMessageChunk, ToolUIPart, DynamicToolUIPart } from 'ai';
2
+ import { ChatTransport, UIMessage, UIMessageChunk, ToolUIPart, DynamicToolUIPart, DataUIPart, UIDataTypes } from 'ai';
3
3
  import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
4
4
  import { StoredMessage, ThreadSummary, SkillCatalogEntry, ThreadDetail, MessageAttachment, QuotaView } from '@dudousxd/nestjs-agent-core';
5
5
  import React from 'react';
@@ -69,6 +69,15 @@ interface AgentChatTransportOptions {
69
69
  * message, and are rendered as native model content parts. Optimistic display of
70
70
  * the user's own attachment thumbnails is the consumer's concern (it stages the
71
71
  * upload), the same way history rendering reads `StoredMessage.attachments`.
72
+ *
73
+ * Frames beyond text/reasoning/tools become AI SDK data parts (seen by `useChat`'s `onData`):
74
+ * - `ui` → `data-ui` part, `id` = the component id (a repeat id updates it in place)
75
+ * - `approval-requested` → `data-approval-requested` part keyed by the call id, plus the SDK's
76
+ * native `tool-approval-request` (the part moves to `approval-requested`)
77
+ * - `title`, `cancelled` → transient `data-title` / `data-cancelled` (never stored on the message)
78
+ * - any other kind → `data-<kind>` part carrying the frame minus `kind`, keyed by its `id`
79
+ * when it has one — forwarded, never dropped
80
+ * `parentId` on a tool frame rides the part's `toolMetadata` next to `toolKind`.
72
81
  */
73
82
  declare class AgentChatTransport implements ChatTransport<UIMessage> {
74
83
  private readonly options;
@@ -105,7 +114,8 @@ declare class AgentChatTransport implements ChatTransport<UIMessage> {
105
114
  * Parse the backend's SSE byte stream and re-emit it as a valid v7 UI-message chunk stream.
106
115
  * Recognized frames:
107
116
  * - `event: meta` `data: {"runId","threadId"}` → records identity
108
- * - `data: <AgentStreamEvent JSON>` → mapped to UI chunks (text / reasoning / tool)
117
+ * - `data: <AgentStreamEvent JSON>` → mapped to UI chunks (text / reasoning / tool /
118
+ * `data-*`; see {@link AgentChatTransport} docs)
109
119
  * - `event: done` `data: {}` → terminates
110
120
  * - `event: error` `data: {code,message}` → error chunk
111
121
  *
@@ -352,11 +362,33 @@ interface TranscriptSettleState {
352
362
  isSubmitting: boolean;
353
363
  run: () => void;
354
364
  }
365
+ /**
366
+ * Who has to settle a parked call, and until when — from the stream's `approval-requested` frame.
367
+ * `null` on a call whose runner never said (the call can still be awaiting approval).
368
+ */
369
+ interface TranscriptApproval {
370
+ /** Open vocabulary the host defines: `'requester'`, `'admin'`, a role… */
371
+ approver: string;
372
+ /** ISO-8601; `null` when the request never lapses. */
373
+ expiresAt: string | null;
374
+ reason: string | null;
375
+ }
355
376
  /** One call in a tool run, with whatever human decision it is parked on. */
356
377
  interface TranscriptToolCall {
357
378
  part: AnyToolUIPart;
358
379
  toolCallId: string;
359
380
  name: string;
381
+ /** `read` / `action` as the stream classified the call; `null` when the backend did not say. */
382
+ toolKind: string | null;
383
+ /** The call this one ran inside (a code-mode `execute`, a delegated agent); `null` for a top-level call. */
384
+ parentId: string | null;
385
+ /**
386
+ * Calls nested under this one within the same block, in stream order. Always empty for a call
387
+ * nothing names as its parent.
388
+ */
389
+ children: TranscriptToolCall[];
390
+ /** Who has to decide, when the runner said so. See {@link TranscriptApproval}. */
391
+ approval: TranscriptApproval | null;
360
392
  /**
361
393
  * Parked on a person. An `action` tool's input lands and its output never follows on its own —
362
394
  * the loop waits for an approval between the two — so a settled-looking card that never settles
@@ -379,6 +411,25 @@ interface TranscriptToolBlock {
379
411
  parts: AnyToolUIPart[];
380
412
  /** The same calls, each with its human-decision state. Same order as `parts`. */
381
413
  calls: TranscriptToolCall[];
414
+ /**
415
+ * The same calls as a tree: every call whose parent is NOT in this block, each carrying its
416
+ * nested calls in `children`. Equal to `calls` when nothing is nested.
417
+ */
418
+ roots: TranscriptToolCall[];
419
+ }
420
+ /**
421
+ * A component the server pushed into the message (the stream's `ui` frame, or a persisted
422
+ * `data-ui` part). Rendered by looking `component` up in the host's own registry.
423
+ */
424
+ interface TranscriptUiBlock {
425
+ kind: 'ui';
426
+ key: string;
427
+ /** The component's identity within the message. */
428
+ id: string;
429
+ component: string;
430
+ props: Record<string, unknown>;
431
+ /** Schema version of `props`; `null` when the server did not stamp one. */
432
+ version: number | null;
382
433
  }
383
434
  /** One choice a question offers, with its live selection state. */
384
435
  interface TranscriptQuestionOption {
@@ -472,7 +523,7 @@ interface TranscriptSourcesBlock {
472
523
  sources: TranscriptSource[];
473
524
  passageCount: number;
474
525
  }
475
- type TranscriptBlock = TranscriptTextBlock | TranscriptFilesBlock | TranscriptReasoningBlock | TranscriptToolBlock | TranscriptSourcesBlock | TranscriptElicitationBlock;
526
+ type TranscriptBlock = TranscriptTextBlock | TranscriptFilesBlock | TranscriptReasoningBlock | TranscriptToolBlock | TranscriptSourcesBlock | TranscriptElicitationBlock | TranscriptUiBlock;
476
527
  /** Where a question set's selection state is held, and where its settlement is sent. */
477
528
  interface ElicitationBlockOptions {
478
529
  /** The values a question is showing, or `undefined` while the user has not touched it. */
@@ -515,9 +566,11 @@ interface BuildBlocksOptions {
515
566
  }
516
567
  /**
517
568
  * Walk a message's parts into renderable blocks, buffering consecutive tool parts into one run and
518
- * consecutive files into one strip. Parts this library has no model for (`data-*`) are dropped
519
- * rather than guessed at, but they still terminate a tool run — their position in the transcript is
520
- * meaningful even when their content is not modelled here.
569
+ * consecutive files into one strip. A `data-ui` part becomes a `ui` block. A
570
+ * `data-approval-requested` part is metadata about a call — it is folded into that call's
571
+ * `approval` and takes no position of its own. Other `data-*` parts are dropped rather than guessed
572
+ * at, but they still terminate a tool run — their position in the transcript is meaningful even
573
+ * when their content is not modelled here.
521
574
  */
522
575
  declare function buildTranscriptBlocks(message: UIMessage, options: BuildBlocksOptions): TranscriptBlock[];
523
576
  /** The message's prose, joined for the clipboard. Reasoning is excluded — it is not the answer. */
@@ -729,6 +782,12 @@ type RenderTextFn = (text: string, ctx: {
729
782
  }) => React.ReactNode;
730
783
  /** Render a run of files — attachments on a user turn, or files the model produced. */
731
784
  type RenderFilesFn = (files: TranscriptFile[]) => React.ReactNode;
785
+ /**
786
+ * Render a component the server pushed into the message — look `block.component` up in your own
787
+ * registry. Omitted → pushed components are not drawn (there is no sensible default for an app's
788
+ * own component).
789
+ */
790
+ type RenderUiFn = (block: TranscriptUiBlock) => React.ReactNode;
732
791
  /** Render the body of a reasoning run; the disclosure toggle around it stays this component's. */
733
792
  type RenderReasoningFn = (text: string, ctx: {
734
793
  isStreaming: boolean;
@@ -761,6 +820,8 @@ interface MessageRenderSlots {
761
820
  renderReasoning?: RenderReasoningFn;
762
821
  /** Draw files yourself — a gallery, a viewer. Omitted → images inline, everything else a link. */
763
822
  renderFiles?: RenderFilesFn;
823
+ /** Draw a server-pushed component (a `ui` stream frame). Omitted → not drawn. */
824
+ renderUi?: RenderUiFn;
764
825
  /**
765
826
  * Extra content for the action row, after the built-in affordances and before usage — a badge
766
827
  * naming which agent answered, a status pill. Rendered for every message that has an action row.
@@ -825,6 +886,8 @@ interface MessageListProps {
825
886
  renderReasoning?: RenderReasoningFn;
826
887
  /** Draw a message's files yourself. Omitted → images inline, everything else a link. */
827
888
  renderFiles?: RenderFilesFn;
889
+ /** Draw a server-pushed component (a `ui` stream frame). Omitted → not drawn. */
890
+ renderUi?: RenderUiFn;
828
891
  reasoningLabel?: React.ReactNode;
829
892
  /** Extra content for one message's action row — e.g. a badge naming which agent answered. */
830
893
  getMeta?: (message: UIMessage) => React.ReactNode;
@@ -860,7 +923,7 @@ interface MessageListProps {
860
923
  * Every decision here comes from `useChatTranscript`; the file below it is markup. A host that
861
924
  * wants a different layout drives that hook directly and never imports this component.
862
925
  */
863
- declare function MessageList({ messages, status, renderToolPart, renderToolGroup, renderText, renderReasoning, renderFiles, reasoningLabel, getMeta, onFork, editable, onEditSubmit, regeneratable, onRegenerate, getUsage, getCreatedAt, emptyState, typingIndicator, followUps, onFollowUpClick, error, onRetry, classNames, }: MessageListProps): React.JSX.Element;
926
+ declare function MessageList({ messages, status, renderToolPart, renderToolGroup, renderText, renderReasoning, renderFiles, renderUi, reasoningLabel, getMeta, onFork, editable, onEditSubmit, regeneratable, onRegenerate, getUsage, getCreatedAt, emptyState, typingIndicator, followUps, onFollowUpClick, error, onRetry, classNames, }: MessageListProps): React.JSX.Element;
864
927
 
865
928
  /**
866
929
  * Languages the dictation mic offers. The Web Speech API expects a
@@ -1219,6 +1282,18 @@ interface UseAgentChatOptions {
1219
1282
  runId: string;
1220
1283
  status: 'completed' | 'failed';
1221
1284
  }) => void;
1285
+ /**
1286
+ * Every data part the stream delivers, as it arrives — including transient ones that are never
1287
+ * stored on a message (`data-title`, `data-cancelled`). Pushed components arrive as `data-ui`,
1288
+ * approval metadata as `data-approval-requested`, and a frame kind this version does not map as
1289
+ * `data-<kind>`. See `AgentChatTransport` for the full mapping.
1290
+ */
1291
+ onData?: (part: DataUIPart<UIDataTypes>) => void;
1292
+ /**
1293
+ * The server set or changed the thread's title while a turn streamed. Lets a header/sidebar
1294
+ * update the moment the title exists instead of refetching after the run settles.
1295
+ */
1296
+ onTitle?: (title: string) => void;
1222
1297
  /**
1223
1298
  * Track DETACHED sub-agents this conversation started: which are still working, and their answers
1224
1299
  * as they land (see {@link ChatBackground}). Default `false`.
@@ -1260,7 +1335,7 @@ interface AddToolResultArgs {
1260
1335
  * `AgentClient`. Mirrors flip's `useAdminChat`, generalized.
1261
1336
  */
1262
1337
  declare function useAgentChat(options: UseAgentChatOptions): {
1263
- sendMessage: (message?: (Omit<UIMessage<unknown, ai.UIDataTypes, ai.UITools>, "id" | "role"> & {
1338
+ sendMessage: (message?: (Omit<UIMessage<unknown, UIDataTypes, ai.UITools>, "id" | "role"> & {
1264
1339
  id?: string;
1265
1340
  role?: "system" | "user" | "assistant";
1266
1341
  } & {
@@ -1313,15 +1388,15 @@ declare function useAgentChat(options: UseAgentChatOptions): {
1313
1388
  }) => Promise<void>;
1314
1389
  regenerate: () => void;
1315
1390
  id: string;
1316
- setMessages: (messages: UIMessage<unknown, ai.UIDataTypes, ai.UITools>[] | ((messages: UIMessage<unknown, ai.UIDataTypes, ai.UITools>[]) => UIMessage<unknown, ai.UIDataTypes, ai.UITools>[])) => void;
1391
+ setMessages: (messages: UIMessage<unknown, UIDataTypes, ai.UITools>[] | ((messages: UIMessage<unknown, UIDataTypes, ai.UITools>[]) => UIMessage<unknown, UIDataTypes, ai.UITools>[])) => void;
1317
1392
  error: Error | undefined;
1318
1393
  stop: () => Promise<void>;
1319
1394
  status: ai.ChatStatus;
1320
- messages: UIMessage<unknown, ai.UIDataTypes, ai.UITools>[];
1395
+ messages: UIMessage<unknown, UIDataTypes, ai.UITools>[];
1321
1396
  resumeStream: (options?: ai.ChatRequestOptions) => Promise<void>;
1322
- addToolOutput: ai.ChatAddToolOutputFunction<UIMessage<unknown, ai.UIDataTypes, ai.UITools>>;
1397
+ addToolOutput: ai.ChatAddToolOutputFunction<UIMessage<unknown, UIDataTypes, ai.UITools>>;
1323
1398
  addToolApprovalResponse: ai.ChatAddToolApproveResponseFunction;
1324
1399
  clearError: () => void;
1325
1400
  };
1326
1401
 
1327
- export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type ElicitationBlockOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type TranscriptActionState, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseSpeechRecognitionOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, createSkillsSource, describeTimestamp, describeUsage, extractMessageText, filterAutocompleteItems, findActiveTrigger, formatRelativeTime, loadStoredSpeechLang, persistSpeechLang, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useChatTranscript, useComposerAutocomplete, useSpeechRecognition, useStickToBottom, useTranscriptItem };
1402
+ export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type ElicitationBlockOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type TranscriptActionState, type TranscriptApproval, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseSpeechRecognitionOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, createSkillsSource, describeTimestamp, describeUsage, extractMessageText, filterAutocompleteItems, findActiveTrigger, formatRelativeTime, loadStoredSpeechLang, persistSpeechLang, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useChatTranscript, useComposerAutocomplete, useSpeechRecognition, useStickToBottom, useTranscriptItem };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as ai from 'ai';
2
- import { ChatTransport, UIMessage, UIMessageChunk, ToolUIPart, DynamicToolUIPart } from 'ai';
2
+ import { ChatTransport, UIMessage, UIMessageChunk, ToolUIPart, DynamicToolUIPart, DataUIPart, UIDataTypes } from 'ai';
3
3
  import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
4
4
  import { StoredMessage, ThreadSummary, SkillCatalogEntry, ThreadDetail, MessageAttachment, QuotaView } from '@dudousxd/nestjs-agent-core';
5
5
  import React from 'react';
@@ -69,6 +69,15 @@ interface AgentChatTransportOptions {
69
69
  * message, and are rendered as native model content parts. Optimistic display of
70
70
  * the user's own attachment thumbnails is the consumer's concern (it stages the
71
71
  * upload), the same way history rendering reads `StoredMessage.attachments`.
72
+ *
73
+ * Frames beyond text/reasoning/tools become AI SDK data parts (seen by `useChat`'s `onData`):
74
+ * - `ui` → `data-ui` part, `id` = the component id (a repeat id updates it in place)
75
+ * - `approval-requested` → `data-approval-requested` part keyed by the call id, plus the SDK's
76
+ * native `tool-approval-request` (the part moves to `approval-requested`)
77
+ * - `title`, `cancelled` → transient `data-title` / `data-cancelled` (never stored on the message)
78
+ * - any other kind → `data-<kind>` part carrying the frame minus `kind`, keyed by its `id`
79
+ * when it has one — forwarded, never dropped
80
+ * `parentId` on a tool frame rides the part's `toolMetadata` next to `toolKind`.
72
81
  */
73
82
  declare class AgentChatTransport implements ChatTransport<UIMessage> {
74
83
  private readonly options;
@@ -105,7 +114,8 @@ declare class AgentChatTransport implements ChatTransport<UIMessage> {
105
114
  * Parse the backend's SSE byte stream and re-emit it as a valid v7 UI-message chunk stream.
106
115
  * Recognized frames:
107
116
  * - `event: meta` `data: {"runId","threadId"}` → records identity
108
- * - `data: <AgentStreamEvent JSON>` → mapped to UI chunks (text / reasoning / tool)
117
+ * - `data: <AgentStreamEvent JSON>` → mapped to UI chunks (text / reasoning / tool /
118
+ * `data-*`; see {@link AgentChatTransport} docs)
109
119
  * - `event: done` `data: {}` → terminates
110
120
  * - `event: error` `data: {code,message}` → error chunk
111
121
  *
@@ -352,11 +362,33 @@ interface TranscriptSettleState {
352
362
  isSubmitting: boolean;
353
363
  run: () => void;
354
364
  }
365
+ /**
366
+ * Who has to settle a parked call, and until when — from the stream's `approval-requested` frame.
367
+ * `null` on a call whose runner never said (the call can still be awaiting approval).
368
+ */
369
+ interface TranscriptApproval {
370
+ /** Open vocabulary the host defines: `'requester'`, `'admin'`, a role… */
371
+ approver: string;
372
+ /** ISO-8601; `null` when the request never lapses. */
373
+ expiresAt: string | null;
374
+ reason: string | null;
375
+ }
355
376
  /** One call in a tool run, with whatever human decision it is parked on. */
356
377
  interface TranscriptToolCall {
357
378
  part: AnyToolUIPart;
358
379
  toolCallId: string;
359
380
  name: string;
381
+ /** `read` / `action` as the stream classified the call; `null` when the backend did not say. */
382
+ toolKind: string | null;
383
+ /** The call this one ran inside (a code-mode `execute`, a delegated agent); `null` for a top-level call. */
384
+ parentId: string | null;
385
+ /**
386
+ * Calls nested under this one within the same block, in stream order. Always empty for a call
387
+ * nothing names as its parent.
388
+ */
389
+ children: TranscriptToolCall[];
390
+ /** Who has to decide, when the runner said so. See {@link TranscriptApproval}. */
391
+ approval: TranscriptApproval | null;
360
392
  /**
361
393
  * Parked on a person. An `action` tool's input lands and its output never follows on its own —
362
394
  * the loop waits for an approval between the two — so a settled-looking card that never settles
@@ -379,6 +411,25 @@ interface TranscriptToolBlock {
379
411
  parts: AnyToolUIPart[];
380
412
  /** The same calls, each with its human-decision state. Same order as `parts`. */
381
413
  calls: TranscriptToolCall[];
414
+ /**
415
+ * The same calls as a tree: every call whose parent is NOT in this block, each carrying its
416
+ * nested calls in `children`. Equal to `calls` when nothing is nested.
417
+ */
418
+ roots: TranscriptToolCall[];
419
+ }
420
+ /**
421
+ * A component the server pushed into the message (the stream's `ui` frame, or a persisted
422
+ * `data-ui` part). Rendered by looking `component` up in the host's own registry.
423
+ */
424
+ interface TranscriptUiBlock {
425
+ kind: 'ui';
426
+ key: string;
427
+ /** The component's identity within the message. */
428
+ id: string;
429
+ component: string;
430
+ props: Record<string, unknown>;
431
+ /** Schema version of `props`; `null` when the server did not stamp one. */
432
+ version: number | null;
382
433
  }
383
434
  /** One choice a question offers, with its live selection state. */
384
435
  interface TranscriptQuestionOption {
@@ -472,7 +523,7 @@ interface TranscriptSourcesBlock {
472
523
  sources: TranscriptSource[];
473
524
  passageCount: number;
474
525
  }
475
- type TranscriptBlock = TranscriptTextBlock | TranscriptFilesBlock | TranscriptReasoningBlock | TranscriptToolBlock | TranscriptSourcesBlock | TranscriptElicitationBlock;
526
+ type TranscriptBlock = TranscriptTextBlock | TranscriptFilesBlock | TranscriptReasoningBlock | TranscriptToolBlock | TranscriptSourcesBlock | TranscriptElicitationBlock | TranscriptUiBlock;
476
527
  /** Where a question set's selection state is held, and where its settlement is sent. */
477
528
  interface ElicitationBlockOptions {
478
529
  /** The values a question is showing, or `undefined` while the user has not touched it. */
@@ -515,9 +566,11 @@ interface BuildBlocksOptions {
515
566
  }
516
567
  /**
517
568
  * Walk a message's parts into renderable blocks, buffering consecutive tool parts into one run and
518
- * consecutive files into one strip. Parts this library has no model for (`data-*`) are dropped
519
- * rather than guessed at, but they still terminate a tool run — their position in the transcript is
520
- * meaningful even when their content is not modelled here.
569
+ * consecutive files into one strip. A `data-ui` part becomes a `ui` block. A
570
+ * `data-approval-requested` part is metadata about a call — it is folded into that call's
571
+ * `approval` and takes no position of its own. Other `data-*` parts are dropped rather than guessed
572
+ * at, but they still terminate a tool run — their position in the transcript is meaningful even
573
+ * when their content is not modelled here.
521
574
  */
522
575
  declare function buildTranscriptBlocks(message: UIMessage, options: BuildBlocksOptions): TranscriptBlock[];
523
576
  /** The message's prose, joined for the clipboard. Reasoning is excluded — it is not the answer. */
@@ -729,6 +782,12 @@ type RenderTextFn = (text: string, ctx: {
729
782
  }) => React.ReactNode;
730
783
  /** Render a run of files — attachments on a user turn, or files the model produced. */
731
784
  type RenderFilesFn = (files: TranscriptFile[]) => React.ReactNode;
785
+ /**
786
+ * Render a component the server pushed into the message — look `block.component` up in your own
787
+ * registry. Omitted → pushed components are not drawn (there is no sensible default for an app's
788
+ * own component).
789
+ */
790
+ type RenderUiFn = (block: TranscriptUiBlock) => React.ReactNode;
732
791
  /** Render the body of a reasoning run; the disclosure toggle around it stays this component's. */
733
792
  type RenderReasoningFn = (text: string, ctx: {
734
793
  isStreaming: boolean;
@@ -761,6 +820,8 @@ interface MessageRenderSlots {
761
820
  renderReasoning?: RenderReasoningFn;
762
821
  /** Draw files yourself — a gallery, a viewer. Omitted → images inline, everything else a link. */
763
822
  renderFiles?: RenderFilesFn;
823
+ /** Draw a server-pushed component (a `ui` stream frame). Omitted → not drawn. */
824
+ renderUi?: RenderUiFn;
764
825
  /**
765
826
  * Extra content for the action row, after the built-in affordances and before usage — a badge
766
827
  * naming which agent answered, a status pill. Rendered for every message that has an action row.
@@ -825,6 +886,8 @@ interface MessageListProps {
825
886
  renderReasoning?: RenderReasoningFn;
826
887
  /** Draw a message's files yourself. Omitted → images inline, everything else a link. */
827
888
  renderFiles?: RenderFilesFn;
889
+ /** Draw a server-pushed component (a `ui` stream frame). Omitted → not drawn. */
890
+ renderUi?: RenderUiFn;
828
891
  reasoningLabel?: React.ReactNode;
829
892
  /** Extra content for one message's action row — e.g. a badge naming which agent answered. */
830
893
  getMeta?: (message: UIMessage) => React.ReactNode;
@@ -860,7 +923,7 @@ interface MessageListProps {
860
923
  * Every decision here comes from `useChatTranscript`; the file below it is markup. A host that
861
924
  * wants a different layout drives that hook directly and never imports this component.
862
925
  */
863
- declare function MessageList({ messages, status, renderToolPart, renderToolGroup, renderText, renderReasoning, renderFiles, reasoningLabel, getMeta, onFork, editable, onEditSubmit, regeneratable, onRegenerate, getUsage, getCreatedAt, emptyState, typingIndicator, followUps, onFollowUpClick, error, onRetry, classNames, }: MessageListProps): React.JSX.Element;
926
+ declare function MessageList({ messages, status, renderToolPart, renderToolGroup, renderText, renderReasoning, renderFiles, renderUi, reasoningLabel, getMeta, onFork, editable, onEditSubmit, regeneratable, onRegenerate, getUsage, getCreatedAt, emptyState, typingIndicator, followUps, onFollowUpClick, error, onRetry, classNames, }: MessageListProps): React.JSX.Element;
864
927
 
865
928
  /**
866
929
  * Languages the dictation mic offers. The Web Speech API expects a
@@ -1219,6 +1282,18 @@ interface UseAgentChatOptions {
1219
1282
  runId: string;
1220
1283
  status: 'completed' | 'failed';
1221
1284
  }) => void;
1285
+ /**
1286
+ * Every data part the stream delivers, as it arrives — including transient ones that are never
1287
+ * stored on a message (`data-title`, `data-cancelled`). Pushed components arrive as `data-ui`,
1288
+ * approval metadata as `data-approval-requested`, and a frame kind this version does not map as
1289
+ * `data-<kind>`. See `AgentChatTransport` for the full mapping.
1290
+ */
1291
+ onData?: (part: DataUIPart<UIDataTypes>) => void;
1292
+ /**
1293
+ * The server set or changed the thread's title while a turn streamed. Lets a header/sidebar
1294
+ * update the moment the title exists instead of refetching after the run settles.
1295
+ */
1296
+ onTitle?: (title: string) => void;
1222
1297
  /**
1223
1298
  * Track DETACHED sub-agents this conversation started: which are still working, and their answers
1224
1299
  * as they land (see {@link ChatBackground}). Default `false`.
@@ -1260,7 +1335,7 @@ interface AddToolResultArgs {
1260
1335
  * `AgentClient`. Mirrors flip's `useAdminChat`, generalized.
1261
1336
  */
1262
1337
  declare function useAgentChat(options: UseAgentChatOptions): {
1263
- sendMessage: (message?: (Omit<UIMessage<unknown, ai.UIDataTypes, ai.UITools>, "id" | "role"> & {
1338
+ sendMessage: (message?: (Omit<UIMessage<unknown, UIDataTypes, ai.UITools>, "id" | "role"> & {
1264
1339
  id?: string;
1265
1340
  role?: "system" | "user" | "assistant";
1266
1341
  } & {
@@ -1313,15 +1388,15 @@ declare function useAgentChat(options: UseAgentChatOptions): {
1313
1388
  }) => Promise<void>;
1314
1389
  regenerate: () => void;
1315
1390
  id: string;
1316
- setMessages: (messages: UIMessage<unknown, ai.UIDataTypes, ai.UITools>[] | ((messages: UIMessage<unknown, ai.UIDataTypes, ai.UITools>[]) => UIMessage<unknown, ai.UIDataTypes, ai.UITools>[])) => void;
1391
+ setMessages: (messages: UIMessage<unknown, UIDataTypes, ai.UITools>[] | ((messages: UIMessage<unknown, UIDataTypes, ai.UITools>[]) => UIMessage<unknown, UIDataTypes, ai.UITools>[])) => void;
1317
1392
  error: Error | undefined;
1318
1393
  stop: () => Promise<void>;
1319
1394
  status: ai.ChatStatus;
1320
- messages: UIMessage<unknown, ai.UIDataTypes, ai.UITools>[];
1395
+ messages: UIMessage<unknown, UIDataTypes, ai.UITools>[];
1321
1396
  resumeStream: (options?: ai.ChatRequestOptions) => Promise<void>;
1322
- addToolOutput: ai.ChatAddToolOutputFunction<UIMessage<unknown, ai.UIDataTypes, ai.UITools>>;
1397
+ addToolOutput: ai.ChatAddToolOutputFunction<UIMessage<unknown, UIDataTypes, ai.UITools>>;
1323
1398
  addToolApprovalResponse: ai.ChatAddToolApproveResponseFunction;
1324
1399
  clearError: () => void;
1325
1400
  };
1326
1401
 
1327
- export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type ElicitationBlockOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type TranscriptActionState, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseSpeechRecognitionOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, createSkillsSource, describeTimestamp, describeUsage, extractMessageText, filterAutocompleteItems, findActiveTrigger, formatRelativeTime, loadStoredSpeechLang, persistSpeechLang, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useChatTranscript, useComposerAutocomplete, useSpeechRecognition, useStickToBottom, useTranscriptItem };
1402
+ export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type ElicitationBlockOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type TranscriptActionState, type TranscriptApproval, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseSpeechRecognitionOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, createSkillsSource, describeTimestamp, describeUsage, extractMessageText, filterAutocompleteItems, findActiveTrigger, formatRelativeTime, loadStoredSpeechLang, persistSpeechLang, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useChatTranscript, useComposerAutocomplete, useSpeechRecognition, useStickToBottom, useTranscriptItem };