ai.matey.utils 0.2.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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/conversation-history.js +139 -0
  3. package/dist/cjs/conversation-history.js.map +1 -0
  4. package/dist/cjs/index.js +42 -0
  5. package/dist/cjs/index.js.map +1 -0
  6. package/dist/cjs/model-cache.js +163 -0
  7. package/dist/cjs/model-cache.js.map +1 -0
  8. package/dist/cjs/parameter-normalizer.js +451 -0
  9. package/dist/cjs/parameter-normalizer.js.map +1 -0
  10. package/dist/cjs/streaming-modes.js +277 -0
  11. package/dist/cjs/streaming-modes.js.map +1 -0
  12. package/dist/cjs/streaming.js +892 -0
  13. package/dist/cjs/streaming.js.map +1 -0
  14. package/dist/cjs/structured-output.js +398 -0
  15. package/dist/cjs/structured-output.js.map +1 -0
  16. package/dist/cjs/system-message.js +222 -0
  17. package/dist/cjs/system-message.js.map +1 -0
  18. package/dist/cjs/validation.js +534 -0
  19. package/dist/cjs/validation.js.map +1 -0
  20. package/dist/cjs/warnings.js +301 -0
  21. package/dist/cjs/warnings.js.map +1 -0
  22. package/dist/esm/conversation-history.js +134 -0
  23. package/dist/esm/conversation-history.js.map +1 -0
  24. package/dist/esm/index.js +26 -0
  25. package/dist/esm/index.js.map +1 -0
  26. package/dist/esm/model-cache.js +158 -0
  27. package/dist/esm/model-cache.js.map +1 -0
  28. package/dist/esm/parameter-normalizer.js +434 -0
  29. package/dist/esm/parameter-normalizer.js.map +1 -0
  30. package/dist/esm/streaming-modes.js +265 -0
  31. package/dist/esm/streaming-modes.js.map +1 -0
  32. package/dist/esm/streaming.js +860 -0
  33. package/dist/esm/streaming.js.map +1 -0
  34. package/dist/esm/structured-output.js +387 -0
  35. package/dist/esm/structured-output.js.map +1 -0
  36. package/dist/esm/system-message.js +213 -0
  37. package/dist/esm/system-message.js.map +1 -0
  38. package/dist/esm/validation.js +523 -0
  39. package/dist/esm/validation.js.map +1 -0
  40. package/dist/esm/warnings.js +284 -0
  41. package/dist/esm/warnings.js.map +1 -0
  42. package/dist/types/conversation-history.d.ts +70 -0
  43. package/dist/types/conversation-history.d.ts.map +1 -0
  44. package/dist/types/index.d.ts +17 -0
  45. package/dist/types/index.d.ts.map +1 -0
  46. package/dist/types/model-cache.d.ts +88 -0
  47. package/dist/types/model-cache.d.ts.map +1 -0
  48. package/dist/types/parameter-normalizer.d.ts +154 -0
  49. package/dist/types/parameter-normalizer.d.ts.map +1 -0
  50. package/dist/types/streaming-modes.d.ts +139 -0
  51. package/dist/types/streaming-modes.d.ts.map +1 -0
  52. package/dist/types/streaming.d.ts +384 -0
  53. package/dist/types/streaming.d.ts.map +1 -0
  54. package/dist/types/structured-output.d.ts +157 -0
  55. package/dist/types/structured-output.d.ts.map +1 -0
  56. package/dist/types/system-message.d.ts +78 -0
  57. package/dist/types/system-message.d.ts.map +1 -0
  58. package/dist/types/validation.d.ts +46 -0
  59. package/dist/types/validation.d.ts.map +1 -0
  60. package/dist/types/warnings.d.ts +149 -0
  61. package/dist/types/warnings.d.ts.map +1 -0
  62. package/package.json +75 -0
  63. package/readme.md +280 -0
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Streaming Mode Conversion Utilities
3
+ *
4
+ * This module handles conversion between delta and accumulated streaming modes.
5
+ * Use these utilities when you need to transform IR stream chunks between formats.
6
+ *
7
+ * For general stream operations (map, filter, collect), see ./streaming.ts
8
+ *
9
+ * @example Converting stream modes
10
+ * ```typescript
11
+ * import { convertStreamMode, createAccumulatorState } from 'ai.matey.utils';
12
+ *
13
+ * const converter = createAccumulatorState();
14
+ * const accumulated = await convertStreamMode(deltaStream, 'accumulated', { converter });
15
+ * ```
16
+ *
17
+ * @module streaming-modes
18
+ */
19
+ import type { IRChatStream, StreamContentChunk } from 'ai.matey.types';
20
+ import type { StreamMode, StreamConversionOptions, StreamingConfig } from 'ai.matey.types';
21
+ /**
22
+ * Stream accumulator state for tracking accumulated content.
23
+ */
24
+ export interface StreamAccumulatorState {
25
+ /**
26
+ * Full accumulated text so far.
27
+ */
28
+ accumulated: string;
29
+ /**
30
+ * Number of chunks processed.
31
+ */
32
+ chunkCount: number;
33
+ /**
34
+ * Last chunk sequence number (for validation).
35
+ */
36
+ lastSequence: number;
37
+ }
38
+ /**
39
+ * Create a new stream accumulator state.
40
+ */
41
+ export declare function createAccumulatorState(): StreamAccumulatorState;
42
+ /**
43
+ * Detect the streaming mode of a content chunk.
44
+ *
45
+ * @param chunk Content chunk to inspect
46
+ * @returns Detected streaming mode
47
+ */
48
+ export declare function detectChunkMode(chunk: StreamContentChunk): StreamMode;
49
+ /**
50
+ * Check if a chunk needs conversion to target mode.
51
+ *
52
+ * @param chunk Content chunk to check
53
+ * @param targetMode Desired streaming mode
54
+ * @param preserveIfMatch Whether to skip conversion if already in target mode
55
+ * @returns true if conversion is needed
56
+ */
57
+ export declare function needsConversion(chunk: StreamContentChunk, targetMode: StreamMode, preserveIfMatch?: boolean): boolean;
58
+ /**
59
+ * Convert IR stream to target streaming mode.
60
+ *
61
+ * This function transforms an IR stream to use the specified streaming mode:
62
+ * - Delta mode: Only incremental deltas
63
+ * - Accumulated mode: Full text in each chunk
64
+ *
65
+ * @param stream Source IR stream
66
+ * @param options Conversion options
67
+ * @returns Converted IR stream
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * // Convert to accumulated mode
72
+ * const accumulated = convertStreamMode(deltaStream, { mode: 'accumulated' });
73
+ *
74
+ * // Convert to delta mode
75
+ * const delta = convertStreamMode(accumulatedStream, { mode: 'delta' });
76
+ * ```
77
+ */
78
+ export declare function convertStreamMode(stream: IRChatStream, options?: StreamConversionOptions): IRChatStream;
79
+ /**
80
+ * Convert a single content chunk to target mode.
81
+ *
82
+ * @param chunk Source content chunk
83
+ * @param targetMode Target streaming mode
84
+ * @param state Accumulator state (updated in place)
85
+ * @param transform Optional transform function
86
+ * @returns Converted content chunk
87
+ */
88
+ export declare function convertChunkMode(chunk: StreamContentChunk, targetMode: StreamMode, state: StreamAccumulatorState, transform?: (text: string) => string): StreamContentChunk;
89
+ /**
90
+ * Get effective streaming mode from cascading configuration.
91
+ *
92
+ * Priority order (highest to lowest):
93
+ * 1. Request-level streamMode
94
+ * 2. Conversion options mode
95
+ * 3. Streaming config mode
96
+ * 4. Default ('delta')
97
+ *
98
+ * @param requestMode Stream mode from request
99
+ * @param conversionMode Stream mode from conversion options
100
+ * @param config Streaming configuration
101
+ * @returns Effective streaming mode
102
+ */
103
+ export declare function getEffectiveStreamMode(requestMode?: StreamMode, conversionMode?: StreamMode, config?: StreamingConfig): StreamMode;
104
+ /**
105
+ * Merge streaming configurations with priority.
106
+ *
107
+ * @param configs Configuration objects in priority order (first wins)
108
+ * @returns Merged configuration
109
+ */
110
+ export declare function mergeStreamingConfig(...configs: (StreamingConfig | undefined)[]): Required<StreamingConfig>;
111
+ /**
112
+ * Ensure all chunks in a stream have a specific mode.
113
+ *
114
+ * If chunks don't have the required format, converts them.
115
+ *
116
+ * @param stream Source stream
117
+ * @param mode Required mode
118
+ * @returns Stream with all chunks in required mode
119
+ */
120
+ export declare function ensureStreamMode(stream: IRChatStream, mode: StreamMode): IRChatStream;
121
+ /**
122
+ * Add accumulated field to all content chunks (dual-mode streaming).
123
+ *
124
+ * Useful for backends that want to provide both delta and accumulated.
125
+ *
126
+ * @param stream Source stream (delta-only)
127
+ * @returns Stream with both delta and accumulated in content chunks
128
+ */
129
+ export declare function addAccumulatedToStream(stream: IRChatStream): IRChatStream;
130
+ /**
131
+ * Strip accumulated field from all content chunks (delta-only streaming).
132
+ *
133
+ * Useful for reducing bandwidth when accumulated isn't needed.
134
+ *
135
+ * @param stream Source stream
136
+ * @returns Stream with only delta in content chunks
137
+ */
138
+ export declare function stripAccumulatedFromStream(stream: IRChatStream): IRChatStream;
139
+ //# sourceMappingURL=streaming-modes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming-modes.d.ts","sourceRoot":"","sources":["../../src/streaming-modes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAO3F;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,sBAAsB,CAM/D;AAMD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,UAAU,CAarE;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,kBAAkB,EACzB,UAAU,EAAE,UAAU,EACtB,eAAe,UAAO,GACrB,OAAO,CAuBT;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAuB,iBAAiB,CACtC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,uBAA4B,GACpC,YAAY,CAuCd;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,kBAAkB,EACzB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,sBAAsB,EAC7B,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACnC,kBAAkB,CAwBpB;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,CAAC,EAAE,UAAU,EACxB,cAAc,CAAC,EAAE,UAAU,EAC3B,MAAM,CAAC,EAAE,eAAe,GACvB,UAAU,CAEZ;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,OAAO,EAAE,CAAC,eAAe,GAAG,SAAS,CAAC,EAAE,GAC1C,QAAQ,CAAC,eAAe,CAAC,CAsB3B;AAMD;;;;;;;;GAQG;AACH,wBAAuB,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,YAAY,CAE5F;AAED;;;;;;;GAOG;AACH,wBAAuB,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAehF;AAED;;;;;;;GAOG;AACH,wBAAuB,0BAA0B,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CASpF"}
@@ -0,0 +1,384 @@
1
+ /**
2
+ * General Stream Utilities
3
+ *
4
+ * This module provides general-purpose stream transformation utilities.
5
+ * Use these for mapping, filtering, collecting, and error handling in streams.
6
+ *
7
+ * For delta/accumulated mode conversion, see ./streaming-modes.ts
8
+ *
9
+ * @example Accumulating stream content
10
+ * ```typescript
11
+ * import { createStreamAccumulator, accumulateChunk } from 'ai.matey.utils';
12
+ *
13
+ * const accumulator = createStreamAccumulator();
14
+ * for await (const chunk of stream) {
15
+ * const updated = accumulateChunk(accumulator, chunk);
16
+ * console.log('Accumulated so far:', updated.content);
17
+ * }
18
+ * ```
19
+ *
20
+ * @module streaming
21
+ */
22
+ import type { IRChatStream, IRStreamChunk, StreamContentChunk, StreamDoneChunk, StreamErrorChunk, IRMessage, IRChatResponse, IRMetadata, IRUsage, FinishReason } from 'ai.matey.types';
23
+ /**
24
+ * Accumulated stream state.
25
+ */
26
+ export interface StreamAccumulator {
27
+ content: string;
28
+ role: 'assistant';
29
+ sequence: number;
30
+ metadata?: Partial<IRMetadata>;
31
+ }
32
+ /**
33
+ * Create a new stream accumulator.
34
+ *
35
+ * @returns Empty accumulator
36
+ */
37
+ export declare function createStreamAccumulator(): StreamAccumulator;
38
+ /**
39
+ * Accumulate a stream chunk.
40
+ *
41
+ * @param accumulator Current accumulator state
42
+ * @param chunk Stream chunk to accumulate
43
+ * @returns Updated accumulator
44
+ */
45
+ export declare function accumulateChunk(accumulator: StreamAccumulator, chunk: IRStreamChunk): StreamAccumulator;
46
+ /**
47
+ * Convert accumulated state to IR message.
48
+ *
49
+ * @param accumulator Stream accumulator
50
+ * @returns IR message
51
+ */
52
+ export declare function accumulatorToMessage(accumulator: StreamAccumulator): IRMessage;
53
+ /**
54
+ * Convert accumulated state and done chunk to IR response.
55
+ *
56
+ * @param accumulator Stream accumulator
57
+ * @param doneChunk Done chunk with finish reason and usage
58
+ * @param requestMetadata Original request metadata
59
+ * @returns IR chat response
60
+ */
61
+ export declare function accumulatorToResponse(accumulator: StreamAccumulator, doneChunk: StreamDoneChunk, requestMetadata: IRMetadata): IRChatResponse;
62
+ /**
63
+ * Transform stream chunks.
64
+ *
65
+ * @param stream Original stream
66
+ * @param transformer Transform function
67
+ * @returns Transformed stream
68
+ */
69
+ export declare function transformStream(stream: IRChatStream, transformer: (chunk: IRStreamChunk) => IRStreamChunk | null): IRChatStream;
70
+ /**
71
+ * Filter stream chunks.
72
+ *
73
+ * @param stream Original stream
74
+ * @param predicate Filter predicate
75
+ * @returns Filtered stream
76
+ */
77
+ export declare function filterStream(stream: IRChatStream, predicate: (chunk: IRStreamChunk) => boolean): IRChatStream;
78
+ /**
79
+ * Map stream chunks.
80
+ *
81
+ * @param stream Original stream
82
+ * @param mapper Mapping function
83
+ * @returns Mapped stream
84
+ */
85
+ export declare function mapStream<T>(stream: IRChatStream, mapper: (chunk: IRStreamChunk) => T): AsyncGenerator<T, void, undefined>;
86
+ /**
87
+ * Tap into stream without modifying it.
88
+ *
89
+ * @param stream Original stream
90
+ * @param callback Function to call for each chunk
91
+ * @returns Same stream
92
+ */
93
+ export declare function tapStream(stream: IRChatStream, callback: (chunk: IRStreamChunk) => void | Promise<void>): IRChatStream;
94
+ /**
95
+ * Collect all chunks from a stream.
96
+ *
97
+ * @param stream Stream to collect
98
+ * @returns Array of all chunks
99
+ */
100
+ export declare function collectStream(stream: IRChatStream): Promise<IRStreamChunk[]>;
101
+ /**
102
+ * Collect stream into a complete response.
103
+ *
104
+ * @param stream Stream to collect
105
+ * @param requestMetadata Original request metadata
106
+ * @returns Complete IR response
107
+ */
108
+ export declare function streamToResponse(stream: IRChatStream, requestMetadata: IRMetadata): Promise<IRChatResponse>;
109
+ /**
110
+ * Collect just the content text from a stream.
111
+ *
112
+ * @param stream Stream to collect
113
+ * @returns Complete text content
114
+ */
115
+ export declare function streamToText(stream: IRChatStream): Promise<string>;
116
+ /**
117
+ * Split a stream into multiple consumers.
118
+ *
119
+ * @param stream Original stream
120
+ * @param consumerCount Number of consumers
121
+ * @returns Array of streams, one per consumer
122
+ */
123
+ export declare function splitStream(stream: IRChatStream, consumerCount: number): IRChatStream[];
124
+ /**
125
+ * Wrap stream with error handling.
126
+ *
127
+ * @param stream Original stream
128
+ * @param onError Error handler
129
+ * @returns Wrapped stream
130
+ */
131
+ export declare function catchStreamErrors(stream: IRChatStream, onError: (error: Error) => IRStreamChunk | null): IRChatStream;
132
+ /**
133
+ * Add timeout to stream.
134
+ *
135
+ * @param stream Original stream
136
+ * @param timeoutMs Timeout in milliseconds
137
+ * @param onTimeout Callback when timeout occurs
138
+ * @returns Stream with timeout
139
+ */
140
+ export declare function streamWithTimeout(stream: IRChatStream, timeoutMs: number, onTimeout: () => IRStreamChunk): IRChatStream;
141
+ /**
142
+ * Check if a chunk is a content chunk.
143
+ */
144
+ export declare function isContentChunk(chunk: IRStreamChunk): chunk is StreamContentChunk;
145
+ /**
146
+ * Check if a chunk is a done chunk.
147
+ */
148
+ export declare function isDoneChunk(chunk: IRStreamChunk): chunk is StreamDoneChunk;
149
+ /**
150
+ * Check if a chunk is an error chunk.
151
+ */
152
+ export declare function isErrorChunk(chunk: IRStreamChunk): chunk is StreamErrorChunk;
153
+ /**
154
+ * Get content deltas from stream.
155
+ *
156
+ * @param stream Stream to process
157
+ * @returns Stream of just content deltas
158
+ */
159
+ export declare function getContentDeltas(stream: IRChatStream): AsyncGenerator<string, void, undefined>;
160
+ /**
161
+ * Convert an IR stream to a simple text iterator.
162
+ * Yields content deltas as strings and throws on errors.
163
+ *
164
+ * @example
165
+ * ```typescript
166
+ * for await (const text of streamToTextIterator(stream)) {
167
+ * process.stdout.write(text);
168
+ * }
169
+ * ```
170
+ */
171
+ export declare function streamToTextIterator(stream: IRChatStream): AsyncGenerator<string, void, undefined>;
172
+ /**
173
+ * Validate chunk sequence numbers.
174
+ *
175
+ * Detects gaps or out-of-order chunks in a stream.
176
+ *
177
+ * @param chunks Array of chunks to validate
178
+ * @returns Validation result
179
+ */
180
+ export interface SequenceValidationResult {
181
+ valid: boolean;
182
+ gaps: number[];
183
+ duplicates: number[];
184
+ outOfOrder: boolean;
185
+ expectedNext: number;
186
+ }
187
+ export declare function validateChunkSequence(chunks: IRStreamChunk[]): SequenceValidationResult;
188
+ /**
189
+ * Create a validating stream wrapper.
190
+ *
191
+ * Validates chunk sequences and throws errors on invalid streams.
192
+ *
193
+ * @param stream Original stream
194
+ * @param options Validation options
195
+ * @returns Validated stream
196
+ */
197
+ export interface StreamValidationOptions {
198
+ /**
199
+ * Throw error on sequence gaps.
200
+ * @default true
201
+ */
202
+ strictSequence?: boolean;
203
+ /**
204
+ * Throw error on duplicate sequences.
205
+ * @default true
206
+ */
207
+ rejectDuplicates?: boolean;
208
+ /**
209
+ * Maximum allowed gap before error.
210
+ * @default 0
211
+ */
212
+ maxGap?: number;
213
+ /**
214
+ * Callback for validation warnings.
215
+ */
216
+ onWarning?: (message: string) => void;
217
+ }
218
+ export declare function validateStream(stream: IRChatStream, options?: StreamValidationOptions): IRChatStream;
219
+ /**
220
+ * Assemble stream chunks into a complete message.
221
+ *
222
+ * Alternative to streamToResponse that returns just the assembled message.
223
+ *
224
+ * @param stream Stream to assemble
225
+ * @returns Assembled message text
226
+ */
227
+ export declare function assembleStreamChunks(stream: IRChatStream): Promise<string>;
228
+ /**
229
+ * Create an error chunk.
230
+ *
231
+ * Helper for creating properly formatted error chunks.
232
+ *
233
+ * @param code Error code
234
+ * @param message Error message
235
+ * @param sequence Sequence number
236
+ * @param details Optional error details
237
+ * @returns Error chunk
238
+ */
239
+ export declare function createStreamError(code: string, message: string, sequence: number, details?: Record<string, unknown>): StreamErrorChunk;
240
+ /**
241
+ * Add backpressure control to stream.
242
+ *
243
+ * Buffers chunks and allows consumer to control flow.
244
+ *
245
+ * @param stream Original stream
246
+ * @param bufferSize Maximum buffer size before pausing
247
+ * @returns Stream with backpressure control
248
+ */
249
+ export declare function streamWithBackpressure(stream: IRChatStream, bufferSize?: number): IRChatStream;
250
+ /**
251
+ * Rate limit stream chunks.
252
+ *
253
+ * Ensures chunks are yielded at a maximum rate.
254
+ *
255
+ * @param stream Original stream
256
+ * @param chunksPerSecond Maximum chunks per second
257
+ * @returns Rate-limited stream
258
+ */
259
+ export declare function rateLimitStream(stream: IRChatStream, chunksPerSecond: number): IRChatStream;
260
+ /**
261
+ * Rich result from collecting a stream.
262
+ * Provides content, message, all chunks, and metadata.
263
+ */
264
+ export interface CollectedStream {
265
+ /**
266
+ * Full accumulated text content.
267
+ */
268
+ readonly content: string;
269
+ /**
270
+ * The final message.
271
+ */
272
+ readonly message: IRMessage;
273
+ /**
274
+ * All chunks received.
275
+ */
276
+ readonly chunks: readonly IRStreamChunk[];
277
+ /**
278
+ * Finish reason from done chunk.
279
+ */
280
+ readonly finishReason: FinishReason;
281
+ /**
282
+ * Token usage if provided.
283
+ */
284
+ readonly usage?: IRUsage;
285
+ /**
286
+ * Request ID from start chunk.
287
+ */
288
+ readonly requestId?: string;
289
+ }
290
+ /**
291
+ * Collect a stream into a rich result with content, message, and metadata.
292
+ *
293
+ * @example
294
+ * ```typescript
295
+ * const stream = backend.executeStream(request);
296
+ * const result = await collectStreamFull(stream);
297
+ * console.log(result.content);
298
+ * console.log('Tokens:', result.usage?.totalTokens);
299
+ * ```
300
+ */
301
+ export declare function collectStreamFull(stream: IRChatStream): Promise<CollectedStream>;
302
+ /**
303
+ * Options for processing a stream with callbacks.
304
+ */
305
+ export interface ProcessStreamOptions {
306
+ /**
307
+ * Called for each content chunk.
308
+ */
309
+ readonly onContent?: (delta: string, accumulated: string) => void;
310
+ /**
311
+ * Called when stream starts.
312
+ */
313
+ readonly onStart?: (requestId: string) => void;
314
+ /**
315
+ * Called when stream ends.
316
+ */
317
+ readonly onDone?: (result: CollectedStream) => void;
318
+ /**
319
+ * Called on error.
320
+ */
321
+ readonly onError?: (error: Error) => void;
322
+ }
323
+ /**
324
+ * Process a stream with callbacks while also returning the collected result.
325
+ *
326
+ * @example
327
+ * ```typescript
328
+ * const result = await processStream(stream, {
329
+ * onContent: (delta) => process.stdout.write(delta),
330
+ * onDone: () => console.log('\nDone!'),
331
+ * });
332
+ * ```
333
+ */
334
+ export declare function processStream(stream: IRChatStream, options?: ProcessStreamOptions): Promise<CollectedStream>;
335
+ /**
336
+ * Convert an IR stream to a line-by-line iterator.
337
+ * Buffers content and yields complete lines.
338
+ *
339
+ * @example
340
+ * ```typescript
341
+ * for await (const line of streamToLines(stream)) {
342
+ * console.log('Line:', line);
343
+ * }
344
+ * ```
345
+ */
346
+ export declare function streamToLines(stream: IRChatStream): AsyncGenerator<string, void, undefined>;
347
+ /**
348
+ * Create a throttled version of a stream that limits how often chunks are yielded.
349
+ * Batches content chunks that arrive faster than the interval.
350
+ * Unlike rateLimitStream, this merges content chunks rather than delaying them.
351
+ *
352
+ * @param stream - The source stream
353
+ * @param intervalMs - Minimum milliseconds between yields
354
+ *
355
+ * @example
356
+ * ```typescript
357
+ * // Update UI at most every 50ms
358
+ * for await (const chunk of throttleStream(stream, 50)) {
359
+ * updateUI(chunk);
360
+ * }
361
+ * ```
362
+ */
363
+ export declare function throttleStream(stream: IRChatStream, intervalMs: number): IRChatStream;
364
+ /**
365
+ * Split a stream into multiple streams that can be consumed independently.
366
+ * Each returned stream receives all chunks from the source.
367
+ * Alias for splitStream with a simpler interface.
368
+ *
369
+ * @param stream - The source stream
370
+ * @param count - Number of streams to create
371
+ *
372
+ * @example
373
+ * ```typescript
374
+ * const [stream1, stream2] = teeStream(originalStream, 2);
375
+ *
376
+ * // Consume independently
377
+ * const [result1, result2] = await Promise.all([
378
+ * collectStreamFull(stream1),
379
+ * processStream(stream2, { onContent: console.log }),
380
+ * ]);
381
+ * ```
382
+ */
383
+ export declare function teeStream(stream: IRChatStream, count?: number): IRChatStream[];
384
+ //# sourceMappingURL=streaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/streaming.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Structured Output with Zod
3
+ *
4
+ * This module provides utilities for working with Zod schemas for structured LLM outputs.
5
+ * It includes:
6
+ * - Schema to tool definition conversion
7
+ * - Runtime validation
8
+ * - Type-safe object generation
9
+ * - Streaming with partial objects
10
+ *
11
+ * **IMPORTANT**: This module requires the optional peer dependency `zod` to be installed.
12
+ * Install it with: `npm install zod`
13
+ */
14
+ /**
15
+ * OpenAI-compatible tool definition format
16
+ */
17
+ export interface ToolDefinition {
18
+ type: 'function';
19
+ function: {
20
+ name: string;
21
+ description: string;
22
+ parameters: JSONSchema;
23
+ };
24
+ }
25
+ /**
26
+ * JSON Schema representation (subset used for tool definitions)
27
+ */
28
+ export interface JSONSchema {
29
+ type: string;
30
+ properties?: Record<string, JSONSchema>;
31
+ items?: JSONSchema;
32
+ enum?: string[];
33
+ required?: string[];
34
+ description?: string;
35
+ }
36
+ /**
37
+ * PII match information
38
+ */
39
+ export interface PIIMatch {
40
+ type: string;
41
+ value: string;
42
+ start: number;
43
+ end: number;
44
+ }
45
+ /**
46
+ * PII detection result
47
+ */
48
+ export interface PIIDetectionResult {
49
+ detected: boolean;
50
+ matches: PIIMatch[];
51
+ }
52
+ /**
53
+ * PII pattern configuration
54
+ */
55
+ export interface PIIPattern {
56
+ type: string;
57
+ pattern: RegExp;
58
+ replacement: string;
59
+ }
60
+ /**
61
+ * Validation result
62
+ */
63
+ export type ValidationResult<T> = {
64
+ success: true;
65
+ data: T;
66
+ } | {
67
+ success: false;
68
+ errors: any[];
69
+ };
70
+ /**
71
+ * Convert a Zod schema to an OpenAI tool definition
72
+ *
73
+ * @param schema - Zod schema to convert
74
+ * @param name - Function name for the tool
75
+ * @param description - Description of what the tool does
76
+ * @returns OpenAI-compatible tool definition
77
+ */
78
+ export declare function schemaToToolDefinition(schema: any, // Using any to avoid importing z.ZodType
79
+ name?: string, description?: string): ToolDefinition;
80
+ /**
81
+ * Validate data against a Zod schema
82
+ *
83
+ * @param data - Data to validate
84
+ * @param schema - Zod schema to validate against
85
+ * @returns Validation result with typed data or errors
86
+ */
87
+ export declare function validateWithSchema<T = any>(data: unknown, schema: any): ValidationResult<T>;
88
+ /**
89
+ * Default PII patterns for detection
90
+ */
91
+ export declare const DEFAULT_PII_PATTERNS: PIIPattern[];
92
+ /**
93
+ * Default prompt injection patterns
94
+ */
95
+ export declare const DEFAULT_INJECTION_PATTERNS: RegExp[];
96
+ /**
97
+ * Detect PII in text
98
+ */
99
+ export declare function detectPII(text: string, patterns?: PIIPattern[]): PIIDetectionResult;
100
+ /**
101
+ * Redact PII from text
102
+ */
103
+ export declare function redactPII(text: string, patterns?: PIIPattern[]): string;
104
+ /**
105
+ * Detect prompt injection attempts
106
+ */
107
+ export declare function detectPromptInjection(text: string, patterns?: RegExp[]): boolean;
108
+ /**
109
+ * Sanitize text by removing control characters
110
+ */
111
+ export declare function sanitizeText(text: string): string;
112
+ /**
113
+ * Options for generateObject
114
+ */
115
+ export interface GenerateObjectOptions<T = any> {
116
+ schema: T;
117
+ prompt: string;
118
+ model?: string;
119
+ temperature?: number;
120
+ maxRetries?: number;
121
+ }
122
+ /**
123
+ * Result from generateObject
124
+ */
125
+ export interface GenerateObjectResult<T> {
126
+ object: T;
127
+ usage?: {
128
+ promptTokens: number;
129
+ completionTokens: number;
130
+ totalTokens: number;
131
+ };
132
+ finishReason: string;
133
+ }
134
+ /**
135
+ * Options for streamObject
136
+ */
137
+ export interface StreamObjectOptions<T = any> {
138
+ schema: T;
139
+ prompt: string;
140
+ model?: string;
141
+ onPartial?: (partial: Partial<T>) => void;
142
+ }
143
+ /**
144
+ * Create a generateObject function bound to a Bridge instance
145
+ *
146
+ * This is a factory function that creates a generateObject implementation
147
+ * that uses the provided Bridge for making LLM calls.
148
+ */
149
+ export declare function createGenerateObject(bridge: any): <T = any>(options: GenerateObjectOptions) => Promise<GenerateObjectResult<T>>;
150
+ /**
151
+ * Create a streamObject function bound to a Bridge instance
152
+ *
153
+ * This is a factory function that creates a streamObject implementation
154
+ * that uses the provided Bridge for making streaming LLM calls.
155
+ */
156
+ export declare function createStreamObject(bridge: any): <T = any>(options: StreamObjectOptions) => AsyncGenerator<Partial<T>, T>;
157
+ //# sourceMappingURL=structured-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-output.d.ts","sourceRoot":"","sources":["../../src/structured-output.ts"],"names":[],"mappings":"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"}