@gedatou/cadenza-ai 0.7.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.
Files changed (57) hide show
  1. package/README.md +71 -0
  2. package/dist/anthropic-DdrANeO1.mjs +236 -0
  3. package/dist/bedrock-534H9yfk.mjs +75 -0
  4. package/dist/catalog-CvvS2JaW.mjs +32 -0
  5. package/dist/deepseek-C1b74T2F.mjs +55 -0
  6. package/dist/gemini-DcJ5Kr3h.mjs +229 -0
  7. package/dist/grok-CffQuBd6.mjs +77 -0
  8. package/dist/groq-Ba6TTYLp.mjs +98 -0
  9. package/dist/index.d.mts +1056 -0
  10. package/dist/index.mjs +2809 -0
  11. package/dist/llmgateway-Pt5CS6aQ.mjs +211 -0
  12. package/dist/mistral-BGMwwbU9.mjs +107 -0
  13. package/dist/mock/index.d.mts +168 -0
  14. package/dist/mock/index.mjs +467 -0
  15. package/dist/ollama-BBJs-3mK.mjs +80 -0
  16. package/dist/openai--FIeahIH.mjs +153 -0
  17. package/dist/openrouter-q-lx-2Cb.mjs +167 -0
  18. package/dist/preset-CEyIPxfS.mjs +157 -0
  19. package/dist/preset-DRT0T14q.d.mts +19 -0
  20. package/dist/providers/anthropic.d.mts +6 -0
  21. package/dist/providers/anthropic.mjs +11 -0
  22. package/dist/providers/bedrock.d.mts +6 -0
  23. package/dist/providers/bedrock.mjs +11 -0
  24. package/dist/providers/byteplus.d.mts +6 -0
  25. package/dist/providers/byteplus.mjs +21 -0
  26. package/dist/providers/deepseek.d.mts +35 -0
  27. package/dist/providers/deepseek.mjs +283 -0
  28. package/dist/providers/gemini.d.mts +6 -0
  29. package/dist/providers/gemini.mjs +11 -0
  30. package/dist/providers/grok.d.mts +6 -0
  31. package/dist/providers/grok.mjs +11 -0
  32. package/dist/providers/groq.d.mts +6 -0
  33. package/dist/providers/groq.mjs +11 -0
  34. package/dist/providers/llmgateway.d.mts +6 -0
  35. package/dist/providers/llmgateway.mjs +11 -0
  36. package/dist/providers/mistral.d.mts +6 -0
  37. package/dist/providers/mistral.mjs +11 -0
  38. package/dist/providers/ollama.d.mts +9 -0
  39. package/dist/providers/ollama.mjs +28 -0
  40. package/dist/providers/openai-compatible.d.mts +32 -0
  41. package/dist/providers/openai-compatible.mjs +45 -0
  42. package/dist/providers/openai.d.mts +6 -0
  43. package/dist/providers/openai.mjs +11 -0
  44. package/dist/providers/openrouter.d.mts +6 -0
  45. package/dist/providers/openrouter.mjs +11 -0
  46. package/dist/providers/vercel-gateway.d.mts +6 -0
  47. package/dist/providers/vercel-gateway.mjs +11 -0
  48. package/dist/providers/vertex.d.mts +6 -0
  49. package/dist/providers/vertex.mjs +11 -0
  50. package/dist/server/index.d.mts +173 -0
  51. package/dist/server/index.mjs +440 -0
  52. package/dist/thinking-CH2uL1dr.mjs +26 -0
  53. package/dist/types-56Hn7Qq2.d.mts +46 -0
  54. package/dist/vercel-gateway-DW3Z0Os1.mjs +109 -0
  55. package/dist/vertex-hg4Dt54O.mjs +20 -0
  56. package/package.json +114 -0
  57. package/styles.css +3 -0
@@ -0,0 +1,1056 @@
1
+ import { a as Provider, i as ModelCost, n as Modality, o as ThinkingLevel, r as Model, s as TokenUsage, t as Catalog } from "./types-56Hn7Qq2.mjs";
2
+ import { ComponentProps, MemoExoticComponent, ReactElement, ReactNode } from "react";
3
+ import { ByokClient, ByokClient as ByokClient$1, ByokPrompt, ByokSnapshot, ByokSnapshot as ByokSnapshot$1, KeyStatus, KeyringStorage, KeyringStorage as KeyringStorage$1, defaultByokStorage, defineByok, isPasskeyStorageSupported, memoryStorage, passkeyStorage } from "@tanstack/ai-client/byok";
4
+ import { AnyClientTool, AudioPart, ContentPart, DocumentPart, EventType, ImagePart, InferToolInput, InferToolOutput, StreamChunk, StructuredOutputPart, TextPart, ThinkingPart, ThinkingPart as ThinkingPart$1, ToolCallPart, ToolResultPart, UIResourcePart, VideoPart, fromSpecTokenUsage, generateMessageId, parsePartialJSON, toolDefinition } from "@tanstack/ai/client";
5
+ import { ButtonProps, ChangeEventDetails, CollapsibleChangeEventDetails, CollapsibleTriggerProps, ComboboxChangeEventDetails, DialogChangeEventDetails, EmptyProps, GenericEventDetails, InputGroupAddonProps, InputGroupButtonProps, InputGroupTextareaProps, MessageAlign, MessageScrollerDefaultScrollPosition, MessageScrollerViewportProps, SelectChangeEventDetails, ToggleChangeEventDetails } from "@gedatou/cadenza-ui";
6
+ import { StreamdownTranslations } from "streamdown";
7
+ import { TokenUsage as TokenUsage$1 } from "@tanstack/ai";
8
+ import { ChatClientPersistence, ChatClientState, ChatClientState as ChatClientState$1, ChatInterrupt, ChatInterrupt as ChatInterrupt$1, InterruptItemStatus, MultimodalContent, MultimodalContent as MultimodalContent$1, QueuedMessage, QueuedMessage as QueuedMessage$1, SendMessageOptions, ToolApprovalInterrupt, UIMessage as UIMessage$1, WhenBusy } from "@tanstack/ai-client";
9
+ export * from "@tanstack/ai-react";
10
+ //#region src/catalog/catalog.d.ts
11
+ declare function modelRef(model: Pick<Model, 'provider' | 'id'>): string;
12
+ /** 只切第一个斜杠:OpenRouter / Vercel Gateway 的模型 id 自带 `vendor/model`。 */
13
+ declare function parseModelRef(ref: string): {
14
+ provider: string;
15
+ id: string;
16
+ };
17
+ declare function createCatalog(providers: readonly Provider[]): Catalog;
18
+ //#endregion
19
+ //#region src/catalog/cost.d.ts
20
+ /**
21
+ * USD;`cost` 缺失返回 undefined。
22
+ *
23
+ * 提示 token 分三档计价:命中缓存的按 `cacheRead`,写入缓存的按 `cacheWrite`
24
+ * (Anthropic 是 input 的 1.25×),其余按 `input`;两个缓存价缺省都回落到 `input`。
25
+ * 两个明细都当作含在 `promptTokens` 里扣除——`usage.ts` 的 `addTokenUsage` 正是这样
26
+ * 累加它们的,而 `Math.max(…, 0)` 兜住厂商把它们单列在外的情形。
27
+ */
28
+ declare function estimateCost(model: Model, usage: TokenUsage): number | undefined;
29
+ //#endregion
30
+ //#region src/catalog/thinking.d.ts
31
+ declare const THINKING_LEVELS: readonly ThinkingLevel[];
32
+ declare function supportedThinkingLevels(model: Model | undefined): readonly ThinkingLevel[];
33
+ /**
34
+ * 向下取最近支持档;目标低于模型下限(Fable 5 这类不可关的模型)时取下限。
35
+ */
36
+ declare function clampThinkingLevel(model: Model | undefined, level: ThinkingLevel): ThinkingLevel;
37
+ //#endregion
38
+ //#region src/catalog/usage-metrics.d.ts
39
+ /** One modality's slice of a prompt or a completion. */
40
+ interface ModalitySlice {
41
+ kind: 'text' | 'image' | 'audio' | 'video' | 'document';
42
+ tokens: number;
43
+ /** Of the side it belongs to (prompt or completion). */
44
+ share: number;
45
+ }
46
+ /**
47
+ * 派生指标。每一项在**分母未知或为零**时是 `undefined` 而不是 0——「没有提示 token
48
+ * 时的缓存命中率」不是零,是无从谈起,两者在界面上该有不同的下场(不显示,而不是
49
+ * 显示一个 0%)。
50
+ */
51
+ interface UsageMetrics {
52
+ /** `completionTokens / promptTokens`:一份提示换回多少回答。 */
53
+ outputRatio: number | undefined;
54
+ /** `cachedTokens / promptTokens`:这次提示有多少是从缓存里读的。 */
55
+ cacheHitRate: number | undefined;
56
+ /** `cacheWriteTokens / promptTokens`:有多少被写进了缓存(下次才省钱)。 */
57
+ cacheWriteRate: number | undefined;
58
+ /** `reasoningTokens / completionTokens`:回答里有多少花在思考上。 */
59
+ reasoningShare: number | undefined;
60
+ /** `promptTokens / model.contextWindow`:上下文占用,同 `ContextUsage` 那根条。 */
61
+ contextRatio: number | undefined;
62
+ /**
63
+ * 缓存读比照原价省下的美元。要模型同时给出 `input` 与 `cacheRead` 才算得出——
64
+ * 没有 `cacheRead` 意味着缓存不打折,而不是省了 0。
65
+ */
66
+ cacheSavings: number | undefined;
67
+ /** 提示里各模态的占比,只列非零项,从大到小。 */
68
+ promptModalities: readonly ModalitySlice[];
69
+ /** 回答里各模态的占比,同上。 */
70
+ completionModalities: readonly ModalitySlice[];
71
+ }
72
+ /**
73
+ * `TokenUsage` 里读得出来的比例,一次算齐。
74
+ *
75
+ * 纯函数,和 `estimateCost` 并排住在目录层:这些数字两端都用得上,且与 React 无关。
76
+ * 输入可以是 `useUsageTracker` 的任意一个粒度——`total` / `lastRun` / `byMessage` 的某一条。
77
+ *
78
+ * `model` 只有两项指标需要(`contextRatio` 要 `contextWindow`,`cacheSavings` 要价格),
79
+ * 不给就是那两项为 `undefined`,其余照算。
80
+ */
81
+ declare function usageMetrics(usage: TokenUsage, model?: Model): UsageMetrics;
82
+ //#endregion
83
+ //#region src/catalog/index.d.ts
84
+ declare const providers: {
85
+ readonly openai: Provider;
86
+ readonly anthropic: Provider;
87
+ readonly gemini: Provider;
88
+ readonly grok: Provider;
89
+ readonly groq: Provider;
90
+ readonly mistral: Provider;
91
+ readonly openrouter: Provider;
92
+ readonly vercelGateway: Provider;
93
+ readonly llmgateway: Provider;
94
+ readonly bedrock: Provider;
95
+ readonly vertex: Provider;
96
+ readonly ollama: Provider;
97
+ readonly deepseek: Provider;
98
+ };
99
+ declare const defaultCatalog: Catalog;
100
+ //#endregion
101
+ //#region src/runtime/attachments.d.ts
102
+ /** 3 MiB: base64 in a JSON body, comfortably under common function payload limits. */
103
+ declare const DEFAULT_MAX_ATTACHMENT_BYTES: number;
104
+ type AttachmentKind = 'image' | 'audio' | 'video' | 'document';
105
+ type AttachmentState = 'idle' | 'uploading' | 'done' | 'error';
106
+ declare function attachmentKindOf(mimeType: string): AttachmentKind | undefined;
107
+ /** Inline a file as a `data` content part; rejects unsupported types and oversize files. */
108
+ declare function fileToContentPart(file: File, options?: {
109
+ maxBytes?: number;
110
+ }): Promise<ContentPart>;
111
+ interface DraftAttachment {
112
+ id: string;
113
+ kind: AttachmentKind;
114
+ state: AttachmentState;
115
+ name: string;
116
+ mimeType: string;
117
+ size: number;
118
+ /** Present for files picked in the browser; converted on `toParts()`. */
119
+ file?: File;
120
+ /** Present for parts handed in ready-made (dictation, pasted URLs). */
121
+ part?: ContentPart;
122
+ error?: string;
123
+ /** Object URL for image thumbnails; revoked on remove / clear. */
124
+ previewUrl?: string;
125
+ }
126
+ interface UseAttachmentDraftOptions {
127
+ maxBytes?: number;
128
+ /** Kinds the picker accepts. Default: all four. */
129
+ accept?: readonly AttachmentKind[];
130
+ }
131
+ interface AttachmentDraft {
132
+ items: readonly DraftAttachment[];
133
+ add: (items: ReadonlyArray<File | ContentPart>) => void;
134
+ remove: (id: string) => void;
135
+ clear: () => void;
136
+ /** Convert every item to content parts, in order; rejects if any file fails. */
137
+ toParts: () => Promise<ContentPart[]>;
138
+ /** `accept` attribute for `<input type="file">`. */
139
+ accept: string;
140
+ }
141
+ declare function useAttachmentDraft(options?: UseAttachmentDraftOptions): AttachmentDraft;
142
+ //#endregion
143
+ //#region src/runtime/byok.d.ts
144
+ interface CreateByokOptions {
145
+ /**
146
+ * `true` keeps the keyring across reloads, encrypted behind a passkey
147
+ * (`defaultByokStorage`: WebAuthn PRF → AES-256-GCM in IndexedDB); where the
148
+ * browser cannot do that it falls back to this tab's memory and says so in
149
+ * `byok.storage.warning`. Default `false` = memory only.
150
+ */
151
+ persistent?: boolean;
152
+ /** Your own `KeyringStorage`; wins over `persistent`. */
153
+ storage?: KeyringStorage$1;
154
+ /** Providers with `keyRequired: false` are marked server-covered up front. */
155
+ catalog?: Catalog;
156
+ }
157
+ /** True for the errors a send throws when the client could not attach a key — the dialog is already asking; the send can run again once the key is in. */
158
+ declare function isByokError(error: unknown): boolean;
159
+ /** A `ByokClient` with the house defaults, ready for `useChat({ byok })`. */
160
+ declare function createByok(options?: CreateByokOptions): ByokClient$1;
161
+ interface ServerCoverage {
162
+ coverage: Record<string, boolean> | undefined;
163
+ providers: readonly Provider[] | undefined;
164
+ error: Error | undefined;
165
+ }
166
+ /**
167
+ * Fetch `/api/ai/catalog` once and merge its `coverage` into the client, so
168
+ * `prepare()` stops asking for keys the server already holds.
169
+ */
170
+ declare function useServerCoverage(byok: ByokClient$1, url?: string): ServerCoverage;
171
+ //#endregion
172
+ //#region src/runtime/messages.d.ts
173
+ /** The message's text parts, joined by blank lines; tool calls and media are skipped. */
174
+ declare function messageText(message: UIMessage$1): string;
175
+ interface MessagesToMarkdownOptions {
176
+ title?: string;
177
+ /** Include thinking parts as block quotes. Default false. */
178
+ includeThinking?: boolean;
179
+ }
180
+ /** A plain Markdown transcript, for copy / download. */
181
+ declare function messagesToMarkdown(messages: readonly UIMessage$1[], options?: MessagesToMarkdownOptions): string;
182
+ /** The slice of `useChat()` that `editAndResend` needs. */
183
+ interface EditableChat {
184
+ messages: readonly UIMessage$1[];
185
+ setMessages: (messages: UIMessage$1[]) => void;
186
+ sendMessage: (content: string | MultimodalContent$1) => Promise<void>;
187
+ status: ChatClientState$1;
188
+ stop: () => void;
189
+ }
190
+ /**
191
+ * Linear edit-and-resend (spec Q2): stop any run, drop the edited user message
192
+ * and everything after it, then send the new content in its place.
193
+ */
194
+ declare function editAndResend(chat: EditableChat, messageId: string, content: string | MultimodalContent$1): Promise<void>;
195
+ /**
196
+ * A thinking part is done when the run is no longer streaming, when the
197
+ * provider signed it, or when a later text / tool-call part has started.
198
+ */
199
+ declare function isThinkingComplete(message: UIMessage$1, partIndex: number, status: ChatClientState$1): boolean;
200
+ interface Source {
201
+ url: string;
202
+ title?: string;
203
+ snippet?: string;
204
+ }
205
+ /**
206
+ * Citations from provider-executed web search: an explicit `metadata.sources`
207
+ * list, or the result payload of a search tool the provider ran itself.
208
+ */
209
+ declare function sourcesOf(message: UIMessage$1): Source[];
210
+ //#endregion
211
+ //#region src/runtime/renderers.d.ts
212
+ /** Every visible string the default part renderers emit. Override through `PartRenderersProvider`. */
213
+ interface PartLabels {
214
+ thinking: string;
215
+ /** Precedes the elapsed seconds `Reasoning` renders as data ("Thought for" → "Thought for 3s"). */
216
+ thought: string;
217
+ toolPending: string;
218
+ toolRunning: string;
219
+ toolApprovalRequested: string;
220
+ toolApproved: string;
221
+ toolDenied: string;
222
+ toolDone: string;
223
+ toolFailed: string;
224
+ toolGroup: (count: number) => string;
225
+ approve: string;
226
+ deny: string;
227
+ sources: (count: number) => string;
228
+ }
229
+ declare const DEFAULT_PART_LABELS: PartLabels;
230
+ /**
231
+ * The approval interrupt as the views see it, for whichever tool set the chat
232
+ * was created with. `useChat().interrupts` is typed per tool and
233
+ * `ToolApprovalInterrupt<T>` is contravariant in `T` through `resolveInterrupt`,
234
+ * so no instantiation accepts every other one; this structural type lists only
235
+ * what the views read, with `resolveInterrupt` as a method (bivariant on
236
+ * purpose) so any tool's interrupt flows in untouched.
237
+ */
238
+ interface AnyToolApprovalInterrupt {
239
+ readonly kind: 'tool-approval';
240
+ readonly toolCallId: string;
241
+ readonly toolName: string;
242
+ readonly originalArgs: unknown;
243
+ readonly status: InterruptItemStatus;
244
+ resolveInterrupt(approved: boolean, options?: {
245
+ editedArgs?: unknown;
246
+ }): void;
247
+ }
248
+ interface ToolRendererProps {
249
+ part: ToolCallPart;
250
+ /** The matching `tool-result` part of the same message, once it exists. */
251
+ result: ToolResultPart | undefined;
252
+ /** The live approval interrupt while the call waits on the user. */
253
+ interrupt: AnyToolApprovalInterrupt | undefined;
254
+ streaming: boolean;
255
+ }
256
+ type ToolRenderer = (props: ToolRendererProps) => ReactNode;
257
+ /** Per-part-type overrides; anything omitted falls back to the built-in renderer. */
258
+ interface PartRenderers {
259
+ text?: (props: {
260
+ part: TextPart;
261
+ message: UIMessage$1;
262
+ streaming: boolean;
263
+ }) => ReactNode;
264
+ thinking?: (props: {
265
+ part: ThinkingPart$1;
266
+ complete: boolean;
267
+ }) => ReactNode;
268
+ /** Keyed by tool name; `default` catches the rest. */
269
+ toolCall?: {
270
+ default?: ToolRenderer;
271
+ } & Record<string, ToolRenderer | undefined>;
272
+ toolResult?: (props: {
273
+ part: ToolResultPart;
274
+ }) => ReactNode;
275
+ image?: (props: {
276
+ part: ImagePart;
277
+ message: UIMessage$1;
278
+ }) => ReactNode;
279
+ audio?: (props: {
280
+ part: AudioPart;
281
+ message: UIMessage$1;
282
+ }) => ReactNode;
283
+ video?: (props: {
284
+ part: VideoPart;
285
+ message: UIMessage$1;
286
+ }) => ReactNode;
287
+ document?: (props: {
288
+ part: DocumentPart;
289
+ message: UIMessage$1;
290
+ }) => ReactNode;
291
+ structuredOutput?: (props: {
292
+ part: StructuredOutputPart;
293
+ }) => ReactNode;
294
+ uiResource?: (props: {
295
+ part: UIResourcePart;
296
+ }) => ReactNode;
297
+ }
298
+ /** Identity with a type check, so a registry can be declared outside a component. */
299
+ declare function definePartRenderers(renderers: PartRenderers): PartRenderers;
300
+ interface PartRenderersContextValue {
301
+ renderers: PartRenderers;
302
+ labels: PartLabels;
303
+ }
304
+ interface PartRenderersProviderProps {
305
+ renderers?: PartRenderers;
306
+ labels?: Partial<PartLabels>;
307
+ children: ReactNode;
308
+ }
309
+ declare function PartRenderersProvider({ renderers, labels, children }: PartRenderersProviderProps): ReactElement;
310
+ declare function usePartRenderers(): PartRenderersContextValue;
311
+ //#endregion
312
+ //#region src/runtime/selection.d.ts
313
+ interface ModelSelection {
314
+ provider: string;
315
+ model: string;
316
+ thinking: ThinkingLevel;
317
+ /** 厂商侧联网搜索开关;模型没有这个能力时恒为 false。 */
318
+ search: boolean;
319
+ }
320
+ interface UseModelSelectionOptions {
321
+ catalog?: Catalog;
322
+ /** `localStorage` key. Default `cadenza-ai:selection`. */
323
+ key?: string;
324
+ /** Default: the catalog's first model with thinking off. */
325
+ initial?: ModelSelection;
326
+ }
327
+ interface UseModelSelectionReturn {
328
+ selection: ModelSelection;
329
+ model: Model | undefined;
330
+ provider: Provider | undefined;
331
+ /** `provider/model`; the thinking level is clamped to what the new model supports, and search drops if it has none. */
332
+ setModel: (ref: string) => void;
333
+ setThinking: (level: ThinkingLevel) => void;
334
+ setSearch: (on: boolean) => void;
335
+ /** 就是上面那个 `selection`,按 `useChat({ forwardedProps })` 的用法起的名字;渲染间稳定。 */
336
+ forwardedProps: ModelSelection;
337
+ }
338
+ /** The user's model + thinking choice, persisted, always valid for the chosen model. */
339
+ declare function useModelSelection(options?: UseModelSelectionOptions): UseModelSelectionReturn;
340
+ //#endregion
341
+ //#region src/runtime/stored-state.d.ts
342
+ /**
343
+ * `useState` whose value round-trips through `localStorage[key]` and stays in
344
+ * sync across hooks and tabs. Falls back to `initial` on the server and to an
345
+ * in-memory copy where storage is unavailable; writes never throw.
346
+ */
347
+ declare function useStoredState<T>(key: string, initial: T): [T, (next: T) => void];
348
+ //#endregion
349
+ //#region src/runtime/threads.d.ts
350
+ interface ThreadMeta {
351
+ id: string;
352
+ title: string;
353
+ createdAt: number;
354
+ updatedAt: number;
355
+ messageCount: number;
356
+ preview: string;
357
+ archived: boolean;
358
+ provider?: string;
359
+ model?: string;
360
+ }
361
+ /**
362
+ * The list side of thread storage. TanStack AI's `ChatClientPersistence` is a
363
+ * per-thread key/value store with no enumeration, so the index keeps the
364
+ * metadata (`ThreadMeta`) apart from the transcripts; `threadPersistence()`
365
+ * keeps the two in step.
366
+ */
367
+ interface ThreadIndex {
368
+ /** Newest first; archived threads after live ones. Stable reference until the next write. */
369
+ list: () => readonly ThreadMeta[];
370
+ get: (id: string) => ThreadMeta | undefined;
371
+ /** Creates (or re-creates) a thread; clears the id's tombstone. */
372
+ create: (init?: Partial<ThreadMeta>) => ThreadMeta;
373
+ /**
374
+ * Upserts: an unknown id is created with `createdAt = now` — unless it was
375
+ * removed in this session, in which case nothing is written (a chat still
376
+ * mounted on a deleted thread flushes once more; the deletion wins).
377
+ */
378
+ touch: (id: string, patch: Partial<Omit<ThreadMeta, 'id'>>) => ThreadMeta;
379
+ rename: (id: string, title: string) => void;
380
+ archive: (id: string, archived: boolean) => void;
381
+ /** Drops the thread and leaves a tombstone so later writes do not resurrect it. */
382
+ remove: (id: string) => void;
383
+ /** Whether `remove(id)` happened in this session and no `create` followed. */
384
+ wasRemoved: (id: string) => boolean;
385
+ subscribe: (listener: () => void) => () => void;
386
+ }
387
+ interface ThreadIndexOptions {
388
+ /** `localStorage` key. Default `cadenza-ai:threads`. */
389
+ key?: string;
390
+ /** `'local'` (default) persists across reloads and tabs; `'memory'` is per page. */
391
+ storage?: 'local' | 'memory';
392
+ }
393
+ declare function newThreadId(): string;
394
+ declare function createThreadIndex(options?: ThreadIndexOptions): ThreadIndex;
395
+ declare function useThreadIndex(index: ThreadIndex): readonly ThreadMeta[];
396
+ /** Title from the first user message; truncated with an ellipsis past `max` characters. */
397
+ declare function threadTitleFrom(messages: readonly UIMessage$1[], max?: number): string;
398
+ /**
399
+ * Wrap a `ChatClientPersistence` so every write also updates the index:
400
+ * message count, preview, timestamp, and — unless one was set by hand or
401
+ * `title: false` — a title derived from the first user message.
402
+ */
403
+ interface ThreadPersistenceOptions {
404
+ /**
405
+ * Title for a thread nobody has named yet. Default: derived from the first
406
+ * user message (`threadTitleFrom`). `false` leaves it empty — for a caller
407
+ * that generates titles, showing the list's `untitled` label meanwhile.
408
+ */
409
+ title?: false | ((messages: readonly UIMessage$1[]) => string);
410
+ }
411
+ declare function threadPersistence(index: ThreadIndex, base: ChatClientPersistence, options?: ThreadPersistenceOptions): ChatClientPersistence;
412
+ type ThreadDayLabel = 'today' | 'yesterday' | 'earlier';
413
+ interface ThreadDayGroup {
414
+ label: ThreadDayLabel;
415
+ threads: readonly ThreadMeta[];
416
+ }
417
+ /** Buckets by local calendar day of `updatedAt`; empty buckets are omitted. */
418
+ declare function groupThreadsByDay(threads: readonly ThreadMeta[], now?: number): readonly ThreadDayGroup[];
419
+ //#endregion
420
+ //#region src/runtime/usage.d.ts
421
+ /** Field-wise sum, including the nested detail breakdowns and the provider's own cost. */
422
+ declare function addTokenUsage(a: TokenUsage$1 | undefined, b: TokenUsage$1): TokenUsage$1;
423
+ interface UsageTracker {
424
+ /** Wire to `useChat({ onChunk })`. */
425
+ onChunk: (chunk: StreamChunk) => void;
426
+ /** Wire to `useChat({ onFinish })`; assigns the run's usage to the finished message. */
427
+ onFinish: (message: UIMessage$1) => void;
428
+ total: TokenUsage$1;
429
+ lastRun: TokenUsage$1 | undefined;
430
+ byMessage: ReadonlyMap<string, TokenUsage$1>;
431
+ reset: () => void;
432
+ }
433
+ /**
434
+ * Sums every `RUN_FINISHED` of a run (tool loops finish once per iteration)
435
+ * and books the sum against the assistant message that closes the run.
436
+ */
437
+ declare function useUsageTracker(): UsageTracker;
438
+ //#endregion
439
+ //#region src/view/approval.d.ts
440
+ interface ApprovalActionsProps {
441
+ interrupt: AnyToolApprovalInterrupt;
442
+ /** `ApprovalApprove` / `ApprovalDeny`, with their own wording. */
443
+ children: ReactNode;
444
+ className?: string;
445
+ }
446
+ /**
447
+ * The approve / deny row under a tool call. Resolves through the interrupt;
448
+ * both buttons disable once `interrupt.status` leaves `pending`. The choice
449
+ * lands on the row as `data-approved` / `data-denied`.
450
+ */
451
+ declare function ApprovalActions({ interrupt, children, className }: ApprovalActionsProps): ReactElement;
452
+ type ApprovalApproveProps = ButtonProps & {
453
+ /** Arguments edited by the user, sent in place of the original ones. */
454
+ editedArgs?: unknown;
455
+ };
456
+ declare function ApprovalApprove({ editedArgs, disabled, onClick, ...props }: ApprovalApproveProps): ReactElement;
457
+ type ApprovalDenyProps = ButtonProps;
458
+ declare function ApprovalDeny({ disabled, onClick, ...props }: ApprovalDenyProps): ReactElement;
459
+ //#endregion
460
+ //#region src/view/byok-key-dialog.d.ts
461
+ /** Every visible string the dialog emits. Override through `labels`. */
462
+ interface ByokKeyDialogLabels {
463
+ title: string;
464
+ description: string;
465
+ save: string;
466
+ clear: string;
467
+ confirm: string;
468
+ unlock: string;
469
+ close: string;
470
+ /** `aria-label` of the icon marking a provider the server already holds a key for. */
471
+ serverKey: string;
472
+ }
473
+ declare const DEFAULT_BYOK_KEY_DIALOG_LABELS: ByokKeyDialogLabels;
474
+ interface ByokKeyDialogProps {
475
+ byok: ByokClient$1;
476
+ catalog: Catalog;
477
+ /**
478
+ * Which providers the server can key from its own env — `useServerCoverage(byok).coverage`.
479
+ * `ByokClient` keeps its coverage private, so the dialog is told separately.
480
+ */
481
+ coverage?: Record<string, boolean>;
482
+ open?: boolean;
483
+ defaultOpen?: boolean;
484
+ /** Programmatic opens (a `byok.request()` prompt) carry `reason: 'none'`; the Confirm button closes with `reason: 'confirm'`. */
485
+ onOpenChange?: (open: boolean, details: DialogChangeEventDetails | ChangeEventDetails<'none' | 'confirm'>) => void;
486
+ labels?: Partial<ByokKeyDialogLabels>;
487
+ /** Omit it and every catalog provider gets a `ByokKeyDialogProvider` row. */
488
+ children?: ReactNode;
489
+ }
490
+ /**
491
+ * The key-entry dialog for a `ByokClient`. Subscribes to the client and opens
492
+ * itself whenever it raises a prompt (`prepare()` blocked on a missing key, or
493
+ * the server answered `byok_missing`), focusing that provider's input.
494
+ */
495
+ declare function ByokKeyDialog({ byok, catalog, coverage, open: openProp, defaultOpen, onOpenChange, labels: labelsProp, children }: ByokKeyDialogProps): ReactElement;
496
+ interface ByokKeyDialogProviderProps {
497
+ /** Catalog provider id. */
498
+ provider: string;
499
+ /** Appended at the end of the row — an OAuth / PKCE button, say. */
500
+ children?: ReactNode;
501
+ className?: string;
502
+ }
503
+ /**
504
+ * One provider's row: label, password input, save / clear icon buttons.
505
+ * `data-key-status` mirrors the client's `empty | set | locked | error`;
506
+ * `data-server-key` marks a provider the server can key on its own;
507
+ * `data-prompted` is on while the client is asking for this provider's key.
508
+ */
509
+ declare function ByokKeyDialogProvider({ provider: id, children, className }: ByokKeyDialogProviderProps): ReactElement;
510
+ //#endregion
511
+ //#region src/view/composer.d.ts
512
+ type ComposerSubmitReason = 'keyboard' | 'none';
513
+ type ComposerChangeEventDetails = ChangeEventDetails<'input-change' | 'none'>;
514
+ /** Mirrored as name-type `data-*` attributes on the root `<form>`; `ready` is the absence of the first three. */
515
+ interface ComposerState {
516
+ submitted: boolean;
517
+ streaming: boolean;
518
+ error: boolean;
519
+ dragging: boolean;
520
+ editing: boolean;
521
+ }
522
+ interface ComposerProps extends Omit<ComponentProps<'form'>, 'onSubmit' | 'onChange' | 'defaultValue' | 'value'> {
523
+ value?: string;
524
+ defaultValue?: string;
525
+ onValueChange?: (value: string, details: ComposerChangeEventDetails) => void;
526
+ /** Enter, or the form's submit. The draft is cleared afterwards. */
527
+ onValueCommitted: (value: string, details: GenericEventDetails<ComposerSubmitReason>) => void;
528
+ status: ChatClientState$1;
529
+ /** Escape while `submitted` / `streaming`, or `ComposerSubmit` pressed in that state. */
530
+ onStop?: (details: GenericEventDetails<'escape-key' | 'none'>) => void;
531
+ editing?: boolean;
532
+ /** Escape while `editing` — takes precedence over `onStop`. */
533
+ onEditCancel?: (details: GenericEventDetails<'escape-key'>) => void;
534
+ disabled?: boolean;
535
+ /** Commit an empty draft too — for a composer whose attachments strip carries the content. Default false. */
536
+ allowEmpty?: boolean;
537
+ /** Files dropped on the form or pasted into it. */
538
+ onFiles?: (files: File[], details: GenericEventDetails<'drag' | 'input-paste'>) => void;
539
+ children: ReactNode;
540
+ }
541
+ interface ComposerContextValue {
542
+ value: string;
543
+ setValue: (value: string, details?: ComposerChangeEventDetails) => void;
544
+ status: ChatClientState$1;
545
+ editing: boolean;
546
+ disabled: boolean;
547
+ /** The draft can be committed: non-empty, or `allowEmpty`. */
548
+ committable: boolean;
549
+ submit: (details: GenericEventDetails<ComposerSubmitReason>) => void;
550
+ /** Forwards to the root's `onStop`; a no-op unless `submitted` / `streaming`. */
551
+ stop: (details: GenericEventDetails<'escape-key' | 'none'>) => void;
552
+ /** Forwards to the root's `onEditCancel`. */
553
+ cancelEdit: (details: GenericEventDetails<'escape-key'>) => void;
554
+ }
555
+ declare function useComposer(): ComposerContextValue;
556
+ /**
557
+ * The input area: a `<form>` around an `InputGroup`, so `ComposerTextarea` and
558
+ * `ComposerToolbar` stay direct children of the group (its auto-height and
559
+ * block-end addon rules key off `>` combinators).
560
+ */
561
+ declare function Composer({ allowEmpty, children, className, defaultValue, disabled, editing, onDragLeave, onDragOver, onDrop, onEditCancel, onFiles, onPaste, onStop, onValueChange, onValueCommitted, status, value: valueProp, ...props }: ComposerProps): ReactElement;
562
+ type ComposerTextareaProps = InputGroupTextareaProps;
563
+ /** The draft text. Enter commits, Shift+Enter breaks a line, IME composition is left alone, Escape cancels or stops. */
564
+ declare function ComposerTextarea({ className, onChange, onKeyDown, ...props }: ComposerTextareaProps): ReactElement;
565
+ type ComposerToolbarProps = InputGroupAddonProps;
566
+ /** The row under the textarea: attach, dictate, pickers, submit. */
567
+ declare function ComposerToolbar(props: ComposerToolbarProps): ReactElement;
568
+ type ComposerSubmitProps = ButtonProps;
569
+ /** Send while idle, stop while busy. Disabled on an empty draft. */
570
+ declare function ComposerSubmit({ children, ...props }: ComposerSubmitProps): ReactElement;
571
+ interface ComposerAttachmentsProps {
572
+ items: readonly DraftAttachment[];
573
+ onRemove: (id: string, details: GenericEventDetails<'none'>) => void;
574
+ className?: string;
575
+ }
576
+ /** The pending-attachments strip; `state` maps straight onto `Attachment`'s. Renders nothing while empty. */
577
+ declare function ComposerAttachments({ items, onRemove, className }: ComposerAttachmentsProps): ReactElement | null;
578
+ type ComposerAttachProps = InputGroupButtonProps & {
579
+ accept?: string;
580
+ multiple?: boolean;
581
+ onFiles: (files: File[], details: GenericEventDetails<'input-change'>) => void;
582
+ };
583
+ /** Opens the file picker; the chosen files go to `onFiles`. */
584
+ declare function ComposerAttach({ accept, children, multiple, onClick, onFiles, ...props }: ComposerAttachProps): ReactElement;
585
+ type ComposerDictateProps = InputGroupButtonProps & {
586
+ onRecording: (part: AudioPart, details: GenericEventDetails<'imperative-action'>) => void;
587
+ };
588
+ /** Press to record, press again to stop; the finished recording's audio part goes to `onRecording`. */
589
+ declare function ComposerDictate({ children, onClick, onRecording, ...props }: ComposerDictateProps): ReactElement;
590
+ //#endregion
591
+ //#region src/view/context-usage.d.ts
592
+ /** The row labels of the detail tooltip. Override through `labels` (the `ByokKeyDialog` route: this part has no renderer registry to read from). */
593
+ interface ContextUsageLabels {
594
+ prompt: string;
595
+ completion: string;
596
+ cached: string;
597
+ total: string;
598
+ cost: string;
599
+ cacheHit: string;
600
+ outputRatio: string;
601
+ reasoningShare: string;
602
+ cacheSaved: string;
603
+ }
604
+ declare const DEFAULT_CONTEXT_USAGE_LABELS: ContextUsageLabels;
605
+ interface ContextUsageProps {
606
+ /** Supplies `contextWindow` (the bar) and `cost` (the price row); without it only the numbers show. */
607
+ model?: Model;
608
+ usage: TokenUsage;
609
+ labels?: Partial<ContextUsageLabels>;
610
+ /** After the prompt-token count ("tokens") — the part ships no unit. */
611
+ children?: ReactNode;
612
+ /** Lands on the trigger. */
613
+ className?: string;
614
+ }
615
+ interface ContextUsageState {
616
+ /** `usage.promptTokens / model.contextWindow`; `undefined` when the model has no window. */
617
+ ratio: number | undefined;
618
+ }
619
+ /**
620
+ * How full the context is (spec O1): a bar for `promptTokens / contextWindow`
621
+ * beside the number, with the token breakdown and `estimateCost` in a tooltip.
622
+ * The whole thing is the tooltip's trigger; `data-ratio` (two decimals) is
623
+ * the bar's value for styling from outside.
624
+ */
625
+ declare function ContextUsage({ model, usage, labels: labelsProp, children, className }: ContextUsageProps): ReactElement;
626
+ //#endregion
627
+ //#region src/view/markdown.d.ts
628
+ interface MarkdownProps {
629
+ content: string;
630
+ /** Still receiving bytes: parse incomplete markdown leniently and animate. */
631
+ streaming?: boolean;
632
+ /** streamdown's own UI strings (copy button, fullscreen …); English by default. */
633
+ translations?: Partial<StreamdownTranslations>;
634
+ /** Lands on streamdown's root `<div>`. */
635
+ className?: string;
636
+ }
637
+ /** Product-grade Markdown: streamdown with code / math / CJK plugins and safe links. */
638
+ declare function Markdown({ content, streaming, translations, className }: MarkdownProps): ReactElement;
639
+ //#endregion
640
+ //#region src/view/media-part.d.ts
641
+ interface MediaPartProps {
642
+ part: ImagePart | AudioPart | VideoPart | DocumentPart;
643
+ className?: string;
644
+ }
645
+ /** A message's media part rendered by type: image card, native audio / video, document card. */
646
+ declare function MediaPart({ part, className }: MediaPartProps): ReactElement;
647
+ //#endregion
648
+ //#region src/view/model-picker.d.ts
649
+ /** The Combobox's own details, passed straight through — `item-press` in practice, `none` for programmatic changes. */
650
+ type ModelPickerChangeEventDetails = ComboboxChangeEventDetails;
651
+ interface ModelPickerProps {
652
+ catalog: Catalog;
653
+ /** A `provider/model` ref. */
654
+ value?: string;
655
+ defaultValue?: string;
656
+ onValueChange: (ref: string, details: ModelPickerChangeEventDetails) => void;
657
+ /** With a snapshot, providers whose key is required but `empty` get `data-key-missing` on their heading. */
658
+ byok?: ByokSnapshot$1;
659
+ disabledProviders?: readonly string[];
660
+ /** Lands on the trigger button. */
661
+ className?: string;
662
+ }
663
+ /** A searchable, provider-grouped model list; the value is the model ref. */
664
+ declare function ModelPicker({ byok, catalog, className, defaultValue, disabledProviders, onValueChange, value }: ModelPickerProps): ReactElement;
665
+ /** The Select's own details, passed straight through. */
666
+ type ThinkingLevelPickerChangeEventDetails = SelectChangeEventDetails;
667
+ interface ThinkingLevelPickerProps {
668
+ model?: Model;
669
+ value?: ThinkingLevel;
670
+ defaultValue?: ThinkingLevel;
671
+ onValueChange: (level: ThinkingLevel, details: ThinkingLevelPickerChangeEventDetails) => void;
672
+ /** Lands on the trigger button. */
673
+ className?: string;
674
+ }
675
+ /** The model's supported thinking levels; renders nothing when there is no choice to make. */
676
+ declare function ThinkingLevelPicker({ className, defaultValue, model, onValueChange, value }: ThinkingLevelPickerProps): ReactElement | null;
677
+ /** The Toggle's own details, passed straight through. */
678
+ type ThinkingToggleChangeEventDetails = ToggleChangeEventDetails;
679
+ interface ThinkingToggleProps {
680
+ model?: Model;
681
+ value?: ThinkingLevel;
682
+ defaultValue?: ThinkingLevel;
683
+ /** The level switching on lands at, clamped to the model. Default `'high'`. */
684
+ onLevel?: ThinkingLevel;
685
+ onValueChange: (level: ThinkingLevel, details: ThinkingToggleChangeEventDetails) => void;
686
+ /** The label — DeepSeek's reads 深度思考. */
687
+ children: ReactNode;
688
+ /** Lands on the toggle. */
689
+ className?: string;
690
+ }
691
+ /**
692
+ * The one-press deep-thinking switch, DeepSeek style: a pill that lights up
693
+ * while thinking is on. Renders nothing for a model without reasoning; a model
694
+ * that cannot switch thinking off (no `'off'` level) shows it pressed and
695
+ * disabled. `data-thinking` mirrors the on state.
696
+ */
697
+ declare function ThinkingToggle({ children, className, defaultValue, model, onLevel, onValueChange, value }: ThinkingToggleProps): ReactElement | null;
698
+ /** The Toggle's own details, passed straight through. */
699
+ type SearchToggleChangeEventDetails = ToggleChangeEventDetails;
700
+ interface SearchToggleProps {
701
+ model?: Model;
702
+ value?: boolean;
703
+ defaultValue?: boolean;
704
+ onValueChange: (on: boolean, details: SearchToggleChangeEventDetails) => void;
705
+ /** The label — DeepSeek's reads 联网搜索. */
706
+ children: ReactNode;
707
+ /** Lands on the toggle. */
708
+ className?: string;
709
+ }
710
+ /**
711
+ * The one-press web-search switch, the same pill as `ThinkingToggle`. Renders
712
+ * nothing for a model without `search`, so it appears and disappears with the
713
+ * model the way the thinking controls do. `data-search` mirrors the on state.
714
+ *
715
+ * The search itself runs on the provider's side; the caller's job is to put the
716
+ * answer into `forwardedProps` so the server can hand that provider its
717
+ * built-in tool (`createChatHandler`'s function form of `tools`).
718
+ */
719
+ declare function SearchToggle({ children, className, defaultValue, model, onValueChange, value }: SearchToggleProps): ReactElement | null;
720
+ //#endregion
721
+ //#region src/view/queue.d.ts
722
+ interface QueueListProps {
723
+ queue: readonly QueuedMessage$1[];
724
+ onCancel: (id: string, details: GenericEventDetails<'none'>) => void;
725
+ /** Rendered after the rows — a heading or a hint the caller writes. */
726
+ children?: ReactNode;
727
+ className?: string;
728
+ }
729
+ /** Messages waiting behind the current turn, each with a cancel. */
730
+ declare function QueueList({ children, className, onCancel, queue }: QueueListProps): ReactElement;
731
+ //#endregion
732
+ //#region src/view/reasoning.d.ts
733
+ /** `trigger-press` from the user, `none` for the automatic collapse on completion. */
734
+ type ReasoningChangeEventDetails = CollapsibleChangeEventDetails | ChangeEventDetails<'none'>;
735
+ interface ReasoningProps {
736
+ content: string;
737
+ complete: boolean;
738
+ /** `Date.now()` when the thinking started. Default: when this part mounted, which is when it arrived. */
739
+ startedAt?: number;
740
+ open?: boolean;
741
+ defaultOpen?: boolean;
742
+ onOpenChange?: (open: boolean, details: ReasoningChangeEventDetails) => void;
743
+ /** The trigger's text ("Thinking…" / "Thought for 3s") — the part ships none. */
744
+ children: ReactNode;
745
+ /** Lands on the Collapsible root. */
746
+ className?: string;
747
+ }
748
+ interface ReasoningState {
749
+ complete: boolean;
750
+ open: boolean;
751
+ }
752
+ /**
753
+ * A thinking block: open while streaming (shimmering trigger), folds itself
754
+ * once when `complete` flips — unless the user has already toggled it by hand.
755
+ */
756
+ declare function Reasoning({ content, complete, startedAt: startedAtProp, open: openProp, defaultOpen, onOpenChange, children, className }: ReasoningProps): ReactElement;
757
+ //#endregion
758
+ //#region src/view/sources.d.ts
759
+ type SourcesChangeEventDetails = CollapsibleChangeEventDetails | ChangeEventDetails<'none'>;
760
+ interface SourcesProps {
761
+ sources: readonly Source[];
762
+ /** The trigger's text ("3 sources") — the part ships none. */
763
+ children: ReactNode;
764
+ open?: boolean;
765
+ defaultOpen?: boolean;
766
+ onOpenChange?: (open: boolean, details: SourcesChangeEventDetails) => void;
767
+ /** Lands on the Collapsible root. */
768
+ className?: string;
769
+ }
770
+ /** The links a provider-executed search returned (spec T12), folded behind a trigger. */
771
+ declare function Sources({ sources, children, open: openProp, defaultOpen, onOpenChange, className }: SourcesProps): ReactElement;
772
+ //#endregion
773
+ //#region src/view/structured-output.d.ts
774
+ interface StructuredOutputProps {
775
+ part: StructuredOutputPart;
776
+ className?: string;
777
+ }
778
+ /** `useChat({ outputSchema })`'s part (spec T23): partial JSON while streaming, the validated data once complete. */
779
+ declare function StructuredOutput({ part, className }: StructuredOutputProps): ReactElement;
780
+ //#endregion
781
+ //#region src/view/suggestions.d.ts
782
+ type SuggestionsChangeEventDetails = ChangeEventDetails<'item-press'>;
783
+ interface SuggestionsProps {
784
+ /** The pressed chip's `value`. Values flow through the root, Base UI Menu / Select style. */
785
+ onValueChange: (value: string, details: SuggestionsChangeEventDetails) => void;
786
+ children: ReactNode;
787
+ /** Lands on the `ScrollArea` root, a plain element. */
788
+ className?: string;
789
+ }
790
+ /** A horizontally scrolling row of prompt chips. */
791
+ declare function Suggestions({ children, className, onValueChange }: SuggestionsProps): ReactElement;
792
+ type SuggestionsItemProps = Omit<ButtonProps, 'value'> & {
793
+ /** What the root's `onValueChange` receives — usually the prompt text itself. */
794
+ value: string;
795
+ };
796
+ declare function SuggestionsItem({ onClick, value, ...props }: SuggestionsItemProps): ReactElement;
797
+ //#endregion
798
+ //#region src/view/thread-list.d.ts
799
+ type ThreadListChangeEventReason = 'item-press' | 'none';
800
+ type ThreadListChangeEventDetails = ChangeEventDetails<ThreadListChangeEventReason>;
801
+ /** The row a `ThreadListItem` action sits in. */
802
+ declare function useThreadListItem(): {
803
+ thread: ThreadMeta;
804
+ active: boolean;
805
+ };
806
+ interface ThreadListProps {
807
+ index: ThreadIndex;
808
+ /** Already filtered by the caller (`useThreadIndex(index)` plus search / archive filters). */
809
+ threads: readonly ThreadMeta[];
810
+ value?: string;
811
+ defaultValue?: string;
812
+ onValueChange: (id: string, details: ThreadListChangeEventDetails) => void;
813
+ /** Omit it and every thread renders as a bare `ThreadListItem` — no groups, no actions. */
814
+ children?: ReactNode;
815
+ /** Lands on the `ScrollArea` root; give it the height. */
816
+ className?: string;
817
+ /** Shown as the title of a thread whose `title` is still empty. */
818
+ untitled?: ReactNode;
819
+ }
820
+ /**
821
+ * The scrolling list of threads. `ScrollArea` root > `div[role=list]`; the
822
+ * current thread is the controlled `value`, and selecting a row (or `ThreadListNew`
823
+ * creating one) reports through `onValueChange(id, details)`.
824
+ */
825
+ declare function ThreadList({ index, threads, value, defaultValue, onValueChange, children, className, untitled }: ThreadListProps): ReactElement;
826
+ interface ThreadListGroupProps {
827
+ /** A `ThreadListGroupLabel` first, then the group's items. */
828
+ children: ReactNode;
829
+ className?: string;
830
+ }
831
+ declare function ThreadListGroup({ children, className }: ThreadListGroupProps): ReactElement;
832
+ type ThreadListGroupLabelProps = ComponentProps<'div'>;
833
+ declare function ThreadListGroupLabel({ className, ...props }: ThreadListGroupLabelProps): ReactElement;
834
+ interface ThreadListItemProps {
835
+ thread: ThreadMeta;
836
+ /** The actions area (`ThreadListRename` / `ThreadListArchive` / `ThreadListDelete`, or a menu holding them). */
837
+ children?: ReactNode;
838
+ className?: string;
839
+ }
840
+ interface ThreadListItemState {
841
+ active: boolean;
842
+ archived: boolean;
843
+ renaming: boolean;
844
+ }
845
+ /**
846
+ * One row: an `Item` whose content is a press target for selection, or — while
847
+ * renaming — an inline `Input` (Enter / blur commit, Escape cancels). Mirrors its
848
+ * state as `data-active` (+ `aria-current="page"`), `data-archived`, `data-renaming`.
849
+ */
850
+ declare function ThreadListItem({ thread, children, className }: ThreadListItemProps): ReactElement;
851
+ type ThreadListRenameProps = ButtonProps;
852
+ /** Switches the row to its inline rename input. */
853
+ declare function ThreadListRename({ children, onClick, ...props }: ThreadListRenameProps): ReactElement;
854
+ type ThreadListArchiveProps = ButtonProps;
855
+ /** Toggles `archived` through the index. */
856
+ declare function ThreadListArchive({ children, onClick, ...props }: ThreadListArchiveProps): ReactElement;
857
+ type ThreadListDeleteProps = ButtonProps;
858
+ /** Removes the thread from the index. Confirmation is the caller's — wrap it in an `AlertDialog`. */
859
+ declare function ThreadListDelete({ children, onClick, ...props }: ThreadListDeleteProps): ReactElement;
860
+ type ThreadListNewProps = ButtonProps;
861
+ /** Creates an empty thread and selects it (`reason: 'item-press'`). */
862
+ declare function ThreadListNew({ onClick, ...props }: ThreadListNewProps): ReactElement;
863
+ //#endregion
864
+ //#region src/view/tool-call.d.ts
865
+ /** `trigger-press` from the user, `none` for programmatic changes. */
866
+ type ToolCallChangeEventDetails = CollapsibleChangeEventDetails | ChangeEventDetails<'none'>;
867
+ interface OpenProps {
868
+ open?: boolean;
869
+ defaultOpen?: boolean;
870
+ onOpenChange?: (open: boolean, details: ToolCallChangeEventDetails) => void;
871
+ }
872
+ interface ToolCallCardProps extends OpenProps {
873
+ part: ToolCallPart;
874
+ /** The matching `tool-result` part, once it exists. */
875
+ result?: ToolResultPart;
876
+ /** The live approval interrupt while the call waits on the user. */
877
+ interrupt?: AnyToolApprovalInterrupt;
878
+ streaming?: boolean;
879
+ /** Rendered at the end of the body — the place for `ApprovalActions`. */
880
+ children?: ReactNode;
881
+ /** Lands on the Collapsible root. */
882
+ className?: string;
883
+ }
884
+ /** The seven `ToolCallState`s folded into five named attributes. */
885
+ interface ToolCallCardState {
886
+ pending: boolean;
887
+ approvalRequested: boolean;
888
+ approvalResponded: boolean;
889
+ complete: boolean;
890
+ error: boolean;
891
+ }
892
+ /**
893
+ * A collapsible card for one tool call: header = tool name + state icon (no
894
+ * words), body = the JSON input and output as Markdown code blocks, then
895
+ * `children`.
896
+ */
897
+ declare function ToolCallCard({ part, result, interrupt: _interrupt, streaming, open: openProp, defaultOpen, onOpenChange, children, className }: ToolCallCardProps): ReactElement;
898
+ interface ToolCallGroupProps extends OpenProps {
899
+ count: number;
900
+ /** `ToolCallGroupTrigger` first, then the cards it folds. */
901
+ children: ReactNode | ReactNode[];
902
+ /** Lands on the Collapsible root. */
903
+ className?: string;
904
+ }
905
+ type ToolCallGroupTriggerProps = CollapsibleTriggerProps;
906
+ /** The group's title — a `CollapsibleTrigger`, wording from the caller. */
907
+ declare function ToolCallGroupTrigger({ className, ...props }: ToolCallGroupTriggerProps): ReactElement;
908
+ /**
909
+ * Folds a run of consecutive tool calls (spec G6). Position contract like
910
+ * `DialogTrigger`: the first child is the `ToolCallGroupTrigger`, the rest
911
+ * go into the panel.
912
+ */
913
+ declare function ToolCallGroup({ count, children, open: openProp, defaultOpen, onOpenChange, className }: ToolCallGroupProps): ReactElement;
914
+ //#endregion
915
+ //#region src/view/transcript.d.ts
916
+ interface ApprovalResponseInput {
917
+ id: string;
918
+ approved: boolean;
919
+ }
920
+ /**
921
+ * `ChatInterrupt`'s default generic folds the approval member away, and the
922
+ * per-tool `ToolApprovalInterrupt<T>` instantiations do not unify (see
923
+ * `AnyToolApprovalInterrupt`), so the transcript names the union itself.
924
+ */
925
+ type TranscriptInterrupt = ChatInterrupt$1 | AnyToolApprovalInterrupt;
926
+ interface TranscriptContextValue {
927
+ status: ChatClientState$1;
928
+ interrupts: readonly TranscriptInterrupt[];
929
+ /** Fallback for `approval-requested` parts that carry no live interrupt (e.g. restored history). */
930
+ addToolApprovalResponse?: (input: ApprovalResponseInput) => Promise<void> | void;
931
+ }
932
+ interface TranscriptProviderProps {
933
+ status: ChatClientState$1;
934
+ interrupts?: readonly TranscriptInterrupt[];
935
+ addToolApprovalResponse?: TranscriptContextValue['addToolApprovalResponse'];
936
+ children: ReactNode;
937
+ }
938
+ /** Hands `useChat()`'s run state to every Transcript part below it. */
939
+ declare function TranscriptProvider({ status, interrupts, addToolApprovalResponse, children }: TranscriptProviderProps): ReactElement;
940
+ declare function useTranscript(): TranscriptContextValue;
941
+ interface TranscriptProps extends Omit<MessageScrollerViewportProps, 'className' | 'children'> {
942
+ children: ReactNode;
943
+ /** Follow new messages while the reader is at the end. Default true. */
944
+ autoScroll?: boolean;
945
+ /** Where a freshly mounted transcript rests. Default `'end'`. */
946
+ defaultScrollPosition?: MessageScrollerDefaultScrollPosition;
947
+ /**
948
+ * Pin each sent user message to the top of the viewport and let the reply fill
949
+ * the space below (the ChatGPT turn anchor). Default true. `false` keeps the
950
+ * classic behaviour: the view stays at the end and follows the reply.
951
+ */
952
+ anchorTurns?: boolean;
953
+ /**
954
+ * How much of the previous row stays visible above a freshly anchored user
955
+ * message, in px. The scroller's default is 80 (a context cue); 0 pins the
956
+ * message flush to the top, ChatGPT style.
957
+ */
958
+ previousPeek?: number;
959
+ /** Rendered beside the viewport, inside the frame — the place for `MessageScrollerButton`. */
960
+ after?: ReactNode;
961
+ /** Lands on the scroller frame. */
962
+ className?: string;
963
+ }
964
+ /** The scrolling frame: `MessageScroller` with the house viewport, one row per `TranscriptMessage`. */
965
+ declare function Transcript({ children, autoScroll, defaultScrollPosition, anchorTurns, previousPeek, after, className, ...viewport }: TranscriptProps): ReactElement;
966
+ interface TranscriptMessageProps {
967
+ message: UIMessage$1;
968
+ /** Default: user rows end-aligned, everything else start-aligned. */
969
+ align?: MessageAlign;
970
+ /** True for the row the current run is writing into. */
971
+ streaming?: boolean;
972
+ /** Default: `<TranscriptParts message={message} />`. A `TranscriptActions` child is lifted into the footer. */
973
+ children?: ReactNode;
974
+ className?: string;
975
+ }
976
+ interface TranscriptMessageState {
977
+ role: string;
978
+ streaming: boolean;
979
+ }
980
+ declare function TranscriptMessageImpl({ message, align, streaming, children, className }: TranscriptMessageProps): ReactElement;
981
+ /** One row. Memoised so a streaming row re-renders alone. */
982
+ declare const TranscriptMessage: MemoExoticComponent<typeof TranscriptMessageImpl>;
983
+ interface TranscriptPartsProps {
984
+ message: UIMessage$1;
985
+ className?: string;
986
+ }
987
+ /** Dispatches every part of a message through the renderer registry and the default parts. */
988
+ declare function TranscriptParts({ message, className }: TranscriptPartsProps): ReactElement;
989
+ interface TranscriptActionsProps {
990
+ children: ReactNode;
991
+ className?: string;
992
+ }
993
+ /** The row's toolbar, hidden while a run streams. Place it as a child of `TranscriptMessage`. */
994
+ declare function TranscriptActions({ children, className }: TranscriptActionsProps): ReactElement;
995
+ type TranscriptActionProps = ButtonProps;
996
+ declare function TranscriptAction({ className, ...props }: TranscriptActionProps): ReactElement;
997
+ type TranscriptEmptyProps = EmptyProps;
998
+ declare function TranscriptEmpty(props: TranscriptEmptyProps): ReactElement;
999
+ interface TranscriptPendingProps {
1000
+ children: ReactNode;
1001
+ className?: string;
1002
+ }
1003
+ /** Shown between submit and the first chunk. */
1004
+ declare function TranscriptPending({ children, className }: TranscriptPendingProps): ReactElement;
1005
+ interface TranscriptErrorProps {
1006
+ error: Error;
1007
+ children: ReactNode;
1008
+ className?: string;
1009
+ }
1010
+ declare function TranscriptError({ error, children, className }: TranscriptErrorProps): ReactElement;
1011
+ //#endregion
1012
+ //#region src/view/usage-stats.d.ts
1013
+ /**
1014
+ * The tile captions. A `labels` prop rather than children because this part has
1015
+ * no composition surface to write them into — the same call `ContextUsage` and
1016
+ * `ByokKeyDialog` make, and the reason is the same: the copy names a computed
1017
+ * quantity, it is not content the caller authored.
1018
+ */
1019
+ interface UsageStatsLabels {
1020
+ cacheHit: string;
1021
+ cacheWrite: string;
1022
+ outputRatio: string;
1023
+ reasoningShare: string;
1024
+ contextUsed: string;
1025
+ cacheSaved: string;
1026
+ promptModalities: string;
1027
+ completionModalities: string;
1028
+ /** Reads the modality kinds; the keys are `ModalitySlice['kind']`. */
1029
+ modality: Record<ModalitySlice['kind'], string>;
1030
+ }
1031
+ declare const DEFAULT_USAGE_STATS_LABELS: UsageStatsLabels;
1032
+ interface UsageStatsProps {
1033
+ usage: TokenUsage;
1034
+ /** Supplies `contextWindow` (context used) and `cost` (saved by cache); without it those two tiles stay away. */
1035
+ model?: Model;
1036
+ labels?: Partial<UsageStatsLabels>;
1037
+ /** Lands on the grid. */
1038
+ className?: string;
1039
+ }
1040
+ /**
1041
+ * The ratios inside a `TokenUsage`, one tile each: how much of the prompt came
1042
+ * from cache, how much answer a prompt bought, how much of the answer was
1043
+ * thinking, how full the context is, and what the cache saved.
1044
+ *
1045
+ * Every tile is skipped when its number is unknown — a rate with no denominator
1046
+ * is not zero — so a provider that reports no cache detail simply shows fewer
1047
+ * tiles rather than a row of 0%.
1048
+ *
1049
+ * It renders one `usage`. Which one is the caller's to decide: `useUsageTracker`
1050
+ * hands over `total`, `lastRun` and `byMessage`, and a switch between them is a
1051
+ * few lines the caller writes anyway, keeping that wording and those variants
1052
+ * where they belong.
1053
+ */
1054
+ declare function UsageStats({ usage, model, labels: labelsProp, className }: UsageStatsProps): ReactElement;
1055
+ //#endregion
1056
+ export { type AnyClientTool, AnyToolApprovalInterrupt, ApprovalActions, ApprovalActionsProps, ApprovalApprove, ApprovalApproveProps, ApprovalDeny, ApprovalDenyProps, ApprovalResponseInput, AttachmentDraft, AttachmentKind, AttachmentState, type ByokClient, ByokKeyDialog, ByokKeyDialogLabels, ByokKeyDialogProps, ByokKeyDialogProvider, ByokKeyDialogProviderProps, type ByokPrompt, type ByokSnapshot, Catalog, type ChatClientState, type ChatInterrupt, Composer, ComposerAttach, ComposerAttachProps, ComposerAttachments, ComposerAttachmentsProps, ComposerChangeEventDetails, ComposerDictate, ComposerDictateProps, ComposerProps, ComposerState, ComposerSubmit, ComposerSubmitProps, ComposerSubmitReason, ComposerTextarea, ComposerTextareaProps, ComposerToolbar, ComposerToolbarProps, ContextUsage, ContextUsageLabels, ContextUsageProps, ContextUsageState, CreateByokOptions, DEFAULT_BYOK_KEY_DIALOG_LABELS, DEFAULT_CONTEXT_USAGE_LABELS, DEFAULT_MAX_ATTACHMENT_BYTES, DEFAULT_PART_LABELS, DEFAULT_USAGE_STATS_LABELS, DraftAttachment, EditableChat, EventType, type InferToolInput, type InferToolOutput, type KeyStatus, type KeyringStorage, Markdown, MarkdownProps, MediaPart, MediaPartProps, MessagesToMarkdownOptions, type Modality, ModalitySlice, Model, ModelCost, ModelPicker, ModelPickerChangeEventDetails, ModelPickerProps, ModelSelection, type MultimodalContent, PartLabels, PartRenderers, PartRenderersContextValue, PartRenderersProvider, PartRenderersProviderProps, Provider, QueueList, QueueListProps, type QueuedMessage, Reasoning, ReasoningChangeEventDetails, ReasoningProps, ReasoningState, SearchToggle, SearchToggleChangeEventDetails, SearchToggleProps, type SendMessageOptions, ServerCoverage, Source, Sources, SourcesChangeEventDetails, SourcesProps, StructuredOutput, StructuredOutputProps, Suggestions, SuggestionsChangeEventDetails, SuggestionsItem, SuggestionsItemProps, SuggestionsProps, THINKING_LEVELS, ThinkingLevel, ThinkingLevelPicker, ThinkingLevelPickerChangeEventDetails, ThinkingLevelPickerProps, type ThinkingPart, ThinkingToggle, ThinkingToggleChangeEventDetails, ThinkingToggleProps, ThreadDayGroup, ThreadDayLabel, ThreadIndex, ThreadIndexOptions, ThreadList, ThreadListArchive, ThreadListArchiveProps, ThreadListChangeEventDetails, ThreadListChangeEventReason, ThreadListDelete, ThreadListDeleteProps, ThreadListGroup, ThreadListGroupLabel, ThreadListGroupLabelProps, ThreadListGroupProps, ThreadListItem, ThreadListItemProps, ThreadListItemState, ThreadListNew, ThreadListNewProps, ThreadListProps, ThreadListRename, ThreadListRenameProps, ThreadMeta, ThreadPersistenceOptions, type TokenUsage, type ToolApprovalInterrupt, ToolCallCard, ToolCallCardProps, ToolCallCardState, ToolCallChangeEventDetails, ToolCallGroup, ToolCallGroupProps, ToolCallGroupTrigger, ToolCallGroupTriggerProps, ToolRenderer, ToolRendererProps, Transcript, TranscriptAction, TranscriptActionProps, TranscriptActions, TranscriptActionsProps, TranscriptContextValue, TranscriptEmpty, TranscriptEmptyProps, TranscriptError, TranscriptErrorProps, TranscriptInterrupt, TranscriptMessage, TranscriptMessageProps, TranscriptMessageState, TranscriptParts, TranscriptPartsProps, TranscriptPending, TranscriptPendingProps, TranscriptProps, TranscriptProvider, TranscriptProviderProps, UsageMetrics, UsageStats, UsageStatsLabels, UsageStatsProps, UsageTracker, UseAttachmentDraftOptions, UseModelSelectionOptions, UseModelSelectionReturn, type WhenBusy, addTokenUsage, attachmentKindOf, clampThinkingLevel, createByok, createCatalog, createThreadIndex, defaultByokStorage, defaultCatalog, defineByok, definePartRenderers, editAndResend, estimateCost, fileToContentPart, fromSpecTokenUsage, generateMessageId, groupThreadsByDay, isByokError, isPasskeyStorageSupported, isThinkingComplete, memoryStorage, messageText, messagesToMarkdown, modelRef, newThreadId, parseModelRef, parsePartialJSON, passkeyStorage, providers, sourcesOf, supportedThinkingLevels, threadPersistence, threadTitleFrom, toolDefinition, usageMetrics, useAttachmentDraft, useComposer, useModelSelection, usePartRenderers, useServerCoverage, useStoredState, useThreadIndex, useThreadListItem, useTranscript, useUsageTracker };