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,265 @@
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 { DEFAULT_CONVERSION_OPTIONS, DEFAULT_STREAMING_CONFIG } from 'ai.matey.types';
20
+ /**
21
+ * Create a new stream accumulator state.
22
+ */
23
+ export function createAccumulatorState() {
24
+ return {
25
+ accumulated: '',
26
+ chunkCount: 0,
27
+ lastSequence: -1,
28
+ };
29
+ }
30
+ // ============================================================================
31
+ // Mode Detection
32
+ // ============================================================================
33
+ /**
34
+ * Detect the streaming mode of a content chunk.
35
+ *
36
+ * @param chunk Content chunk to inspect
37
+ * @returns Detected streaming mode
38
+ */
39
+ export function detectChunkMode(chunk) {
40
+ // If both delta and accumulated are present, it's providing both
41
+ if (chunk.delta && chunk.accumulated) {
42
+ return 'accumulated'; // Preferred mode when both available
43
+ }
44
+ // If only accumulated, it's accumulated mode
45
+ if (chunk.accumulated) {
46
+ return 'accumulated';
47
+ }
48
+ // Default: delta mode
49
+ return 'delta';
50
+ }
51
+ /**
52
+ * Check if a chunk needs conversion to target mode.
53
+ *
54
+ * @param chunk Content chunk to check
55
+ * @param targetMode Desired streaming mode
56
+ * @param preserveIfMatch Whether to skip conversion if already in target mode
57
+ * @returns true if conversion is needed
58
+ */
59
+ export function needsConversion(chunk, targetMode, preserveIfMatch = true) {
60
+ if (!preserveIfMatch) {
61
+ return true;
62
+ }
63
+ const currentMode = detectChunkMode(chunk);
64
+ // No conversion needed if already in target mode
65
+ if (currentMode === targetMode) {
66
+ return false;
67
+ }
68
+ // If target is delta and chunk has delta, no conversion needed
69
+ if (targetMode === 'delta' && chunk.delta) {
70
+ return false;
71
+ }
72
+ // If target is accumulated and chunk has accumulated, no conversion needed
73
+ if (targetMode === 'accumulated' && chunk.accumulated) {
74
+ return false;
75
+ }
76
+ return true;
77
+ }
78
+ // ============================================================================
79
+ // Stream Conversion
80
+ // ============================================================================
81
+ /**
82
+ * Convert IR stream to target streaming mode.
83
+ *
84
+ * This function transforms an IR stream to use the specified streaming mode:
85
+ * - Delta mode: Only incremental deltas
86
+ * - Accumulated mode: Full text in each chunk
87
+ *
88
+ * @param stream Source IR stream
89
+ * @param options Conversion options
90
+ * @returns Converted IR stream
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * // Convert to accumulated mode
95
+ * const accumulated = convertStreamMode(deltaStream, { mode: 'accumulated' });
96
+ *
97
+ * // Convert to delta mode
98
+ * const delta = convertStreamMode(accumulatedStream, { mode: 'delta' });
99
+ * ```
100
+ */
101
+ export async function* convertStreamMode(stream, options = {}) {
102
+ const { mode = DEFAULT_CONVERSION_OPTIONS.mode, preserveIfMatch = DEFAULT_CONVERSION_OPTIONS.preserveIfMatch, transform, validateSequence = DEFAULT_CONVERSION_OPTIONS.validateSequence, } = options;
103
+ const state = createAccumulatorState();
104
+ for await (const chunk of stream) {
105
+ // Only convert content chunks
106
+ if (chunk.type !== 'content') {
107
+ yield chunk;
108
+ continue;
109
+ }
110
+ // Validate sequence if requested
111
+ if (validateSequence && chunk.sequence !== undefined) {
112
+ if (chunk.sequence <= state.lastSequence) {
113
+ throw new Error(`Out of order chunk: expected sequence > ${state.lastSequence}, got ${chunk.sequence}`);
114
+ }
115
+ state.lastSequence = chunk.sequence;
116
+ }
117
+ // Check if conversion is needed
118
+ if (!needsConversion(chunk, mode, preserveIfMatch)) {
119
+ yield chunk;
120
+ continue;
121
+ }
122
+ // Convert chunk to target mode
123
+ const converted = convertChunkMode(chunk, mode, state, transform);
124
+ yield converted;
125
+ state.chunkCount++;
126
+ }
127
+ }
128
+ /**
129
+ * Convert a single content chunk to target mode.
130
+ *
131
+ * @param chunk Source content chunk
132
+ * @param targetMode Target streaming mode
133
+ * @param state Accumulator state (updated in place)
134
+ * @param transform Optional transform function
135
+ * @returns Converted content chunk
136
+ */
137
+ export function convertChunkMode(chunk, targetMode, state, transform) {
138
+ // Update accumulated state
139
+ state.accumulated += chunk.delta;
140
+ if (targetMode === 'delta') {
141
+ // Delta mode: ensure only delta is present
142
+ return {
143
+ type: 'content',
144
+ sequence: chunk.sequence,
145
+ delta: chunk.delta,
146
+ role: chunk.role,
147
+ };
148
+ }
149
+ else {
150
+ // Accumulated mode: provide accumulated text
151
+ const accumulated = transform ? transform(state.accumulated) : state.accumulated;
152
+ return {
153
+ type: 'content',
154
+ sequence: chunk.sequence,
155
+ delta: chunk.delta, // Still provide delta for compatibility
156
+ accumulated,
157
+ role: chunk.role,
158
+ };
159
+ }
160
+ }
161
+ // ============================================================================
162
+ // Configuration Helpers
163
+ // ============================================================================
164
+ /**
165
+ * Get effective streaming mode from cascading configuration.
166
+ *
167
+ * Priority order (highest to lowest):
168
+ * 1. Request-level streamMode
169
+ * 2. Conversion options mode
170
+ * 3. Streaming config mode
171
+ * 4. Default ('delta')
172
+ *
173
+ * @param requestMode Stream mode from request
174
+ * @param conversionMode Stream mode from conversion options
175
+ * @param config Streaming configuration
176
+ * @returns Effective streaming mode
177
+ */
178
+ export function getEffectiveStreamMode(requestMode, conversionMode, config) {
179
+ return requestMode || conversionMode || config?.mode || DEFAULT_STREAMING_CONFIG.mode;
180
+ }
181
+ /**
182
+ * Merge streaming configurations with priority.
183
+ *
184
+ * @param configs Configuration objects in priority order (first wins)
185
+ * @returns Merged configuration
186
+ */
187
+ export function mergeStreamingConfig(...configs) {
188
+ const result = { ...DEFAULT_STREAMING_CONFIG };
189
+ // Apply configs in reverse order (last has lowest priority)
190
+ for (let i = configs.length - 1; i >= 0; i--) {
191
+ const config = configs[i];
192
+ if (!config) {
193
+ continue;
194
+ }
195
+ if (config.mode !== undefined) {
196
+ result.mode = config.mode;
197
+ }
198
+ if (config.includeBoth !== undefined) {
199
+ result.includeBoth = config.includeBoth;
200
+ }
201
+ if (config.bufferStrategy !== undefined) {
202
+ result.bufferStrategy = config.bufferStrategy;
203
+ }
204
+ }
205
+ return result;
206
+ }
207
+ // ============================================================================
208
+ // Stream Utilities
209
+ // ============================================================================
210
+ /**
211
+ * Ensure all chunks in a stream have a specific mode.
212
+ *
213
+ * If chunks don't have the required format, converts them.
214
+ *
215
+ * @param stream Source stream
216
+ * @param mode Required mode
217
+ * @returns Stream with all chunks in required mode
218
+ */
219
+ export async function* ensureStreamMode(stream, mode) {
220
+ yield* convertStreamMode(stream, { mode, preserveIfMatch: true });
221
+ }
222
+ /**
223
+ * Add accumulated field to all content chunks (dual-mode streaming).
224
+ *
225
+ * Useful for backends that want to provide both delta and accumulated.
226
+ *
227
+ * @param stream Source stream (delta-only)
228
+ * @returns Stream with both delta and accumulated in content chunks
229
+ */
230
+ export async function* addAccumulatedToStream(stream) {
231
+ const state = createAccumulatorState();
232
+ for await (const chunk of stream) {
233
+ if (chunk.type === 'content') {
234
+ state.accumulated += chunk.delta;
235
+ yield {
236
+ ...chunk,
237
+ accumulated: state.accumulated,
238
+ };
239
+ state.chunkCount++;
240
+ }
241
+ else {
242
+ yield chunk;
243
+ }
244
+ }
245
+ }
246
+ /**
247
+ * Strip accumulated field from all content chunks (delta-only streaming).
248
+ *
249
+ * Useful for reducing bandwidth when accumulated isn't needed.
250
+ *
251
+ * @param stream Source stream
252
+ * @returns Stream with only delta in content chunks
253
+ */
254
+ export async function* stripAccumulatedFromStream(stream) {
255
+ for await (const chunk of stream) {
256
+ if (chunk.type === 'content') {
257
+ const { accumulated: _accumulated, ...deltaOnly } = chunk;
258
+ yield deltaOnly;
259
+ }
260
+ else {
261
+ yield chunk;
262
+ }
263
+ }
264
+ }
265
+ //# sourceMappingURL=streaming-modes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming-modes.js","sourceRoot":"","sources":["../../src/streaming-modes.ts"],"names":[],"mappings":"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"}