@dudousxd/nestjs-agent-react 0.9.0 → 0.10.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,7 +1,7 @@
1
1
  import * as ai from 'ai';
2
2
  import { ChatTransport, UIMessage, UIMessageChunk, ToolUIPart, DynamicToolUIPart, DataUIPart, UIDataTypes } from 'ai';
3
3
  import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
4
- import { StoredMessage, ThreadSummary, SkillCatalogEntry, ThreadDetail, MessageAttachment, QuotaView } from '@dudousxd/nestjs-agent-core';
4
+ import { StoredMessage, ThreadSummary, SkillCatalogEntry, ToolCatalogEntry, ThreadDetail, MessageAttachment, QuotaView, ToolPresentation, ToolResultField, ToolResultView, ToolPresentationTone } from '@dudousxd/nestjs-agent-core';
5
5
  import React from 'react';
6
6
 
7
7
  /** Identity surfaced by the backend's `meta` SSE frame / response headers. */
@@ -211,6 +211,12 @@ declare class AgentClient {
211
211
  * one conversation; omitted, the server reads it as a brand-new thread.
212
212
  */
213
213
  listSkills(threadId?: string): Promise<SkillCatalogEntry[]>;
214
+ /**
215
+ * The tools this caller can reach through `agent` (the default agent when omitted), each with the
216
+ * server-declared `presentation` a chat narrates it by — the same list the model is offered.
217
+ * Prefer {@link useToolCatalog}, which fetches it once and shares it.
218
+ */
219
+ listTools(agent?: string): Promise<ToolCatalogEntry[]>;
214
220
  getThread(id: string): Promise<ThreadDetail>;
215
221
  deleteThread(id: string): Promise<void>;
216
222
  forkFromMessage(threadId: string, messageId: string): Promise<ThreadSummary>;
@@ -299,6 +305,172 @@ interface ChatInputProps {
299
305
  */
300
306
  declare function ChatInput({ onSubmit, disabled, placeholder, rows, enableSpeech, speechLang, sendLabel, onStop, isStreaming, stopLabel, className, textareaClassName, sendButtonClassName, micButtonClassName, stopButtonClassName, renderMic, }: ChatInputProps): React.JSX.Element;
301
307
 
308
+ /** Tool name → how the server said it is spoken about. */
309
+ type ToolCatalog = Record<string, ToolPresentation>;
310
+ /** Index `GET <base>/tools` by tool name, keeping only the tools that declared a presentation. */
311
+ declare function toolCatalogFrom(entries: readonly ToolCatalogEntry[]): ToolCatalog;
312
+ /** Dotted-path read. `undefined` rather than a throw, so a template can outlive a field. */
313
+ declare function readPath(value: unknown, path: string): unknown;
314
+ /**
315
+ * Fill `{dotted.path}` placeholders from `context`. A placeholder with nothing behind it collapses
316
+ * along with the whitespace in front of it, so "Reading {key}" degrades to "Reading" rather than
317
+ * printing braces at a person; a filled one keeps the whitespace the author wrote ("({n} files)").
318
+ */
319
+ declare function fillTemplate(template: string, context: unknown): string;
320
+ /**
321
+ * The sentence for one call: the presentation's `running` or `done` template over the call's input.
322
+ *
323
+ * Nothing here reads the tool's name. A tool the catalog does not describe — added since the catalog
324
+ * loaded, or declared without a presentation — is narrated generically (`fallback`), because the only
325
+ * other thing available to say is its identifier.
326
+ */
327
+ declare function phraseFor(presentation: ToolPresentation | undefined, input: unknown, isSettled: boolean, fallback?: {
328
+ running: string;
329
+ done: string;
330
+ }): string;
331
+
332
+ /** One labelled reading of a `metrics` view. */
333
+ interface ResolvedReading {
334
+ label: string;
335
+ /** The value as text (`—` for nothing). */
336
+ value: string;
337
+ unit: string | null;
338
+ }
339
+ /**
340
+ * A tool's output resolved through its view into plain data a renderer draws — never the payload
341
+ * itself. `null` from {@link resolveResultView} means "draw nothing".
342
+ */
343
+ type ResolvedResultView = {
344
+ kind: 'metrics';
345
+ readings: ResolvedReading[];
346
+ } | {
347
+ kind: 'table';
348
+ columns: ToolResultField[];
349
+ rows: string[][];
350
+ empty: string | null;
351
+ } | {
352
+ kind: 'log';
353
+ lines: string[];
354
+ } | {
355
+ kind: 'note';
356
+ text: string;
357
+ };
358
+ /**
359
+ * A view for an output whose tool declared none, from its shape: an array of flat records is a
360
+ * table, an array of strings a log, a flat record a set of readings. `undefined` when nothing fits —
361
+ * a serialized payload is what a person-facing surface exists to avoid, so failing to infer must not
362
+ * fall back to one.
363
+ */
364
+ declare function inferResultView(output: unknown): ToolResultView | undefined;
365
+ /**
366
+ * Read `output` through `view` (or one inferred from its shape when `view` is omitted and `infer` is
367
+ * on). `null` when there is nothing to draw: an `elsewhere` view, an empty reading set, a missing
368
+ * array. A table whose rows array is present but empty resolves with no rows and its `empty` line.
369
+ */
370
+ declare function resolveResultView(output: unknown, view: ToolResultView | undefined, options?: {
371
+ infer?: boolean;
372
+ }): ResolvedResultView | null;
373
+
374
+ /**
375
+ * Where one call stands, as a person reads it:
376
+ * - `running` — input streaming or the tool executing;
377
+ * - `awaiting-approval` — an `action` call parked on a person;
378
+ * - `done` / `failed` / `denied` — settled. A tool that RETURNS `{ error }` has failed just as much
379
+ * as one that threw; the two arrive differently and read the same to a person.
380
+ */
381
+ type ToolCallStatus = 'running' | 'awaiting-approval' | 'done' | 'failed' | 'denied';
382
+ interface ToolCallState {
383
+ status: ToolCallStatus;
384
+ isSettled: boolean;
385
+ isFailed: boolean;
386
+ isDenied: boolean;
387
+ output: unknown;
388
+ error: string | null;
389
+ }
390
+ /** Whether the stream classified this call as an `action` (it parks for approval before it runs). */
391
+ declare function isActionCall(part: AnyToolUIPart): boolean;
392
+ declare function toolCallState(part: AnyToolUIPart): ToolCallState;
393
+ /**
394
+ * Which failed calls the model went on to correct, by call id: a call that failed and was followed,
395
+ * in the same run, by a SUCCESS of the same tool. The operator wants to know a retry happened, not
396
+ * to read every attempt. A failed read is not corrected by a successful query.
397
+ */
398
+ declare function correctedCallIds(parts: readonly AnyToolUIPart[]): Set<string>;
399
+ /** Everything a surface needs to talk about one call without naming it. */
400
+ interface ToolCallDescription {
401
+ status: ToolCallStatus;
402
+ /** "Querying orders" / "Queried orders" — or the generic fallback when the tool declared nothing. */
403
+ phrase: string;
404
+ /** The server's noun phrase for the tool; `null` when it declared no presentation. */
405
+ label: string | null;
406
+ icon: string | null;
407
+ tone: ToolPresentationTone;
408
+ detail: string | null;
409
+ /** The approval prompt, templated over the call's input; `null` when the tool declared none. */
410
+ confirm: {
411
+ title: string;
412
+ verb: string;
413
+ detail: string | null;
414
+ } | null;
415
+ /** The output read through its view, once the call is `done`; `null` otherwise or when nothing to draw. */
416
+ result: ResolvedResultView | null;
417
+ error: string | null;
418
+ presentation: ToolPresentation | null;
419
+ }
420
+ interface DescribeToolCallOptions {
421
+ /** Words for a tool the catalog does not describe. Default `Working` / `Done`. */
422
+ fallback?: {
423
+ running: string;
424
+ done: string;
425
+ };
426
+ /** Infer a result view from the output's shape when the tool declared none. Default `false`. */
427
+ inferResult?: boolean;
428
+ }
429
+ declare function describeToolCall(part: AnyToolUIPart, catalog: ToolCatalog | undefined, options?: DescribeToolCallOptions): ToolCallDescription;
430
+ /**
431
+ * Calls folded under one key — "Database query ×3" — with the state that matters most across them.
432
+ */
433
+ interface ToolActivityGroup {
434
+ key: string;
435
+ /** The server's label for the group's tool; `null` when it declared no presentation. */
436
+ label: string | null;
437
+ icon: string | null;
438
+ /** Worst-first across the calls: running › awaiting-approval › failed › denied › done. */
439
+ status: ToolCallStatus;
440
+ count: number;
441
+ /** The phrase of the group's LATEST call — what is happening now. */
442
+ phrase: string;
443
+ calls: TranscriptToolCall[];
444
+ /** Calls nested under the group's calls (all depths), when nesting was not expanded. */
445
+ innerCount: number;
446
+ }
447
+ interface GroupToolActivityOptions {
448
+ catalog?: ToolCatalog;
449
+ /**
450
+ * What makes two calls "the same activity". Default: the tool's presentation `label`, else its
451
+ * name. Flippy-style source grouping passes its own (e.g. `github:search`).
452
+ */
453
+ keyOf?: (call: TranscriptToolCall, presentation: ToolPresentation | undefined) => string;
454
+ /**
455
+ * Replace a call that has nested calls with those calls (recursively), so the activity reads as
456
+ * what the code-mode run DID rather than "ran code". Default `false`: groups are built over the
457
+ * top-level calls, and `innerCount` says how much ran beneath them.
458
+ */
459
+ expandNested?: boolean;
460
+ /** Drop failed calls the model corrected with a later success of the same tool. Default `false`. */
461
+ hideCorrected?: boolean;
462
+ fallback?: {
463
+ running: string;
464
+ done: string;
465
+ };
466
+ }
467
+ /**
468
+ * Fold a tool run into activity groups, in order of first appearance. Pass `block.roots` (the
469
+ * transcript's call tree) so nesting is honoured; a flat `block.calls` works too and simply has
470
+ * nothing nested.
471
+ */
472
+ declare function groupToolActivity(calls: readonly TranscriptToolCall[], options?: GroupToolActivityOptions): ToolActivityGroup[];
473
+
302
474
  /** A tool UI part on a `UIMessage` — a static `tool-*` part or the `dynamic-tool` part. */
303
475
  type AnyToolUIPart = ToolUIPart | DynamicToolUIPart;
304
476
  type ChatStatus = 'ready' | 'submitted' | 'streaming' | 'error';
@@ -395,6 +567,11 @@ interface TranscriptToolCall {
395
567
  children: TranscriptToolCall[];
396
568
  /** Who has to decide, when the runner said so. See {@link TranscriptApproval}. */
397
569
  approval: TranscriptApproval | null;
570
+ /**
571
+ * How to talk about this call without naming it — status, phrase, label, icon, approval prompt,
572
+ * resolved result — from the server's presentation when `toolCatalog` was given, generic otherwise.
573
+ */
574
+ description: ToolCallDescription;
398
575
  /**
399
576
  * Parked on a person. An `action` tool's input lands and its output never follows on its own —
400
577
  * the loop waits for an approval between the two — so a settled-looking card that never settles
@@ -422,6 +599,11 @@ interface TranscriptToolBlock {
422
599
  * nested calls in `children`. Equal to `calls` when nothing is nested.
423
600
  */
424
601
  roots: TranscriptToolCall[];
602
+ /**
603
+ * The run folded into activity groups ("Database query ×3"), over `roots`, keyed by each tool's
604
+ * presentation label (else its name). For another grouping, call `groupToolActivity` yourself.
605
+ */
606
+ activity: ToolActivityGroup[];
425
607
  }
426
608
  /**
427
609
  * A component the server pushed into the message (the stream's `ui` frame, or a persisted
@@ -569,6 +751,8 @@ interface BuildBlocksOptions {
569
751
  elicitation?: ElicitationBlockOptions;
570
752
  /** Wire approve/reject onto the calls parked on a human. Omitted → they are reported, not actionable. */
571
753
  approval?: ApprovalBlockOptions;
754
+ /** Server-declared tool presentations (`useToolCatalog`), for each call's `description`. */
755
+ toolCatalog?: ToolCatalog;
572
756
  }
573
757
  /**
574
758
  * Walk a message's parts into renderable blocks, buffering consecutive tool parts into one run and
@@ -703,6 +887,11 @@ interface TranscriptItemOptions {
703
887
  * run. Off by default, so a renderer already drawing tool cards keeps drawing them.
704
888
  */
705
889
  sources?: boolean;
890
+ /**
891
+ * Server-declared tool presentations (`useToolCatalog(...).catalog`). Given → each tool call's
892
+ * `description` and each tool block's `activity` speak in the tool's own words; omitted → generic.
893
+ */
894
+ toolCatalog?: ToolCatalog;
706
895
  /**
707
896
  * Settle a parked question set — wire to `useAgentChat`'s `answer`. Supplying it is what lifts a
708
897
  * question set out of the tool run into an `elicitation` block: without somewhere to send an
@@ -1157,6 +1346,34 @@ interface ComposerAutocomplete {
1157
1346
  */
1158
1347
  declare function useComposerAutocomplete(options: UseComposerAutocompleteOptions): ComposerAutocomplete;
1159
1348
 
1349
+ interface UseToolCatalogOptions {
1350
+ /**
1351
+ * The client to ask — `useAgentChat(...).client`, or one of your own. Must be STABLE across
1352
+ * renders (the shared copy is keyed by it): a client constructed inline refetches every render.
1353
+ */
1354
+ client: AgentClient;
1355
+ /** The agent whose tools to list. Omitted → the server's default agent. */
1356
+ agent?: string;
1357
+ /** `false` holds the request (e.g. until the user is signed in). Default `true`. */
1358
+ enabled?: boolean;
1359
+ }
1360
+ interface ToolCatalogState {
1361
+ /** Tool name → presentation, for the tools that declared one. `{}` until loaded. */
1362
+ catalog: ToolCatalog;
1363
+ /** Everything `GET <base>/tools` returned, kinds included. */
1364
+ entries: ToolCatalogEntry[];
1365
+ isLoading: boolean;
1366
+ error: Error | null;
1367
+ /** Drop the shared copy and ask again. */
1368
+ refresh: () => void;
1369
+ }
1370
+ /**
1371
+ * The server-declared presentation of the tools this actor can reach (`GET <base>/tools`), for
1372
+ * `phraseFor`, `describeToolCall` and `groupToolActivity` — or pass `catalog` to
1373
+ * `useChatTranscript({ toolCatalog })` and read the phrases off the transcript's calls.
1374
+ */
1375
+ declare function useToolCatalog(options: UseToolCatalogOptions): ToolCatalogState;
1376
+
1160
1377
  /** The thinking time stamped on a reasoning part, or `null` when it carries none. */
1161
1378
  declare function readReasoningMs(part: {
1162
1379
  providerMetadata?: unknown;
@@ -1431,4 +1648,4 @@ declare function useAgentChat(options: UseAgentChatOptions): {
1431
1648
  clearError: () => void;
1432
1649
  };
1433
1650
 
1434
- export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type ElicitationBlockOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type TranscriptActionState, type TranscriptApproval, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseSpeechRecognitionOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, createSkillsSource, describeTimestamp, describeUsage, extractMessageText, filterAutocompleteItems, findActiveTrigger, formatElapsed, formatRelativeTime, loadStoredSpeechLang, persistSpeechLang, readReasoningMs, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useChatTranscript, useComposerAutocomplete, useElapsed, useSpeechRecognition, useStickToBottom, useTranscriptItem };
1651
+ export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type DescribeToolCallOptions, type ElicitationBlockOptions, type GroupToolActivityOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type ResolvedReading, type ResolvedResultView, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type ToolActivityGroup, type ToolCallDescription, type ToolCallState, type ToolCallStatus, type ToolCatalog, type ToolCatalogState, type TranscriptActionState, type TranscriptApproval, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseSpeechRecognitionOptions, type UseToolCatalogOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, correctedCallIds, createSkillsSource, describeTimestamp, describeToolCall, describeUsage, extractMessageText, fillTemplate, filterAutocompleteItems, findActiveTrigger, formatElapsed, formatRelativeTime, groupToolActivity, inferResultView, isActionCall, loadStoredSpeechLang, persistSpeechLang, phraseFor, readPath, readReasoningMs, resolveResultView, storedMessageToUiMessage, storedThreadToUiMessages, toolCallState, toolCatalogFrom, useAgentChat, useChatTranscript, useComposerAutocomplete, useElapsed, useSpeechRecognition, useStickToBottom, useToolCatalog, useTranscriptItem };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as ai from 'ai';
2
2
  import { ChatTransport, UIMessage, UIMessageChunk, ToolUIPart, DynamicToolUIPart, DataUIPart, UIDataTypes } from 'ai';
3
3
  import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
4
- import { StoredMessage, ThreadSummary, SkillCatalogEntry, ThreadDetail, MessageAttachment, QuotaView } from '@dudousxd/nestjs-agent-core';
4
+ import { StoredMessage, ThreadSummary, SkillCatalogEntry, ToolCatalogEntry, ThreadDetail, MessageAttachment, QuotaView, ToolPresentation, ToolResultField, ToolResultView, ToolPresentationTone } from '@dudousxd/nestjs-agent-core';
5
5
  import React from 'react';
6
6
 
7
7
  /** Identity surfaced by the backend's `meta` SSE frame / response headers. */
@@ -211,6 +211,12 @@ declare class AgentClient {
211
211
  * one conversation; omitted, the server reads it as a brand-new thread.
212
212
  */
213
213
  listSkills(threadId?: string): Promise<SkillCatalogEntry[]>;
214
+ /**
215
+ * The tools this caller can reach through `agent` (the default agent when omitted), each with the
216
+ * server-declared `presentation` a chat narrates it by — the same list the model is offered.
217
+ * Prefer {@link useToolCatalog}, which fetches it once and shares it.
218
+ */
219
+ listTools(agent?: string): Promise<ToolCatalogEntry[]>;
214
220
  getThread(id: string): Promise<ThreadDetail>;
215
221
  deleteThread(id: string): Promise<void>;
216
222
  forkFromMessage(threadId: string, messageId: string): Promise<ThreadSummary>;
@@ -299,6 +305,172 @@ interface ChatInputProps {
299
305
  */
300
306
  declare function ChatInput({ onSubmit, disabled, placeholder, rows, enableSpeech, speechLang, sendLabel, onStop, isStreaming, stopLabel, className, textareaClassName, sendButtonClassName, micButtonClassName, stopButtonClassName, renderMic, }: ChatInputProps): React.JSX.Element;
301
307
 
308
+ /** Tool name → how the server said it is spoken about. */
309
+ type ToolCatalog = Record<string, ToolPresentation>;
310
+ /** Index `GET <base>/tools` by tool name, keeping only the tools that declared a presentation. */
311
+ declare function toolCatalogFrom(entries: readonly ToolCatalogEntry[]): ToolCatalog;
312
+ /** Dotted-path read. `undefined` rather than a throw, so a template can outlive a field. */
313
+ declare function readPath(value: unknown, path: string): unknown;
314
+ /**
315
+ * Fill `{dotted.path}` placeholders from `context`. A placeholder with nothing behind it collapses
316
+ * along with the whitespace in front of it, so "Reading {key}" degrades to "Reading" rather than
317
+ * printing braces at a person; a filled one keeps the whitespace the author wrote ("({n} files)").
318
+ */
319
+ declare function fillTemplate(template: string, context: unknown): string;
320
+ /**
321
+ * The sentence for one call: the presentation's `running` or `done` template over the call's input.
322
+ *
323
+ * Nothing here reads the tool's name. A tool the catalog does not describe — added since the catalog
324
+ * loaded, or declared without a presentation — is narrated generically (`fallback`), because the only
325
+ * other thing available to say is its identifier.
326
+ */
327
+ declare function phraseFor(presentation: ToolPresentation | undefined, input: unknown, isSettled: boolean, fallback?: {
328
+ running: string;
329
+ done: string;
330
+ }): string;
331
+
332
+ /** One labelled reading of a `metrics` view. */
333
+ interface ResolvedReading {
334
+ label: string;
335
+ /** The value as text (`—` for nothing). */
336
+ value: string;
337
+ unit: string | null;
338
+ }
339
+ /**
340
+ * A tool's output resolved through its view into plain data a renderer draws — never the payload
341
+ * itself. `null` from {@link resolveResultView} means "draw nothing".
342
+ */
343
+ type ResolvedResultView = {
344
+ kind: 'metrics';
345
+ readings: ResolvedReading[];
346
+ } | {
347
+ kind: 'table';
348
+ columns: ToolResultField[];
349
+ rows: string[][];
350
+ empty: string | null;
351
+ } | {
352
+ kind: 'log';
353
+ lines: string[];
354
+ } | {
355
+ kind: 'note';
356
+ text: string;
357
+ };
358
+ /**
359
+ * A view for an output whose tool declared none, from its shape: an array of flat records is a
360
+ * table, an array of strings a log, a flat record a set of readings. `undefined` when nothing fits —
361
+ * a serialized payload is what a person-facing surface exists to avoid, so failing to infer must not
362
+ * fall back to one.
363
+ */
364
+ declare function inferResultView(output: unknown): ToolResultView | undefined;
365
+ /**
366
+ * Read `output` through `view` (or one inferred from its shape when `view` is omitted and `infer` is
367
+ * on). `null` when there is nothing to draw: an `elsewhere` view, an empty reading set, a missing
368
+ * array. A table whose rows array is present but empty resolves with no rows and its `empty` line.
369
+ */
370
+ declare function resolveResultView(output: unknown, view: ToolResultView | undefined, options?: {
371
+ infer?: boolean;
372
+ }): ResolvedResultView | null;
373
+
374
+ /**
375
+ * Where one call stands, as a person reads it:
376
+ * - `running` — input streaming or the tool executing;
377
+ * - `awaiting-approval` — an `action` call parked on a person;
378
+ * - `done` / `failed` / `denied` — settled. A tool that RETURNS `{ error }` has failed just as much
379
+ * as one that threw; the two arrive differently and read the same to a person.
380
+ */
381
+ type ToolCallStatus = 'running' | 'awaiting-approval' | 'done' | 'failed' | 'denied';
382
+ interface ToolCallState {
383
+ status: ToolCallStatus;
384
+ isSettled: boolean;
385
+ isFailed: boolean;
386
+ isDenied: boolean;
387
+ output: unknown;
388
+ error: string | null;
389
+ }
390
+ /** Whether the stream classified this call as an `action` (it parks for approval before it runs). */
391
+ declare function isActionCall(part: AnyToolUIPart): boolean;
392
+ declare function toolCallState(part: AnyToolUIPart): ToolCallState;
393
+ /**
394
+ * Which failed calls the model went on to correct, by call id: a call that failed and was followed,
395
+ * in the same run, by a SUCCESS of the same tool. The operator wants to know a retry happened, not
396
+ * to read every attempt. A failed read is not corrected by a successful query.
397
+ */
398
+ declare function correctedCallIds(parts: readonly AnyToolUIPart[]): Set<string>;
399
+ /** Everything a surface needs to talk about one call without naming it. */
400
+ interface ToolCallDescription {
401
+ status: ToolCallStatus;
402
+ /** "Querying orders" / "Queried orders" — or the generic fallback when the tool declared nothing. */
403
+ phrase: string;
404
+ /** The server's noun phrase for the tool; `null` when it declared no presentation. */
405
+ label: string | null;
406
+ icon: string | null;
407
+ tone: ToolPresentationTone;
408
+ detail: string | null;
409
+ /** The approval prompt, templated over the call's input; `null` when the tool declared none. */
410
+ confirm: {
411
+ title: string;
412
+ verb: string;
413
+ detail: string | null;
414
+ } | null;
415
+ /** The output read through its view, once the call is `done`; `null` otherwise or when nothing to draw. */
416
+ result: ResolvedResultView | null;
417
+ error: string | null;
418
+ presentation: ToolPresentation | null;
419
+ }
420
+ interface DescribeToolCallOptions {
421
+ /** Words for a tool the catalog does not describe. Default `Working` / `Done`. */
422
+ fallback?: {
423
+ running: string;
424
+ done: string;
425
+ };
426
+ /** Infer a result view from the output's shape when the tool declared none. Default `false`. */
427
+ inferResult?: boolean;
428
+ }
429
+ declare function describeToolCall(part: AnyToolUIPart, catalog: ToolCatalog | undefined, options?: DescribeToolCallOptions): ToolCallDescription;
430
+ /**
431
+ * Calls folded under one key — "Database query ×3" — with the state that matters most across them.
432
+ */
433
+ interface ToolActivityGroup {
434
+ key: string;
435
+ /** The server's label for the group's tool; `null` when it declared no presentation. */
436
+ label: string | null;
437
+ icon: string | null;
438
+ /** Worst-first across the calls: running › awaiting-approval › failed › denied › done. */
439
+ status: ToolCallStatus;
440
+ count: number;
441
+ /** The phrase of the group's LATEST call — what is happening now. */
442
+ phrase: string;
443
+ calls: TranscriptToolCall[];
444
+ /** Calls nested under the group's calls (all depths), when nesting was not expanded. */
445
+ innerCount: number;
446
+ }
447
+ interface GroupToolActivityOptions {
448
+ catalog?: ToolCatalog;
449
+ /**
450
+ * What makes two calls "the same activity". Default: the tool's presentation `label`, else its
451
+ * name. Flippy-style source grouping passes its own (e.g. `github:search`).
452
+ */
453
+ keyOf?: (call: TranscriptToolCall, presentation: ToolPresentation | undefined) => string;
454
+ /**
455
+ * Replace a call that has nested calls with those calls (recursively), so the activity reads as
456
+ * what the code-mode run DID rather than "ran code". Default `false`: groups are built over the
457
+ * top-level calls, and `innerCount` says how much ran beneath them.
458
+ */
459
+ expandNested?: boolean;
460
+ /** Drop failed calls the model corrected with a later success of the same tool. Default `false`. */
461
+ hideCorrected?: boolean;
462
+ fallback?: {
463
+ running: string;
464
+ done: string;
465
+ };
466
+ }
467
+ /**
468
+ * Fold a tool run into activity groups, in order of first appearance. Pass `block.roots` (the
469
+ * transcript's call tree) so nesting is honoured; a flat `block.calls` works too and simply has
470
+ * nothing nested.
471
+ */
472
+ declare function groupToolActivity(calls: readonly TranscriptToolCall[], options?: GroupToolActivityOptions): ToolActivityGroup[];
473
+
302
474
  /** A tool UI part on a `UIMessage` — a static `tool-*` part or the `dynamic-tool` part. */
303
475
  type AnyToolUIPart = ToolUIPart | DynamicToolUIPart;
304
476
  type ChatStatus = 'ready' | 'submitted' | 'streaming' | 'error';
@@ -395,6 +567,11 @@ interface TranscriptToolCall {
395
567
  children: TranscriptToolCall[];
396
568
  /** Who has to decide, when the runner said so. See {@link TranscriptApproval}. */
397
569
  approval: TranscriptApproval | null;
570
+ /**
571
+ * How to talk about this call without naming it — status, phrase, label, icon, approval prompt,
572
+ * resolved result — from the server's presentation when `toolCatalog` was given, generic otherwise.
573
+ */
574
+ description: ToolCallDescription;
398
575
  /**
399
576
  * Parked on a person. An `action` tool's input lands and its output never follows on its own —
400
577
  * the loop waits for an approval between the two — so a settled-looking card that never settles
@@ -422,6 +599,11 @@ interface TranscriptToolBlock {
422
599
  * nested calls in `children`. Equal to `calls` when nothing is nested.
423
600
  */
424
601
  roots: TranscriptToolCall[];
602
+ /**
603
+ * The run folded into activity groups ("Database query ×3"), over `roots`, keyed by each tool's
604
+ * presentation label (else its name). For another grouping, call `groupToolActivity` yourself.
605
+ */
606
+ activity: ToolActivityGroup[];
425
607
  }
426
608
  /**
427
609
  * A component the server pushed into the message (the stream's `ui` frame, or a persisted
@@ -569,6 +751,8 @@ interface BuildBlocksOptions {
569
751
  elicitation?: ElicitationBlockOptions;
570
752
  /** Wire approve/reject onto the calls parked on a human. Omitted → they are reported, not actionable. */
571
753
  approval?: ApprovalBlockOptions;
754
+ /** Server-declared tool presentations (`useToolCatalog`), for each call's `description`. */
755
+ toolCatalog?: ToolCatalog;
572
756
  }
573
757
  /**
574
758
  * Walk a message's parts into renderable blocks, buffering consecutive tool parts into one run and
@@ -703,6 +887,11 @@ interface TranscriptItemOptions {
703
887
  * run. Off by default, so a renderer already drawing tool cards keeps drawing them.
704
888
  */
705
889
  sources?: boolean;
890
+ /**
891
+ * Server-declared tool presentations (`useToolCatalog(...).catalog`). Given → each tool call's
892
+ * `description` and each tool block's `activity` speak in the tool's own words; omitted → generic.
893
+ */
894
+ toolCatalog?: ToolCatalog;
706
895
  /**
707
896
  * Settle a parked question set — wire to `useAgentChat`'s `answer`. Supplying it is what lifts a
708
897
  * question set out of the tool run into an `elicitation` block: without somewhere to send an
@@ -1157,6 +1346,34 @@ interface ComposerAutocomplete {
1157
1346
  */
1158
1347
  declare function useComposerAutocomplete(options: UseComposerAutocompleteOptions): ComposerAutocomplete;
1159
1348
 
1349
+ interface UseToolCatalogOptions {
1350
+ /**
1351
+ * The client to ask — `useAgentChat(...).client`, or one of your own. Must be STABLE across
1352
+ * renders (the shared copy is keyed by it): a client constructed inline refetches every render.
1353
+ */
1354
+ client: AgentClient;
1355
+ /** The agent whose tools to list. Omitted → the server's default agent. */
1356
+ agent?: string;
1357
+ /** `false` holds the request (e.g. until the user is signed in). Default `true`. */
1358
+ enabled?: boolean;
1359
+ }
1360
+ interface ToolCatalogState {
1361
+ /** Tool name → presentation, for the tools that declared one. `{}` until loaded. */
1362
+ catalog: ToolCatalog;
1363
+ /** Everything `GET <base>/tools` returned, kinds included. */
1364
+ entries: ToolCatalogEntry[];
1365
+ isLoading: boolean;
1366
+ error: Error | null;
1367
+ /** Drop the shared copy and ask again. */
1368
+ refresh: () => void;
1369
+ }
1370
+ /**
1371
+ * The server-declared presentation of the tools this actor can reach (`GET <base>/tools`), for
1372
+ * `phraseFor`, `describeToolCall` and `groupToolActivity` — or pass `catalog` to
1373
+ * `useChatTranscript({ toolCatalog })` and read the phrases off the transcript's calls.
1374
+ */
1375
+ declare function useToolCatalog(options: UseToolCatalogOptions): ToolCatalogState;
1376
+
1160
1377
  /** The thinking time stamped on a reasoning part, or `null` when it carries none. */
1161
1378
  declare function readReasoningMs(part: {
1162
1379
  providerMetadata?: unknown;
@@ -1431,4 +1648,4 @@ declare function useAgentChat(options: UseAgentChatOptions): {
1431
1648
  clearError: () => void;
1432
1649
  };
1433
1650
 
1434
- export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type ElicitationBlockOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type TranscriptActionState, type TranscriptApproval, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseSpeechRecognitionOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, createSkillsSource, describeTimestamp, describeUsage, extractMessageText, filterAutocompleteItems, findActiveTrigger, formatElapsed, formatRelativeTime, loadStoredSpeechLang, persistSpeechLang, readReasoningMs, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useChatTranscript, useComposerAutocomplete, useElapsed, useSpeechRecognition, useStickToBottom, useTranscriptItem };
1651
+ export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type DescribeToolCallOptions, type ElicitationBlockOptions, type GroupToolActivityOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type ResolvedReading, type ResolvedResultView, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type ToolActivityGroup, type ToolCallDescription, type ToolCallState, type ToolCallStatus, type ToolCatalog, type ToolCatalogState, type TranscriptActionState, type TranscriptApproval, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseSpeechRecognitionOptions, type UseToolCatalogOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, correctedCallIds, createSkillsSource, describeTimestamp, describeToolCall, describeUsage, extractMessageText, fillTemplate, filterAutocompleteItems, findActiveTrigger, formatElapsed, formatRelativeTime, groupToolActivity, inferResultView, isActionCall, loadStoredSpeechLang, persistSpeechLang, phraseFor, readPath, readReasoningMs, resolveResultView, storedMessageToUiMessage, storedThreadToUiMessages, toolCallState, toolCatalogFrom, useAgentChat, useChatTranscript, useComposerAutocomplete, useElapsed, useSpeechRecognition, useStickToBottom, useToolCatalog, useTranscriptItem };