@tanstack/ai 0.6.3 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/esm/activities/chat/index.d.ts +20 -0
- package/dist/esm/activities/chat/index.js +248 -213
- package/dist/esm/activities/chat/index.js.map +1 -1
- package/dist/esm/activities/chat/middleware/compose.d.ts +66 -0
- package/dist/esm/activities/chat/middleware/compose.js +327 -0
- package/dist/esm/activities/chat/middleware/compose.js.map +1 -0
- package/dist/esm/activities/chat/middleware/index.d.ts +2 -0
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.d.ts +89 -0
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js +76 -0
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js.map +1 -0
- package/dist/esm/activities/chat/middleware/types.d.ts +307 -0
- package/dist/esm/activities/chat/stream/processor.d.ts +64 -40
- package/dist/esm/activities/chat/stream/processor.js +466 -218
- package/dist/esm/activities/chat/stream/processor.js.map +1 -1
- package/dist/esm/activities/chat/stream/types.d.ts +17 -0
- package/dist/esm/activities/chat/tools/tool-calls.d.ts +16 -1
- package/dist/esm/activities/chat/tools/tool-calls.js +148 -64
- package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
- package/dist/esm/activities/generateImage/index.js +1 -1
- package/dist/esm/activities/generateImage/index.js.map +1 -1
- package/dist/esm/activities/generateSpeech/index.js +1 -1
- package/dist/esm/activities/generateSpeech/index.js.map +1 -1
- package/dist/esm/activities/generateTranscription/index.js +1 -1
- package/dist/esm/activities/generateTranscription/index.js.map +1 -1
- package/dist/esm/activities/generateVideo/index.js +1 -1
- package/dist/esm/activities/generateVideo/index.js.map +1 -1
- package/dist/esm/activities/summarize/index.js +1 -1
- package/dist/esm/activities/summarize/index.js.map +1 -1
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/middlewares/content-guard.d.ts +77 -0
- package/dist/esm/middlewares/content-guard.js +155 -0
- package/dist/esm/middlewares/content-guard.js.map +1 -0
- package/dist/esm/middlewares/index.d.ts +2 -0
- package/dist/esm/middlewares/index.js +7 -0
- package/dist/esm/middlewares/index.js.map +1 -0
- package/dist/esm/middlewares/tool-cache.d.ts +1 -0
- package/dist/esm/realtime/index.d.ts +30 -0
- package/dist/esm/realtime/index.js +8 -0
- package/dist/esm/realtime/index.js.map +1 -0
- package/dist/esm/realtime/types.d.ts +234 -0
- package/dist/esm/types.d.ts +18 -4
- package/package.json +6 -6
- package/src/activities/chat/index.ts +322 -256
- package/src/activities/chat/middleware/compose.ts +392 -0
- package/src/activities/chat/middleware/index.ts +17 -0
- package/src/activities/chat/middleware/tool-cache-middleware.ts +189 -0
- package/src/activities/chat/middleware/types.ts +419 -0
- package/src/activities/chat/stream/processor.ts +630 -259
- package/src/activities/chat/stream/types.ts +18 -0
- package/src/activities/chat/tools/tool-calls.ts +225 -87
- package/src/activities/generateImage/index.ts +1 -1
- package/src/activities/generateSpeech/index.ts +1 -1
- package/src/activities/generateTranscription/index.ts +1 -1
- package/src/activities/generateVideo/index.ts +1 -1
- package/src/activities/summarize/index.ts +1 -1
- package/src/index.ts +41 -2
- package/src/middlewares/content-guard.ts +285 -0
- package/src/middlewares/index.ts +13 -0
- package/src/middlewares/tool-cache.ts +6 -0
- package/src/realtime/index.ts +38 -0
- package/src/realtime/types.ts +294 -0
- package/src/types.ts +19 -2
- package/dist/esm/event-client.d.ts +0 -394
- package/dist/esm/event-client.js +0 -13
- package/dist/esm/event-client.js.map +0 -1
- package/src/event-client.ts +0 -497
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { ModelMessage, StreamChunk, Tool, ToolCall } from '../../../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Phase of the chat middleware lifecycle.
|
|
4
|
+
* - 'init': Initial config transform before the chat engine starts
|
|
5
|
+
* - 'beforeModel': Before each adapter chatStream call (per agent iteration)
|
|
6
|
+
* - 'modelStream': During model streaming
|
|
7
|
+
* - 'beforeTools': Before tool execution phase
|
|
8
|
+
* - 'afterTools': After tool execution phase
|
|
9
|
+
*/
|
|
10
|
+
export type ChatMiddlewarePhase = 'init' | 'beforeModel' | 'modelStream' | 'beforeTools' | 'afterTools';
|
|
11
|
+
/**
|
|
12
|
+
* Stable context object passed to all middleware hooks.
|
|
13
|
+
* Created once per chat() invocation and shared across all hooks.
|
|
14
|
+
*/
|
|
15
|
+
export interface ChatMiddlewareContext {
|
|
16
|
+
/** Unique identifier for this chat request */
|
|
17
|
+
requestId: string;
|
|
18
|
+
/** Unique identifier for this stream */
|
|
19
|
+
streamId: string;
|
|
20
|
+
/** Conversation identifier, if provided by the caller */
|
|
21
|
+
conversationId?: string;
|
|
22
|
+
/** Current lifecycle phase */
|
|
23
|
+
phase: ChatMiddlewarePhase;
|
|
24
|
+
/** Current agent loop iteration (0-indexed) */
|
|
25
|
+
iteration: number;
|
|
26
|
+
/** Running count of chunks yielded so far */
|
|
27
|
+
chunkIndex: number;
|
|
28
|
+
/** Abort signal from the chat request */
|
|
29
|
+
signal?: AbortSignal;
|
|
30
|
+
/** Abort the chat run with a reason */
|
|
31
|
+
abort: (reason?: string) => void;
|
|
32
|
+
/** Opaque user-provided value from chat() options */
|
|
33
|
+
context: unknown;
|
|
34
|
+
/**
|
|
35
|
+
* Defer a non-blocking side-effect promise.
|
|
36
|
+
* Deferred promises do not block streaming and are awaited
|
|
37
|
+
* after the terminal hook (onFinish/onAbort/onError).
|
|
38
|
+
*/
|
|
39
|
+
defer: (promise: Promise<unknown>) => void;
|
|
40
|
+
/** Provider name (e.g., 'openai', 'anthropic') */
|
|
41
|
+
provider: string;
|
|
42
|
+
/** Model identifier (e.g., 'gpt-4o') */
|
|
43
|
+
model: string;
|
|
44
|
+
/** Source of the chat invocation — always 'server' for server-side chat */
|
|
45
|
+
source: 'client' | 'server';
|
|
46
|
+
/** Whether the chat is streaming */
|
|
47
|
+
streaming: boolean;
|
|
48
|
+
/** System prompts configured for this chat */
|
|
49
|
+
systemPrompts: Array<string>;
|
|
50
|
+
/** Names of configured tools, if any */
|
|
51
|
+
toolNames?: Array<string>;
|
|
52
|
+
/** Flattened generation options (temperature, topP, maxTokens, metadata) */
|
|
53
|
+
options?: Record<string, unknown>;
|
|
54
|
+
/** Provider-specific model options */
|
|
55
|
+
modelOptions?: Record<string, unknown>;
|
|
56
|
+
/** Number of messages at the start of the request */
|
|
57
|
+
messageCount: number;
|
|
58
|
+
/** Whether tools are configured */
|
|
59
|
+
hasTools: boolean;
|
|
60
|
+
/** Current assistant message ID (changes per iteration) */
|
|
61
|
+
currentMessageId: string | null;
|
|
62
|
+
/** Accumulated text content for the current iteration */
|
|
63
|
+
accumulatedContent: string;
|
|
64
|
+
/** Current messages array (read-only view) */
|
|
65
|
+
messages: ReadonlyArray<ModelMessage>;
|
|
66
|
+
/** Generate a unique ID with the given prefix */
|
|
67
|
+
createId: (prefix: string) => string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Chat configuration that middleware can observe or transform.
|
|
71
|
+
* This is a subset of the chat engine's effective configuration
|
|
72
|
+
* that middleware is allowed to modify.
|
|
73
|
+
*/
|
|
74
|
+
export interface ChatMiddlewareConfig {
|
|
75
|
+
messages: Array<ModelMessage>;
|
|
76
|
+
systemPrompts: Array<string>;
|
|
77
|
+
tools: Array<Tool>;
|
|
78
|
+
temperature?: number;
|
|
79
|
+
topP?: number;
|
|
80
|
+
maxTokens?: number;
|
|
81
|
+
metadata?: Record<string, unknown>;
|
|
82
|
+
modelOptions?: Record<string, unknown>;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Context provided to tool call hooks (onBeforeToolCall / onAfterToolCall).
|
|
86
|
+
*/
|
|
87
|
+
export interface ToolCallHookContext {
|
|
88
|
+
/** The tool call being executed */
|
|
89
|
+
toolCall: ToolCall;
|
|
90
|
+
/** The resolved tool definition, if found */
|
|
91
|
+
tool: Tool | undefined;
|
|
92
|
+
/** Parsed arguments for the tool call */
|
|
93
|
+
args: unknown;
|
|
94
|
+
/** Name of the tool */
|
|
95
|
+
toolName: string;
|
|
96
|
+
/** ID of the tool call */
|
|
97
|
+
toolCallId: string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Decision returned from onBeforeToolCall.
|
|
101
|
+
* - undefined/void: continue with normal execution
|
|
102
|
+
* - { type: 'transformArgs', args }: replace args used for execution
|
|
103
|
+
* - { type: 'skip', result }: skip execution, use provided result
|
|
104
|
+
* - { type: 'abort', reason }: abort the entire chat run
|
|
105
|
+
*/
|
|
106
|
+
export type BeforeToolCallDecision = void | undefined | null | {
|
|
107
|
+
type: 'transformArgs';
|
|
108
|
+
args: unknown;
|
|
109
|
+
} | {
|
|
110
|
+
type: 'skip';
|
|
111
|
+
result: unknown;
|
|
112
|
+
} | {
|
|
113
|
+
type: 'abort';
|
|
114
|
+
reason?: string;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Outcome information provided to onAfterToolCall.
|
|
118
|
+
*/
|
|
119
|
+
export interface AfterToolCallInfo {
|
|
120
|
+
/** The tool call that was executed */
|
|
121
|
+
toolCall: ToolCall;
|
|
122
|
+
/** The resolved tool definition */
|
|
123
|
+
tool: Tool | undefined;
|
|
124
|
+
/** Name of the tool */
|
|
125
|
+
toolName: string;
|
|
126
|
+
/** ID of the tool call */
|
|
127
|
+
toolCallId: string;
|
|
128
|
+
/** Whether the execution succeeded */
|
|
129
|
+
ok: boolean;
|
|
130
|
+
/** Duration of tool execution in milliseconds */
|
|
131
|
+
duration: number;
|
|
132
|
+
/** The result (if ok) or error (if not ok) */
|
|
133
|
+
result?: unknown;
|
|
134
|
+
error?: unknown;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Information passed to onIteration at the start of each agent loop iteration.
|
|
138
|
+
*/
|
|
139
|
+
export interface IterationInfo {
|
|
140
|
+
/** 0-based iteration index */
|
|
141
|
+
iteration: number;
|
|
142
|
+
/** The assistant message ID created for this iteration */
|
|
143
|
+
messageId: string;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Aggregate information passed to onToolPhaseComplete after all tool calls
|
|
147
|
+
* in an iteration have been processed.
|
|
148
|
+
*/
|
|
149
|
+
export interface ToolPhaseCompleteInfo {
|
|
150
|
+
/** Tool calls that were assigned to the assistant message */
|
|
151
|
+
toolCalls: Array<ToolCall>;
|
|
152
|
+
/** Completed tool results */
|
|
153
|
+
results: Array<{
|
|
154
|
+
toolCallId: string;
|
|
155
|
+
toolName: string;
|
|
156
|
+
result: unknown;
|
|
157
|
+
duration?: number;
|
|
158
|
+
}>;
|
|
159
|
+
/** Tools that need user approval */
|
|
160
|
+
needsApproval: Array<{
|
|
161
|
+
toolCallId: string;
|
|
162
|
+
toolName: string;
|
|
163
|
+
input: unknown;
|
|
164
|
+
approvalId: string;
|
|
165
|
+
}>;
|
|
166
|
+
/** Tools that need client-side execution */
|
|
167
|
+
needsClientExecution: Array<{
|
|
168
|
+
toolCallId: string;
|
|
169
|
+
toolName: string;
|
|
170
|
+
input: unknown;
|
|
171
|
+
}>;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Token usage statistics passed to the onUsage hook.
|
|
175
|
+
* Extracted from the RUN_FINISHED chunk when usage data is present.
|
|
176
|
+
*/
|
|
177
|
+
export interface UsageInfo {
|
|
178
|
+
promptTokens: number;
|
|
179
|
+
completionTokens: number;
|
|
180
|
+
totalTokens: number;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Information passed to onFinish.
|
|
184
|
+
*/
|
|
185
|
+
export interface FinishInfo {
|
|
186
|
+
/** The finish reason from the last model response */
|
|
187
|
+
finishReason: string | null;
|
|
188
|
+
/** Total duration of the chat run in milliseconds */
|
|
189
|
+
duration: number;
|
|
190
|
+
/** Final accumulated text content */
|
|
191
|
+
content: string;
|
|
192
|
+
/** Final usage totals, if available */
|
|
193
|
+
usage?: {
|
|
194
|
+
promptTokens: number;
|
|
195
|
+
completionTokens: number;
|
|
196
|
+
totalTokens: number;
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Information passed to onAbort.
|
|
201
|
+
*/
|
|
202
|
+
export interface AbortInfo {
|
|
203
|
+
/** The reason for the abort, if provided */
|
|
204
|
+
reason?: string;
|
|
205
|
+
/** Duration until abort in milliseconds */
|
|
206
|
+
duration: number;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Information passed to onError.
|
|
210
|
+
*/
|
|
211
|
+
export interface ErrorInfo {
|
|
212
|
+
/** The error that caused the failure */
|
|
213
|
+
error: unknown;
|
|
214
|
+
/** Duration until error in milliseconds */
|
|
215
|
+
duration: number;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Chat middleware interface.
|
|
219
|
+
*
|
|
220
|
+
* All hooks are optional. Middleware is composed in array order:
|
|
221
|
+
* - `onConfig`: config piped through middlewares in order (first transform influences later)
|
|
222
|
+
* - `onChunk`: each output chunk is fed into the next middleware in order
|
|
223
|
+
*
|
|
224
|
+
* @example Logging middleware
|
|
225
|
+
* ```ts
|
|
226
|
+
* const loggingMiddleware: ChatMiddleware = {
|
|
227
|
+
* name: 'logging',
|
|
228
|
+
* onStart(ctx) { console.log('Chat started', ctx.requestId) },
|
|
229
|
+
* onChunk(ctx, chunk) { console.log('Chunk:', chunk.type) },
|
|
230
|
+
* onFinish(ctx, info) { console.log('Done:', info.duration, 'ms') },
|
|
231
|
+
* }
|
|
232
|
+
* ```
|
|
233
|
+
*
|
|
234
|
+
* @example Redaction middleware
|
|
235
|
+
* ```ts
|
|
236
|
+
* const redactionMiddleware: ChatMiddleware = {
|
|
237
|
+
* name: 'redaction',
|
|
238
|
+
* onChunk(ctx, chunk) {
|
|
239
|
+
* if (chunk.type === 'TEXT_MESSAGE_CONTENT') {
|
|
240
|
+
* return { ...chunk, delta: redact(chunk.delta) }
|
|
241
|
+
* }
|
|
242
|
+
* },
|
|
243
|
+
* }
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
export interface ChatMiddleware {
|
|
247
|
+
/** Optional name for debugging and identification */
|
|
248
|
+
name?: string;
|
|
249
|
+
/**
|
|
250
|
+
* Called to observe or transform the chat configuration.
|
|
251
|
+
* Called at init and at the beginning of each agent iteration.
|
|
252
|
+
*
|
|
253
|
+
* Return a partial config to merge with the current config, or void to pass through.
|
|
254
|
+
* Only the fields you return are overwritten — everything else is preserved.
|
|
255
|
+
*/
|
|
256
|
+
onConfig?: (ctx: ChatMiddlewareContext, config: ChatMiddlewareConfig) => void | null | Partial<ChatMiddlewareConfig> | Promise<void | Partial<ChatMiddlewareConfig>>;
|
|
257
|
+
/**
|
|
258
|
+
* Called when the chat run starts (after initial onConfig).
|
|
259
|
+
*/
|
|
260
|
+
onStart?: (ctx: ChatMiddlewareContext) => void | Promise<void>;
|
|
261
|
+
/**
|
|
262
|
+
* Called at the start of each agent loop iteration, after a new assistant message ID
|
|
263
|
+
* is created. Use this to observe iteration boundaries.
|
|
264
|
+
*/
|
|
265
|
+
onIteration?: (ctx: ChatMiddlewareContext, info: IterationInfo) => void | Promise<void>;
|
|
266
|
+
/**
|
|
267
|
+
* Called for every chunk yielded by chat().
|
|
268
|
+
* Can observe, transform, expand, or drop chunks.
|
|
269
|
+
*
|
|
270
|
+
* @returns void (pass through), chunk (replace), chunk[] (expand), null (drop)
|
|
271
|
+
*/
|
|
272
|
+
onChunk?: (ctx: ChatMiddlewareContext, chunk: StreamChunk) => void | StreamChunk | Array<StreamChunk> | null | Promise<void | StreamChunk | Array<StreamChunk> | null>;
|
|
273
|
+
/**
|
|
274
|
+
* Called before a tool is executed.
|
|
275
|
+
* Can observe, transform args, skip execution, or abort the run.
|
|
276
|
+
*/
|
|
277
|
+
onBeforeToolCall?: (ctx: ChatMiddlewareContext, hookCtx: ToolCallHookContext) => BeforeToolCallDecision | Promise<BeforeToolCallDecision>;
|
|
278
|
+
/**
|
|
279
|
+
* Called after a tool execution completes (success or failure).
|
|
280
|
+
*/
|
|
281
|
+
onAfterToolCall?: (ctx: ChatMiddlewareContext, info: AfterToolCallInfo) => void | Promise<void>;
|
|
282
|
+
/**
|
|
283
|
+
* Called after all tool calls in an iteration have been processed.
|
|
284
|
+
* Provides aggregate data about tool execution results, approvals, and client tools.
|
|
285
|
+
*/
|
|
286
|
+
onToolPhaseComplete?: (ctx: ChatMiddlewareContext, info: ToolPhaseCompleteInfo) => void | Promise<void>;
|
|
287
|
+
/**
|
|
288
|
+
* Called when usage data is available from a RUN_FINISHED chunk.
|
|
289
|
+
* Called once per model iteration that reports usage.
|
|
290
|
+
*/
|
|
291
|
+
onUsage?: (ctx: ChatMiddlewareContext, usage: UsageInfo) => void | Promise<void>;
|
|
292
|
+
/**
|
|
293
|
+
* Called when the chat run completes normally.
|
|
294
|
+
* Exactly one of onFinish/onAbort/onError will be called per run.
|
|
295
|
+
*/
|
|
296
|
+
onFinish?: (ctx: ChatMiddlewareContext, info: FinishInfo) => void | Promise<void>;
|
|
297
|
+
/**
|
|
298
|
+
* Called when the chat run is aborted.
|
|
299
|
+
* Exactly one of onFinish/onAbort/onError will be called per run.
|
|
300
|
+
*/
|
|
301
|
+
onAbort?: (ctx: ChatMiddlewareContext, info: AbortInfo) => void | Promise<void>;
|
|
302
|
+
/**
|
|
303
|
+
* Called when the chat run encounters an unhandled error.
|
|
304
|
+
* Exactly one of onFinish/onAbort/onError will be called per run.
|
|
305
|
+
*/
|
|
306
|
+
onError?: (ctx: ChatMiddlewareContext, info: ErrorInfo) => void | Promise<void>;
|
|
307
|
+
}
|
|
@@ -50,9 +50,8 @@ export interface StreamProcessorOptions {
|
|
|
50
50
|
*
|
|
51
51
|
* State tracking:
|
|
52
52
|
* - Full message array
|
|
53
|
-
* -
|
|
54
|
-
* -
|
|
55
|
-
* - Multiple parallel tool calls
|
|
53
|
+
* - Per-message stream state (text, tool calls, thinking)
|
|
54
|
+
* - Multiple concurrent message streams
|
|
56
55
|
* - Tool call completion via TOOL_CALL_END events
|
|
57
56
|
*
|
|
58
57
|
* @see docs/chat-architecture.md#streamprocessor-internal-state — State field reference
|
|
@@ -64,13 +63,11 @@ export declare class StreamProcessor {
|
|
|
64
63
|
private jsonParser;
|
|
65
64
|
private recordingEnabled;
|
|
66
65
|
private messages;
|
|
67
|
-
private
|
|
68
|
-
private
|
|
69
|
-
private
|
|
70
|
-
private
|
|
71
|
-
private
|
|
72
|
-
private toolCalls;
|
|
73
|
-
private toolCallOrder;
|
|
66
|
+
private messageStates;
|
|
67
|
+
private activeMessageIds;
|
|
68
|
+
private toolCallToMessage;
|
|
69
|
+
private pendingManualMessageId;
|
|
70
|
+
private activeRuns;
|
|
74
71
|
private finishReason;
|
|
75
72
|
private hasError;
|
|
76
73
|
private isDone;
|
|
@@ -117,24 +114,13 @@ export declare class StreamProcessor {
|
|
|
117
114
|
* @deprecated Use prepareAssistantMessage() instead. This eagerly creates
|
|
118
115
|
* an assistant message which can cause empty message flicker.
|
|
119
116
|
*/
|
|
120
|
-
startAssistantMessage(): string;
|
|
117
|
+
startAssistantMessage(messageId?: string): string;
|
|
121
118
|
/**
|
|
122
119
|
* Get the current assistant message ID (if one has been created).
|
|
123
120
|
* Returns null if prepareAssistantMessage() was called but no content
|
|
124
121
|
* has arrived yet.
|
|
125
122
|
*/
|
|
126
123
|
getCurrentAssistantMessageId(): string | null;
|
|
127
|
-
/**
|
|
128
|
-
* Lazily create the assistant message if it hasn't been created yet.
|
|
129
|
-
* Called by content handlers on the first content-bearing chunk.
|
|
130
|
-
* Returns the message ID.
|
|
131
|
-
*
|
|
132
|
-
* Content-bearing chunks that trigger this:
|
|
133
|
-
* TEXT_MESSAGE_CONTENT, TOOL_CALL_START, STEP_FINISHED, RUN_ERROR.
|
|
134
|
-
*
|
|
135
|
-
* @see docs/chat-architecture.md#streamprocessor-internal-state — Lazy creation pattern
|
|
136
|
-
*/
|
|
137
|
-
private ensureAssistantMessage;
|
|
138
124
|
/**
|
|
139
125
|
* Add a tool result (called by client after handling onToolCall)
|
|
140
126
|
*/
|
|
@@ -173,23 +159,46 @@ export declare class StreamProcessor {
|
|
|
173
159
|
*
|
|
174
160
|
* Central dispatch for all AG-UI events. Each event type maps to a specific
|
|
175
161
|
* handler. Events not listed in the switch are intentionally ignored
|
|
176
|
-
* (RUN_STARTED,
|
|
162
|
+
* (RUN_STARTED, STEP_STARTED, STATE_DELTA).
|
|
177
163
|
*
|
|
178
164
|
* @see docs/chat-architecture.md#adapter-contract — Expected event types and ordering
|
|
179
165
|
*/
|
|
180
166
|
processChunk(chunk: StreamChunk): void;
|
|
181
167
|
/**
|
|
182
|
-
*
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
*
|
|
187
|
-
|
|
168
|
+
* Create a new MessageStreamState for a message
|
|
169
|
+
*/
|
|
170
|
+
private createMessageState;
|
|
171
|
+
/**
|
|
172
|
+
* Get the MessageStreamState for a message
|
|
173
|
+
*/
|
|
174
|
+
private getMessageState;
|
|
175
|
+
/**
|
|
176
|
+
* Get the most recent active assistant message ID.
|
|
177
|
+
* Used as fallback for events that don't include a messageId.
|
|
178
|
+
*/
|
|
179
|
+
private getActiveAssistantMessageId;
|
|
180
|
+
/**
|
|
181
|
+
* Ensure an active assistant message exists, creating one if needed.
|
|
182
|
+
* Used for backward compat when events arrive without prior TEXT_MESSAGE_START.
|
|
188
183
|
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
184
|
+
* On reconnect/resume, a TEXT_MESSAGE_CONTENT may arrive for a message that
|
|
185
|
+
* already exists in this.messages (e.g. from initialMessages or a prior
|
|
186
|
+
* MESSAGES_SNAPSHOT) but whose transient state was cleared. In that case we
|
|
187
|
+
* hydrate state from the existing message rather than creating a duplicate.
|
|
188
|
+
*/
|
|
189
|
+
private ensureAssistantMessage;
|
|
190
|
+
/**
|
|
191
|
+
* Handle TEXT_MESSAGE_START event
|
|
191
192
|
*/
|
|
192
193
|
private handleTextMessageStartEvent;
|
|
194
|
+
/**
|
|
195
|
+
* Handle TEXT_MESSAGE_END event
|
|
196
|
+
*/
|
|
197
|
+
private handleTextMessageEndEvent;
|
|
198
|
+
/**
|
|
199
|
+
* Handle MESSAGES_SNAPSHOT event
|
|
200
|
+
*/
|
|
201
|
+
private handleMessagesSnapshotEvent;
|
|
193
202
|
/**
|
|
194
203
|
* Handle TEXT_MESSAGE_CONTENT event.
|
|
195
204
|
*
|
|
@@ -244,12 +253,19 @@ export declare class StreamProcessor {
|
|
|
244
253
|
* @see docs/chat-architecture.md#single-shot-tool-call-response — End-to-end flow
|
|
245
254
|
*/
|
|
246
255
|
private handleToolCallEndEvent;
|
|
256
|
+
/**
|
|
257
|
+
* Handle RUN_STARTED event.
|
|
258
|
+
*
|
|
259
|
+
* Registers the run so that RUN_FINISHED can determine whether other
|
|
260
|
+
* runs are still active before finalizing.
|
|
261
|
+
*/
|
|
262
|
+
private handleRunStartedEvent;
|
|
247
263
|
/**
|
|
248
264
|
* Handle RUN_FINISHED event.
|
|
249
265
|
*
|
|
250
|
-
* Records the finishReason and
|
|
251
|
-
*
|
|
252
|
-
*
|
|
266
|
+
* Records the finishReason and removes the run from activeRuns.
|
|
267
|
+
* Only finalizes when no more runs are active, so that concurrent
|
|
268
|
+
* runs don't interfere with each other.
|
|
253
269
|
*
|
|
254
270
|
* @see docs/chat-architecture.md#single-shot-tool-call-response — finishReason semantics
|
|
255
271
|
* @see docs/chat-architecture.md#adapter-contract — Why RUN_FINISHED is mandatory
|
|
@@ -280,7 +296,11 @@ export declare class StreamProcessor {
|
|
|
280
296
|
*/
|
|
281
297
|
private handleCustomEvent;
|
|
282
298
|
/**
|
|
283
|
-
*
|
|
299
|
+
* Detect if an incoming content chunk represents a NEW text segment
|
|
300
|
+
*/
|
|
301
|
+
private isNewTextSegment;
|
|
302
|
+
/**
|
|
303
|
+
* Complete all tool calls across all active messages — safety net for stream termination.
|
|
284
304
|
*
|
|
285
305
|
* Called by RUN_FINISHED and finalizeStream(). Force-transitions any tool call
|
|
286
306
|
* not yet in input-complete state. Handles cases where TOOL_CALL_END was
|
|
@@ -289,12 +309,16 @@ export declare class StreamProcessor {
|
|
|
289
309
|
* @see docs/chat-architecture.md#single-shot-tool-call-response — Safety net behavior
|
|
290
310
|
*/
|
|
291
311
|
private completeAllToolCalls;
|
|
312
|
+
/**
|
|
313
|
+
* Complete all tool calls for a specific message
|
|
314
|
+
*/
|
|
315
|
+
private completeAllToolCallsForMessage;
|
|
292
316
|
/**
|
|
293
317
|
* Mark a tool call as complete and emit event
|
|
294
318
|
*/
|
|
295
319
|
private completeToolCall;
|
|
296
320
|
/**
|
|
297
|
-
* Emit pending text update.
|
|
321
|
+
* Emit pending text update for a specific message.
|
|
298
322
|
*
|
|
299
323
|
* Calls updateTextPart() which has critical append-vs-replace logic:
|
|
300
324
|
* - If last UIMessage part is TextPart → replaces its content (same segment).
|
|
@@ -302,7 +326,7 @@ export declare class StreamProcessor {
|
|
|
302
326
|
*
|
|
303
327
|
* @see docs/chat-architecture.md#uimessage-part-ordering-invariants — Replace vs. push logic
|
|
304
328
|
*/
|
|
305
|
-
private
|
|
329
|
+
private emitTextUpdateForMessage;
|
|
306
330
|
/**
|
|
307
331
|
* Emit messages change event
|
|
308
332
|
*/
|
|
@@ -318,15 +342,15 @@ export declare class StreamProcessor {
|
|
|
318
342
|
*/
|
|
319
343
|
finalizeStream(): void;
|
|
320
344
|
/**
|
|
321
|
-
* Get completed tool calls in API format
|
|
345
|
+
* Get completed tool calls in API format (aggregated across all messages)
|
|
322
346
|
*/
|
|
323
347
|
private getCompletedToolCalls;
|
|
324
348
|
/**
|
|
325
|
-
* Get current result
|
|
349
|
+
* Get current result (aggregated across all messages)
|
|
326
350
|
*/
|
|
327
351
|
private getResult;
|
|
328
352
|
/**
|
|
329
|
-
* Get current processor state
|
|
353
|
+
* Get current processor state (aggregated across all messages)
|
|
330
354
|
*/
|
|
331
355
|
getState(): ProcessorState;
|
|
332
356
|
/**
|