@tanstack/ai-client 0.7.1 → 0.7.4
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/README.md +6 -6
- package/dist/esm/chat-client.d.ts +62 -3
- package/dist/esm/chat-client.js +264 -54
- package/dist/esm/chat-client.js.map +1 -1
- package/dist/esm/connection-adapters.d.ts +28 -12
- package/dist/esm/connection-adapters.js +93 -0
- package/dist/esm/connection-adapters.js.map +1 -1
- package/dist/esm/generation-client.d.ts +5 -5
- package/dist/esm/generation-client.js +1 -1
- package/dist/esm/generation-client.js.map +1 -1
- package/dist/esm/generation-types.d.ts +5 -5
- package/dist/esm/generation-types.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/types.d.ts +23 -2
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/video-generation-client.d.ts +5 -5
- package/dist/esm/video-generation-client.js +1 -1
- package/dist/esm/video-generation-client.js.map +1 -1
- package/package.json +3 -3
- package/src/chat-client.ts +355 -86
- package/src/connection-adapters.ts +147 -12
- package/src/generation-client.ts +7 -7
- package/src/generation-types.ts +5 -5
- package/src/index.ts +3 -0
- package/src/types.ts +31 -2
- package/src/video-generation-client.ts +6 -6
|
@@ -62,15 +62,9 @@ async function* readStreamLines(
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
* Connection adapter interface - converts a connection into a stream of chunks
|
|
67
|
-
*/
|
|
68
|
-
export interface ConnectionAdapter {
|
|
65
|
+
export interface ConnectConnectionAdapter {
|
|
69
66
|
/**
|
|
70
|
-
* Connect and return an async iterable of StreamChunks
|
|
71
|
-
* @param messages - The messages to send (UIMessages or ModelMessages)
|
|
72
|
-
* @param data - Additional data to send
|
|
73
|
-
* @param abortSignal - Optional abort signal for request cancellation
|
|
67
|
+
* Connect and return an async iterable of StreamChunks.
|
|
74
68
|
*/
|
|
75
69
|
connect: (
|
|
76
70
|
messages: Array<UIMessage> | Array<ModelMessage>,
|
|
@@ -79,6 +73,147 @@ export interface ConnectionAdapter {
|
|
|
79
73
|
) => AsyncIterable<StreamChunk>
|
|
80
74
|
}
|
|
81
75
|
|
|
76
|
+
export interface SubscribeConnectionAdapter {
|
|
77
|
+
/**
|
|
78
|
+
* Subscribe to stream chunks.
|
|
79
|
+
*/
|
|
80
|
+
subscribe: (abortSignal?: AbortSignal) => AsyncIterable<StreamChunk>
|
|
81
|
+
/**
|
|
82
|
+
* Send a request; chunks arrive through subscribe().
|
|
83
|
+
*/
|
|
84
|
+
send: (
|
|
85
|
+
messages: Array<UIMessage> | Array<ModelMessage>,
|
|
86
|
+
data?: Record<string, any>,
|
|
87
|
+
abortSignal?: AbortSignal,
|
|
88
|
+
) => Promise<void>
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Connection adapter union.
|
|
93
|
+
* Provide either `connect`, or `subscribe` + `send`.
|
|
94
|
+
*/
|
|
95
|
+
export type ConnectionAdapter =
|
|
96
|
+
| ConnectConnectionAdapter
|
|
97
|
+
| SubscribeConnectionAdapter
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Normalize a ConnectionAdapter to subscribe/send operations.
|
|
101
|
+
*
|
|
102
|
+
* If a connection provides native subscribe/send, that mode is used.
|
|
103
|
+
* Otherwise, connect() is wrapped using an async queue.
|
|
104
|
+
*/
|
|
105
|
+
export function normalizeConnectionAdapter(
|
|
106
|
+
connection: ConnectionAdapter | undefined,
|
|
107
|
+
): SubscribeConnectionAdapter {
|
|
108
|
+
if (!connection) {
|
|
109
|
+
throw new Error('Connection adapter is required')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const hasConnect = 'connect' in connection
|
|
113
|
+
const hasSubscribe = 'subscribe' in connection
|
|
114
|
+
const hasSend = 'send' in connection
|
|
115
|
+
|
|
116
|
+
if (hasConnect && (hasSubscribe || hasSend)) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
'Connection adapter must provide either connect or both subscribe and send, not both modes',
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (hasSubscribe && hasSend) {
|
|
123
|
+
return {
|
|
124
|
+
subscribe: connection.subscribe.bind(connection),
|
|
125
|
+
send: connection.send.bind(connection),
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!hasConnect) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
'Connection adapter must provide either connect or both subscribe and send',
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Legacy connect() wrapper
|
|
136
|
+
let activeBuffer: Array<StreamChunk> = []
|
|
137
|
+
let activeWaiters: Array<(chunk: StreamChunk | null) => void> = []
|
|
138
|
+
|
|
139
|
+
function push(chunk: StreamChunk): void {
|
|
140
|
+
const waiter = activeWaiters.shift()
|
|
141
|
+
if (waiter) {
|
|
142
|
+
waiter(chunk)
|
|
143
|
+
} else {
|
|
144
|
+
activeBuffer.push(chunk)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
subscribe(abortSignal?: AbortSignal): AsyncIterable<StreamChunk> {
|
|
150
|
+
// Transfer ownership to the latest subscriber so only one active
|
|
151
|
+
// subscribe() call receives chunks from the shared connect-wrapper queue.
|
|
152
|
+
const myBuffer: Array<StreamChunk> = activeBuffer.splice(0)
|
|
153
|
+
const myWaiters: Array<(chunk: StreamChunk | null) => void> = []
|
|
154
|
+
activeBuffer = myBuffer
|
|
155
|
+
activeWaiters = myWaiters
|
|
156
|
+
|
|
157
|
+
return (async function* () {
|
|
158
|
+
while (!abortSignal?.aborted) {
|
|
159
|
+
let chunk: StreamChunk | null
|
|
160
|
+
if (myBuffer.length > 0) {
|
|
161
|
+
chunk = myBuffer.shift()!
|
|
162
|
+
} else {
|
|
163
|
+
chunk = await new Promise<StreamChunk | null>((resolve) => {
|
|
164
|
+
const onAbort = () => resolve(null)
|
|
165
|
+
myWaiters.push((c) => {
|
|
166
|
+
abortSignal?.removeEventListener('abort', onAbort)
|
|
167
|
+
resolve(c)
|
|
168
|
+
})
|
|
169
|
+
abortSignal?.addEventListener('abort', onAbort, { once: true })
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
if (chunk !== null) yield chunk
|
|
173
|
+
}
|
|
174
|
+
})()
|
|
175
|
+
},
|
|
176
|
+
async send(messages, data, abortSignal) {
|
|
177
|
+
let hasTerminalEvent = false
|
|
178
|
+
try {
|
|
179
|
+
const stream = connection.connect(messages, data, abortSignal)
|
|
180
|
+
for await (const chunk of stream) {
|
|
181
|
+
if (chunk.type === 'RUN_FINISHED' || chunk.type === 'RUN_ERROR') {
|
|
182
|
+
hasTerminalEvent = true
|
|
183
|
+
}
|
|
184
|
+
push(chunk)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// If the connect stream ended cleanly without a terminal event,
|
|
188
|
+
// synthesize RUN_FINISHED so request-scoped consumers can complete.
|
|
189
|
+
if (!abortSignal?.aborted && !hasTerminalEvent) {
|
|
190
|
+
push({
|
|
191
|
+
type: 'RUN_FINISHED',
|
|
192
|
+
runId: `run-${Date.now()}`,
|
|
193
|
+
model: 'connect-wrapper',
|
|
194
|
+
timestamp: Date.now(),
|
|
195
|
+
finishReason: 'stop',
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
} catch (err) {
|
|
199
|
+
if (!abortSignal?.aborted && !hasTerminalEvent) {
|
|
200
|
+
push({
|
|
201
|
+
type: 'RUN_ERROR',
|
|
202
|
+
timestamp: Date.now(),
|
|
203
|
+
error: {
|
|
204
|
+
message:
|
|
205
|
+
err instanceof Error
|
|
206
|
+
? err.message
|
|
207
|
+
: 'Unknown error in connect()',
|
|
208
|
+
},
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
throw err
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
82
217
|
/**
|
|
83
218
|
* Options for fetch-based connection adapters
|
|
84
219
|
*/
|
|
@@ -129,7 +264,7 @@ export function fetchServerSentEvents(
|
|
|
129
264
|
options:
|
|
130
265
|
| FetchConnectionOptions
|
|
131
266
|
| (() => FetchConnectionOptions | Promise<FetchConnectionOptions>) = {},
|
|
132
|
-
):
|
|
267
|
+
): ConnectConnectionAdapter {
|
|
133
268
|
return {
|
|
134
269
|
async *connect(messages, data, abortSignal) {
|
|
135
270
|
// Resolve URL and options if they are functions
|
|
@@ -228,7 +363,7 @@ export function fetchHttpStream(
|
|
|
228
363
|
options:
|
|
229
364
|
| FetchConnectionOptions
|
|
230
365
|
| (() => FetchConnectionOptions | Promise<FetchConnectionOptions>) = {},
|
|
231
|
-
):
|
|
366
|
+
): ConnectConnectionAdapter {
|
|
232
367
|
return {
|
|
233
368
|
async *connect(messages, data, abortSignal) {
|
|
234
369
|
// Resolve URL and options if they are functions
|
|
@@ -301,7 +436,7 @@ export function stream(
|
|
|
301
436
|
messages: Array<UIMessage> | Array<ModelMessage>,
|
|
302
437
|
data?: Record<string, any>,
|
|
303
438
|
) => AsyncIterable<StreamChunk>,
|
|
304
|
-
):
|
|
439
|
+
): ConnectConnectionAdapter {
|
|
305
440
|
return {
|
|
306
441
|
async *connect(messages, data) {
|
|
307
442
|
// Pass messages as-is (UIMessages with parts preserved)
|
|
@@ -332,7 +467,7 @@ export function rpcStream(
|
|
|
332
467
|
messages: Array<UIMessage> | Array<ModelMessage>,
|
|
333
468
|
data?: Record<string, any>,
|
|
334
469
|
) => AsyncIterable<StreamChunk>,
|
|
335
|
-
):
|
|
470
|
+
): ConnectConnectionAdapter {
|
|
336
471
|
return {
|
|
337
472
|
async *connect(messages, data) {
|
|
338
473
|
// Pass messages as-is (UIMessages with parts preserved)
|
package/src/generation-client.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { GENERATION_EVENTS } from './generation-types'
|
|
2
2
|
import { parseSSEResponse } from './sse-parser'
|
|
3
3
|
import type { StreamChunk } from '@tanstack/ai'
|
|
4
|
-
import type {
|
|
4
|
+
import type { ConnectConnectionAdapter } from './connection-adapters'
|
|
5
5
|
import type {
|
|
6
6
|
GenerationClientOptions,
|
|
7
7
|
GenerationClientState,
|
|
@@ -27,7 +27,7 @@ interface GenerationCallbacks<TResult, TOutput> {
|
|
|
27
27
|
* (image, speech, transcription, summarize).
|
|
28
28
|
*
|
|
29
29
|
* Supports two transport modes:
|
|
30
|
-
* - **
|
|
30
|
+
* - **ConnectConnectionAdapter** — Streaming transport (SSE, HTTP stream, custom).
|
|
31
31
|
* Server wraps results in StreamChunk events with CUSTOM event names.
|
|
32
32
|
* - **Fetcher** — Direct async function call. No streaming protocol needed.
|
|
33
33
|
*
|
|
@@ -36,7 +36,7 @@ interface GenerationCallbacks<TResult, TOutput> {
|
|
|
36
36
|
*
|
|
37
37
|
* @example
|
|
38
38
|
* ```typescript
|
|
39
|
-
* // With
|
|
39
|
+
* // With streaming connection adapter
|
|
40
40
|
* const client = new GenerationClient<ImageGenerateInput, ImageGenerationResult>({
|
|
41
41
|
* connection: fetchServerSentEvents('/api/generate/image'),
|
|
42
42
|
* onResultChange: setResult,
|
|
@@ -62,7 +62,7 @@ export class GenerationClient<
|
|
|
62
62
|
TResult,
|
|
63
63
|
TOutput = TResult,
|
|
64
64
|
> {
|
|
65
|
-
private connection:
|
|
65
|
+
private connection: ConnectConnectionAdapter | undefined
|
|
66
66
|
private fetcher: GenerationFetcher<TInput, TResult> | undefined
|
|
67
67
|
private body: Record<string, any>
|
|
68
68
|
private result: TOutput | null = null
|
|
@@ -75,7 +75,7 @@ export class GenerationClient<
|
|
|
75
75
|
constructor(
|
|
76
76
|
options: GenerationClientOptions<TInput, TResult, TOutput> &
|
|
77
77
|
(
|
|
78
|
-
| { connection:
|
|
78
|
+
| { connection: ConnectConnectionAdapter; fetcher?: never }
|
|
79
79
|
| {
|
|
80
80
|
fetcher: GenerationFetcher<TInput, TResult>
|
|
81
81
|
connection?: never
|
|
@@ -127,7 +127,7 @@ export class GenerationClient<
|
|
|
127
127
|
this.setStatus('success')
|
|
128
128
|
}
|
|
129
129
|
} else if (this.connection) {
|
|
130
|
-
//
|
|
130
|
+
// Streaming adapter path
|
|
131
131
|
const mergedData = { ...this.body, ...input }
|
|
132
132
|
const stream = this.connection.connect([], mergedData, signal)
|
|
133
133
|
await this.processStream(stream)
|
|
@@ -149,7 +149,7 @@ export class GenerationClient<
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
/**
|
|
152
|
-
* Process a stream of AG-UI events from the
|
|
152
|
+
* Process a stream of AG-UI events from the streaming connection adapter.
|
|
153
153
|
*/
|
|
154
154
|
private async processStream(
|
|
155
155
|
source: AsyncIterable<StreamChunk>,
|
package/src/generation-types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StreamChunk } from '@tanstack/ai'
|
|
2
|
-
import type {
|
|
2
|
+
import type { ConnectConnectionAdapter } from './connection-adapters'
|
|
3
3
|
|
|
4
4
|
// ===========================
|
|
5
5
|
// Inference Utilities
|
|
@@ -81,10 +81,10 @@ export type GenerationFetcher<TInput, TResult> = (
|
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
83
|
* Transport configuration for generation clients.
|
|
84
|
-
* Supports either a
|
|
84
|
+
* Supports either a connect-based streaming adapter or a direct fetcher function.
|
|
85
85
|
*/
|
|
86
86
|
export type GenerationTransport<TInput, TResult> =
|
|
87
|
-
| { connection:
|
|
87
|
+
| { connection: ConnectConnectionAdapter; fetcher?: never }
|
|
88
88
|
| { fetcher: GenerationFetcher<TInput, TResult>; connection?: never }
|
|
89
89
|
|
|
90
90
|
// ===========================
|
|
@@ -103,7 +103,7 @@ export interface GenerationClientOptions<_TInput, TResult, TOutput = TResult> {
|
|
|
103
103
|
/** Unique identifier for this generation client instance */
|
|
104
104
|
id?: string
|
|
105
105
|
|
|
106
|
-
/** Additional body parameters to send with
|
|
106
|
+
/** Additional body parameters to send with connect-based adapter requests */
|
|
107
107
|
body?: Record<string, any>
|
|
108
108
|
|
|
109
109
|
/**
|
|
@@ -119,7 +119,7 @@ export interface GenerationClientOptions<_TInput, TResult, TOutput = TResult> {
|
|
|
119
119
|
onError?: (error: Error) => void
|
|
120
120
|
/** Callback when progress is reported (0-100) */
|
|
121
121
|
onProgress?: (progress: number, message?: string) => void
|
|
122
|
-
/** Callback for each stream chunk (
|
|
122
|
+
/** Callback for each stream chunk (connect-based adapter mode only) */
|
|
123
123
|
onChunk?: (chunk: StreamChunk) => void
|
|
124
124
|
|
|
125
125
|
// Framework state callbacks (set by hooks, not users)
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type {
|
|
|
15
15
|
ChatRequestBody,
|
|
16
16
|
InferChatMessages,
|
|
17
17
|
ChatClientState,
|
|
18
|
+
ConnectionStatus,
|
|
18
19
|
// Multimodal content input type
|
|
19
20
|
MultimodalContent,
|
|
20
21
|
} from './types'
|
|
@@ -55,8 +56,10 @@ export {
|
|
|
55
56
|
fetchHttpStream,
|
|
56
57
|
stream,
|
|
57
58
|
rpcStream,
|
|
59
|
+
type ConnectConnectionAdapter,
|
|
58
60
|
type ConnectionAdapter,
|
|
59
61
|
type FetchConnectionOptions,
|
|
62
|
+
type SubscribeConnectionAdapter,
|
|
60
63
|
} from './connection-adapters'
|
|
61
64
|
|
|
62
65
|
// Re-export message converters from @tanstack/ai
|
package/src/types.ts
CHANGED
|
@@ -36,6 +36,15 @@ export type ToolResultState =
|
|
|
36
36
|
*/
|
|
37
37
|
export type ChatClientState = 'ready' | 'submitted' | 'streaming' | 'error'
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Connection lifecycle state for the subscription loop.
|
|
41
|
+
*/
|
|
42
|
+
export type ConnectionStatus =
|
|
43
|
+
| 'disconnected'
|
|
44
|
+
| 'connecting'
|
|
45
|
+
| 'connected'
|
|
46
|
+
| 'error'
|
|
47
|
+
|
|
39
48
|
/**
|
|
40
49
|
* Multimodal content input for sending messages with rich media.
|
|
41
50
|
* Allows sending text, images, audio, video, and documents to the LLM.
|
|
@@ -178,8 +187,9 @@ export interface ChatClientOptions<
|
|
|
178
187
|
TTools extends ReadonlyArray<AnyClientTool> = any,
|
|
179
188
|
> {
|
|
180
189
|
/**
|
|
181
|
-
* Connection adapter for streaming
|
|
182
|
-
*
|
|
190
|
+
* Connection adapter for streaming.
|
|
191
|
+
* Supports mutually exclusive modes: request-response via `connect()`, or
|
|
192
|
+
* subscribe/send mode via `subscribe()` + `send()`.
|
|
183
193
|
*/
|
|
184
194
|
connection: ConnectionAdapter
|
|
185
195
|
|
|
@@ -239,6 +249,25 @@ export interface ChatClientOptions<
|
|
|
239
249
|
*/
|
|
240
250
|
onStatusChange?: (status: ChatClientState) => void
|
|
241
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Callback when subscription lifecycle changes.
|
|
254
|
+
* This is independent from request lifecycle (`isLoading`, `status`).
|
|
255
|
+
*/
|
|
256
|
+
onSubscriptionChange?: (isSubscribed: boolean) => void
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Callback when connection lifecycle changes.
|
|
260
|
+
*/
|
|
261
|
+
onConnectionStatusChange?: (status: ConnectionStatus) => void
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Callback when session generation activity changes.
|
|
265
|
+
* Derived from stream run events (RUN_STARTED / RUN_FINISHED / RUN_ERROR).
|
|
266
|
+
* Unlike `onLoadingChange` (request-local), this reflects shared generation
|
|
267
|
+
* activity visible to all subscribers (e.g. across tabs/devices).
|
|
268
|
+
*/
|
|
269
|
+
onSessionGeneratingChange?: (isGenerating: boolean) => void
|
|
270
|
+
|
|
242
271
|
/**
|
|
243
272
|
* Callback when a custom event is received from a server-side tool.
|
|
244
273
|
* Custom events are emitted by tools using `context.emitCustomEvent()` during execution.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { GENERATION_EVENTS } from './generation-types'
|
|
2
2
|
import { parseSSEResponse } from './sse-parser'
|
|
3
3
|
import type { StreamChunk } from '@tanstack/ai'
|
|
4
|
-
import type {
|
|
4
|
+
import type { ConnectConnectionAdapter } from './connection-adapters'
|
|
5
5
|
import type {
|
|
6
6
|
GenerationClientState,
|
|
7
7
|
GenerationFetcher,
|
|
@@ -36,14 +36,14 @@ interface VideoCallbacks<TOutput> {
|
|
|
36
36
|
* until completion. This client handles the full lifecycle.
|
|
37
37
|
*
|
|
38
38
|
* Supports two transport modes:
|
|
39
|
-
* - **
|
|
39
|
+
* - **ConnectConnectionAdapter** — Server handles the polling loop internally and
|
|
40
40
|
* streams status updates via CUSTOM events.
|
|
41
41
|
* - **Fetcher** — Direct async function that returns a completed
|
|
42
42
|
* `VideoGenerateResult`.
|
|
43
43
|
*
|
|
44
44
|
* @example
|
|
45
45
|
* ```typescript
|
|
46
|
-
* // With
|
|
46
|
+
* // With streaming connection adapter (server-driven polling)
|
|
47
47
|
* const client = new VideoGenerationClient({
|
|
48
48
|
* connection: fetchServerSentEvents('/api/generate/video'),
|
|
49
49
|
* onResultChange: setResult,
|
|
@@ -65,7 +65,7 @@ interface VideoCallbacks<TOutput> {
|
|
|
65
65
|
* ```
|
|
66
66
|
*/
|
|
67
67
|
export class VideoGenerationClient<TOutput = VideoGenerateResult> {
|
|
68
|
-
private connection:
|
|
68
|
+
private connection: ConnectConnectionAdapter | undefined
|
|
69
69
|
private fetcher:
|
|
70
70
|
| GenerationFetcher<VideoGenerateInput, VideoGenerateResult>
|
|
71
71
|
| undefined
|
|
@@ -83,7 +83,7 @@ export class VideoGenerationClient<TOutput = VideoGenerateResult> {
|
|
|
83
83
|
constructor(
|
|
84
84
|
options: VideoGenerationClientOptions<TOutput> &
|
|
85
85
|
(
|
|
86
|
-
| { connection:
|
|
86
|
+
| { connection: ConnectConnectionAdapter; fetcher?: never }
|
|
87
87
|
| {
|
|
88
88
|
fetcher: GenerationFetcher<VideoGenerateInput, VideoGenerateResult>
|
|
89
89
|
connection?: never
|
|
@@ -174,7 +174,7 @@ export class VideoGenerationClient<TOutput = VideoGenerateResult> {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
/**
|
|
177
|
-
* Process a stream of AG-UI events from the
|
|
177
|
+
* Process a stream of AG-UI events from the streaming connection adapter.
|
|
178
178
|
* The server handles the polling loop and streams status updates.
|
|
179
179
|
*/
|
|
180
180
|
private async processStream(
|