@tanstack/ai 0.6.2 → 0.8.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/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/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.d.ts +19 -6
- package/dist/esm/activities/generateImage/index.js +12 -3
- package/dist/esm/activities/generateImage/index.js.map +1 -1
- package/dist/esm/activities/generateSpeech/index.d.ts +19 -6
- package/dist/esm/activities/generateSpeech/index.js +12 -3
- package/dist/esm/activities/generateSpeech/index.js.map +1 -1
- package/dist/esm/activities/generateTranscription/index.d.ts +30 -6
- package/dist/esm/activities/generateTranscription/index.js +14 -3
- package/dist/esm/activities/generateTranscription/index.js.map +1 -1
- package/dist/esm/activities/generateVideo/index.d.ts +45 -7
- package/dist/esm/activities/generateVideo/index.js +91 -2
- package/dist/esm/activities/generateVideo/index.js.map +1 -1
- package/dist/esm/activities/stream-generation-result.d.ts +14 -0
- package/dist/esm/activities/stream-generation-result.js +40 -0
- package/dist/esm/activities/stream-generation-result.js.map +1 -0
- package/dist/esm/activities/summarize/index.js +3 -18
- 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/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/tools/tool-calls.ts +225 -87
- package/src/activities/generateImage/index.ts +50 -8
- package/src/activities/generateSpeech/index.ts +42 -8
- package/src/activities/generateTranscription/index.ts +60 -10
- package/src/activities/generateVideo/index.ts +174 -7
- package/src/activities/stream-generation-result.ts +62 -0
- package/src/activities/summarize/index.ts +4 -23
- 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/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,419 @@
|
|
|
1
|
+
import type { ModelMessage, StreamChunk, Tool, ToolCall } from '../../../types'
|
|
2
|
+
|
|
3
|
+
// ===========================
|
|
4
|
+
// Middleware Context
|
|
5
|
+
// ===========================
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Phase of the chat middleware lifecycle.
|
|
9
|
+
* - 'init': Initial config transform before the chat engine starts
|
|
10
|
+
* - 'beforeModel': Before each adapter chatStream call (per agent iteration)
|
|
11
|
+
* - 'modelStream': During model streaming
|
|
12
|
+
* - 'beforeTools': Before tool execution phase
|
|
13
|
+
* - 'afterTools': After tool execution phase
|
|
14
|
+
*/
|
|
15
|
+
export type ChatMiddlewarePhase =
|
|
16
|
+
| 'init'
|
|
17
|
+
| 'beforeModel'
|
|
18
|
+
| 'modelStream'
|
|
19
|
+
| 'beforeTools'
|
|
20
|
+
| 'afterTools'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Stable context object passed to all middleware hooks.
|
|
24
|
+
* Created once per chat() invocation and shared across all hooks.
|
|
25
|
+
*/
|
|
26
|
+
export interface ChatMiddlewareContext {
|
|
27
|
+
/** Unique identifier for this chat request */
|
|
28
|
+
requestId: string
|
|
29
|
+
/** Unique identifier for this stream */
|
|
30
|
+
streamId: string
|
|
31
|
+
/** Conversation identifier, if provided by the caller */
|
|
32
|
+
conversationId?: string
|
|
33
|
+
/** Current lifecycle phase */
|
|
34
|
+
phase: ChatMiddlewarePhase
|
|
35
|
+
/** Current agent loop iteration (0-indexed) */
|
|
36
|
+
iteration: number
|
|
37
|
+
/** Running count of chunks yielded so far */
|
|
38
|
+
chunkIndex: number
|
|
39
|
+
/** Abort signal from the chat request */
|
|
40
|
+
signal?: AbortSignal
|
|
41
|
+
/** Abort the chat run with a reason */
|
|
42
|
+
abort: (reason?: string) => void
|
|
43
|
+
/** Opaque user-provided value from chat() options */
|
|
44
|
+
context: unknown
|
|
45
|
+
/**
|
|
46
|
+
* Defer a non-blocking side-effect promise.
|
|
47
|
+
* Deferred promises do not block streaming and are awaited
|
|
48
|
+
* after the terminal hook (onFinish/onAbort/onError).
|
|
49
|
+
*/
|
|
50
|
+
defer: (promise: Promise<unknown>) => void
|
|
51
|
+
|
|
52
|
+
// --- Provider / adapter info (immutable for the lifetime of the request) ---
|
|
53
|
+
|
|
54
|
+
/** Provider name (e.g., 'openai', 'anthropic') */
|
|
55
|
+
provider: string
|
|
56
|
+
/** Model identifier (e.g., 'gpt-4o') */
|
|
57
|
+
model: string
|
|
58
|
+
/** Source of the chat invocation — always 'server' for server-side chat */
|
|
59
|
+
source: 'client' | 'server'
|
|
60
|
+
/** Whether the chat is streaming */
|
|
61
|
+
streaming: boolean
|
|
62
|
+
|
|
63
|
+
// --- Config-derived info (may update per-iteration via onConfig) ---
|
|
64
|
+
|
|
65
|
+
/** System prompts configured for this chat */
|
|
66
|
+
systemPrompts: Array<string>
|
|
67
|
+
/** Names of configured tools, if any */
|
|
68
|
+
toolNames?: Array<string>
|
|
69
|
+
/** Flattened generation options (temperature, topP, maxTokens, metadata) */
|
|
70
|
+
options?: Record<string, unknown>
|
|
71
|
+
/** Provider-specific model options */
|
|
72
|
+
modelOptions?: Record<string, unknown>
|
|
73
|
+
|
|
74
|
+
// --- Computed info ---
|
|
75
|
+
|
|
76
|
+
/** Number of messages at the start of the request */
|
|
77
|
+
messageCount: number
|
|
78
|
+
/** Whether tools are configured */
|
|
79
|
+
hasTools: boolean
|
|
80
|
+
|
|
81
|
+
// --- Mutable per-iteration state ---
|
|
82
|
+
|
|
83
|
+
/** Current assistant message ID (changes per iteration) */
|
|
84
|
+
currentMessageId: string | null
|
|
85
|
+
/** Accumulated text content for the current iteration */
|
|
86
|
+
accumulatedContent: string
|
|
87
|
+
|
|
88
|
+
// --- References ---
|
|
89
|
+
|
|
90
|
+
/** Current messages array (read-only view) */
|
|
91
|
+
messages: ReadonlyArray<ModelMessage>
|
|
92
|
+
/** Generate a unique ID with the given prefix */
|
|
93
|
+
createId: (prefix: string) => string
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ===========================
|
|
97
|
+
// Config passed to onConfig
|
|
98
|
+
// ===========================
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Chat configuration that middleware can observe or transform.
|
|
102
|
+
* This is a subset of the chat engine's effective configuration
|
|
103
|
+
* that middleware is allowed to modify.
|
|
104
|
+
*/
|
|
105
|
+
export interface ChatMiddlewareConfig {
|
|
106
|
+
messages: Array<ModelMessage>
|
|
107
|
+
systemPrompts: Array<string>
|
|
108
|
+
tools: Array<Tool>
|
|
109
|
+
temperature?: number
|
|
110
|
+
topP?: number
|
|
111
|
+
maxTokens?: number
|
|
112
|
+
metadata?: Record<string, unknown>
|
|
113
|
+
modelOptions?: Record<string, unknown>
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ===========================
|
|
117
|
+
// Tool Call Hook Context
|
|
118
|
+
// ===========================
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Context provided to tool call hooks (onBeforeToolCall / onAfterToolCall).
|
|
122
|
+
*/
|
|
123
|
+
export interface ToolCallHookContext {
|
|
124
|
+
/** The tool call being executed */
|
|
125
|
+
toolCall: ToolCall
|
|
126
|
+
/** The resolved tool definition, if found */
|
|
127
|
+
tool: Tool | undefined
|
|
128
|
+
/** Parsed arguments for the tool call */
|
|
129
|
+
args: unknown
|
|
130
|
+
/** Name of the tool */
|
|
131
|
+
toolName: string
|
|
132
|
+
/** ID of the tool call */
|
|
133
|
+
toolCallId: string
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Decision returned from onBeforeToolCall.
|
|
138
|
+
* - undefined/void: continue with normal execution
|
|
139
|
+
* - { type: 'transformArgs', args }: replace args used for execution
|
|
140
|
+
* - { type: 'skip', result }: skip execution, use provided result
|
|
141
|
+
* - { type: 'abort', reason }: abort the entire chat run
|
|
142
|
+
*/
|
|
143
|
+
export type BeforeToolCallDecision =
|
|
144
|
+
| void
|
|
145
|
+
| undefined
|
|
146
|
+
| null
|
|
147
|
+
| { type: 'transformArgs'; args: unknown }
|
|
148
|
+
| { type: 'skip'; result: unknown }
|
|
149
|
+
| { type: 'abort'; reason?: string }
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Outcome information provided to onAfterToolCall.
|
|
153
|
+
*/
|
|
154
|
+
export interface AfterToolCallInfo {
|
|
155
|
+
/** The tool call that was executed */
|
|
156
|
+
toolCall: ToolCall
|
|
157
|
+
/** The resolved tool definition */
|
|
158
|
+
tool: Tool | undefined
|
|
159
|
+
/** Name of the tool */
|
|
160
|
+
toolName: string
|
|
161
|
+
/** ID of the tool call */
|
|
162
|
+
toolCallId: string
|
|
163
|
+
/** Whether the execution succeeded */
|
|
164
|
+
ok: boolean
|
|
165
|
+
/** Duration of tool execution in milliseconds */
|
|
166
|
+
duration: number
|
|
167
|
+
/** The result (if ok) or error (if not ok) */
|
|
168
|
+
result?: unknown
|
|
169
|
+
error?: unknown
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ===========================
|
|
173
|
+
// Iteration Info
|
|
174
|
+
// ===========================
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Information passed to onIteration at the start of each agent loop iteration.
|
|
178
|
+
*/
|
|
179
|
+
export interface IterationInfo {
|
|
180
|
+
/** 0-based iteration index */
|
|
181
|
+
iteration: number
|
|
182
|
+
/** The assistant message ID created for this iteration */
|
|
183
|
+
messageId: string
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ===========================
|
|
187
|
+
// Tool Phase Complete Info
|
|
188
|
+
// ===========================
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Aggregate information passed to onToolPhaseComplete after all tool calls
|
|
192
|
+
* in an iteration have been processed.
|
|
193
|
+
*/
|
|
194
|
+
export interface ToolPhaseCompleteInfo {
|
|
195
|
+
/** Tool calls that were assigned to the assistant message */
|
|
196
|
+
toolCalls: Array<ToolCall>
|
|
197
|
+
/** Completed tool results */
|
|
198
|
+
results: Array<{
|
|
199
|
+
toolCallId: string
|
|
200
|
+
toolName: string
|
|
201
|
+
result: unknown
|
|
202
|
+
duration?: number
|
|
203
|
+
}>
|
|
204
|
+
/** Tools that need user approval */
|
|
205
|
+
needsApproval: Array<{
|
|
206
|
+
toolCallId: string
|
|
207
|
+
toolName: string
|
|
208
|
+
input: unknown
|
|
209
|
+
approvalId: string
|
|
210
|
+
}>
|
|
211
|
+
/** Tools that need client-side execution */
|
|
212
|
+
needsClientExecution: Array<{
|
|
213
|
+
toolCallId: string
|
|
214
|
+
toolName: string
|
|
215
|
+
input: unknown
|
|
216
|
+
}>
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// ===========================
|
|
220
|
+
// Usage Info
|
|
221
|
+
// ===========================
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Token usage statistics passed to the onUsage hook.
|
|
225
|
+
* Extracted from the RUN_FINISHED chunk when usage data is present.
|
|
226
|
+
*/
|
|
227
|
+
export interface UsageInfo {
|
|
228
|
+
promptTokens: number
|
|
229
|
+
completionTokens: number
|
|
230
|
+
totalTokens: number
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// ===========================
|
|
234
|
+
// Terminal Hook Info
|
|
235
|
+
// ===========================
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Information passed to onFinish.
|
|
239
|
+
*/
|
|
240
|
+
export interface FinishInfo {
|
|
241
|
+
/** The finish reason from the last model response */
|
|
242
|
+
finishReason: string | null
|
|
243
|
+
/** Total duration of the chat run in milliseconds */
|
|
244
|
+
duration: number
|
|
245
|
+
/** Final accumulated text content */
|
|
246
|
+
content: string
|
|
247
|
+
/** Final usage totals, if available */
|
|
248
|
+
usage?: {
|
|
249
|
+
promptTokens: number
|
|
250
|
+
completionTokens: number
|
|
251
|
+
totalTokens: number
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Information passed to onAbort.
|
|
257
|
+
*/
|
|
258
|
+
export interface AbortInfo {
|
|
259
|
+
/** The reason for the abort, if provided */
|
|
260
|
+
reason?: string
|
|
261
|
+
/** Duration until abort in milliseconds */
|
|
262
|
+
duration: number
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Information passed to onError.
|
|
267
|
+
*/
|
|
268
|
+
export interface ErrorInfo {
|
|
269
|
+
/** The error that caused the failure */
|
|
270
|
+
error: unknown
|
|
271
|
+
/** Duration until error in milliseconds */
|
|
272
|
+
duration: number
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// ===========================
|
|
276
|
+
// Middleware Interface
|
|
277
|
+
// ===========================
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Chat middleware interface.
|
|
281
|
+
*
|
|
282
|
+
* All hooks are optional. Middleware is composed in array order:
|
|
283
|
+
* - `onConfig`: config piped through middlewares in order (first transform influences later)
|
|
284
|
+
* - `onChunk`: each output chunk is fed into the next middleware in order
|
|
285
|
+
*
|
|
286
|
+
* @example Logging middleware
|
|
287
|
+
* ```ts
|
|
288
|
+
* const loggingMiddleware: ChatMiddleware = {
|
|
289
|
+
* name: 'logging',
|
|
290
|
+
* onStart(ctx) { console.log('Chat started', ctx.requestId) },
|
|
291
|
+
* onChunk(ctx, chunk) { console.log('Chunk:', chunk.type) },
|
|
292
|
+
* onFinish(ctx, info) { console.log('Done:', info.duration, 'ms') },
|
|
293
|
+
* }
|
|
294
|
+
* ```
|
|
295
|
+
*
|
|
296
|
+
* @example Redaction middleware
|
|
297
|
+
* ```ts
|
|
298
|
+
* const redactionMiddleware: ChatMiddleware = {
|
|
299
|
+
* name: 'redaction',
|
|
300
|
+
* onChunk(ctx, chunk) {
|
|
301
|
+
* if (chunk.type === 'TEXT_MESSAGE_CONTENT') {
|
|
302
|
+
* return { ...chunk, delta: redact(chunk.delta) }
|
|
303
|
+
* }
|
|
304
|
+
* },
|
|
305
|
+
* }
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
export interface ChatMiddleware {
|
|
309
|
+
/** Optional name for debugging and identification */
|
|
310
|
+
name?: string
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Called to observe or transform the chat configuration.
|
|
314
|
+
* Called at init and at the beginning of each agent iteration.
|
|
315
|
+
*
|
|
316
|
+
* Return a partial config to merge with the current config, or void to pass through.
|
|
317
|
+
* Only the fields you return are overwritten — everything else is preserved.
|
|
318
|
+
*/
|
|
319
|
+
onConfig?: (
|
|
320
|
+
ctx: ChatMiddlewareContext,
|
|
321
|
+
config: ChatMiddlewareConfig,
|
|
322
|
+
) =>
|
|
323
|
+
| void
|
|
324
|
+
| null
|
|
325
|
+
| Partial<ChatMiddlewareConfig>
|
|
326
|
+
| Promise<void | Partial<ChatMiddlewareConfig>>
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Called when the chat run starts (after initial onConfig).
|
|
330
|
+
*/
|
|
331
|
+
onStart?: (ctx: ChatMiddlewareContext) => void | Promise<void>
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Called at the start of each agent loop iteration, after a new assistant message ID
|
|
335
|
+
* is created. Use this to observe iteration boundaries.
|
|
336
|
+
*/
|
|
337
|
+
onIteration?: (
|
|
338
|
+
ctx: ChatMiddlewareContext,
|
|
339
|
+
info: IterationInfo,
|
|
340
|
+
) => void | Promise<void>
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Called for every chunk yielded by chat().
|
|
344
|
+
* Can observe, transform, expand, or drop chunks.
|
|
345
|
+
*
|
|
346
|
+
* @returns void (pass through), chunk (replace), chunk[] (expand), null (drop)
|
|
347
|
+
*/
|
|
348
|
+
onChunk?: (
|
|
349
|
+
ctx: ChatMiddlewareContext,
|
|
350
|
+
chunk: StreamChunk,
|
|
351
|
+
) =>
|
|
352
|
+
| void
|
|
353
|
+
| StreamChunk
|
|
354
|
+
| Array<StreamChunk>
|
|
355
|
+
| null
|
|
356
|
+
| Promise<void | StreamChunk | Array<StreamChunk> | null>
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Called before a tool is executed.
|
|
360
|
+
* Can observe, transform args, skip execution, or abort the run.
|
|
361
|
+
*/
|
|
362
|
+
onBeforeToolCall?: (
|
|
363
|
+
ctx: ChatMiddlewareContext,
|
|
364
|
+
hookCtx: ToolCallHookContext,
|
|
365
|
+
) => BeforeToolCallDecision | Promise<BeforeToolCallDecision>
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Called after a tool execution completes (success or failure).
|
|
369
|
+
*/
|
|
370
|
+
onAfterToolCall?: (
|
|
371
|
+
ctx: ChatMiddlewareContext,
|
|
372
|
+
info: AfterToolCallInfo,
|
|
373
|
+
) => void | Promise<void>
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Called after all tool calls in an iteration have been processed.
|
|
377
|
+
* Provides aggregate data about tool execution results, approvals, and client tools.
|
|
378
|
+
*/
|
|
379
|
+
onToolPhaseComplete?: (
|
|
380
|
+
ctx: ChatMiddlewareContext,
|
|
381
|
+
info: ToolPhaseCompleteInfo,
|
|
382
|
+
) => void | Promise<void>
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Called when usage data is available from a RUN_FINISHED chunk.
|
|
386
|
+
* Called once per model iteration that reports usage.
|
|
387
|
+
*/
|
|
388
|
+
onUsage?: (
|
|
389
|
+
ctx: ChatMiddlewareContext,
|
|
390
|
+
usage: UsageInfo,
|
|
391
|
+
) => void | Promise<void>
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Called when the chat run completes normally.
|
|
395
|
+
* Exactly one of onFinish/onAbort/onError will be called per run.
|
|
396
|
+
*/
|
|
397
|
+
onFinish?: (
|
|
398
|
+
ctx: ChatMiddlewareContext,
|
|
399
|
+
info: FinishInfo,
|
|
400
|
+
) => void | Promise<void>
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Called when the chat run is aborted.
|
|
404
|
+
* Exactly one of onFinish/onAbort/onError will be called per run.
|
|
405
|
+
*/
|
|
406
|
+
onAbort?: (
|
|
407
|
+
ctx: ChatMiddlewareContext,
|
|
408
|
+
info: AbortInfo,
|
|
409
|
+
) => void | Promise<void>
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Called when the chat run encounters an unhandled error.
|
|
413
|
+
* Exactly one of onFinish/onAbort/onError will be called per run.
|
|
414
|
+
*/
|
|
415
|
+
onError?: (
|
|
416
|
+
ctx: ChatMiddlewareContext,
|
|
417
|
+
info: ErrorInfo,
|
|
418
|
+
) => void | Promise<void>
|
|
419
|
+
}
|