assistant-stream 0.0.21 → 0.0.23
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/ai-sdk.d.mts +20 -4
- package/dist/ai-sdk.d.ts +20 -4
- package/dist/ai-sdk.js +693 -42
- package/dist/ai-sdk.js.map +1 -1
- package/dist/ai-sdk.mjs +190 -44
- package/dist/ai-sdk.mjs.map +1 -1
- package/dist/assistant-stream-CEVTPU3I.d.mts +211 -0
- package/dist/assistant-stream-CEVTPU3I.d.ts +211 -0
- package/dist/chunk-O77LIKT5.mjs +934 -0
- package/dist/chunk-O77LIKT5.mjs.map +1 -0
- package/dist/index.d.mts +23 -103
- package/dist/index.d.ts +23 -103
- package/dist/index.js +1193 -492
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +417 -625
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/AssistantStream-dm_T4K6d.d.mts +0 -28
- package/dist/AssistantStream-dm_T4K6d.d.ts +0 -28
- package/dist/chunk-ZSSWV6GU.mjs +0 -11
- package/dist/chunk-ZSSWV6GU.mjs.map +0 -1
package/dist/ai-sdk.js
CHANGED
|
@@ -20,11 +20,291 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/ai-sdk.ts
|
|
21
21
|
var ai_sdk_exports = {};
|
|
22
22
|
__export(ai_sdk_exports, {
|
|
23
|
+
LanguageModelV1StreamDecoder: () => LanguageModelV1StreamDecoder,
|
|
23
24
|
fromStreamObject: () => fromStreamObject,
|
|
24
25
|
fromStreamText: () => fromStreamText
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(ai_sdk_exports);
|
|
27
28
|
|
|
29
|
+
// src/core/utils/stream/merge.ts
|
|
30
|
+
var promiseWithResolvers = () => {
|
|
31
|
+
let resolve;
|
|
32
|
+
let reject;
|
|
33
|
+
const promise = new Promise((res, rej) => {
|
|
34
|
+
resolve = res;
|
|
35
|
+
reject = rej;
|
|
36
|
+
});
|
|
37
|
+
return { promise, resolve, reject };
|
|
38
|
+
};
|
|
39
|
+
var createMergeStream = () => {
|
|
40
|
+
const list = [];
|
|
41
|
+
let sealed = false;
|
|
42
|
+
let controller;
|
|
43
|
+
let currentPull;
|
|
44
|
+
const handlePull = (item) => {
|
|
45
|
+
if (!item.promise) {
|
|
46
|
+
item.promise = item.reader.read().then(({ done, value }) => {
|
|
47
|
+
item.promise = void 0;
|
|
48
|
+
if (done) {
|
|
49
|
+
list.splice(list.indexOf(item), 1);
|
|
50
|
+
if (sealed && list.length === 0) {
|
|
51
|
+
controller.close();
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
controller.enqueue(value);
|
|
55
|
+
}
|
|
56
|
+
currentPull?.resolve();
|
|
57
|
+
currentPull = void 0;
|
|
58
|
+
}).catch((e) => {
|
|
59
|
+
console.error(e);
|
|
60
|
+
list.forEach((item2) => {
|
|
61
|
+
item2.reader.cancel();
|
|
62
|
+
});
|
|
63
|
+
list.length = 0;
|
|
64
|
+
controller.error(e);
|
|
65
|
+
currentPull?.reject(e);
|
|
66
|
+
currentPull = void 0;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const readable = new ReadableStream({
|
|
71
|
+
start(c) {
|
|
72
|
+
controller = c;
|
|
73
|
+
},
|
|
74
|
+
pull() {
|
|
75
|
+
currentPull = promiseWithResolvers();
|
|
76
|
+
list.forEach((item) => {
|
|
77
|
+
handlePull(item);
|
|
78
|
+
});
|
|
79
|
+
return currentPull.promise;
|
|
80
|
+
},
|
|
81
|
+
cancel() {
|
|
82
|
+
list.forEach((item) => {
|
|
83
|
+
item.reader.cancel();
|
|
84
|
+
});
|
|
85
|
+
list.length = 0;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return {
|
|
89
|
+
readable,
|
|
90
|
+
isSealed() {
|
|
91
|
+
return sealed;
|
|
92
|
+
},
|
|
93
|
+
seal() {
|
|
94
|
+
sealed = true;
|
|
95
|
+
if (list.length === 0) controller.close();
|
|
96
|
+
},
|
|
97
|
+
addStream(stream) {
|
|
98
|
+
if (sealed)
|
|
99
|
+
throw new Error(
|
|
100
|
+
"Cannot add streams after the run callback has settled."
|
|
101
|
+
);
|
|
102
|
+
const item = { reader: stream.getReader() };
|
|
103
|
+
list.push(item);
|
|
104
|
+
handlePull(item);
|
|
105
|
+
},
|
|
106
|
+
enqueue(chunk) {
|
|
107
|
+
this.addStream(
|
|
108
|
+
new ReadableStream({
|
|
109
|
+
start(c) {
|
|
110
|
+
c.enqueue(chunk);
|
|
111
|
+
c.close();
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// src/core/modules/text.ts
|
|
120
|
+
var TextStreamControllerImpl = class {
|
|
121
|
+
_controller;
|
|
122
|
+
_isClosed = false;
|
|
123
|
+
constructor(controller) {
|
|
124
|
+
this._controller = controller;
|
|
125
|
+
}
|
|
126
|
+
append(textDelta) {
|
|
127
|
+
this._controller.enqueue({
|
|
128
|
+
type: "text-delta",
|
|
129
|
+
path: [],
|
|
130
|
+
textDelta
|
|
131
|
+
});
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
close() {
|
|
135
|
+
if (this._isClosed) return;
|
|
136
|
+
this._isClosed = true;
|
|
137
|
+
this._controller.enqueue({
|
|
138
|
+
type: "part-finish",
|
|
139
|
+
path: []
|
|
140
|
+
});
|
|
141
|
+
this._controller.close();
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
var createTextStream = (readable) => {
|
|
145
|
+
return new ReadableStream({
|
|
146
|
+
start(c) {
|
|
147
|
+
return readable.start?.(new TextStreamControllerImpl(c));
|
|
148
|
+
},
|
|
149
|
+
pull(c) {
|
|
150
|
+
return readable.pull?.(new TextStreamControllerImpl(c));
|
|
151
|
+
},
|
|
152
|
+
cancel(c) {
|
|
153
|
+
return readable.cancel?.(c);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
var createTextStreamController = () => {
|
|
158
|
+
let controller;
|
|
159
|
+
const stream = createTextStream({
|
|
160
|
+
start(c) {
|
|
161
|
+
controller = c;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
return [stream, controller];
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// src/core/modules/tool-call.ts
|
|
168
|
+
var ToolCallStreamControllerImpl = class {
|
|
169
|
+
constructor(_controller) {
|
|
170
|
+
this._controller = _controller;
|
|
171
|
+
const stream = createTextStream({
|
|
172
|
+
start: (c) => {
|
|
173
|
+
this._argsTextController = c;
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
this._mergeTask = stream.pipeTo(
|
|
177
|
+
new WritableStream({
|
|
178
|
+
write: (chunk) => {
|
|
179
|
+
switch (chunk.type) {
|
|
180
|
+
case "text-delta":
|
|
181
|
+
this._controller.enqueue(chunk);
|
|
182
|
+
break;
|
|
183
|
+
case "part-finish":
|
|
184
|
+
this._controller.enqueue({
|
|
185
|
+
type: "tool-call-args-text-finish",
|
|
186
|
+
path: []
|
|
187
|
+
});
|
|
188
|
+
break;
|
|
189
|
+
default:
|
|
190
|
+
throw new Error(`Unexpected chunk type: ${chunk.type}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
})
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
_isClosed = false;
|
|
197
|
+
_mergeTask;
|
|
198
|
+
get argsText() {
|
|
199
|
+
return this._argsTextController;
|
|
200
|
+
}
|
|
201
|
+
_argsTextController;
|
|
202
|
+
setResult(result, isError) {
|
|
203
|
+
this._controller.enqueue({
|
|
204
|
+
type: "result",
|
|
205
|
+
path: [],
|
|
206
|
+
result,
|
|
207
|
+
isError: isError ?? false
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
async close() {
|
|
211
|
+
if (this._isClosed) return;
|
|
212
|
+
this._isClosed = true;
|
|
213
|
+
this._argsTextController.close();
|
|
214
|
+
await this._mergeTask;
|
|
215
|
+
this._controller.enqueue({
|
|
216
|
+
type: "part-finish",
|
|
217
|
+
path: []
|
|
218
|
+
});
|
|
219
|
+
this._controller.close();
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
var createToolCallStream = (readable) => {
|
|
223
|
+
return new ReadableStream({
|
|
224
|
+
start(c) {
|
|
225
|
+
return readable.start?.(new ToolCallStreamControllerImpl(c));
|
|
226
|
+
},
|
|
227
|
+
pull(c) {
|
|
228
|
+
return readable.pull?.(new ToolCallStreamControllerImpl(c));
|
|
229
|
+
},
|
|
230
|
+
cancel(c) {
|
|
231
|
+
return readable.cancel?.(c);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
};
|
|
235
|
+
var createToolCallStreamController = () => {
|
|
236
|
+
let controller;
|
|
237
|
+
const stream = createToolCallStream({
|
|
238
|
+
start(c) {
|
|
239
|
+
controller = c;
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
return [stream, controller];
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
// src/core/utils/Counter.ts
|
|
246
|
+
var Counter = class {
|
|
247
|
+
value = -1;
|
|
248
|
+
up() {
|
|
249
|
+
return ++this.value;
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// src/core/utils/stream/path-utils.ts
|
|
254
|
+
var PathAppendEncoder = class extends TransformStream {
|
|
255
|
+
constructor(idx) {
|
|
256
|
+
super({
|
|
257
|
+
transform(chunk, controller) {
|
|
258
|
+
controller.enqueue({
|
|
259
|
+
...chunk,
|
|
260
|
+
path: [idx, ...chunk.path]
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
var PathAppendDecoder = class extends TransformStream {
|
|
267
|
+
constructor(idx) {
|
|
268
|
+
super({
|
|
269
|
+
transform(chunk, controller) {
|
|
270
|
+
const {
|
|
271
|
+
path: [idx2, ...path]
|
|
272
|
+
} = chunk;
|
|
273
|
+
if (idx !== idx2)
|
|
274
|
+
throw new Error(`Path mismatch: expected ${idx}, got ${idx2}`);
|
|
275
|
+
controller.enqueue({
|
|
276
|
+
...chunk,
|
|
277
|
+
path
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
var PathMergeEncoder = class extends TransformStream {
|
|
284
|
+
constructor(counter) {
|
|
285
|
+
const innerCounter = new Counter();
|
|
286
|
+
const mapping = /* @__PURE__ */ new Map();
|
|
287
|
+
super({
|
|
288
|
+
transform(chunk, controller) {
|
|
289
|
+
if (chunk.type === "part-start" && chunk.path.length === 0) {
|
|
290
|
+
mapping.set(innerCounter.up(), counter.up());
|
|
291
|
+
}
|
|
292
|
+
const [idx, ...path] = chunk.path;
|
|
293
|
+
if (idx === void 0) {
|
|
294
|
+
controller.enqueue(chunk);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const mappedIdx = mapping.get(idx);
|
|
298
|
+
if (mappedIdx === void 0) throw new Error("Path not found");
|
|
299
|
+
controller.enqueue({
|
|
300
|
+
...chunk,
|
|
301
|
+
path: [mappedIdx, ...path]
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
|
|
28
308
|
// src/core/utils/generateId.tsx
|
|
29
309
|
var import_non_secure = require("nanoid/non-secure");
|
|
30
310
|
var generateId = (0, import_non_secure.customAlphabet)(
|
|
@@ -32,109 +312,383 @@ var generateId = (0, import_non_secure.customAlphabet)(
|
|
|
32
312
|
7
|
|
33
313
|
);
|
|
34
314
|
|
|
315
|
+
// src/core/modules/assistant-stream.ts
|
|
316
|
+
var AssistantStreamControllerImpl = class {
|
|
317
|
+
_merger = createMergeStream();
|
|
318
|
+
_append;
|
|
319
|
+
_contentCounter = new Counter();
|
|
320
|
+
get __internal_isClosed() {
|
|
321
|
+
return this._merger.isSealed();
|
|
322
|
+
}
|
|
323
|
+
__internal_getReadable() {
|
|
324
|
+
return this._merger.readable;
|
|
325
|
+
}
|
|
326
|
+
_closeSubscriber;
|
|
327
|
+
__internal_subscribeToClose(callback) {
|
|
328
|
+
this._closeSubscriber = callback;
|
|
329
|
+
}
|
|
330
|
+
_addPart(part, stream) {
|
|
331
|
+
this.enqueue({
|
|
332
|
+
type: "part-start",
|
|
333
|
+
part,
|
|
334
|
+
path: []
|
|
335
|
+
});
|
|
336
|
+
this._merger.addStream(
|
|
337
|
+
stream.pipeThrough(new PathAppendEncoder(this._contentCounter.value))
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
merge(stream) {
|
|
341
|
+
this._merger.addStream(
|
|
342
|
+
stream.pipeThrough(new PathMergeEncoder(this._contentCounter))
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
appendText(textDelta) {
|
|
346
|
+
if (this._append?.kind !== "text") {
|
|
347
|
+
if (this._append) {
|
|
348
|
+
this._append.controller.close();
|
|
349
|
+
}
|
|
350
|
+
this._append = {
|
|
351
|
+
kind: "text",
|
|
352
|
+
controller: this.addTextPart()
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
this._append.controller.append(textDelta);
|
|
356
|
+
}
|
|
357
|
+
appendReasoning(textDelta) {
|
|
358
|
+
if (this._append?.kind !== "reasoning") {
|
|
359
|
+
if (this._append) {
|
|
360
|
+
this._append.controller.close();
|
|
361
|
+
}
|
|
362
|
+
this._append = {
|
|
363
|
+
kind: "reasoning",
|
|
364
|
+
controller: this.addReasoningPart()
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
this._append.controller.append(textDelta);
|
|
368
|
+
}
|
|
369
|
+
addTextPart() {
|
|
370
|
+
const [stream, controller] = createTextStreamController();
|
|
371
|
+
this._addPart({ type: "text" }, stream);
|
|
372
|
+
return controller;
|
|
373
|
+
}
|
|
374
|
+
addReasoningPart() {
|
|
375
|
+
const [stream, controller] = createTextStreamController();
|
|
376
|
+
this._addPart({ type: "reasoning" }, stream);
|
|
377
|
+
return controller;
|
|
378
|
+
}
|
|
379
|
+
addToolCallPart(options) {
|
|
380
|
+
const opt = typeof options === "string" ? { toolName: options } : options;
|
|
381
|
+
const toolName = opt.toolName;
|
|
382
|
+
const toolCallId = opt.toolCallId ?? generateId();
|
|
383
|
+
const [stream, controller] = createToolCallStreamController();
|
|
384
|
+
this._addPart({ type: "tool-call", toolName, toolCallId }, stream);
|
|
385
|
+
if (opt.args !== void 0) {
|
|
386
|
+
controller.argsText.append(JSON.stringify(opt.args));
|
|
387
|
+
controller.argsText.close();
|
|
388
|
+
}
|
|
389
|
+
if (opt.result !== void 0) {
|
|
390
|
+
controller.setResult(opt.result, opt.isError);
|
|
391
|
+
}
|
|
392
|
+
return controller;
|
|
393
|
+
}
|
|
394
|
+
appendSource(options) {
|
|
395
|
+
this._addPart(
|
|
396
|
+
options,
|
|
397
|
+
new ReadableStream({
|
|
398
|
+
start(controller) {
|
|
399
|
+
controller.enqueue({
|
|
400
|
+
type: "part-finish",
|
|
401
|
+
path: []
|
|
402
|
+
});
|
|
403
|
+
controller.close();
|
|
404
|
+
}
|
|
405
|
+
})
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
appendFile(options) {
|
|
409
|
+
this._addPart(
|
|
410
|
+
options,
|
|
411
|
+
new ReadableStream({
|
|
412
|
+
start(controller) {
|
|
413
|
+
controller.enqueue({
|
|
414
|
+
type: "part-finish",
|
|
415
|
+
path: []
|
|
416
|
+
});
|
|
417
|
+
controller.close();
|
|
418
|
+
}
|
|
419
|
+
})
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
enqueue(chunk) {
|
|
423
|
+
this._merger.enqueue(chunk);
|
|
424
|
+
if (chunk.type === "part-start" && chunk.path.length === 0) {
|
|
425
|
+
this._contentCounter.up();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
close() {
|
|
429
|
+
this._merger.seal();
|
|
430
|
+
this._append?.controller?.close();
|
|
431
|
+
this._closeSubscriber?.();
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
function createAssistantStream(callback) {
|
|
435
|
+
const controller = new AssistantStreamControllerImpl();
|
|
436
|
+
let promiseOrVoid;
|
|
437
|
+
try {
|
|
438
|
+
promiseOrVoid = callback(controller);
|
|
439
|
+
} catch (e) {
|
|
440
|
+
if (!controller.__internal_isClosed) {
|
|
441
|
+
controller.enqueue({
|
|
442
|
+
type: "error",
|
|
443
|
+
path: [],
|
|
444
|
+
error: String(e)
|
|
445
|
+
});
|
|
446
|
+
controller.close();
|
|
447
|
+
}
|
|
448
|
+
throw e;
|
|
449
|
+
}
|
|
450
|
+
if (promiseOrVoid instanceof Promise) {
|
|
451
|
+
const runTask = async () => {
|
|
452
|
+
try {
|
|
453
|
+
await promiseOrVoid;
|
|
454
|
+
} catch (e) {
|
|
455
|
+
if (!controller.__internal_isClosed) {
|
|
456
|
+
controller.enqueue({
|
|
457
|
+
type: "error",
|
|
458
|
+
path: [],
|
|
459
|
+
error: String(e)
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
throw e;
|
|
463
|
+
} finally {
|
|
464
|
+
if (!controller.__internal_isClosed) {
|
|
465
|
+
controller.close();
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
runTask();
|
|
470
|
+
} else {
|
|
471
|
+
if (!controller.__internal_isClosed) {
|
|
472
|
+
controller.close();
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return controller.__internal_getReadable();
|
|
476
|
+
}
|
|
477
|
+
var promiseWithResolvers2 = function() {
|
|
478
|
+
let resolve;
|
|
479
|
+
let reject;
|
|
480
|
+
const promise = new Promise((res, rej) => {
|
|
481
|
+
resolve = res;
|
|
482
|
+
reject = rej;
|
|
483
|
+
});
|
|
484
|
+
if (!resolve || !reject) throw new Error("Failed to create promise");
|
|
485
|
+
return { promise, resolve, reject };
|
|
486
|
+
};
|
|
487
|
+
function createAssistantStreamController() {
|
|
488
|
+
const { resolve, promise } = promiseWithResolvers2();
|
|
489
|
+
let controller;
|
|
490
|
+
const stream = createAssistantStream((c) => {
|
|
491
|
+
controller = c;
|
|
492
|
+
controller.__internal_subscribeToClose(
|
|
493
|
+
resolve
|
|
494
|
+
);
|
|
495
|
+
return promise;
|
|
496
|
+
});
|
|
497
|
+
return [stream, controller];
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// src/core/utils/stream/AssistantTransformStream.ts
|
|
501
|
+
var AssistantTransformStream = class extends TransformStream {
|
|
502
|
+
constructor(transformer, writableStrategy, readableStrategy) {
|
|
503
|
+
const [stream, runController] = createAssistantStreamController();
|
|
504
|
+
let runPipeTask;
|
|
505
|
+
super(
|
|
506
|
+
{
|
|
507
|
+
start(controller) {
|
|
508
|
+
runPipeTask = stream.pipeTo(
|
|
509
|
+
new WritableStream({
|
|
510
|
+
write(chunk) {
|
|
511
|
+
controller.enqueue(chunk);
|
|
512
|
+
},
|
|
513
|
+
abort(reason) {
|
|
514
|
+
controller.error(reason);
|
|
515
|
+
},
|
|
516
|
+
close() {
|
|
517
|
+
controller.terminate();
|
|
518
|
+
}
|
|
519
|
+
})
|
|
520
|
+
).catch((error) => {
|
|
521
|
+
controller.error(error);
|
|
522
|
+
});
|
|
523
|
+
return transformer.start?.(runController);
|
|
524
|
+
},
|
|
525
|
+
transform(chunk) {
|
|
526
|
+
return transformer.transform?.(chunk, runController);
|
|
527
|
+
},
|
|
528
|
+
async flush() {
|
|
529
|
+
await transformer.flush?.(runController);
|
|
530
|
+
runController.close();
|
|
531
|
+
await runPipeTask;
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
writableStrategy,
|
|
535
|
+
readableStrategy
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
|
|
35
540
|
// src/ai-sdk/index.ts
|
|
36
541
|
var fromStreamText = (stream) => {
|
|
37
|
-
const
|
|
542
|
+
const toolControllers = /* @__PURE__ */ new Map();
|
|
543
|
+
let currentToolCallArgsText;
|
|
544
|
+
const endCurrentToolCallArgsText = () => {
|
|
545
|
+
if (!currentToolCallArgsText) return;
|
|
546
|
+
currentToolCallArgsText.argsText.close();
|
|
547
|
+
currentToolCallArgsText = void 0;
|
|
548
|
+
};
|
|
549
|
+
const transformer = new AssistantTransformStream({
|
|
38
550
|
transform(chunk, controller) {
|
|
39
551
|
const { type } = chunk;
|
|
552
|
+
if (type !== "tool-call-delta" && type !== "error") {
|
|
553
|
+
endCurrentToolCallArgsText();
|
|
554
|
+
}
|
|
40
555
|
switch (type) {
|
|
41
556
|
case "text-delta": {
|
|
42
557
|
const { textDelta } = chunk;
|
|
43
|
-
controller.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
558
|
+
controller.appendText(textDelta);
|
|
559
|
+
break;
|
|
560
|
+
}
|
|
561
|
+
case "reasoning": {
|
|
562
|
+
const { textDelta } = chunk;
|
|
563
|
+
controller.appendReasoning(textDelta);
|
|
47
564
|
break;
|
|
48
565
|
}
|
|
49
566
|
case "tool-call-streaming-start": {
|
|
50
567
|
const { toolCallId, toolName } = chunk;
|
|
51
|
-
controller.
|
|
52
|
-
type: "tool-call-begin",
|
|
568
|
+
currentToolCallArgsText = controller.addToolCallPart({
|
|
53
569
|
toolCallId,
|
|
54
570
|
toolName
|
|
55
571
|
});
|
|
572
|
+
toolControllers.set(toolCallId, currentToolCallArgsText);
|
|
56
573
|
break;
|
|
57
574
|
}
|
|
58
575
|
case "tool-call-delta": {
|
|
59
576
|
const { toolCallId, argsTextDelta } = chunk;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
argsTextDelta
|
|
64
|
-
});
|
|
577
|
+
const toolController = toolControllers.get(toolCallId);
|
|
578
|
+
if (!toolController) throw new Error("Tool call not found");
|
|
579
|
+
toolController.argsText.append(argsTextDelta);
|
|
65
580
|
break;
|
|
66
581
|
}
|
|
67
582
|
case "tool-result": {
|
|
68
583
|
const { toolCallId, result } = chunk;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
584
|
+
const toolController = toolControllers.get(toolCallId);
|
|
585
|
+
if (!toolController) throw new Error("Tool call not found");
|
|
586
|
+
toolController.setResult(result);
|
|
587
|
+
toolController.close();
|
|
588
|
+
toolControllers.delete(toolCallId);
|
|
74
589
|
break;
|
|
75
590
|
}
|
|
76
591
|
case "tool-call": {
|
|
77
592
|
const { toolCallId, toolName, args } = chunk;
|
|
78
|
-
controller.
|
|
79
|
-
type: "tool-call-begin",
|
|
593
|
+
const toolController = controller.addToolCallPart({
|
|
80
594
|
toolCallId,
|
|
81
595
|
toolName
|
|
82
596
|
});
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
argsTextDelta: JSON.stringify(args)
|
|
87
|
-
});
|
|
597
|
+
toolController.argsText.append(JSON.stringify(args));
|
|
598
|
+
toolController.argsText.close();
|
|
599
|
+
toolControllers.set(toolCallId, toolController);
|
|
88
600
|
break;
|
|
89
601
|
}
|
|
90
|
-
case "reasoning":
|
|
91
602
|
case "step-start":
|
|
603
|
+
controller.enqueue({
|
|
604
|
+
type: "step-start",
|
|
605
|
+
path: [],
|
|
606
|
+
messageId: chunk.messageId
|
|
607
|
+
});
|
|
608
|
+
break;
|
|
92
609
|
case "step-finish":
|
|
610
|
+
controller.enqueue({
|
|
611
|
+
type: "step-finish",
|
|
612
|
+
path: [],
|
|
613
|
+
finishReason: chunk.finishReason,
|
|
614
|
+
usage: chunk.usage,
|
|
615
|
+
isContinued: chunk.isContinued
|
|
616
|
+
});
|
|
617
|
+
break;
|
|
93
618
|
case "error":
|
|
619
|
+
controller.enqueue({
|
|
620
|
+
type: "error",
|
|
621
|
+
path: [],
|
|
622
|
+
error: String(chunk.error)
|
|
623
|
+
});
|
|
624
|
+
break;
|
|
94
625
|
case "finish": {
|
|
626
|
+
controller.enqueue({
|
|
627
|
+
type: "message-finish",
|
|
628
|
+
path: [],
|
|
629
|
+
finishReason: chunk.finishReason,
|
|
630
|
+
usage: chunk.usage
|
|
631
|
+
});
|
|
95
632
|
break;
|
|
96
633
|
}
|
|
634
|
+
case "source":
|
|
635
|
+
controller.appendSource({
|
|
636
|
+
type: "source",
|
|
637
|
+
...chunk.source
|
|
638
|
+
});
|
|
639
|
+
break;
|
|
640
|
+
case "file":
|
|
641
|
+
controller.appendFile({
|
|
642
|
+
type: "file",
|
|
643
|
+
mimeType: chunk.mimeType,
|
|
644
|
+
data: chunk.base64
|
|
645
|
+
});
|
|
646
|
+
break;
|
|
647
|
+
case "reasoning-signature":
|
|
648
|
+
case "redacted-reasoning":
|
|
649
|
+
break;
|
|
97
650
|
default: {
|
|
98
651
|
const unhandledType = type;
|
|
99
652
|
throw new Error(`Unhandled chunk type: ${unhandledType}`);
|
|
100
653
|
}
|
|
101
654
|
}
|
|
655
|
+
},
|
|
656
|
+
flush() {
|
|
657
|
+
for (const toolController of toolControllers.values()) {
|
|
658
|
+
toolController.close();
|
|
659
|
+
}
|
|
660
|
+
toolControllers.clear();
|
|
102
661
|
}
|
|
103
662
|
});
|
|
104
663
|
return stream.pipeThrough(transformer);
|
|
105
664
|
};
|
|
106
665
|
var fromStreamObject = (stream, toolName) => {
|
|
107
|
-
|
|
108
|
-
const transformer = new
|
|
666
|
+
let toolCall;
|
|
667
|
+
const transformer = new AssistantTransformStream({
|
|
109
668
|
start(controller) {
|
|
110
|
-
controller.
|
|
111
|
-
type: "tool-call-begin",
|
|
112
|
-
toolName,
|
|
113
|
-
toolCallId
|
|
114
|
-
});
|
|
669
|
+
toolCall = controller.addToolCallPart(toolName);
|
|
115
670
|
},
|
|
116
671
|
transform(chunk, controller) {
|
|
117
672
|
const { type } = chunk;
|
|
118
673
|
switch (type) {
|
|
119
674
|
case "text-delta": {
|
|
120
675
|
const { textDelta } = chunk;
|
|
121
|
-
|
|
122
|
-
type: "tool-call-delta",
|
|
123
|
-
toolCallId,
|
|
124
|
-
argsTextDelta: textDelta
|
|
125
|
-
});
|
|
676
|
+
toolCall.argsText.append(textDelta);
|
|
126
677
|
break;
|
|
127
678
|
}
|
|
128
679
|
case "finish": {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
toolCallId,
|
|
132
|
-
result: ""
|
|
133
|
-
});
|
|
680
|
+
toolCall.argsText.close();
|
|
681
|
+
toolCall.setResult("");
|
|
134
682
|
break;
|
|
135
683
|
}
|
|
136
684
|
case "object":
|
|
685
|
+
break;
|
|
137
686
|
case "error": {
|
|
687
|
+
controller.enqueue({
|
|
688
|
+
type: "error",
|
|
689
|
+
path: [],
|
|
690
|
+
error: String(chunk.error)
|
|
691
|
+
});
|
|
138
692
|
break;
|
|
139
693
|
}
|
|
140
694
|
default: {
|
|
@@ -146,8 +700,105 @@ var fromStreamObject = (stream, toolName) => {
|
|
|
146
700
|
});
|
|
147
701
|
return stream.pipeThrough(transformer);
|
|
148
702
|
};
|
|
703
|
+
|
|
704
|
+
// src/ai-sdk/language-model.ts
|
|
705
|
+
function bufferToBase64(buffer) {
|
|
706
|
+
return btoa(String.fromCharCode(...buffer));
|
|
707
|
+
}
|
|
708
|
+
var LanguageModelV1StreamDecoder = class extends AssistantTransformStream {
|
|
709
|
+
constructor() {
|
|
710
|
+
let currentToolCall;
|
|
711
|
+
const endCurrentToolCall = () => {
|
|
712
|
+
if (!currentToolCall) return;
|
|
713
|
+
currentToolCall.controller.argsText.close();
|
|
714
|
+
currentToolCall.controller.close();
|
|
715
|
+
currentToolCall = void 0;
|
|
716
|
+
};
|
|
717
|
+
super({
|
|
718
|
+
transform(chunk, controller) {
|
|
719
|
+
const { type } = chunk;
|
|
720
|
+
if (type !== "tool-call-delta" && type !== "error") {
|
|
721
|
+
endCurrentToolCall();
|
|
722
|
+
}
|
|
723
|
+
switch (type) {
|
|
724
|
+
case "text-delta": {
|
|
725
|
+
controller.appendText(chunk.textDelta);
|
|
726
|
+
break;
|
|
727
|
+
}
|
|
728
|
+
case "reasoning": {
|
|
729
|
+
controller.appendReasoning(chunk.textDelta);
|
|
730
|
+
break;
|
|
731
|
+
}
|
|
732
|
+
case "source": {
|
|
733
|
+
controller.appendSource({
|
|
734
|
+
type: "source",
|
|
735
|
+
...chunk.source
|
|
736
|
+
});
|
|
737
|
+
break;
|
|
738
|
+
}
|
|
739
|
+
case "file": {
|
|
740
|
+
controller.appendFile({
|
|
741
|
+
type: "file",
|
|
742
|
+
mimeType: chunk.mimeType,
|
|
743
|
+
data: typeof chunk.data === "string" ? chunk.data : bufferToBase64(chunk.data)
|
|
744
|
+
});
|
|
745
|
+
break;
|
|
746
|
+
}
|
|
747
|
+
case "tool-call-delta": {
|
|
748
|
+
const { toolCallId, toolName, argsTextDelta } = chunk;
|
|
749
|
+
if (currentToolCall?.toolCallId === toolCallId) {
|
|
750
|
+
currentToolCall.controller.argsText.append(argsTextDelta);
|
|
751
|
+
} else {
|
|
752
|
+
endCurrentToolCall();
|
|
753
|
+
currentToolCall = {
|
|
754
|
+
toolCallId,
|
|
755
|
+
controller: controller.addToolCallPart({
|
|
756
|
+
toolCallId,
|
|
757
|
+
toolName
|
|
758
|
+
})
|
|
759
|
+
};
|
|
760
|
+
currentToolCall.controller.argsText.append(argsTextDelta);
|
|
761
|
+
}
|
|
762
|
+
break;
|
|
763
|
+
}
|
|
764
|
+
case "tool-call": {
|
|
765
|
+
const { toolCallId, toolName, args } = chunk;
|
|
766
|
+
const toolController = controller.addToolCallPart({
|
|
767
|
+
toolCallId,
|
|
768
|
+
toolName
|
|
769
|
+
});
|
|
770
|
+
toolController.argsText.append(JSON.stringify(args));
|
|
771
|
+
toolController.argsText.close();
|
|
772
|
+
toolController.close();
|
|
773
|
+
break;
|
|
774
|
+
}
|
|
775
|
+
case "finish": {
|
|
776
|
+
controller.enqueue({
|
|
777
|
+
type: "message-finish",
|
|
778
|
+
finishReason: chunk.finishReason,
|
|
779
|
+
usage: chunk.usage,
|
|
780
|
+
path: []
|
|
781
|
+
});
|
|
782
|
+
controller.close();
|
|
783
|
+
break;
|
|
784
|
+
}
|
|
785
|
+
case "error":
|
|
786
|
+
case "response-metadata":
|
|
787
|
+
case "reasoning-signature":
|
|
788
|
+
case "redacted-reasoning":
|
|
789
|
+
break;
|
|
790
|
+
default: {
|
|
791
|
+
const unhandledType = type;
|
|
792
|
+
throw new Error(`Unhandled chunk type: ${unhandledType}`);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
};
|
|
149
799
|
// Annotate the CommonJS export names for ESM import in node:
|
|
150
800
|
0 && (module.exports = {
|
|
801
|
+
LanguageModelV1StreamDecoder,
|
|
151
802
|
fromStreamObject,
|
|
152
803
|
fromStreamText
|
|
153
804
|
});
|