@dudousxd/nestjs-agent-react 0.19.0 → 0.20.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,135 +1,14 @@
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 AgentClient, b as AttachmentUploadStrategy, Q as QuotaToday } from './client-0Wd-WPsu.cjs';
4
+ export { c as AgentBackendUnsupportedError, 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-0Wd-WPsu.cjs';
3
5
  import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
4
- import { ThreadSummary, ThreadDetail, MessageAttachment, ToolCatalogEntry, SkillCatalogEntry, QuotaView, QuotaReport, ModelCatalogView, AgentCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogEntry, QuotaWindow, QuotaBlock, StoredMessage } 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';
5
7
  export { ElicitationInput, ElicitationInputType, validateElicitationAnswer as validateAnswer, validateElicitationValue as validateAnswerValue } from '@dudousxd/nestjs-agent-core';
6
8
  import React__default, { ReactNode, Context } from 'react';
7
9
  import { T as TranscriptUiBlock, a as TranscriptBlock, U as UsageSummary, b as TimestampInfo, C as ChatStatus, M as MessageUsageInfo, c as ToolCatalog, A as ApproveOptions, d as AnyToolUIPart, e as TranscriptFile } from './model-gHqjNjLJ.cjs';
8
10
  export { f as ApprovalBlockOptions, B as BuildBlocksOptions, g as CoercibleQuestion, D as DescribeToolCallOptions, E as ElicitationBlockOptions, G as GroupToolActivityOptions, R as RawAnswer, h as ResolvedReading, i as ResolvedResultView, j as RetrievedPassage, S as SettleAction, k as ToolActivityGroup, l as ToolCallDescription, m as ToolCallState, n as ToolCallStatus, o as TranscriptApproval, p as TranscriptApprovalStatus, q as TranscriptElicitationBlock, r as TranscriptElicitationOutcome, s as TranscriptFilesBlock, t as TranscriptQuestion, u as TranscriptQuestionOption, v as TranscriptReasoningBlock, w as TranscriptSettleState, x as TranscriptSource, y as TranscriptSourcesBlock, z as TranscriptTextBlock, F as TranscriptToolBlock, H as TranscriptToolCall, I as buildTranscriptBlocks, J as coerceAnswer, K as correctedCallIds, L as describeTimestamp, N as describeToolCall, O as describeUsage, P as extractMessageText, Q as fillTemplate, V as formatRelativeTime, W as groupToolActivity, X as inferResultView, Y as isActionCall, Z as phraseFor, _ as readPath, $ as resolveResultView, a0 as toolCallState, a1 as toolCatalogFrom } from './model-gHqjNjLJ.cjs';
9
11
 
10
- /**
11
- * Partial update accepted by `PATCH <base>/threads/:threadId`. `defaultAgent: null` clears a
12
- * previously-set default back to the module's own default; omitting it leaves the thread's
13
- * current default untouched.
14
- */
15
- interface ThreadPatch {
16
- title?: string;
17
- defaultAgent?: string | null;
18
- /** Pin a catalog model on the thread; `null` unpins it. */
19
- model?: string | null;
20
- }
21
- /** Starting a turn: the body `POST <base>/chat` takes (see docs/stream-protocol.md). */
22
- interface ChatStreamRequest {
23
- /** `{ message, threadId?, agent?, model?, attachments?, pageContext?, regenerate?, … }`. */
24
- body: Record<string, unknown>;
25
- /** Per-request headers the AI SDK was handed for this send. */
26
- headers?: Record<string, string>;
27
- /** Aborted when the user stops the turn. */
28
- signal?: AbortSignal;
29
- }
30
- /** Attaching to a run that is already streaming: `GET <base>/chat/:runId/stream?after=<seq>`. */
31
- interface ResumeStreamRequest {
32
- runId: string;
33
- /**
34
- * The sequence number (SSE `id:`) of the last frame the client already has. Omitted → replay
35
- * from the first frame. A backend that cannot skip may ignore it: the transport also drops frames
36
- * at or below it.
37
- */
38
- after?: number;
39
- headers?: Record<string, string>;
40
- signal?: AbortSignal;
41
- }
42
- /**
43
- * An open chat stream: the raw `text/event-stream` bytes in the stream-protocol framing, plus the
44
- * identity a backend may learn before the first frame (the `X-Agent-Run-Id` / `X-Agent-Thread-Id`
45
- * headers). The body's own `event: meta` frame supplies them otherwise.
46
- */
47
- interface ChatStreamResponse {
48
- body: ReadableStream<Uint8Array>;
49
- runId?: string;
50
- threadId?: string;
51
- }
52
- /** What `POST <base>/messages/:id/feedback` takes. `value: null` clears the rating. */
53
- interface MessageFeedbackInput {
54
- value: MessageFeedbackValue | null;
55
- comment?: string;
56
- }
57
- interface UploadAttachmentOptions {
58
- signal?: AbortSignal;
59
- /** Called with 0..1 as the upload progresses, when the backend can observe it. */
60
- onProgress?: (fraction: number) => void;
61
- }
62
- /**
63
- * Everything the React layer asks of a server — the seam between `useAgentChat` (and the other
64
- * hooks) and whatever serves the agent. {@link AgentClient} is the default implementation, over the
65
- * library's own REST routes with `fetch`. An app with its own client — a generated one, a different
66
- * auth scheme (cookie session + CSRF header), a backend that is not this library at all but speaks
67
- * docs/stream-protocol.md — implements this instead and passes it as `useAgentChat({ backend })`.
68
- *
69
- * The streaming, thread and cancel members are required: without them there is no chat. The rest
70
- * are optional; a hook that needs one the backend does not have throws
71
- * {@link AgentBackendUnsupportedError} when it is called, so a backend only implements what its
72
- * server supports.
73
- */
74
- interface AgentBackend {
75
- /** Start a turn and return its SSE stream. Throw on a non-2xx answer. */
76
- openChatStream(request: ChatStreamRequest): Promise<ChatStreamResponse>;
77
- /** Attach to a streaming run. Resolve `null` when nothing is streaming under that id (HTTP 404). */
78
- resumeChatStream(request: ResumeStreamRequest): Promise<ChatStreamResponse | null>;
79
- /** Hard-stop a run server-side. */
80
- cancelStream(runId: string): Promise<unknown>;
81
- listThreads(): Promise<ThreadSummary[]>;
82
- getThread(id: string): Promise<ThreadDetail>;
83
- updateThread(id: string, patch: ThreadPatch): Promise<unknown>;
84
- deleteThread(id: string): Promise<unknown>;
85
- forkFromMessage?(threadId: string, messageId: string): Promise<ThreadSummary>;
86
- promoteThread?(id: string): Promise<unknown>;
87
- truncateFromMessage?(threadId: string, messageId: string): Promise<unknown>;
88
- approveToolCall?(input: {
89
- toolCallId: string;
90
- remember?: boolean;
91
- via?: string;
92
- }): Promise<unknown>;
93
- rejectToolCall?(input: {
94
- toolCallId: string;
95
- reason?: string;
96
- via?: string;
97
- }): Promise<unknown>;
98
- answerToolCall?(input: {
99
- toolCallId: string;
100
- answers?: Record<string, string[]>;
101
- }): Promise<unknown>;
102
- skipToolCall?(input: {
103
- toolCallId: string;
104
- }): Promise<unknown>;
105
- uploadAttachment?(file: File, options?: UploadAttachmentOptions): Promise<MessageAttachment>;
106
- listTools?(agent?: string): Promise<ToolCatalogEntry[]>;
107
- listSkills?(threadId?: string): Promise<SkillCatalogEntry[]>;
108
- getQuotaToday?(): Promise<QuotaView>;
109
- /** `GET <base>/quota` — every budget window, and which one blocks sends, if any. */
110
- getQuota?(): Promise<QuotaReport>;
111
- /** `GET <base>/models?agent=` — what a model picker offers. */
112
- listModels?(agent?: string): Promise<ModelCatalogView>;
113
- /** `GET <base>/agents` — what an agent picker offers. */
114
- listAgents?(): Promise<AgentCatalogEntry[]>;
115
- setMessageFeedback?(messageId: string, input: MessageFeedbackInput): Promise<{
116
- feedback: MessageFeedback | null;
117
- }>;
118
- }
119
- /** An optional {@link AgentBackend} member the bound backend does not implement was called. */
120
- declare class AgentBackendUnsupportedError extends Error {
121
- readonly method: string;
122
- constructor(method: string);
123
- }
124
- type OptionalMethod = {
125
- [K in keyof AgentBackend]-?: undefined extends AgentBackend[K] ? K : never;
126
- }[keyof AgentBackend];
127
- /**
128
- * The optional backend method `name`, bound — or a throw naming it. For hook code that has to call
129
- * something a backend may not offer.
130
- */
131
- declare function requireBackendMethod<K extends OptionalMethod>(backend: AgentBackend, name: K): NonNullable<AgentBackend[K]>;
132
-
133
12
  /** Identity surfaced by the backend's `meta` SSE frame / response headers. */
134
13
  interface AgentStreamMeta {
135
14
  runId: string;
@@ -618,141 +497,6 @@ interface BackgroundRun {
618
497
  */
619
498
  declare function backgroundRunsFromThread(messages: readonly StoredMessage[]): BackgroundRun[];
620
499
 
621
- /**
622
- * Thrown by {@link AgentClient} on a non-2xx response. Carries the HTTP `status` so callers can
623
- * branch (e.g. 403 → "not your thread", 429 → quota) instead of string-matching a generic Error.
624
- */
625
- declare class AgentHttpError extends Error {
626
- readonly status: number;
627
- readonly method: string;
628
- readonly path: string;
629
- constructor(status: number, method: string, path: string, statusText: string);
630
- }
631
- /** The quota-today read-model: usage, the configured limit (null → unlimited), and USD spend. */
632
- type QuotaToday = QuotaView;
633
- interface CancelResult {
634
- aborted: boolean;
635
- }
636
- interface OkResult {
637
- ok: boolean;
638
- }
639
- interface AgentClientOptions {
640
- /** Origin + base path, e.g. `https://api.example.com`. Defaults to `''`. */
641
- baseUrl?: string;
642
- /** Static headers merged into every request. */
643
- headers?: Record<string, string>;
644
- /**
645
- * Resolved per request — for short-lived bearer tokens, or a CSRF header read from a cookie
646
- * (`{ 'X-XSRF-TOKEN': readCookie('XSRF-TOKEN') }`), which has to be read at request time because
647
- * the server may rotate it.
648
- */
649
- getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
650
- /**
651
- * Forwarded to fetch so cookie auth works. Same-origin requests send cookies by default; set
652
- * `'include'` when the API lives on another origin (and have it answer with credentialed CORS).
653
- */
654
- credentials?: RequestCredentials;
655
- /** Injectable for tests / non-browser runtimes. */
656
- fetch?: typeof fetch;
657
- }
658
- /**
659
- * Framework-agnostic REST client for the nestjs-agent endpoints — the default {@link AgentBackend}.
660
- * Used by `useAgentChat`, but standalone-usable (vanilla fetch, no React).
661
- */
662
- declare class AgentClient implements AgentBackend {
663
- private readonly options;
664
- constructor(options?: AgentClientOptions);
665
- /** `POST /agent/chat` → the turn's SSE stream. Throws {@link AgentHttpError} on a non-2xx. */
666
- openChatStream(request: ChatStreamRequest): Promise<ChatStreamResponse>;
667
- /**
668
- * `GET /agent/chat/:runId/stream[?after=<seq>]` → the run's SSE stream, or `null` when nothing is
669
- * streaming under that id (404).
670
- */
671
- resumeChatStream(request: ResumeStreamRequest): Promise<ChatStreamResponse | null>;
672
- /**
673
- * Rate a message (`'up'`/`'down'`, optional comment) or clear its rating (`value: null`). Answers
674
- * the stored rating.
675
- */
676
- setMessageFeedback(messageId: string, input: MessageFeedbackInput): Promise<{
677
- feedback: MessageFeedback | null;
678
- }>;
679
- listThreads(): Promise<ThreadSummary[]>;
680
- /**
681
- * The skills this caller can invoke right now, scope-resolved — the same list, built by the same
682
- * call, that the model is offered, so what a user can type after a `/` and what the agent can
683
- * reach cannot drift apart. `threadId` reaches the host's own resolver, which may scope a skill to
684
- * one conversation; omitted, the server reads it as a brand-new thread.
685
- */
686
- listSkills(threadId?: string): Promise<SkillCatalogEntry[]>;
687
- /**
688
- * The tools this caller can reach through `agent` (the default agent when omitted), each with the
689
- * server-declared `presentation` a chat narrates it by — the same list the model is offered.
690
- * Prefer {@link useToolCatalog}, which fetches it once and shares it.
691
- */
692
- listTools(agent?: string): Promise<ToolCatalogEntry[]>;
693
- getThread(id: string): Promise<ThreadDetail>;
694
- deleteThread(id: string): Promise<void>;
695
- forkFromMessage(threadId: string, messageId: string): Promise<ThreadSummary>;
696
- renameThread(id: string, title: string): Promise<OkResult>;
697
- /** General `PATCH /agent/threads/:threadId` — title and/or the thread's pinned default agent. */
698
- updateThread(id: string, patch: ThreadPatch): Promise<OkResult>;
699
- /**
700
- * Uploads a file (image/PDF) for a vision-capable model turn. Multipart, field name `file` —
701
- * mirrors the backend's `POST /agent/attachments`. The returned {@link MessageAttachment} is
702
- * what a caller then rides on `sendMessage({ text }, { body: { attachments: [...] } })`.
703
- */
704
- uploadAttachment(file: File, options?: UploadAttachmentOptions): Promise<MessageAttachment>;
705
- private uploadWithProgress;
706
- promoteThread(id: string): Promise<OkResult>;
707
- truncateFromMessage(threadId: string, messageId: string): Promise<OkResult>;
708
- /** `GET /agent/models?agent=` — the models this caller may pick, grouped by provider. */
709
- listModels(agent?: string): Promise<ModelCatalogView>;
710
- /** `GET /agent/agents` — the registered agents, the default one flagged. */
711
- listAgents(): Promise<AgentCatalogEntry[]>;
712
- /** `GET /agent/quota` — the caller's budget windows and the one blocking sends, if any. */
713
- getQuota(): Promise<QuotaReport>;
714
- getQuotaToday(): Promise<QuotaToday>;
715
- cancelStream(runId: string): Promise<CancelResult>;
716
- /**
717
- * `remember` approves later calls of the same tool in the same thread; `via` names the surface
718
- * the decision came through (the server records `'web'` when omitted).
719
- */
720
- approveToolCall(input: {
721
- toolCallId: string;
722
- remember?: boolean;
723
- via?: string;
724
- }): Promise<void>;
725
- rejectToolCall(input: {
726
- toolCallId: string;
727
- reason?: string;
728
- via?: string;
729
- }): Promise<void>;
730
- /**
731
- * Settle a parked question set. `answers` is questionId → chosen option values; a question left
732
- * out takes the pre-picked default the request carried, resolved server-side against the request
733
- * the run already holds. Omit the whole object and the user has confirmed every pre-picked
734
- * answer — which is the point of the surface, so it is a valid submission rather than a blank.
735
- */
736
- answerToolCall(input: {
737
- toolCallId: string;
738
- answers?: Record<string, string[]>;
739
- }): Promise<void>;
740
- /**
741
- * Decline to answer and let the agent proceed on its own pre-picked values. Lands on the same
742
- * values a confirmation would, and persists differently on purpose — only one of them is
743
- * evidence the user chose them.
744
- */
745
- skipToolCall(input: {
746
- toolCallId: string;
747
- }): Promise<void>;
748
- private fetchImpl;
749
- private baseUrl;
750
- private resolveHeaders;
751
- private credentials;
752
- private request;
753
- private handleResponse;
754
- }
755
-
756
500
  /** Draws a server-pushed component block. */
757
501
  type AmbientRenderUi = (block: TranscriptUiBlock) => ReactNode;
758
502
  /**
@@ -1551,6 +1295,12 @@ interface UseAgentChatOptions<B extends AgentBackend = AgentClient> {
1551
1295
  credentials?: RequestCredentials;
1552
1296
  /** Injectable for tests / non-browser runtimes. */
1553
1297
  fetch?: typeof fetch;
1298
+ /**
1299
+ * How the built-in client uploads attachments (ignored when a backend is given) — e.g.
1300
+ * `mediaAttachments()` from `@dudousxd/nestjs-agent-react/media`. Pass `chat.backend` to
1301
+ * `useAttachments` and every composer uses it.
1302
+ */
1303
+ attachments?: AttachmentUploadStrategy;
1554
1304
  /** Reuse an existing client instead of constructing one. Prefer {@link backend}. */
1555
1305
  client?: B;
1556
1306
  /** Named agent to run each turn. */
@@ -1757,4 +1507,4 @@ declare class QuotaBlockedError extends Error {
1757
1507
  constructor(block: QuotaBlock);
1758
1508
  }
1759
1509
 
1760
- export { type AgentBackend, AgentBackendUnsupportedError, AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentMessageMetadata, type AgentStreamMeta, type AgentsState, type AggregatedTurnUsage, type AmbientRenderUi, AmbientRenderUiContext, AnyToolUIPart, type ApprovalCountdown, ApproveOptions, type AttachmentRejection, type AttachmentsState, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, ChatStatus, type ChatStreamRequest, type ChatStreamResponse, type ChatTranscript, type ClipboardLikeEvent, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type DragLikeEvent, type MessageFeedbackInput, 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 QuotaToday, type ReconnectOptions, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type ResumeStreamRequest, SPEECH_LANGUAGES, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StagedAttachment, type StagedAttachmentStatus, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type StreamConnectionState, type ThreadPatch, 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, type 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, requireBackendMethod, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useAgents, useAmbientRenderUi, useApprovalCountdown, useAttachments, useChatTranscript, useComposerAutocomplete, useElapsed, useMessageFeedback, useModels, useQuota, useSpeechRecognition, useStickToBottom, useThreads, useToolCatalog, useTranscriptItem };
1510
+ export { AgentBackend, AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentMessageMetadata, 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, useAgentChat, useAgents, useAmbientRenderUi, useApprovalCountdown, useAttachments, useChatTranscript, useComposerAutocomplete, useElapsed, useMessageFeedback, useModels, useQuota, useSpeechRecognition, useStickToBottom, useThreads, useToolCatalog, useTranscriptItem };
package/dist/index.d.ts CHANGED
@@ -1,135 +1,14 @@
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 AgentClient, b as AttachmentUploadStrategy, Q as QuotaToday } from './client-0Wd-WPsu.js';
4
+ export { c as AgentBackendUnsupportedError, 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-0Wd-WPsu.js';
3
5
  import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
4
- import { ThreadSummary, ThreadDetail, MessageAttachment, ToolCatalogEntry, SkillCatalogEntry, QuotaView, QuotaReport, ModelCatalogView, AgentCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogEntry, QuotaWindow, QuotaBlock, StoredMessage } 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';
5
7
  export { ElicitationInput, ElicitationInputType, validateElicitationAnswer as validateAnswer, validateElicitationValue as validateAnswerValue } from '@dudousxd/nestjs-agent-core';
6
8
  import React__default, { ReactNode, Context } from 'react';
7
9
  import { T as TranscriptUiBlock, a as TranscriptBlock, U as UsageSummary, b as TimestampInfo, C as ChatStatus, M as MessageUsageInfo, c as ToolCatalog, A as ApproveOptions, d as AnyToolUIPart, e as TranscriptFile } from './model-gHqjNjLJ.js';
8
10
  export { f as ApprovalBlockOptions, B as BuildBlocksOptions, g as CoercibleQuestion, D as DescribeToolCallOptions, E as ElicitationBlockOptions, G as GroupToolActivityOptions, R as RawAnswer, h as ResolvedReading, i as ResolvedResultView, j as RetrievedPassage, S as SettleAction, k as ToolActivityGroup, l as ToolCallDescription, m as ToolCallState, n as ToolCallStatus, o as TranscriptApproval, p as TranscriptApprovalStatus, q as TranscriptElicitationBlock, r as TranscriptElicitationOutcome, s as TranscriptFilesBlock, t as TranscriptQuestion, u as TranscriptQuestionOption, v as TranscriptReasoningBlock, w as TranscriptSettleState, x as TranscriptSource, y as TranscriptSourcesBlock, z as TranscriptTextBlock, F as TranscriptToolBlock, H as TranscriptToolCall, I as buildTranscriptBlocks, J as coerceAnswer, K as correctedCallIds, L as describeTimestamp, N as describeToolCall, O as describeUsage, P as extractMessageText, Q as fillTemplate, V as formatRelativeTime, W as groupToolActivity, X as inferResultView, Y as isActionCall, Z as phraseFor, _ as readPath, $ as resolveResultView, a0 as toolCallState, a1 as toolCatalogFrom } from './model-gHqjNjLJ.js';
9
11
 
10
- /**
11
- * Partial update accepted by `PATCH <base>/threads/:threadId`. `defaultAgent: null` clears a
12
- * previously-set default back to the module's own default; omitting it leaves the thread's
13
- * current default untouched.
14
- */
15
- interface ThreadPatch {
16
- title?: string;
17
- defaultAgent?: string | null;
18
- /** Pin a catalog model on the thread; `null` unpins it. */
19
- model?: string | null;
20
- }
21
- /** Starting a turn: the body `POST <base>/chat` takes (see docs/stream-protocol.md). */
22
- interface ChatStreamRequest {
23
- /** `{ message, threadId?, agent?, model?, attachments?, pageContext?, regenerate?, … }`. */
24
- body: Record<string, unknown>;
25
- /** Per-request headers the AI SDK was handed for this send. */
26
- headers?: Record<string, string>;
27
- /** Aborted when the user stops the turn. */
28
- signal?: AbortSignal;
29
- }
30
- /** Attaching to a run that is already streaming: `GET <base>/chat/:runId/stream?after=<seq>`. */
31
- interface ResumeStreamRequest {
32
- runId: string;
33
- /**
34
- * The sequence number (SSE `id:`) of the last frame the client already has. Omitted → replay
35
- * from the first frame. A backend that cannot skip may ignore it: the transport also drops frames
36
- * at or below it.
37
- */
38
- after?: number;
39
- headers?: Record<string, string>;
40
- signal?: AbortSignal;
41
- }
42
- /**
43
- * An open chat stream: the raw `text/event-stream` bytes in the stream-protocol framing, plus the
44
- * identity a backend may learn before the first frame (the `X-Agent-Run-Id` / `X-Agent-Thread-Id`
45
- * headers). The body's own `event: meta` frame supplies them otherwise.
46
- */
47
- interface ChatStreamResponse {
48
- body: ReadableStream<Uint8Array>;
49
- runId?: string;
50
- threadId?: string;
51
- }
52
- /** What `POST <base>/messages/:id/feedback` takes. `value: null` clears the rating. */
53
- interface MessageFeedbackInput {
54
- value: MessageFeedbackValue | null;
55
- comment?: string;
56
- }
57
- interface UploadAttachmentOptions {
58
- signal?: AbortSignal;
59
- /** Called with 0..1 as the upload progresses, when the backend can observe it. */
60
- onProgress?: (fraction: number) => void;
61
- }
62
- /**
63
- * Everything the React layer asks of a server — the seam between `useAgentChat` (and the other
64
- * hooks) and whatever serves the agent. {@link AgentClient} is the default implementation, over the
65
- * library's own REST routes with `fetch`. An app with its own client — a generated one, a different
66
- * auth scheme (cookie session + CSRF header), a backend that is not this library at all but speaks
67
- * docs/stream-protocol.md — implements this instead and passes it as `useAgentChat({ backend })`.
68
- *
69
- * The streaming, thread and cancel members are required: without them there is no chat. The rest
70
- * are optional; a hook that needs one the backend does not have throws
71
- * {@link AgentBackendUnsupportedError} when it is called, so a backend only implements what its
72
- * server supports.
73
- */
74
- interface AgentBackend {
75
- /** Start a turn and return its SSE stream. Throw on a non-2xx answer. */
76
- openChatStream(request: ChatStreamRequest): Promise<ChatStreamResponse>;
77
- /** Attach to a streaming run. Resolve `null` when nothing is streaming under that id (HTTP 404). */
78
- resumeChatStream(request: ResumeStreamRequest): Promise<ChatStreamResponse | null>;
79
- /** Hard-stop a run server-side. */
80
- cancelStream(runId: string): Promise<unknown>;
81
- listThreads(): Promise<ThreadSummary[]>;
82
- getThread(id: string): Promise<ThreadDetail>;
83
- updateThread(id: string, patch: ThreadPatch): Promise<unknown>;
84
- deleteThread(id: string): Promise<unknown>;
85
- forkFromMessage?(threadId: string, messageId: string): Promise<ThreadSummary>;
86
- promoteThread?(id: string): Promise<unknown>;
87
- truncateFromMessage?(threadId: string, messageId: string): Promise<unknown>;
88
- approveToolCall?(input: {
89
- toolCallId: string;
90
- remember?: boolean;
91
- via?: string;
92
- }): Promise<unknown>;
93
- rejectToolCall?(input: {
94
- toolCallId: string;
95
- reason?: string;
96
- via?: string;
97
- }): Promise<unknown>;
98
- answerToolCall?(input: {
99
- toolCallId: string;
100
- answers?: Record<string, string[]>;
101
- }): Promise<unknown>;
102
- skipToolCall?(input: {
103
- toolCallId: string;
104
- }): Promise<unknown>;
105
- uploadAttachment?(file: File, options?: UploadAttachmentOptions): Promise<MessageAttachment>;
106
- listTools?(agent?: string): Promise<ToolCatalogEntry[]>;
107
- listSkills?(threadId?: string): Promise<SkillCatalogEntry[]>;
108
- getQuotaToday?(): Promise<QuotaView>;
109
- /** `GET <base>/quota` — every budget window, and which one blocks sends, if any. */
110
- getQuota?(): Promise<QuotaReport>;
111
- /** `GET <base>/models?agent=` — what a model picker offers. */
112
- listModels?(agent?: string): Promise<ModelCatalogView>;
113
- /** `GET <base>/agents` — what an agent picker offers. */
114
- listAgents?(): Promise<AgentCatalogEntry[]>;
115
- setMessageFeedback?(messageId: string, input: MessageFeedbackInput): Promise<{
116
- feedback: MessageFeedback | null;
117
- }>;
118
- }
119
- /** An optional {@link AgentBackend} member the bound backend does not implement was called. */
120
- declare class AgentBackendUnsupportedError extends Error {
121
- readonly method: string;
122
- constructor(method: string);
123
- }
124
- type OptionalMethod = {
125
- [K in keyof AgentBackend]-?: undefined extends AgentBackend[K] ? K : never;
126
- }[keyof AgentBackend];
127
- /**
128
- * The optional backend method `name`, bound — or a throw naming it. For hook code that has to call
129
- * something a backend may not offer.
130
- */
131
- declare function requireBackendMethod<K extends OptionalMethod>(backend: AgentBackend, name: K): NonNullable<AgentBackend[K]>;
132
-
133
12
  /** Identity surfaced by the backend's `meta` SSE frame / response headers. */
134
13
  interface AgentStreamMeta {
135
14
  runId: string;
@@ -618,141 +497,6 @@ interface BackgroundRun {
618
497
  */
619
498
  declare function backgroundRunsFromThread(messages: readonly StoredMessage[]): BackgroundRun[];
620
499
 
621
- /**
622
- * Thrown by {@link AgentClient} on a non-2xx response. Carries the HTTP `status` so callers can
623
- * branch (e.g. 403 → "not your thread", 429 → quota) instead of string-matching a generic Error.
624
- */
625
- declare class AgentHttpError extends Error {
626
- readonly status: number;
627
- readonly method: string;
628
- readonly path: string;
629
- constructor(status: number, method: string, path: string, statusText: string);
630
- }
631
- /** The quota-today read-model: usage, the configured limit (null → unlimited), and USD spend. */
632
- type QuotaToday = QuotaView;
633
- interface CancelResult {
634
- aborted: boolean;
635
- }
636
- interface OkResult {
637
- ok: boolean;
638
- }
639
- interface AgentClientOptions {
640
- /** Origin + base path, e.g. `https://api.example.com`. Defaults to `''`. */
641
- baseUrl?: string;
642
- /** Static headers merged into every request. */
643
- headers?: Record<string, string>;
644
- /**
645
- * Resolved per request — for short-lived bearer tokens, or a CSRF header read from a cookie
646
- * (`{ 'X-XSRF-TOKEN': readCookie('XSRF-TOKEN') }`), which has to be read at request time because
647
- * the server may rotate it.
648
- */
649
- getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
650
- /**
651
- * Forwarded to fetch so cookie auth works. Same-origin requests send cookies by default; set
652
- * `'include'` when the API lives on another origin (and have it answer with credentialed CORS).
653
- */
654
- credentials?: RequestCredentials;
655
- /** Injectable for tests / non-browser runtimes. */
656
- fetch?: typeof fetch;
657
- }
658
- /**
659
- * Framework-agnostic REST client for the nestjs-agent endpoints — the default {@link AgentBackend}.
660
- * Used by `useAgentChat`, but standalone-usable (vanilla fetch, no React).
661
- */
662
- declare class AgentClient implements AgentBackend {
663
- private readonly options;
664
- constructor(options?: AgentClientOptions);
665
- /** `POST /agent/chat` → the turn's SSE stream. Throws {@link AgentHttpError} on a non-2xx. */
666
- openChatStream(request: ChatStreamRequest): Promise<ChatStreamResponse>;
667
- /**
668
- * `GET /agent/chat/:runId/stream[?after=<seq>]` → the run's SSE stream, or `null` when nothing is
669
- * streaming under that id (404).
670
- */
671
- resumeChatStream(request: ResumeStreamRequest): Promise<ChatStreamResponse | null>;
672
- /**
673
- * Rate a message (`'up'`/`'down'`, optional comment) or clear its rating (`value: null`). Answers
674
- * the stored rating.
675
- */
676
- setMessageFeedback(messageId: string, input: MessageFeedbackInput): Promise<{
677
- feedback: MessageFeedback | null;
678
- }>;
679
- listThreads(): Promise<ThreadSummary[]>;
680
- /**
681
- * The skills this caller can invoke right now, scope-resolved — the same list, built by the same
682
- * call, that the model is offered, so what a user can type after a `/` and what the agent can
683
- * reach cannot drift apart. `threadId` reaches the host's own resolver, which may scope a skill to
684
- * one conversation; omitted, the server reads it as a brand-new thread.
685
- */
686
- listSkills(threadId?: string): Promise<SkillCatalogEntry[]>;
687
- /**
688
- * The tools this caller can reach through `agent` (the default agent when omitted), each with the
689
- * server-declared `presentation` a chat narrates it by — the same list the model is offered.
690
- * Prefer {@link useToolCatalog}, which fetches it once and shares it.
691
- */
692
- listTools(agent?: string): Promise<ToolCatalogEntry[]>;
693
- getThread(id: string): Promise<ThreadDetail>;
694
- deleteThread(id: string): Promise<void>;
695
- forkFromMessage(threadId: string, messageId: string): Promise<ThreadSummary>;
696
- renameThread(id: string, title: string): Promise<OkResult>;
697
- /** General `PATCH /agent/threads/:threadId` — title and/or the thread's pinned default agent. */
698
- updateThread(id: string, patch: ThreadPatch): Promise<OkResult>;
699
- /**
700
- * Uploads a file (image/PDF) for a vision-capable model turn. Multipart, field name `file` —
701
- * mirrors the backend's `POST /agent/attachments`. The returned {@link MessageAttachment} is
702
- * what a caller then rides on `sendMessage({ text }, { body: { attachments: [...] } })`.
703
- */
704
- uploadAttachment(file: File, options?: UploadAttachmentOptions): Promise<MessageAttachment>;
705
- private uploadWithProgress;
706
- promoteThread(id: string): Promise<OkResult>;
707
- truncateFromMessage(threadId: string, messageId: string): Promise<OkResult>;
708
- /** `GET /agent/models?agent=` — the models this caller may pick, grouped by provider. */
709
- listModels(agent?: string): Promise<ModelCatalogView>;
710
- /** `GET /agent/agents` — the registered agents, the default one flagged. */
711
- listAgents(): Promise<AgentCatalogEntry[]>;
712
- /** `GET /agent/quota` — the caller's budget windows and the one blocking sends, if any. */
713
- getQuota(): Promise<QuotaReport>;
714
- getQuotaToday(): Promise<QuotaToday>;
715
- cancelStream(runId: string): Promise<CancelResult>;
716
- /**
717
- * `remember` approves later calls of the same tool in the same thread; `via` names the surface
718
- * the decision came through (the server records `'web'` when omitted).
719
- */
720
- approveToolCall(input: {
721
- toolCallId: string;
722
- remember?: boolean;
723
- via?: string;
724
- }): Promise<void>;
725
- rejectToolCall(input: {
726
- toolCallId: string;
727
- reason?: string;
728
- via?: string;
729
- }): Promise<void>;
730
- /**
731
- * Settle a parked question set. `answers` is questionId → chosen option values; a question left
732
- * out takes the pre-picked default the request carried, resolved server-side against the request
733
- * the run already holds. Omit the whole object and the user has confirmed every pre-picked
734
- * answer — which is the point of the surface, so it is a valid submission rather than a blank.
735
- */
736
- answerToolCall(input: {
737
- toolCallId: string;
738
- answers?: Record<string, string[]>;
739
- }): Promise<void>;
740
- /**
741
- * Decline to answer and let the agent proceed on its own pre-picked values. Lands on the same
742
- * values a confirmation would, and persists differently on purpose — only one of them is
743
- * evidence the user chose them.
744
- */
745
- skipToolCall(input: {
746
- toolCallId: string;
747
- }): Promise<void>;
748
- private fetchImpl;
749
- private baseUrl;
750
- private resolveHeaders;
751
- private credentials;
752
- private request;
753
- private handleResponse;
754
- }
755
-
756
500
  /** Draws a server-pushed component block. */
757
501
  type AmbientRenderUi = (block: TranscriptUiBlock) => ReactNode;
758
502
  /**
@@ -1551,6 +1295,12 @@ interface UseAgentChatOptions<B extends AgentBackend = AgentClient> {
1551
1295
  credentials?: RequestCredentials;
1552
1296
  /** Injectable for tests / non-browser runtimes. */
1553
1297
  fetch?: typeof fetch;
1298
+ /**
1299
+ * How the built-in client uploads attachments (ignored when a backend is given) — e.g.
1300
+ * `mediaAttachments()` from `@dudousxd/nestjs-agent-react/media`. Pass `chat.backend` to
1301
+ * `useAttachments` and every composer uses it.
1302
+ */
1303
+ attachments?: AttachmentUploadStrategy;
1554
1304
  /** Reuse an existing client instead of constructing one. Prefer {@link backend}. */
1555
1305
  client?: B;
1556
1306
  /** Named agent to run each turn. */
@@ -1757,4 +1507,4 @@ declare class QuotaBlockedError extends Error {
1757
1507
  constructor(block: QuotaBlock);
1758
1508
  }
1759
1509
 
1760
- export { type AgentBackend, AgentBackendUnsupportedError, AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentMessageMetadata, type AgentStreamMeta, type AgentsState, type AggregatedTurnUsage, type AmbientRenderUi, AmbientRenderUiContext, AnyToolUIPart, type ApprovalCountdown, ApproveOptions, type AttachmentRejection, type AttachmentsState, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, ChatStatus, type ChatStreamRequest, type ChatStreamResponse, type ChatTranscript, type ClipboardLikeEvent, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type DragLikeEvent, type MessageFeedbackInput, 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 QuotaToday, type ReconnectOptions, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type ResumeStreamRequest, SPEECH_LANGUAGES, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StagedAttachment, type StagedAttachmentStatus, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type StreamConnectionState, type ThreadPatch, 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, type 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, requireBackendMethod, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useAgents, useAmbientRenderUi, useApprovalCountdown, useAttachments, useChatTranscript, useComposerAutocomplete, useElapsed, useMessageFeedback, useModels, useQuota, useSpeechRecognition, useStickToBottom, useThreads, useToolCatalog, useTranscriptItem };
1510
+ export { AgentBackend, AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentMessageMetadata, 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, useAgentChat, useAgents, useAmbientRenderUi, useApprovalCountdown, useAttachments, useChatTranscript, useComposerAutocomplete, useElapsed, useMessageFeedback, useModels, useQuota, useSpeechRecognition, useStickToBottom, useThreads, useToolCatalog, useTranscriptItem };
package/dist/index.js CHANGED
@@ -125,6 +125,9 @@ var AgentClient = class {
125
125
  * what a caller then rides on `sendMessage({ text }, { body: { attachments: [...] } })`.
126
126
  */
127
127
  async uploadAttachment(file, options = {}) {
128
+ if (this.options.attachments !== void 0) {
129
+ return this.options.attachments(file, options, this.connection());
130
+ }
128
131
  if (options.onProgress !== void 0 && this.options.fetch === void 0 && typeof XMLHttpRequest !== "undefined") {
129
132
  return this.uploadWithProgress(file, options);
130
133
  }
@@ -239,6 +242,15 @@ var AgentClient = class {
239
242
  fetchImpl() {
240
243
  return this.options.fetch ?? globalThis.fetch;
241
244
  }
245
+ /** This client's connection, for an {@link AttachmentUploadStrategy}. */
246
+ connection() {
247
+ return {
248
+ baseUrl: this.baseUrl(),
249
+ headers: /* @__PURE__ */ __name(() => this.resolveHeaders(), "headers"),
250
+ fetch: this.fetchImpl(),
251
+ ...this.credentials()
252
+ };
253
+ }
242
254
  baseUrl() {
243
255
  return (this.options.baseUrl ?? "").replace(/\/$/, "");
244
256
  }
@@ -4437,6 +4449,9 @@ function useAgentChat(options) {
4437
4449
  ...options.fetch !== void 0 ? {
4438
4450
  fetch: options.fetch
4439
4451
  } : {},
4452
+ ...options.attachments !== void 0 ? {
4453
+ attachments: options.attachments
4454
+ } : {},
4440
4455
  getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
4441
4456
  });
4442
4457
  }, []);