@tanstack/ai-client 0.24.0 → 0.25.2

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/src/types.ts CHANGED
@@ -9,6 +9,7 @@ import type {
9
9
  DocumentPart,
10
10
  ImagePart,
11
11
  InferSchemaType,
12
+ InterruptDefinition,
12
13
  InferToolInput,
13
14
  InferToolOutput,
14
15
  InputSchemaOf,
@@ -86,6 +87,51 @@ export interface GenericAGUIInterrupt extends BoundInterruptBase {
86
87
  resolveInterrupt: (payload: unknown) => void
87
88
  }
88
89
 
90
+ type InterruptResponseInput<TDefinition> =
91
+ TDefinition extends InterruptDefinition<any, any, infer TResponseSchema, any>
92
+ ? InferSchemaType<TResponseSchema>
93
+ : never
94
+
95
+ type RegisteredGenericInterruptFor<
96
+ TDefinition extends InterruptDefinition<any, any, any, any>,
97
+ > =
98
+ TDefinition extends InterruptDefinition<
99
+ infer TDefinitionId,
100
+ any,
101
+ any,
102
+ infer TPayload
103
+ >
104
+ ? BoundInterruptBase & {
105
+ readonly kind: 'generic'
106
+ readonly definitionId: TDefinitionId
107
+ readonly key: string
108
+ readonly payload: TPayload | undefined
109
+ readonly binding: Readonly<
110
+ Extract<InterruptBinding, { kind: 'generic' }> & {
111
+ definitionId: TDefinitionId
112
+ key: string
113
+ batchIndex: number
114
+ }
115
+ >
116
+ resolveInterrupt: (
117
+ response: InterruptResponseInput<TDefinition>,
118
+ ) => void
119
+ }
120
+ : never
121
+
122
+ export type RegisteredGenericInterrupt<
123
+ TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,
124
+ > = TInterrupts[number] extends infer TDefinition
125
+ ? TDefinition extends InterruptDefinition<any, any, any, any>
126
+ ? RegisteredGenericInterruptFor<TDefinition>
127
+ : never
128
+ : never
129
+
130
+ /** A bound generic interrupt for one `defineInterrupt()` definition. */
131
+ export type GenericInterrupt<
132
+ TDefinition extends InterruptDefinition<any, any, any, any>,
133
+ > = RegisteredGenericInterruptFor<TDefinition>
134
+
89
135
  /**
90
136
  * An interrupt that arrived on the stream carrying no resume binding this
91
137
  * client understands — no `tanstack:interruptBinding`, or one written at a
@@ -98,7 +144,10 @@ export interface GenericAGUIInterrupt extends BoundInterruptBase {
98
144
  * send an answer no one is waiting for. Render it, or route it to whatever
99
145
  * actually owns the pause.
100
146
  */
101
- export interface UnboundInterrupt extends BoundInterruptBase {
147
+ export interface UnboundInterrupt extends Omit<
148
+ BoundInterruptBase,
149
+ 'cancel' | 'clearResolution'
150
+ > {
102
151
  readonly kind: 'unbound'
103
152
  readonly binding?: undefined
104
153
  readonly canResolve: false
@@ -188,18 +237,37 @@ type ApprovalInterrupts<TTools extends ReadonlyArray<AnyClientTool>> =
188
237
  // union.
189
238
  export type ChatInterrupt<
190
239
  TTools extends ReadonlyArray<AnyClientTool> = ReadonlyArray<AnyClientTool>,
191
- > = GenericAGUIInterrupt | UnboundInterrupt | ApprovalInterrupts<TTools>
240
+ TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> =
241
+ readonly [],
242
+ > =
243
+ | GenericAGUIInterrupt
244
+ | RegisteredGenericInterrupt<TInterrupts>
245
+ | UnboundInterrupt
246
+ | ApprovalInterrupts<TTools>
247
+
248
+ export type ResolvableChatInterrupt<
249
+ TTools extends ReadonlyArray<AnyClientTool> = ReadonlyArray<AnyClientTool>,
250
+ TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> =
251
+ readonly [],
252
+ > =
253
+ | GenericAGUIInterrupt
254
+ | RegisteredGenericInterrupt<TInterrupts>
255
+ | ApprovalInterrupts<TTools>
192
256
 
193
257
  export type BoundInterrupts<
194
258
  TTools extends ReadonlyArray<AnyClientTool> = ReadonlyArray<AnyClientTool>,
195
- > = ReadonlyArray<ChatInterrupt<TTools>>
259
+ TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> =
260
+ readonly [],
261
+ > = ReadonlyArray<ChatInterrupt<TTools, TInterrupts>>
196
262
 
197
263
  export interface ChatInterruptState<
198
264
  TTools extends ReadonlyArray<AnyClientTool> = ReadonlyArray<AnyClientTool>,
265
+ TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> =
266
+ readonly [],
199
267
  > {
200
- readonly interrupts: BoundInterrupts<TTools>
268
+ readonly interrupts: BoundInterrupts<TTools, TInterrupts>
201
269
  /** @deprecated Use `interrupts`. Same snapshot today. */
202
- readonly pendingInterrupts: BoundInterrupts<TTools>
270
+ readonly pendingInterrupts: BoundInterrupts<TTools, TInterrupts>
203
271
  readonly interruptErrors: ReadonlyArray<BatchInterruptError>
204
272
  readonly resuming: boolean
205
273
  }
@@ -742,6 +810,8 @@ export type ClientContextOptionFromTools<TTools, TContext> = [
742
810
  export interface ChatClientBaseOptions<
743
811
  TTools extends ReadonlyArray<AnyClientTool> = any,
744
812
  TContext = unknown,
813
+ TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> =
814
+ readonly [],
745
815
  > {
746
816
  /**
747
817
  * Initial messages to populate the chat
@@ -864,7 +934,7 @@ export interface ChatClientBaseOptions<
864
934
  */
865
935
  onResumeStateChange?: (
866
936
  resumeState: ChatResumeState | null,
867
- pendingInterrupts: BoundInterrupts<TTools>,
937
+ pendingInterrupts: BoundInterrupts<TTools, TInterrupts>,
868
938
  ) => void
869
939
 
870
940
  /**
@@ -873,8 +943,15 @@ export interface ChatClientBaseOptions<
873
943
  */
874
944
  onRunIdChange?: (runId: string | null) => void
875
945
 
876
- /** Callback when the immutable interrupt state snapshot changes. */
877
- onInterruptStateChange?: (state: ChatInterruptState<TTools>) => void
946
+ /**
947
+ * Callback when the immutable interrupt state snapshot changes.
948
+ * Snapshot restoration passes `{ source: 'hydrate' }`; streamed and
949
+ * client-initiated updates pass `{ source: 'live' }`.
950
+ */
951
+ onInterruptStateChange?: (
952
+ state: ChatInterruptState<TTools, TInterrupts>,
953
+ context: { source: 'hydrate' | 'live' },
954
+ ) => void
878
955
 
879
956
  /**
880
957
  * Callback when a custom event is received from a server-side tool.
@@ -896,6 +973,9 @@ export interface ChatClientBaseOptions<
896
973
  */
897
974
  tools?: TTools
898
975
 
976
+ /** First-party generic interrupts this client can type and resolve. */
977
+ interrupts?: TInterrupts
978
+
899
979
  /**
900
980
  * Devtools hook metadata for this client instance.
901
981
  */
@@ -931,7 +1011,12 @@ export interface ChatClientBaseOptions<
931
1011
  export type ChatClientOptions<
932
1012
  TTools extends ReadonlyArray<AnyClientTool> = any,
933
1013
  TContext = InferredClientContext<TTools>,
934
- > = DistributedOmit<ChatClientBaseOptions<TTools, TContext>, 'context'> &
1014
+ TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> =
1015
+ readonly [],
1016
+ > = DistributedOmit<
1017
+ ChatClientBaseOptions<TTools, TContext, TInterrupts>,
1018
+ 'context'
1019
+ > &
935
1020
  ClientContextOptionFromTools<TTools, TContext> &
936
1021
  ChatTransport &
937
1022
  ChatPersistenceOptions<TTools>
@@ -981,9 +1066,12 @@ export function clientTools<const T extends Array<AnyClientTool>>(
981
1066
  export function createChatClientOptions<
982
1067
  const TTools extends ReadonlyArray<AnyClientTool>,
983
1068
  TContext = InferredClientContext<TTools>,
1069
+ const TInterrupts extends ReadonlyArray<
1070
+ InterruptDefinition<any, any, any, any>
1071
+ > = readonly [],
984
1072
  >(
985
- options: ChatClientOptions<TTools, TContext>,
986
- ): ChatClientOptions<TTools, TContext> {
1073
+ options: ChatClientOptions<TTools, TContext, TInterrupts>,
1074
+ ): ChatClientOptions<TTools, TContext, TInterrupts> {
987
1075
  return options
988
1076
  }
989
1077