@tanstack/ai 0.47.3 → 0.48.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.
Files changed (101) hide show
  1. package/README.md +2 -1
  2. package/dist/esm/activities/chat/adapter.d.ts +5 -4
  3. package/dist/esm/activities/chat/adapter.js.map +1 -1
  4. package/dist/esm/activities/chat/index.d.ts +4 -7
  5. package/dist/esm/activities/chat/index.js +201 -243
  6. package/dist/esm/activities/chat/index.js.map +1 -1
  7. package/dist/esm/activities/chat/messages.js +115 -25
  8. package/dist/esm/activities/chat/messages.js.map +1 -1
  9. package/dist/esm/activities/chat/stream/processor.d.ts +38 -17
  10. package/dist/esm/activities/chat/stream/processor.js +186 -101
  11. package/dist/esm/activities/chat/stream/processor.js.map +1 -1
  12. package/dist/esm/activities/chat/tools/tool-calls.d.ts +3 -2
  13. package/dist/esm/activities/chat/tools/tool-calls.js +15 -10
  14. package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
  15. package/dist/esm/activities/generateVideo/index.js +6 -6
  16. package/dist/esm/activities/generateVideo/index.js.map +1 -1
  17. package/dist/esm/activities/stream-generation-result.js +7 -8
  18. package/dist/esm/activities/stream-generation-result.js.map +1 -1
  19. package/dist/esm/activities/summarize/chat-stream-summarize.d.ts +2 -1
  20. package/dist/esm/activities/summarize/chat-stream-summarize.js +56 -53
  21. package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -1
  22. package/dist/esm/adapter-internals.d.ts +2 -0
  23. package/dist/esm/adapter-internals.js +3 -1
  24. package/dist/esm/client.d.ts +8 -1
  25. package/dist/esm/client.js +7 -2
  26. package/dist/esm/client.js.map +1 -1
  27. package/dist/esm/index.d.ts +6 -0
  28. package/dist/esm/index.js +6 -2
  29. package/dist/esm/middlewares/otel.js +11 -4
  30. package/dist/esm/middlewares/otel.js.map +1 -1
  31. package/dist/esm/stream-to-response.js +8 -5
  32. package/dist/esm/stream-to-response.js.map +1 -1
  33. package/dist/esm/stream-to-websocket.js +4 -2
  34. package/dist/esm/stream-to-websocket.js.map +1 -1
  35. package/dist/esm/strip-to-spec-middleware.d.ts +10 -13
  36. package/dist/esm/strip-to-spec-middleware.js +24 -22
  37. package/dist/esm/strip-to-spec-middleware.js.map +1 -1
  38. package/dist/esm/types.d.ts +82 -305
  39. package/dist/esm/utilities/adapter-yield-chunk.d.ts +31 -0
  40. package/dist/esm/utilities/ag-ui-usage.d.ts +24 -0
  41. package/dist/esm/utilities/ag-ui-usage.js +66 -0
  42. package/dist/esm/utilities/ag-ui-usage.js.map +1 -0
  43. package/dist/esm/utilities/ag-ui-wire.d.ts +14 -7
  44. package/dist/esm/utilities/ag-ui-wire.js +71 -30
  45. package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
  46. package/dist/esm/utilities/chat-params.d.ts +3 -3
  47. package/dist/esm/utilities/chat-params.js +10 -30
  48. package/dist/esm/utilities/chat-params.js.map +1 -1
  49. package/dist/esm/utilities/chunk-ids.d.ts +5 -0
  50. package/dist/esm/utilities/chunk-ids.js +25 -0
  51. package/dist/esm/utilities/chunk-ids.js.map +1 -0
  52. package/dist/esm/utilities/merge-metadata.d.ts +14 -0
  53. package/dist/esm/utilities/merge-metadata.js +43 -0
  54. package/dist/esm/utilities/merge-metadata.js.map +1 -0
  55. package/dist/esm/utilities/normalize-stream-chunk.d.ts +3 -0
  56. package/dist/esm/utilities/normalize-stream-chunk.js +100 -0
  57. package/dist/esm/utilities/normalize-stream-chunk.js.map +1 -0
  58. package/dist/esm/utilities/reasoning-encrypted-value.d.ts +8 -0
  59. package/dist/esm/utilities/reasoning-encrypted-value.js +16 -0
  60. package/dist/esm/utilities/reasoning-encrypted-value.js.map +1 -0
  61. package/dist/esm/utilities/restore-inbound-chunk.d.ts +15 -0
  62. package/dist/esm/utilities/restore-inbound-chunk.js +43 -0
  63. package/dist/esm/utilities/restore-inbound-chunk.js.map +1 -0
  64. package/dist/esm/utilities/spec-event-keys.d.ts +2 -0
  65. package/dist/esm/utilities/spec-event-keys.js +56 -0
  66. package/dist/esm/utilities/spec-event-keys.js.map +1 -0
  67. package/dist/esm/utilities/structured-output-events.d.ts +3 -3
  68. package/dist/esm/utilities/structured-output-events.js.map +1 -1
  69. package/package.json +2 -2
  70. package/src/activities/chat/adapter.ts +4 -4
  71. package/src/activities/chat/index.ts +398 -400
  72. package/src/activities/chat/messages.ts +174 -34
  73. package/src/activities/chat/stream/processor.ts +289 -218
  74. package/src/activities/chat/tools/tool-calls.ts +23 -22
  75. package/src/activities/generateVideo/index.ts +7 -6
  76. package/src/activities/stream-generation-result.ts +8 -12
  77. package/src/activities/summarize/chat-stream-summarize.ts +94 -70
  78. package/src/adapter-internals.ts +2 -0
  79. package/src/client.ts +13 -0
  80. package/src/index.ts +6 -0
  81. package/src/middlewares/otel.ts +16 -8
  82. package/src/stream-to-response.ts +11 -4
  83. package/src/stream-to-websocket.ts +3 -1
  84. package/src/strip-to-spec-middleware.ts +48 -24
  85. package/src/types.ts +109 -393
  86. package/src/utilities/adapter-yield-chunk.ts +30 -0
  87. package/src/utilities/ag-ui-usage.test.ts +194 -0
  88. package/src/utilities/ag-ui-usage.ts +148 -0
  89. package/src/utilities/ag-ui-wire.ts +149 -31
  90. package/src/utilities/chat-params.ts +22 -39
  91. package/src/utilities/chunk-ids.ts +24 -0
  92. package/src/utilities/merge-metadata.test.ts +117 -0
  93. package/src/utilities/merge-metadata.ts +59 -0
  94. package/src/utilities/normalize-stream-chunk.test.ts +423 -0
  95. package/src/utilities/normalize-stream-chunk.ts +186 -0
  96. package/src/utilities/reasoning-encrypted-value.ts +18 -0
  97. package/src/utilities/restore-inbound-chunk.test.ts +133 -0
  98. package/src/utilities/restore-inbound-chunk.ts +72 -0
  99. package/src/utilities/spec-event-keys.test.ts +34 -0
  100. package/src/utilities/spec-event-keys.ts +74 -0
  101. package/src/utilities/structured-output-events.ts +3 -3
@@ -3,9 +3,9 @@ import { InternalLogger } from './logger/internal-logger.js';
3
3
  import { SystemPrompt } from './system-prompts.js';
4
4
  import { CapabilityContext } from './activities/chat/middleware/capabilities.js';
5
5
  import { InterruptSubmissionError } from './interrupts.js';
6
- import { ProviderTool } from './tools/provider-tool.js';
7
6
  import { BilledUsage, BillingUnit, CompletionTokensDetails, PromptTokensDetails, ProviderUsageDetails, TokenUsage, UsageCostBreakdown } from '@tanstack/ai-event-client';
8
7
  import { BaseEvent as AGUIBaseEvent, CustomEvent as AGUICustomEvent, Interrupt as AGUIInterrupt, MessagesSnapshotEvent as AGUIMessagesSnapshotEvent, ReasoningEncryptedValueEvent as AGUIReasoningEncryptedValueEvent, ReasoningEndEvent as AGUIReasoningEndEvent, ReasoningMessageContentEvent as AGUIReasoningMessageContentEvent, ReasoningMessageEndEvent as AGUIReasoningMessageEndEvent, ReasoningMessageStartEvent as AGUIReasoningMessageStartEvent, ReasoningStartEvent as AGUIReasoningStartEvent, ResumeEntry as AGUIResumeEntry, RunErrorEvent as AGUIRunErrorEvent, RunFinishedEvent as AGUIRunFinishedEvent, RunFinishedOutcome as AGUIRunFinishedOutcome, RunStartedEvent as AGUIRunStartedEvent, StateDeltaEvent as AGUIStateDeltaEvent, StateSnapshotEvent as AGUIStateSnapshotEvent, StepFinishedEvent as AGUIStepFinishedEvent, StepStartedEvent as AGUIStepStartedEvent, TextMessageContentEvent as AGUITextMessageContentEvent, TextMessageEndEvent as AGUITextMessageEndEvent, TextMessageStartEvent as AGUITextMessageStartEvent, ToolCallArgsEvent as AGUIToolCallArgsEvent, ToolCallEndEvent as AGUIToolCallEndEvent, ToolCallResultEvent as AGUIToolCallResultEvent, ToolCallStartEvent as AGUIToolCallStartEvent, EventType } from '@ag-ui/core';
8
+ import { SpecTokenUsage, TokenUsageLeftover } from './utilities/ag-ui-usage.js';
9
9
  export type { ProviderTool } from './tools/provider-tool.js';
10
10
  /**
11
11
  * Tool call states - track the lifecycle of a tool call
@@ -374,6 +374,41 @@ export interface UIResourcePart {
374
374
  meta?: Record<string, unknown>;
375
375
  }
376
376
  export type MessagePart<TData = unknown> = TextPart | ImagePart | AudioPart | VideoPart | DocumentPart | ToolCallPart | ToolResultPart | ThinkingPart | StructuredOutputPart<TData> | UIResourcePart;
377
+ /**
378
+ * Shape of `metadata.tanstack` on a message.
379
+ * `createdAt` is an ISO-8601 string.
380
+ */
381
+ export interface TanStackMessageMetadata {
382
+ createdAt?: string;
383
+ model?: string;
384
+ /** Thinking signature for a `role: 'reasoning'` fan-out message. */
385
+ signature?: string;
386
+ /** Per-tool-call provider metadata keyed by tool call id (e.g. Gemini thoughtSignature). */
387
+ toolCallMetadata?: Record<string, unknown>;
388
+ structuredOutput?: {
389
+ status?: 'streaming' | 'complete' | 'error';
390
+ raw?: string;
391
+ errorMessage?: string;
392
+ };
393
+ uiResources?: Array<UIResourcePart>;
394
+ }
395
+ /**
396
+ * Shape of `metadata.tanstack` on run events.
397
+ */
398
+ export interface TanStackRunMetadata {
399
+ model?: string;
400
+ finishReason?: 'stop' | 'length' | 'content_filter' | 'tool_calls' | null;
401
+ /** TokenUsage fields that have no AG-UI `usage[]` equivalent. */
402
+ usage?: TokenUsageLeftover;
403
+ interruptErrors?: ReadonlyArray<InterruptSubmissionError>;
404
+ threadId?: string;
405
+ runId?: string;
406
+ sessionId?: string;
407
+ index?: number;
408
+ state?: ToolOutputState;
409
+ /** Parsed `TOOL_CALL_END` input. Spec `TOOL_CALL_END` has no top-level `input`. */
410
+ input?: unknown;
411
+ }
377
412
  /**
378
413
  * UIMessage - Domain-specific message format optimized for building chat UIs
379
414
  * Contains parts that can be text, tool calls, or tool results. Generic over
@@ -386,6 +421,11 @@ export interface UIMessage<TData = unknown> {
386
421
  role: 'system' | 'user' | 'assistant';
387
422
  parts: Array<MessagePart<TData>>;
388
423
  createdAt?: Date;
424
+ /**
425
+ * Optional AG-UI metadata bag. TanStack writes the `tanstack` key.
426
+ * User keys stay at the top.
427
+ */
428
+ metadata?: Record<string, any>;
389
429
  }
390
430
  export type InputModalitiesTypes = {
391
431
  inputModalities: ReadonlyArray<Modality>;
@@ -876,25 +916,20 @@ export type AGUIEventType = `${EventType}`;
876
916
  export type StreamChunkType = AGUIEventType;
877
917
  /**
878
918
  * Base structure for AG-UI events.
879
- * Extends @ag-ui/core BaseEvent with TanStack AI additions.
919
+ * Extends @ag-ui/core BaseEvent. TanStack extras ride in `metadata`.
880
920
  *
881
921
  * @ag-ui/core provides: `type`, `timestamp?`, `rawEvent?`
882
- * TanStack AI adds: `model?`
883
922
  */
884
923
  export interface BaseAGUIEvent extends AGUIBaseEvent {
885
- /** Model identifier for multi-model support */
886
- model?: string;
924
+ metadata?: Record<string, any>;
887
925
  }
888
926
  /**
889
927
  * Emitted when a run starts.
890
928
  * This is the first event in any streaming response.
891
929
  *
892
930
  * @ag-ui/core provides: `threadId`, `runId`, `parentRunId?`, `input?`
893
- * TanStack AI adds: `model?`
894
931
  */
895
932
  export interface RunStartedEvent extends AGUIRunStartedEvent {
896
- /** Model identifier for multi-model support */
897
- model?: string;
898
933
  }
899
934
  export type { BilledUsage, BillingUnit, CompletionTokensDetails, PromptTokensDetails, ProviderUsageDetails, TokenUsage, UsageCostBreakdown, };
900
935
  /**
@@ -912,201 +947,123 @@ export type RunAgentResumeItem = AGUIResumeEntry & {
912
947
  /**
913
948
  * Emitted when a run completes successfully.
914
949
  *
915
- * @ag-ui/core provides: `threadId`, `runId`, `result?`
916
- * TanStack AI adds: `model?`, `finishReason?`, `usage?`
950
+ * @ag-ui/core provides: `threadId`, `runId`, `result?`, `outcome?`
951
+ * Spec `usage[]` is provider/model token counts. TanStack leftovers live in
952
+ * `metadata.tanstack`.
917
953
  */
918
- export interface RunFinishedEvent extends AGUIRunFinishedEvent {
919
- /** Model identifier for multi-model support */
954
+ export interface RunFinishedEvent extends Pick<AGUIRunFinishedEvent, 'threadId' | 'runId' | 'result' | 'outcome' | 'timestamp' | 'rawEvent'> {
955
+ type: EventType.RUN_FINISHED;
956
+ usage?: Array<SpecTokenUsage> | TokenUsage;
957
+ /** Restored on the client from `metadata.tanstack`. */
920
958
  model?: string;
921
- /** Why the generation stopped */
959
+ /** Restored on the client from `metadata.tanstack`. */
922
960
  finishReason?: 'stop' | 'length' | 'content_filter' | 'tool_calls' | null;
923
- /** Token usage statistics with optional detailed breakdowns and provider-reported cost. */
924
- usage?: TokenUsage;
961
+ metadata?: {
962
+ tanstack?: TanStackRunMetadata;
963
+ } & Record<string, any>;
925
964
  }
926
965
  /**
927
966
  * Emitted when an error occurs during a run.
928
967
  *
929
968
  * @ag-ui/core provides: `message`, `code?`
930
- * TanStack AI adds: `model?`, `error?` (deprecated nested form)
969
+ * Spec `usage[]` is provider/model token counts. Interrupt errors live in
970
+ * `metadata.tanstack.interruptErrors`.
931
971
  */
932
- export interface RunErrorEvent extends AGUIRunErrorEvent {
933
- /** Model identifier for multi-model support */
972
+ export interface RunErrorEvent extends Pick<AGUIRunErrorEvent, 'message' | 'code' | 'timestamp' | 'rawEvent'> {
973
+ type: EventType.RUN_ERROR;
974
+ usage?: Array<SpecTokenUsage> | TokenUsage;
975
+ /** Restored on the client from `metadata.tanstack`. */
976
+ threadId?: string;
977
+ /** Restored on the client from `metadata.tanstack`. */
978
+ runId?: string;
979
+ /** Restored on the client from `metadata.tanstack`. */
934
980
  model?: string;
935
- /** Exhaustive TanStack interrupt submission failures for this run. */
936
- 'tanstack:interruptErrors'?: ReadonlyArray<InterruptSubmissionError>;
937
- /**
938
- * @deprecated Use top-level `message` and `code` fields instead.
939
- * Kept for backward compatibility.
940
- */
981
+ /** Nested payload kept for in-process / durability consumers. */
941
982
  error?: {
942
983
  message: string;
943
- code?: string | undefined;
944
- } | undefined;
984
+ code?: string;
985
+ };
986
+ metadata?: {
987
+ tanstack?: TanStackRunMetadata;
988
+ } & Record<string, any>;
945
989
  }
946
990
  /**
947
991
  * Emitted when a text message starts.
948
992
  *
949
993
  * @ag-ui/core provides: `messageId`, `role?`, `name?`
950
- * TanStack AI adds: `model?`
951
994
  */
952
995
  export interface TextMessageStartEvent extends AGUITextMessageStartEvent {
953
- /** Model identifier for multi-model support */
954
- model?: string;
955
996
  }
956
997
  /**
957
998
  * Emitted when text content is generated (streaming tokens).
958
999
  *
959
1000
  * @ag-ui/core provides: `messageId`, `delta`
960
- * TanStack AI adds: `model?`, `content?` (accumulated)
961
1001
  */
962
1002
  export interface TextMessageContentEvent extends AGUITextMessageContentEvent {
963
- /** Model identifier for multi-model support */
964
- model?: string;
965
- /** Full accumulated content so far (TanStack AI internal, for debugging) */
966
- content?: string;
967
1003
  }
968
1004
  /**
969
1005
  * Emitted when a text message completes.
970
1006
  *
971
1007
  * @ag-ui/core provides: `messageId`
972
- * TanStack AI adds: `model?`
973
1008
  */
974
1009
  export interface TextMessageEndEvent extends AGUITextMessageEndEvent {
975
- /** Model identifier for multi-model support */
976
- model?: string;
977
1010
  }
978
1011
  /**
979
1012
  * Emitted when a tool call starts.
980
1013
  *
981
1014
  * @ag-ui/core provides: `toolCallId`, `toolCallName`, `parentMessageId?`
982
- * TanStack AI adds: `model?`, `toolName` (deprecated alias), `index?`, `metadata?`
983
1015
  *
984
1016
  * Field shapes are taken from AG-UI via `Pick` (not `extends`) so Zod
985
1017
  * `.passthrough()` index signatures do not pollute the StreamChunk
986
- * discriminated union — required for {@link TypedStreamChunk} narrowing.
987
- *
988
- * @typeParam TToolName - Constrained tool name type. Defaults to `string` (untyped).
989
- * When the stream is returned from `chat()` with typed tools, `TypedStreamChunk`
990
- * intersects a literal onto `toolCallName` and `toolName` for discrimination.
1018
+ * discriminated union — required for {@link KnownCustomEvent} narrowing.
991
1019
  */
992
- export interface ToolCallStartEvent<TToolName extends string = string> extends Pick<AGUIToolCallStartEvent, 'toolCallId' | 'toolCallName' | 'parentMessageId' | 'timestamp' | 'rawEvent'> {
1020
+ export interface ToolCallStartEvent extends Pick<AGUIToolCallStartEvent, 'toolCallId' | 'toolCallName' | 'parentMessageId' | 'timestamp' | 'rawEvent'> {
993
1021
  type: 'TOOL_CALL_START';
994
- /** Model identifier for multi-model support */
995
- model?: string;
996
- /**
997
- * @deprecated Use `toolCallName` instead (from @ag-ui/core spec).
998
- * Kept for backward compatibility.
999
- *
1000
- * Carries `TToolName` on the base interface; for `toolCallName` narrowing use
1001
- * {@link TypedStreamChunk} (distributed variants intersect the AG-UI field).
1002
- */
1003
- toolName: TToolName;
1004
- /** Index for parallel tool calls */
1005
- index?: number;
1006
- /** Provider-specific metadata to carry into the ToolCall.
1007
- * Untyped at the event layer because events flow through a discriminated
1008
- * union that does not survive generics; adapters cast it to their typed
1009
- * `TToolCallMetadata` shape when emitting. */
1010
- metadata?: Record<string, unknown>;
1022
+ /** Alias of `toolCallName`. Kept so existing stream readers still compile. */
1023
+ toolName?: string;
1024
+ /** Provider-specific metadata to carry into the ToolCall. */
1025
+ metadata?: Record<string, any>;
1011
1026
  }
1012
1027
  /**
1013
1028
  * Emitted when tool call arguments are streaming.
1014
1029
  *
1015
1030
  * @ag-ui/core provides: `toolCallId`, `delta`
1016
- * TanStack AI adds: `model?`, `args?` (accumulated)
1017
1031
  */
1018
1032
  export interface ToolCallArgsEvent extends AGUIToolCallArgsEvent {
1019
- /** Model identifier for multi-model support */
1020
- model?: string;
1021
- /** Full accumulated arguments so far (TanStack AI internal) */
1022
- args?: string;
1023
1033
  }
1024
1034
  /**
1025
1035
  * Emitted when a tool call completes.
1026
1036
  *
1027
1037
  * @ag-ui/core provides: `toolCallId`
1028
- * TanStack AI adds: `model?`, `toolCallName?`, `toolName?` (deprecated), `input?`, `output?`, `result?`
1029
1038
  *
1030
1039
  * Same `Pick` (not `extends`) rationale as {@link ToolCallStartEvent}.
1031
- *
1032
- * @typeParam TToolName - Constrained tool name type. Defaults to `string` (untyped).
1033
- * @typeParam TInput - Constrained input arguments type. Defaults to `unknown`.
1034
- * @typeParam TOutput - Constrained output type from the tool's `outputSchema`. Defaults to `unknown`.
1035
1040
  */
1036
- export interface ToolCallEndEvent<TToolName extends string = string, TInput = unknown, TOutput = unknown> extends Pick<AGUIToolCallEndEvent, 'toolCallId' | 'timestamp' | 'rawEvent'> {
1041
+ export interface ToolCallEndEvent extends Pick<AGUIToolCallEndEvent, 'toolCallId' | 'timestamp' | 'rawEvent'> {
1037
1042
  type: 'TOOL_CALL_END';
1038
- /** Model identifier for multi-model support */
1039
- model?: string;
1040
- /** Name of the tool that completed (AG-UI-compatible optional field) */
1041
- toolCallName?: TToolName;
1042
- /**
1043
- * @deprecated Use `toolCallName` instead.
1044
- * Kept for backward compatibility.
1045
- */
1046
- toolName?: TToolName;
1047
- /** Final parsed input arguments (TanStack AI internal) */
1048
- input?: TInput;
1049
- /**
1050
- * Tool execution output, validated against the tool's `outputSchema` when
1051
- * one is declared. Prefer this over parsing `result` when present.
1052
- * Undefined for tools without execute, client tools pending approval, or
1053
- * when execution throws.
1054
- */
1055
- output?: TOutput;
1056
- /** Tool execution result (TanStack AI internal / wire form) */
1057
- result?: string | Array<ContentPart>;
1058
- /** Tool execution output state (TanStack AI internal) */
1059
- state?: ToolOutputState;
1043
+ /** Parsed tool arguments when the adapter already parsed them. */
1044
+ input?: unknown;
1045
+ metadata?: Record<string, any>;
1060
1046
  }
1061
1047
  /**
1062
1048
  * Emitted when a tool call result is available.
1063
1049
  *
1064
1050
  * @ag-ui/core provides: `messageId`, `toolCallId`, `content`, `role?`
1065
- * TanStack AI adds: `model?`
1066
1051
  */
1067
1052
  export interface ToolCallResultEvent extends AGUIToolCallResultEvent {
1068
- /** Model identifier for multi-model support */
1069
- model?: string;
1070
- /** Tool execution output state (TanStack AI internal) */
1071
- state?: ToolOutputState;
1072
1053
  }
1073
1054
  /**
1074
1055
  * Emitted when a thinking/reasoning step starts.
1075
1056
  *
1076
1057
  * @ag-ui/core provides: `stepName`
1077
- * TanStack AI adds: `model?`, `stepId?` (deprecated alias), `stepType?`
1078
1058
  */
1079
1059
  export interface StepStartedEvent extends AGUIStepStartedEvent {
1080
- /** Model identifier for multi-model support */
1081
- model?: string;
1082
- /**
1083
- * @deprecated Use `stepName` instead (from @ag-ui/core spec).
1084
- * Kept for backward compatibility.
1085
- */
1086
- stepId?: string;
1087
- /** Type of step (e.g., 'thinking', 'planning') */
1088
- stepType?: string;
1089
1060
  }
1090
1061
  /**
1091
1062
  * Emitted when a thinking/reasoning step finishes.
1092
1063
  *
1093
1064
  * @ag-ui/core provides: `stepName`
1094
- * TanStack AI adds: `model?`, `stepId?` (deprecated alias), `delta?`, `content?`
1095
1065
  */
1096
1066
  export interface StepFinishedEvent extends AGUIStepFinishedEvent {
1097
- /** Model identifier for multi-model support */
1098
- model?: string;
1099
- /**
1100
- * @deprecated Use `stepName` instead (from @ag-ui/core spec).
1101
- * Kept for backward compatibility.
1102
- */
1103
- stepId?: string;
1104
- /** Incremental thinking content (TanStack AI internal) */
1105
- delta?: string;
1106
- /** Full accumulated thinking content (TanStack AI internal) */
1107
- content?: string;
1108
- /** Provider signature for the thinking block */
1109
- signature?: string;
1110
1067
  }
1111
1068
  /**
1112
1069
  * Emitted to provide a snapshot of all messages in a conversation.
@@ -1115,62 +1072,37 @@ export interface StepFinishedEvent extends AGUIStepFinishedEvent {
1115
1072
  * MessagesSnapshot specifically delivers the conversation transcript.
1116
1073
  *
1117
1074
  * @ag-ui/core provides: `messages` (as @ag-ui/core Message[])
1118
- * TanStack AI adds: `model?`
1119
1075
  *
1120
1076
  * Note: The `messages` field uses the @ag-ui/core Message type.
1121
1077
  * Use converters to transform to/from TanStack UIMessage format.
1122
1078
  */
1123
1079
  export interface MessagesSnapshotEvent extends AGUIMessagesSnapshotEvent {
1124
- /** Model identifier for multi-model support */
1125
- model?: string;
1126
1080
  }
1127
1081
  /**
1128
1082
  * Emitted to provide a full state snapshot.
1129
1083
  *
1130
1084
  * @ag-ui/core provides: `snapshot` (any)
1131
- * TanStack AI adds: `model?`, `state?` (deprecated alias for snapshot)
1132
1085
  */
1133
1086
  export interface StateSnapshotEvent extends AGUIStateSnapshotEvent {
1134
- /** Model identifier for multi-model support */
1135
- model?: string;
1136
- /**
1137
- * @deprecated Use `snapshot` instead (from @ag-ui/core spec).
1138
- * Kept for backward compatibility.
1139
- */
1140
- state?: Record<string, unknown>;
1141
1087
  }
1142
1088
  /**
1143
1089
  * Emitted to provide an incremental state update.
1144
1090
  *
1145
1091
  * @ag-ui/core provides: `delta` (any[] - JSON Patch RFC 6902)
1146
- * TanStack AI adds: `model?`
1147
1092
  */
1148
1093
  export interface StateDeltaEvent extends AGUIStateDeltaEvent {
1149
- /** Model identifier for multi-model support */
1150
- model?: string;
1151
1094
  }
1152
1095
  /**
1153
1096
  * Custom event for extensibility.
1154
1097
  *
1155
1098
  * @ag-ui/core provides: `name`, `value`
1156
- * TanStack AI adds: `model?`
1157
1099
  *
1158
1100
  * Uses `Pick` (not `extends`) so the Zod passthrough index signature does not
1159
- * erase discriminant property access on {@link KnownCustomEvent} /
1160
- * {@link TypedStreamChunk} unions.
1101
+ * erase discriminant property access on {@link KnownCustomEvent} unions.
1161
1102
  */
1162
1103
  export interface CustomEvent extends Pick<AGUICustomEvent, 'name' | 'value' | 'timestamp' | 'rawEvent'> {
1163
1104
  type: 'CUSTOM';
1164
- /** Model identifier for multi-model support */
1165
- model?: string;
1166
- /**
1167
- * Routing metadata the TanStack engine attaches when emitting CUSTOM
1168
- * events that need to be correlated with a specific thread/run.
1169
- * Stripped by `strip-to-spec-middleware` before going on the wire so
1170
- * the AG-UI consumer never sees them (when that middleware is enabled).
1171
- */
1172
- threadId?: string;
1173
- runId?: string;
1105
+ metadata?: Record<string, any>;
1174
1106
  }
1175
1107
  /**
1176
1108
  * Final event of a streaming structured-output run. Carries the validated
@@ -1415,61 +1347,43 @@ export type StructuredOutputStream<T = unknown> = AsyncIterable<Exclude<StreamCh
1415
1347
  * Emitted when reasoning starts for a message.
1416
1348
  *
1417
1349
  * @ag-ui/core provides: `messageId`
1418
- * TanStack AI adds: `model?`
1419
1350
  */
1420
1351
  export interface ReasoningStartEvent extends AGUIReasoningStartEvent {
1421
- /** Model identifier for multi-model support */
1422
- model?: string;
1423
1352
  }
1424
1353
  /**
1425
1354
  * Emitted when a reasoning message starts.
1426
1355
  *
1427
1356
  * @ag-ui/core provides: `messageId`, `role` ("reasoning")
1428
- * TanStack AI adds: `model?`
1429
1357
  */
1430
1358
  export interface ReasoningMessageStartEvent extends AGUIReasoningMessageStartEvent {
1431
- /** Model identifier for multi-model support */
1432
- model?: string;
1433
1359
  }
1434
1360
  /**
1435
1361
  * Emitted when reasoning message content is generated.
1436
1362
  *
1437
1363
  * @ag-ui/core provides: `messageId`, `delta`
1438
- * TanStack AI adds: `model?`
1439
1364
  */
1440
1365
  export interface ReasoningMessageContentEvent extends AGUIReasoningMessageContentEvent {
1441
- /** Model identifier for multi-model support */
1442
- model?: string;
1443
1366
  }
1444
1367
  /**
1445
1368
  * Emitted when a reasoning message ends.
1446
1369
  *
1447
1370
  * @ag-ui/core provides: `messageId`
1448
- * TanStack AI adds: `model?`
1449
1371
  */
1450
1372
  export interface ReasoningMessageEndEvent extends AGUIReasoningMessageEndEvent {
1451
- /** Model identifier for multi-model support */
1452
- model?: string;
1453
1373
  }
1454
1374
  /**
1455
1375
  * Emitted when reasoning ends for a message.
1456
1376
  *
1457
1377
  * @ag-ui/core provides: `messageId`
1458
- * TanStack AI adds: `model?`
1459
1378
  */
1460
1379
  export interface ReasoningEndEvent extends AGUIReasoningEndEvent {
1461
- /** Model identifier for multi-model support */
1462
- model?: string;
1463
1380
  }
1464
1381
  /**
1465
1382
  * Emitted for encrypted reasoning values.
1466
1383
  *
1467
1384
  * @ag-ui/core provides: `subtype`, `entityId`, `encryptedValue`
1468
- * TanStack AI adds: `model?`
1469
1385
  */
1470
1386
  export interface ReasoningEncryptedValueEvent extends AGUIReasoningEncryptedValueEvent {
1471
- /** Model identifier for multi-model support */
1472
- model?: string;
1473
1387
  }
1474
1388
  /**
1475
1389
  * Union of all AG-UI events.
@@ -1480,107 +1394,6 @@ export type AGUIEvent = RunStartedEvent | RunFinishedEvent | RunErrorEvent | Tex
1480
1394
  * Uses the AG-UI protocol event format.
1481
1395
  */
1482
1396
  export type StreamChunk = AGUIEvent;
1483
- /**
1484
- * Detect the `any` type. Returns `true` for `any`, `false` for everything else.
1485
- * @internal
1486
- */
1487
- type IsAny<T> = 0 extends 1 & T ? true : false;
1488
- /**
1489
- * Partition out provider-specific tools from a tools array. `ProviderTool`
1490
- * carries opaque provider metadata (e.g. `webSearchTool` from
1491
- * `@tanstack/ai-anthropic`) and intentionally has a generic `string` name —
1492
- * if we included it in the discriminated union, it would widen `toolName`
1493
- * back to `string` and defeat the entire typing exercise.
1494
- *
1495
- * @internal
1496
- */
1497
- type NonProviderTools<TTools extends ReadonlyArray<AnyTool>> = Exclude<TTools[number], ProviderTool<string, string>>;
1498
- /**
1499
- * Check whether the tools array carries typed tool definitions.
1500
- * Returns `false` for empty arrays or arrays whose only entries are
1501
- * `ProviderTool`s (which have generic `string` names).
1502
- *
1503
- * The partitioning step matters: a user who passes
1504
- * `[webSearchTool, myTypedTool]` should still get typed narrowing for
1505
- * `myTypedTool`. Evaluating `string extends TTools[number]['name']` without
1506
- * filtering provider tools first would always return `false` (because
1507
- * `ProviderTool`'s `name` is `string`) and silently fall through to the
1508
- * untyped branch.
1509
- *
1510
- * @internal
1511
- */
1512
- type HasTypedTools<TTools extends ReadonlyArray<AnyTool>> = [
1513
- NonProviderTools<TTools>
1514
- ] extends [never] ? false : string extends NonProviderTools<TTools>['name'] ? false : true;
1515
- /**
1516
- * Safely infer input type for a single tool, guarding against `any` leaks.
1517
- * Returns `unknown` when the tool has no inputSchema, when the schema
1518
- * parameter defaults to `undefined` (no-schema tool definitions), or when
1519
- * InferSchemaType produces `any` (e.g. for plain JSON Schema tools).
1520
- * @internal
1521
- */
1522
- type SafeToolInput<T> = T extends {
1523
- inputSchema?: infer TInput;
1524
- } ? [TInput] extends [undefined] ? unknown : IsAny<InferSchemaType<NonNullable<TInput>>> extends true ? unknown : InferSchemaType<NonNullable<TInput>> : unknown;
1525
- /**
1526
- * Safely infer output type for a single tool. Mirrors `SafeToolInput`,
1527
- * picking `outputSchema` instead. Returns `unknown` when the tool has no
1528
- * `outputSchema` declared, when the schema parameter defaults to `undefined`,
1529
- * or when `InferSchemaType` produces `any`.
1530
- * @internal
1531
- */
1532
- type SafeToolOutput<T> = T extends {
1533
- outputSchema?: infer TOutput;
1534
- } ? [TOutput] extends [undefined] ? unknown : IsAny<InferSchemaType<NonNullable<TOutput>>> extends true ? unknown : InferSchemaType<NonNullable<TOutput>> : unknown;
1535
- /**
1536
- * Distribute over each non-provider tool to create a per-tool
1537
- * `ToolCallStartEvent`.
1538
- *
1539
- * This produces a discriminated union — one variant per tool name literal.
1540
- * We distribute over `NonProviderTools<TTools>` (not `TTools[number]`) so
1541
- * that provider tools with generic `string` names do not leak into the
1542
- * union and widen `toolCallName` / `toolName` back to `string`.
1543
- *
1544
- * The trailing `& { toolCallName: TName; toolName: TName }` intersection
1545
- * narrows the base `AGUIToolCallStartEvent['toolCallName']` (declared as
1546
- * `string`) to the literal name — TypeScript intersects `string & TName`
1547
- * down to `TName` for literal `TName`.
1548
- *
1549
- * The `name` parameter constraint on the inner `extends` picks up any
1550
- * tool-like shape — including `ServerTool`, `ClientTool`, and the bare
1551
- * `Tool` definition — because all three expose `name: TName`.
1552
- * @internal
1553
- */
1554
- type DistributedToolCallStart<TTools extends ReadonlyArray<AnyTool>> = NonProviderTools<TTools> extends infer T ? T extends {
1555
- name: infer TName extends string;
1556
- } ? ToolCallStartEvent<TName> & {
1557
- toolCallName: TName;
1558
- toolName: TName;
1559
- } : never : never;
1560
- /**
1561
- * Distribute over each non-provider tool to create a per-tool
1562
- * `ToolCallEndEvent`.
1563
- *
1564
- * Each variant pairs the tool's name literal with its specific input type,
1565
- * enabling discriminated narrowing: checking `toolName === 'x'` narrows
1566
- * `input`.
1567
- *
1568
- * `toolName`/`toolCallName` are intersected as required in the distributed
1569
- * variants so that `Extract<..., { toolName: 'x' }>` works for consumers
1570
- * relying on the discriminated-union pattern, even though the base
1571
- * interface keeps them optional for compatibility with the broader AG-UI
1572
- * surface.
1573
- *
1574
- * Distribution happens over `NonProviderTools<TTools>` for the same
1575
- * reason as in `DistributedToolCallStart`.
1576
- * @internal
1577
- */
1578
- type DistributedToolCallEnd<TTools extends ReadonlyArray<AnyTool>> = NonProviderTools<TTools> extends infer T ? T extends {
1579
- name: infer TName extends string;
1580
- } ? ToolCallEndEvent<TName, SafeToolInput<T>, SafeToolOutput<T>> & {
1581
- toolCallName: TName;
1582
- toolName: TName;
1583
- } : never : never;
1584
1397
  /**
1585
1398
  * Discriminated union of the orchestrator-tagged `CUSTOM` events. Each variant
1586
1399
  * has a literal `name`, so a single narrow on `chunk.name` yields a typed
@@ -1605,42 +1418,6 @@ type DistributedToolCallEnd<TTools extends ReadonlyArray<AnyTool>> = NonProvider
1605
1418
  * or cast the chunk to `StreamChunk` to recover the wider shape.
1606
1419
  */
1607
1420
  export type TaggedCustomEvent<T = unknown> = StructuredOutputStartEvent | StructuredOutputCompleteEvent<T> | ApprovalRequestedEvent | ToolInputAvailableEvent;
1608
- /**
1609
- * Stream chunk type parameterized by the tools array for type-safe tool call events.
1610
- *
1611
- * When specific tool types are provided (e.g. from `chat({ tools: [myTool] })`):
1612
- * - `TOOL_CALL_START` and `TOOL_CALL_END` events form a **discriminated union**
1613
- * over tool names — checking `toolName === 'x'` narrows `input` to that tool's type.
1614
- * - `TOOL_CALL_END` events have `input` typed per-tool via Standard Schema inference.
1615
- *
1616
- * `CUSTOM` events are narrowed to the discriminated {@link KnownCustomEvent}
1617
- * union (sandbox, code-mode, structured-output, approvals, UI resources, etc.).
1618
- * Free-form user-emitted custom events (via `emitCustomEvent`) still flow at
1619
- * runtime but are excluded from the type to avoid `any` poisoning the union;
1620
- * cast to `StreamChunk` if you need to read those.
1621
- *
1622
- * When tools are untyped or absent, the tool-call events stay as plain
1623
- * `ToolCallStartEvent` / `ToolCallEndEvent` (no per-tool name narrowing) and
1624
- * the type is equivalent to the element type of {@link ChatStream}.
1625
- */
1626
- /**
1627
- * Replace tool-call and bare CUSTOM variants; keep every other StreamChunk
1628
- * arm. Matches on the string-literal `type` discriminant that TanStack tool
1629
- * events declare (see ToolCallStartEvent / ToolCallEndEvent). AG-UI events
1630
- * that still use the EventType enum are kept as-is via the final branch.
1631
- *
1632
- * Do **not** use `Exclude<StreamChunk, { type: 'TOOL_CALL_*' }>` — under
1633
- * @ag-ui/core passthrough index signatures that form removes *every* arm.
1634
- * @internal
1635
- */
1636
- type RemapStreamChunkForTools<TChunk, TTools extends ReadonlyArray<AnyTool>> = TChunk extends {
1637
- type: 'TOOL_CALL_START';
1638
- } ? DistributedToolCallStart<TTools> : TChunk extends {
1639
- type: 'TOOL_CALL_END';
1640
- } ? DistributedToolCallEnd<TTools> : TChunk extends {
1641
- type: 'CUSTOM';
1642
- } ? never : TChunk;
1643
- export type TypedStreamChunk<TTools extends ReadonlyArray<AnyTool> = ReadonlyArray<AnyTool>> = HasTypedTools<TTools> extends true ? RemapStreamChunkForTools<StreamChunk, TTools> | KnownCustomEvent : Exclude<StreamChunk, CustomEvent> | KnownCustomEvent;
1644
1421
  export interface TextCompletionChunk {
1645
1422
  id: string;
1646
1423
  model: string;
@@ -0,0 +1,31 @@
1
+ import { InterruptSubmissionError } from '../interrupts.js';
2
+ import { ContentPart, StreamChunk, ToolOutputState } from '../types.js';
3
+ /**
4
+ * Adapter / engine yield before normalize. Public StreamChunk is spec-only.
5
+ * This type still allows the old extra fields.
6
+ */
7
+ export type AdapterYieldChunk = StreamChunk & {
8
+ model?: string;
9
+ finishReason?: 'stop' | 'length' | 'content_filter' | 'tool_calls' | null;
10
+ usage?: any;
11
+ content?: string;
12
+ args?: string;
13
+ toolName?: string;
14
+ toolCallName?: string;
15
+ index?: number;
16
+ input?: unknown;
17
+ output?: unknown;
18
+ result?: string | Array<ContentPart>;
19
+ state?: ToolOutputState | Record<string, unknown>;
20
+ stepId?: string;
21
+ stepType?: string;
22
+ delta?: string | ReadonlyArray<unknown>;
23
+ signature?: string;
24
+ error?: {
25
+ message: string;
26
+ code?: string;
27
+ };
28
+ 'tanstack:interruptErrors'?: ReadonlyArray<InterruptSubmissionError>;
29
+ threadId?: string;
30
+ runId?: string;
31
+ };
@@ -0,0 +1,24 @@
1
+ import { TokenUsage } from '../types.js';
2
+ /** AG-UI spec `usage[]` item (provider/model labels + token counts only). */
3
+ export interface SpecTokenUsage {
4
+ provider?: string;
5
+ model?: string;
6
+ inputTokens?: number;
7
+ outputTokens?: number;
8
+ totalTokens?: number;
9
+ reasoningTokens?: number;
10
+ cachedInputTokens?: number;
11
+ }
12
+ export interface ToSpecTokenUsageOptions {
13
+ provider?: string;
14
+ model?: string;
15
+ }
16
+ /** TokenUsage fields that have no AG-UI `usage[]` equivalent. */
17
+ export type TokenUsageLeftover = Omit<TokenUsage, 'promptTokens' | 'completionTokens' | 'totalTokens'>;
18
+ export declare function isTanstackUsage(usage: unknown): usage is TokenUsage;
19
+ export declare function toSpecTokenUsage(usage: TokenUsage, options?: ToSpecTokenUsageOptions): {
20
+ usage: Array<SpecTokenUsage>;
21
+ leftover?: TokenUsageLeftover;
22
+ };
23
+ export declare function rebuildTokenUsage(usage: unknown, leftover?: TokenUsageLeftover): TokenUsage | undefined;
24
+ export declare function fromSpecTokenUsage(usage: ReadonlyArray<SpecTokenUsage> | undefined, leftover?: TokenUsageLeftover): TokenUsage | undefined;