@dudousxd/nestjs-agent-react 0.21.0 → 0.22.1

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,13 +1,12 @@
1
1
  import * as ai from 'ai';
2
2
  import { ChatTransport, UIMessage, UIMessageChunk, DataUIPart, UIDataTypes } from 'ai';
3
- import { A as AgentBackend, U as UploadAttachmentOptions, a as AttachmentUploadStrategy, Q as QuotaToday } from './client-ePlgRwP-.cjs';
4
- export { b as AgentBackendUnsupportedError, c as AgentClient, d as AgentClientOptions, e as AgentConnection, f as AgentHttpError, C as CancelResult, g as ChatStreamRequest, h as ChatStreamResponse, M as MessageFeedbackInput, R as ResumeStreamRequest, T as ThreadPatch, r as requireBackendMethod } from './client-ePlgRwP-.cjs';
5
- import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
6
- import { MessageAttachment, AgentCatalogEntry, ModelCatalogEntry, ModelCatalogView, QuotaReport, QuotaWindow, QuotaBlock, MessageFeedback, MessageFeedbackValue, ThreadSummary, StoredMessage, ToolCatalogEntry, ThreadDetail } from '@dudousxd/nestjs-agent-core';
3
+ import { A as AgentBackend, U as UploadAttachmentOptions, a as AttachmentUploadStrategy } from './client-CYlhK7XD.cjs';
4
+ export { b as AgentBackendUnsupportedError, c as AgentClient, d as AgentClientOptions, e as AgentConnection, f as AgentHttpError, C as CancelResult, g as ChatStreamRequest, h as ChatStreamResponse, M as MessageFeedbackInput, R as ResumeStreamRequest, T as ThreadPatch, r as requireBackendMethod } from './client-CYlhK7XD.cjs';
5
+ import { MessageAttachment, AgentCatalogEntry, ModelCatalogEntry, ModelCatalogView, QuotaReport, QuotaWindow, QuotaBlock, MessageFeedback, MessageFeedbackValue, ThreadSummary, StoredMessage, ToolCatalogEntry } from '@dudousxd/nestjs-agent-core';
7
6
  export { ElicitationInput, ElicitationInputType, validateElicitationAnswer as validateAnswer, validateElicitationValue as validateAnswerValue } from '@dudousxd/nestjs-agent-core';
8
7
  import * as React from 'react';
9
8
  import React__default, { ReactNode, Context } from 'react';
10
- import { o as GenuiProviderValue, T as TranscriptUiBlock, t as TranscriptBlock, U as UsageSummary, v as TimestampInfo, C as ChatStatus, M as MessageUsageInfo, w as ToolCatalog, A as ApproveOptions, x as AnyToolUIPart, y as TranscriptFile } from './generative-ui-9AJNVKBZ.cjs';
9
+ import { o as GenuiProviderValue, T as TranscriptUiBlock, A as ApproveOptions, t as TranscriptBlock, U as UsageSummary, v as TimestampInfo, C as ChatStatus, M as MessageUsageInfo, w as ToolCatalog, x as AnyToolUIPart, y as TranscriptFile } from './generative-ui-9AJNVKBZ.cjs';
11
10
  export { z as ApprovalBlockOptions, B as BuildBlocksOptions, D as CoercibleQuestion, E as DescribeToolCallOptions, F as ElicitationBlockOptions, H as GroupToolActivityOptions, I as RawAnswer, J as ResolvedReading, K as ResolvedResultView, L as RetrievedPassage, S as SettleAction, N as ToolActivityGroup, O as ToolCallDescription, P as ToolCallState, Q as ToolCallStatus, V as TranscriptApproval, W as TranscriptApprovalStatus, X as TranscriptElicitationBlock, Y as TranscriptElicitationOutcome, Z as TranscriptFilesBlock, _ as TranscriptQuestion, $ as TranscriptQuestionOption, a0 as TranscriptReasoningBlock, a1 as TranscriptSettleState, a2 as TranscriptSource, a3 as TranscriptSourcesBlock, a4 as TranscriptTextBlock, a5 as TranscriptToolBlock, a6 as TranscriptToolCall, a7 as buildTranscriptBlocks, a8 as coerceAnswer, a9 as correctedCallIds, aa as describeTimestamp, ab as describeToolCall, ac as describeUsage, ad as extractMessageText, ae as fillTemplate, af as formatRelativeTime, ag as groupToolActivity, ah as inferResultView, ai as isActionCall, aj as phraseFor, ak as readPath, al as resolveResultView, am as toolCallState, an as toolCatalogFrom } from './generative-ui-9AJNVKBZ.cjs';
12
11
 
13
12
  /** Identity surfaced by the backend's `meta` SSE frame / response headers. */
@@ -688,15 +687,47 @@ interface TranscriptItem {
688
687
  fork: TranscriptActionState;
689
688
  regenerate: TranscriptActionState;
690
689
  }
690
+ /** What an edit-and-resubmit sends. */
691
+ interface EditSubmitInput {
692
+ messageId: string;
693
+ text: string;
694
+ }
695
+ /** Names the message an action is about. */
696
+ interface MessageActionInput {
697
+ messageId: string;
698
+ }
699
+ /** Settling a parked question set. `answers` holds only the questions the user touched. */
700
+ interface AnswerInput {
701
+ toolCallId: string;
702
+ answers?: Record<string, string[]>;
703
+ }
704
+ /** Declining a parked question set. */
705
+ interface SkipInput {
706
+ toolCallId: string;
707
+ }
708
+ /** Approving a tool call parked on a human. */
709
+ interface ApproveInput extends ApproveOptions {
710
+ toolCallId: string;
711
+ /** The surface the decision came through; the server records `'web'` when omitted. */
712
+ via?: string;
713
+ }
714
+ /** Rejecting a tool call parked on a human. */
715
+ interface RejectInput {
716
+ toolCallId: string;
717
+ reason?: string;
718
+ via?: string;
719
+ }
691
720
  interface TranscriptItemOptions {
692
721
  /** User messages get an inline edit-and-resubmit machine. */
693
722
  editable?: boolean;
694
- onEditSubmit?: (messageId: string, text: string) => void | Promise<void>;
695
- onFork?: (messageId: string) => void | Promise<void>;
723
+ onEditSubmit?: (input: EditSubmitInput) => void | Promise<void>;
724
+ onFork?: (input: MessageActionInput) => void | Promise<void>;
696
725
  /** Only the LAST assistant message gets a regenerate machine. */
697
726
  regeneratable?: boolean;
698
- onRegenerate?: (messageId: string) => void | Promise<void>;
727
+ onRegenerate?: (input: MessageActionInput) => void | Promise<void>;
728
+ /** Default: `metadata.usage` (replayed turns; see `AgentMessageMetadata`). */
699
729
  getUsage?: (message: UIMessage) => MessageUsageInfo | null;
730
+ /** Default: `metadata.createdAt` (replayed and streamed messages). */
700
731
  getCreatedAt?: (message: UIMessage) => string | null;
701
732
  /** How long `copy.copied` stays true. Default 1500ms. */
702
733
  copyResetMs?: number;
@@ -713,23 +744,24 @@ interface TranscriptItemOptions {
713
744
  */
714
745
  toolCatalog?: ToolCatalog;
715
746
  /**
716
- * Settle a parked question set — wire to `useAgentChat`'s `answer`. Supplying it is what lifts a
717
- * question set out of the tool run into an `elicitation` block: without somewhere to send an
718
- * answer, a form is a card the user cannot act on.
747
+ * Settle a parked question set. Default: the in-scope backend's `answerToolCall` (the enclosing
748
+ * `<AgentProvider>`'s), so a question set is an `elicitation` block the user can act on without
749
+ * any wiring. `null` turns question sets back into plain tool calls.
719
750
  *
720
751
  * `answers` holds ONLY the questions the user touched. An omitted one takes its own pre-picked
721
752
  * default server-side, which is what keeps "just confirmed" and "picked exactly what was
722
753
  * pre-picked" distinguishable in the settled row.
723
754
  */
724
- onAnswer?: (toolCallId: string, answers: Record<string, string[]>) => void | Promise<void>;
725
- /** Decline the question set and let the agent proceed on its own picks — `useAgentChat`'s `skip`. */
726
- onSkip?: (toolCallId: string) => void | Promise<void>;
755
+ onAnswer?: ((input: AnswerInput) => void | Promise<void>) | null;
756
+ /** Decline the question set and let the agent proceed on its own picks. Default: the backend's. */
757
+ onSkip?: ((input: SkipInput) => void | Promise<void>) | null;
727
758
  /**
728
- * Settle a tool call parked on a human — `useAgentChat`'s `approve` / `reject`. `options.remember`
729
- * is what `call.approve.run({ remember: true })` passed.
759
+ * Settle a tool call parked on a human. Default: the in-scope backend's `approveToolCall` /
760
+ * `rejectToolCall`. `remember` is what `call.approve.run({ remember: true })` passed. `null`
761
+ * leaves the call without the affordance.
730
762
  */
731
- onApprove?: (toolCallId: string, options?: ApproveOptions) => void | Promise<void>;
732
- onReject?: (toolCallId: string) => void | Promise<void>;
763
+ onApprove?: ((input: ApproveInput) => void | Promise<void>) | null;
764
+ onReject?: ((input: RejectInput) => void | Promise<void>) | null;
733
765
  }
734
766
  interface TranscriptWindow {
735
767
  visibleCount: number;
@@ -858,12 +890,12 @@ interface MessageItemProps extends MessageRenderSlots {
858
890
  isStreaming?: boolean;
859
891
  /** User bubble gets a pencil → inline textarea; submitting calls back with the new text. */
860
892
  editable?: boolean;
861
- onEditSubmit?: (newText: string) => void | Promise<void>;
893
+ onEditSubmit?: (input: EditSubmitInput) => void | Promise<void>;
862
894
  /** Assistant bubble gets a "Regenerate" affordance. */
863
895
  regeneratable?: boolean;
864
- onRegenerate?: () => void | Promise<void>;
896
+ onRegenerate?: (input: MessageActionInput) => void | Promise<void>;
865
897
  /** When provided, a "Fork" affordance calls back with this message's id. */
866
- onFork?: (uiMessageId: string) => void | Promise<void>;
898
+ onFork?: (input: MessageActionInput) => void | Promise<void>;
867
899
  /** Server-aggregated usage for this assistant turn (cost + tokens line). */
868
900
  usage?: MessageUsageInfo | null;
869
901
  /** ISO timestamp of the persisted message; rendered as a relative-time line when set. */
@@ -913,13 +945,13 @@ interface MessageListProps {
913
945
  /** Extra content for one message's action row — e.g. a badge naming which agent answered. */
914
946
  getMeta?: (message: UIMessage) => React__default.ReactNode;
915
947
  /** When set, every message gets a "Fork" affordance calling back with its id. */
916
- onFork?: (uiMessageId: string) => void | Promise<void>;
948
+ onFork?: (input: MessageActionInput) => void | Promise<void>;
917
949
  /** User messages get an inline edit-and-resubmit affordance. */
918
950
  editable?: boolean;
919
- onEditSubmit?: (uiMessageId: string, newText: string) => void | Promise<void>;
951
+ onEditSubmit?: (input: EditSubmitInput) => void | Promise<void>;
920
952
  /** The last assistant message gets a "Regenerate" affordance. */
921
953
  regeneratable?: boolean;
922
- onRegenerate?: (uiMessageId: string) => void | Promise<void>;
954
+ onRegenerate?: (input: MessageActionInput) => void | Promise<void>;
923
955
  /** Per-message resolvers for the usage line and the persisted timestamp. */
924
956
  getUsage?: (message: UIMessage) => MessageUsageInfo | null;
925
957
  getCreatedAt?: (message: UIMessage) => string | null;
@@ -1283,6 +1315,8 @@ interface AgentMessageMetadata extends Partial<StoredTurnMetadata> {
1283
1315
  feedback?: MessageFeedback;
1284
1316
  runId?: string;
1285
1317
  costUsd?: number | null;
1318
+ /** ISO timestamp: the stored row's `createdAt` (a merged turn: its first row's), or when a live turn started streaming. */
1319
+ createdAt?: string;
1286
1320
  }
1287
1321
  /**
1288
1322
  * Convert a thread's full `StoredMessage[]` history into `UIMessage[]`, merging consecutive
@@ -1339,65 +1373,74 @@ interface UseAgentChatOptions<B extends AgentBackend = AgentBackend> {
1339
1373
  /** Named agent to run each turn. */
1340
1374
  agent?: string;
1341
1375
  /**
1342
- * The quota window blocking sends — `useQuota(...).blocked`. While set, `sendMessage` and
1343
- * `regenerate` refuse with {@link QuotaBlockedError} instead of starting a turn the server would
1344
- * refuse anyway.
1376
+ * Thread this chat is bound to. Omitted → the backend creates one on the first send
1377
+ * ({@link UseAgentChatOptions.onThreadCreated}). Changing it switches the chat to that thread:
1378
+ * its history loads and a turn still streaming on it is re-attached. Switching to the thread this
1379
+ * chat just created (syncing a URL) keeps the live conversation as it is.
1345
1380
  */
1346
- blocked?: QuotaBlock | null;
1381
+ threadId?: string;
1347
1382
  /**
1348
- * Catalog model to run each turn on (see `useModels`), sent as the body's `model`. Read at every
1349
- * send, so a picker can change it between turns. Omitted → the thread's pinned model, else the
1350
- * server default. A single send can still override it with `sendMessage(msg, { body: { model } })`.
1383
+ * Load a `threadId`'s persisted history into the chat (`GET <base>/threads/:id`). Default `true`;
1384
+ * skipped when {@link UseAgentChatOptions.initialMessages} is given. `false` opts out.
1351
1385
  */
1352
- model?: string;
1353
- /** Thread this chat is bound to. Omitted → backend creates one on send. */
1354
- threadId?: string;
1355
- /** Persisted history to seed `useChat` with (consumed on mount only). */
1386
+ history?: boolean;
1387
+ /** Persisted history you already have — seeds the chat instead of loading it (read per thread). */
1356
1388
  initialMessages?: UIMessage[];
1357
1389
  /**
1358
- * Run id of a buffered stream to reconnect to on mount — wire this to the thread's
1359
- * `activeStreamId`. Its presence both gates the SDK's `resume` and names the run, so a normal
1360
- * mount (no id) never fires a doomed resume GET. Omitted → no resume.
1361
- *
1362
- * For the common case (no id in hand yet), prefer {@link UseAgentChatOptions.resume} — it does
1363
- * this fetch-and-wire for you.
1390
+ * Re-attach to a turn that was still streaming on `threadId` when the page (re)loaded — read off
1391
+ * the thread's `activeRunId`, so a reload mid-answer keeps streaming it. Default `true`; `false`
1392
+ * opts out.
1393
+ */
1394
+ resume?: boolean;
1395
+ /**
1396
+ * A run id you already know is streaming — attached to on mount without reading the thread first.
1397
+ * Rarely needed: {@link UseAgentChatOptions.resume} finds it by itself.
1364
1398
  */
1365
1399
  resumeRunId?: string;
1366
1400
  /**
1367
- * When `true` and the hook (re)mounts with a `threadId`, the hook fetches the thread and, if its
1368
- * `activeRunId` is non-null (a turn was still streaming when the page loaded/reloaded), attaches
1369
- * to that run's `GET /agent/chat/:runId/stream` automatically — the in-flight turn streams into
1370
- * this session's message state exactly as if the send had happened here. A no-op when `threadId`
1371
- * is omitted (nothing to resume) or the fetched thread has no active run. Default `false`.
1401
+ * The model every turn runs on, controlled by you. Omitted → `chat.models.selected` (what
1402
+ * `chat.models.select(id)` picked), else the thread's pinned model, else the server default. A
1403
+ * single send can still override it with `sendMessage(msg, { body: { model } })`.
1372
1404
  */
1373
- resume?: boolean;
1405
+ model?: string;
1406
+ /**
1407
+ * Read the caller's budget (`GET <base>/quota`) and refuse sends while a window is exhausted.
1408
+ * Default `true` when the backend implements `getQuota`; `false` skips the request.
1409
+ */
1410
+ quota?: boolean;
1411
+ /**
1412
+ * Override the quota gate: `null` never blocks, a {@link QuotaBlock} always does. Omitted → the
1413
+ * gate follows {@link UseAgentChatOptions.quota}'s report. While blocked, `sendMessage` and
1414
+ * `regenerate` refuse with {@link QuotaBlockedError}.
1415
+ */
1416
+ blocked?: QuotaBlock | null;
1417
+ /** Validation and upload for `chat.composer.files` — see `useAttachments`. */
1418
+ composer?: Omit<UseAttachmentsOptions, 'backend'>;
1419
+ /**
1420
+ * Overrides for `chat.transcript` — anything `useChatTranscript` takes (`sources`, `editable` +
1421
+ * `onEditSubmit`, `followUps`, `getUsage`, a `toolCatalog` of your own, `onApprove: null`, …).
1422
+ * Yours win over the chat's own wiring.
1423
+ */
1424
+ transcript?: Partial<Omit<UseChatTranscriptOptions, 'messages' | 'status'>>;
1374
1425
  /** Read at every send to capture a page snapshot for the page-assistant. */
1375
1426
  getPageContext?: () => Record<string, unknown> | null;
1376
1427
  /** Fired after each streamed turn finishes (e.g. to refetch the sidebar). */
1377
1428
  onFinish?: () => void;
1378
1429
  /**
1379
- * Fired once when a threadless chat's first send makes the backend create a thread — carries the
1380
- * new id so the consumer can sync its URL/router. Not fired when `threadId` was supplied. The hook
1381
- * ALSO remembers the id internally, so every subsequent send reuses it (no new thread per message)
1382
- * even before the consumer navigates.
1430
+ * Fired when this chat moves to a thread it created: the first send of a threadless chat (the
1431
+ * backend created one), or `chat.fork(…)`. Carries the id so the host can sync its URL/router.
1432
+ * The hook already remembers a created thread, so every later send reuses it even before the
1433
+ * host navigates.
1383
1434
  */
1384
1435
  onThreadCreated?: (threadId: string) => void;
1385
1436
  /**
1386
1437
  * Fired exactly once per run when its stream settles — normally (`'completed'`) or via a thrown
1387
1438
  * failure / the backend's `event: error` frame (`'failed'`) — including a RESUMED stream's own
1388
1439
  * completion. By the time this fires, the server has already derived and persisted the thread's
1389
- * title (and the run's terminal state), so it's the signal `onFinish` doesn't give you: `onFinish`
1390
- * only says "a turn rendered," never "the server is done writing" — without this, a host has no
1391
- * reason to refetch the thread/list queries, and the header/sidebar title is stuck on "Untitled".
1440
+ * title (and the run's terminal state).
1392
1441
  *
1393
- * Skipped when the attempt never got far enough to learn a run id (e.g. the initial POST itself
1394
- * failed before any response headers/meta frame arrived) — nothing was created server-side, so
1395
- * there's nothing to refetch.
1396
- *
1397
- * A user-initiated `cancel()`/`stop()` reports `'completed'` here (the AI SDK's own abort signal
1398
- * doesn't set its `isError` flag) — the server-side cancel already recorded its own terminal run
1399
- * state; this callback only reflects whether the CLIENT's stream loop exited with or without an
1400
- * error, not why it stopped.
1442
+ * Skipped when the attempt never got far enough to learn a run id. A user-initiated `cancel()`
1443
+ * reports `'completed'` (the server-side cancel records its own terminal state).
1401
1444
  */
1402
1445
  onRunSettled?: (outcome: {
1403
1446
  runId: string;
@@ -1410,29 +1453,16 @@ interface UseAgentChatOptions<B extends AgentBackend = AgentBackend> {
1410
1453
  * `data-<kind>`. See `AgentChatTransport` for the full mapping.
1411
1454
  */
1412
1455
  onData?: (part: DataUIPart<UIDataTypes>) => void;
1413
- /**
1414
- * The server set or changed the thread's title while a turn streamed. Lets a header/sidebar
1415
- * update the moment the title exists instead of refetching after the run settles.
1416
- */
1456
+ /** The server set or changed the thread's title while a turn streamed. */
1417
1457
  onTitle?: (title: string) => void;
1418
1458
  /**
1419
1459
  * Track DETACHED sub-agents this conversation started: which are still working, and their answers
1420
1460
  * as they land (see {@link ChatBackground}). Default `false`.
1421
- *
1422
- * Opt-in for the same reason {@link UseAgentChatOptions.resume} is — it reads the thread, and a
1423
- * plain mount must not spend a request on a feature the host is not using. Leaving it off still
1424
- * leaves {@link ChatBackground.refresh} callable, for a host that would rather drive it itself.
1425
1461
  */
1426
1462
  background?: boolean;
1427
1463
  /**
1428
1464
  * How often to re-read the thread while a detached sub-agent is still working, in ms. Default
1429
1465
  * 5000; `0` turns the interval off, leaving {@link ChatBackground.refresh} as the only trigger.
1430
- *
1431
- * A poll rather than a second stream, because what a background run produces is a persisted
1432
- * MESSAGE, not tokens this chat should render as they arrive: its answer belongs to its own run,
1433
- * it can land while the user is mid-turn or has the tab closed, and it has to be there on the next
1434
- * reload either way. The interval exists only while something is outstanding, which is rare and
1435
- * bounded by how many delegations a conversation has started.
1436
1466
  */
1437
1467
  backgroundPollMs?: number;
1438
1468
  }
@@ -1444,16 +1474,49 @@ interface ChatBackground {
1444
1474
  /** Re-read the thread now, instead of waiting for the next poll. */
1445
1475
  refresh: () => Promise<void>;
1446
1476
  }
1477
+ /** The chat's model picker state. Loaded the first time `list`/`providers` is read. */
1478
+ interface ChatModels {
1479
+ /** Every model the caller may pick, flattened (`[]` until loaded). */
1480
+ readonly list: ModelOption[];
1481
+ /** The same, grouped by provider. */
1482
+ readonly providers: ModelsState['providers'];
1483
+ /** What the next turn runs on: the `model` option, the pick, the thread's pin, else the default. */
1484
+ selected: string | null;
1485
+ /** Run the following turns on `id` (sent as the body's `model`). */
1486
+ select: (id: string) => void;
1487
+ /**
1488
+ * Pin `id` on the thread (`null` unpins) — every later turn without its own `model` runs on it,
1489
+ * across reloads. On a chat with no thread yet, the pin lands when the first send creates one.
1490
+ */
1491
+ pinToThread: (id: string | null) => Promise<void>;
1492
+ isLoading: boolean;
1493
+ error: Error | null;
1494
+ }
1495
+ /** Why the composer cannot send right now. */
1496
+ type ComposerBlock = 'empty' | 'busy' | 'uploading' | 'quota';
1497
+ /** A headless composer: the draft, its files, and whether (and why not) it can send. */
1498
+ interface ChatComposer {
1499
+ text: string;
1500
+ setText: (text: string) => void;
1501
+ /** The staged attachments — `useAttachments` state on the chat's backend. */
1502
+ files: AttachmentsState;
1503
+ canSend: boolean;
1504
+ /** Why `canSend` is false, or `null`. */
1505
+ blockedBy: ComposerBlock | null;
1506
+ /** Send the draft with the ready files attached, then clear both. A no-op while blocked. */
1507
+ submit: () => Promise<void>;
1508
+ }
1447
1509
  interface AddToolResultArgs {
1448
1510
  tool: string;
1449
1511
  toolCallId: string;
1450
1512
  output: unknown;
1451
1513
  }
1452
1514
  /**
1453
- * Generalized `useChat` wiring for the nestjs-agent backend. Wraps the
1454
- * AI SDK v7 hook with `AgentChatTransport`, plus thread list/load/delete/
1455
- * fork, quota, cancel, and HITL approve/reject — all driven through
1456
- * `AgentClient`. Mirrors flip's `useAdminChat`, generalized.
1515
+ * The agent chat, wired: the AI SDK v7 `useChat` over `AgentChatTransport`, a thread's history
1516
+ * loaded and a streaming turn re-attached on its own, a quota send gate, a model picker, a headless
1517
+ * composer with attachments, and a transcript whose approve/reject/answer/skip/stop/fork/regenerate
1518
+ * are already bound. Every piece is also a hook of its own (`useChatTranscript`, `useAttachments`,
1519
+ * `useModels`, `useQuota`, `useThreads`) for a host that wants to wire it differently.
1457
1520
  */
1458
1521
  declare function useAgentChat<B extends AgentBackend = AgentBackend>(options?: UseAgentChatOptions<B>): {
1459
1522
  status: ChatStatus;
@@ -1482,46 +1545,44 @@ declare function useAgentChat<B extends AgentBackend = AgentBackend>(options?: U
1482
1545
  /** Sub-agents this conversation started and did not wait for. */
1483
1546
  background: ChatBackground;
1484
1547
  runId: string | undefined;
1485
- /** The `resume`-fetched thread's active run id, or `null` once resolved with none. */
1548
+ /** The loaded thread's running turn, or `null` once read with none. */
1486
1549
  activeRunId: string | null;
1550
+ /** The thread's history is being read. */
1551
+ isLoadingHistory: boolean;
1552
+ /** Reading the thread's history failed. */
1553
+ historyError: Error | null;
1487
1554
  /**
1488
1555
  * The thread this chat is on right now: the `threadId` option, else the one the backend created
1489
1556
  * on the first send. A getter, because the created id is learned mid-stream.
1490
1557
  */
1491
1558
  getThreadId: () => string | undefined;
1492
- setThreadModel: (model: string | null) => Promise<void>;
1493
1559
  /** The backend this chat talks to — the same one every other hook under the provider uses. */
1494
1560
  backend: B;
1495
- threads: ThreadSummary[];
1496
- loadThreads: () => Promise<ThreadSummary[]>;
1497
- loadThread: (id: string) => Promise<ThreadDetail>;
1498
- deleteThread: (id: string) => Promise<void>;
1499
- forkThread: (threadId: string, messageId: string) => Promise<ThreadSummary>;
1500
- renameThread: (id: string, title: string) => Promise<void>;
1501
- promoteThread: (id: string) => Promise<void>;
1502
- truncateFromMessage: (threadId: string, messageId: string) => Promise<void>;
1503
- quota: _dudousxd_nestjs_agent_core.QuotaView | null;
1504
- loadQuota: () => Promise<QuotaToday>;
1561
+ /** The transcript model, with every action already bound to this chat. */
1562
+ transcript: ChatTranscript;
1563
+ /** A headless composer: draft, files, send gate, `submit()`. */
1564
+ composer: ChatComposer;
1565
+ /** The model picker: `list`, `selected`, `select(id)`, `pinToThread(id)`. */
1566
+ models: ChatModels;
1567
+ /** The caller's budget (`GET <base>/quota`); `quota.blocked` gates sends. */
1568
+ quota: QuotaState;
1569
+ /** The window blocking sends right now (the `blocked` option, else the quota report's). */
1570
+ blocked: QuotaBlock | null;
1505
1571
  cancel: () => Promise<void>;
1506
- approve: ({ toolCallId, remember, via, }: {
1507
- toolCallId: string;
1508
- /** Approve later calls of the same tool in this thread without asking. */
1509
- remember?: boolean;
1510
- via?: string;
1511
- }) => Promise<void>;
1512
- reject: ({ toolCallId, reason, via, }: {
1513
- toolCallId: string;
1514
- reason?: string;
1515
- via?: string;
1516
- }) => Promise<void>;
1517
- answer: ({ toolCallId, answers, }: {
1518
- toolCallId: string;
1519
- answers?: Record<string, string[]>;
1572
+ approve: ({ toolCallId, remember, via }: ApproveInput) => Promise<void>;
1573
+ reject: ({ toolCallId, reason, via }: RejectInput) => Promise<void>;
1574
+ answer: ({ toolCallId, answers }: AnswerInput) => Promise<void>;
1575
+ skip: ({ toolCallId }: SkipInput) => Promise<void>;
1576
+ regenerate: (_input?: Partial<MessageActionInput>) => void;
1577
+ fork: ({ messageId, threadId, }: MessageActionInput & {
1578
+ threadId?: string;
1579
+ }) => Promise<ThreadSummary>;
1580
+ truncateFrom: ({ messageId, threadId }: MessageActionInput & {
1581
+ threadId?: string;
1520
1582
  }) => Promise<void>;
1521
- skip: ({ toolCallId }: {
1522
- toolCallId: string;
1583
+ promote: ({ threadId }?: {
1584
+ threadId?: string;
1523
1585
  }) => Promise<void>;
1524
- regenerate: () => void;
1525
1586
  id: string;
1526
1587
  setMessages: (messages: UIMessage<unknown, UIDataTypes, ai.UITools>[] | ((messages: UIMessage<unknown, UIDataTypes, ai.UITools>[]) => UIMessage<unknown, UIDataTypes, ai.UITools>[])) => void;
1527
1588
  error: Error | undefined;
@@ -1532,10 +1593,10 @@ declare function useAgentChat<B extends AgentBackend = AgentBackend>(options?: U
1532
1593
  addToolApprovalResponse: ai.ChatAddToolApproveResponseFunction;
1533
1594
  clearError: () => void;
1534
1595
  };
1535
- /** A send refused on the client because a quota window is exhausted (`useAgentChat({ blocked })`). */
1596
+ /** A send refused on the client because a quota window is exhausted. */
1536
1597
  declare class QuotaBlockedError extends Error {
1537
1598
  readonly block: QuotaBlock;
1538
1599
  constructor(block: QuotaBlock);
1539
1600
  }
1540
1601
 
1541
- export { AgentBackend, AgentChatTransport, type AgentChatTransportOptions, type AgentMessageMetadata, AgentProvider, type AgentProviderProps, type AgentStreamMeta, type AgentsState, type AggregatedTurnUsage, type AmbientRenderUi, AmbientRenderUiContext, AnyToolUIPart, type ApprovalCountdown, ApproveOptions, type AttachmentRejection, AttachmentUploadStrategy, type AttachmentsState, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type ChatBackground, ChatInput, type ChatInputProps, ChatStatus, type ChatTranscript, type ClipboardLikeEvent, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type DragLikeEvent, type MessageFeedbackState, type MessageFile, type MessageFileKind, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, MessageUsageInfo, type ModelOption, type ModelsState, QuotaBlockedError, type QuotaState, QuotaToday, type ReconnectOptions, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, SPEECH_LANGUAGES, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StagedAttachment, type StagedAttachmentStatus, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type StreamConnectionState, type ThreadsEvent, type ThreadsState, TimestampInfo, ToolCatalog, type ToolCatalogState, type TranscriptActionState, TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, TranscriptFile, type TranscriptItem, type TranscriptItemOptions, type TranscriptStopState, TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, UploadAttachmentOptions, UsageSummary, type UseAgentChatOptions, type UseAgentsOptions, type UseApprovalCountdownOptions, type UseAttachmentsOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseMessageFeedbackOptions, type UseModelsOptions, type UseQuotaOptions, type UseSpeechRecognitionOptions, type UseThreadsOptions, type UseToolCatalogOptions, type UseTranscriptItemOptions, acceptsFile, applyCompletion, approvalCountdown, backgroundRunsFromThread, createSkillsSource, dragHasFiles, fileKind, filesFromClipboard, filterAutocompleteItems, findActiveTrigger, formatElapsed, loadStoredSpeechLang, messageFiles, notifyThreads, onThreadsEvent, persistSpeechLang, readReasoningMs, storedMessageToUiMessage, storedThreadToUiMessages, useAgentBackend, useAgentChat, useAgents, useAmbientRenderUi, useApprovalCountdown, useAttachments, useChatTranscript, useComposerAutocomplete, useElapsed, useMessageFeedback, useModels, useQuota, useSpeechRecognition, useStickToBottom, useThreads, useToolCatalog, useTranscriptItem };
1602
+ export { AgentBackend, AgentChatTransport, type AgentChatTransportOptions, type AgentMessageMetadata, AgentProvider, type AgentProviderProps, type AgentStreamMeta, type AgentsState, type AggregatedTurnUsage, type AmbientRenderUi, AmbientRenderUiContext, type AnswerInput, AnyToolUIPart, type ApprovalCountdown, type ApproveInput, ApproveOptions, type AttachmentRejection, AttachmentUploadStrategy, type AttachmentsState, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type ChatBackground, ChatInput, type ChatInputProps, ChatStatus, type ChatTranscript, type ClipboardLikeEvent, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type DragLikeEvent, type EditSubmitInput, type MessageActionInput, type MessageFeedbackState, type MessageFile, type MessageFileKind, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, MessageUsageInfo, type ModelOption, type ModelsState, QuotaBlockedError, type QuotaState, type ReconnectOptions, type RejectInput, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, SPEECH_LANGUAGES, type SkillSuggestionData, type SkillsSourceOptions, type SkipInput, type SpeechLanguage, type SpeechRecognitionHook, type StagedAttachment, type StagedAttachmentStatus, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type StreamConnectionState, type ThreadsEvent, type ThreadsState, TimestampInfo, ToolCatalog, type ToolCatalogState, type TranscriptActionState, TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, TranscriptFile, type TranscriptItem, type TranscriptItemOptions, type TranscriptStopState, TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, UploadAttachmentOptions, UsageSummary, type UseAgentChatOptions, type UseAgentsOptions, type UseApprovalCountdownOptions, type UseAttachmentsOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseMessageFeedbackOptions, type UseModelsOptions, type UseQuotaOptions, type UseSpeechRecognitionOptions, type UseThreadsOptions, type UseToolCatalogOptions, type UseTranscriptItemOptions, acceptsFile, applyCompletion, approvalCountdown, backgroundRunsFromThread, createSkillsSource, dragHasFiles, fileKind, filesFromClipboard, filterAutocompleteItems, findActiveTrigger, formatElapsed, loadStoredSpeechLang, messageFiles, notifyThreads, onThreadsEvent, persistSpeechLang, readReasoningMs, storedMessageToUiMessage, storedThreadToUiMessages, useAgentBackend, useAgentChat, useAgents, useAmbientRenderUi, useApprovalCountdown, useAttachments, useChatTranscript, useComposerAutocomplete, useElapsed, useMessageFeedback, useModels, useQuota, useSpeechRecognition, useStickToBottom, useThreads, useToolCatalog, useTranscriptItem };