@terminaluse/vercel-ai-sdk-provider 0.4.0 → 0.4.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.
Files changed (2) hide show
  1. package/dist/index.mjs +121 -62
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -196,6 +196,8 @@ function createTerminalUseTransformStream(config, taskId, signal, arg4, arg5) {
196
196
  streamHeaders: streamOverride?.streamHeaders
197
197
  });
198
198
  let emittedStreamStart = false;
199
+ const pendingParts = [];
200
+ const trackedParts = createStreamedPartTracker();
199
201
  return new ReadableStream({
200
202
  async pull(controller) {
201
203
  if (!emittedStreamStart) {
@@ -206,6 +208,13 @@ function createTerminalUseTransformStream(config, taskId, signal, arg4, arg5) {
206
208
  });
207
209
  return;
208
210
  }
211
+ if (pendingParts.length > 0) {
212
+ const pendingPart = pendingParts.shift();
213
+ if (pendingPart) {
214
+ controller.enqueue(pendingPart);
215
+ return;
216
+ }
217
+ }
209
218
  try {
210
219
  while (true) {
211
220
  const { value, done } = await eventGenerator.next();
@@ -214,14 +223,16 @@ function createTerminalUseTransformStream(config, taskId, signal, arg4, arg5) {
214
223
  return;
215
224
  }
216
225
  const event = value;
217
- const transformed = transformEvent(event, taskId);
226
+ const transformedParts = transformEvent(event, taskId, trackedParts);
218
227
  if (shouldCloseStream(event, closeConfig)) {
219
- if (transformed) controller.enqueue(transformed);
228
+ for (const part of transformedParts) controller.enqueue(part);
220
229
  controller.close();
221
230
  return;
222
231
  }
223
- if (transformed) {
224
- controller.enqueue(transformed);
232
+ if (transformedParts.length > 0) {
233
+ const [firstPart, ...restParts] = transformedParts;
234
+ controller.enqueue(firstPart);
235
+ if (restParts.length > 0) pendingParts.push(...restParts);
225
236
  return;
226
237
  }
227
238
  }
@@ -237,19 +248,19 @@ function createTerminalUseTransformStream(config, taskId, signal, arg4, arg5) {
237
248
  }
238
249
  /**
239
250
  * Transforms a single v2 TextStreamPart event to AI SDK v3 LanguageModelV3StreamPart.
240
- * Returns null for events that should be skipped (e.g., finish-step, start).
251
+ * Returns an array to support synthesizing start parts for orphan deltas.
241
252
  */
242
- function transformEvent(event, taskId) {
253
+ function transformEvent(event, taskId, trackedParts) {
243
254
  switch (event.type) {
244
- case "start": return null;
245
- case "start-step": return {
255
+ case "start": return [];
256
+ case "start-step": return [{
246
257
  type: "response-metadata",
247
258
  id: taskId,
248
259
  timestamp: /* @__PURE__ */ new Date(),
249
260
  modelId: "terminaluse-agent"
250
- };
251
- case "finish-step": return null;
252
- case "finish": return {
261
+ }];
262
+ case "finish-step": return [];
263
+ case "finish": return [{
253
264
  type: "finish",
254
265
  finishReason: {
255
266
  unified: event.finishReason,
@@ -268,74 +279,122 @@ function transformEvent(event, taskId) {
268
279
  reasoning: void 0
269
280
  }
270
281
  }
271
- };
272
- case "handler-complete": return null;
273
- case "text-start": return {
274
- type: "text-start",
275
- id: event.id
276
- };
277
- case "text-delta": return {
278
- type: "text-delta",
279
- id: event.id,
280
- delta: event.text
281
- };
282
- case "text-end": return {
283
- type: "text-end",
284
- id: event.id
285
- };
286
- case "reasoning-start": return {
287
- type: "reasoning-start",
288
- id: event.id
289
- };
290
- case "reasoning-delta": return {
291
- type: "reasoning-delta",
292
- id: event.id,
293
- delta: event.text
294
- };
295
- case "reasoning-end": return {
296
- type: "reasoning-end",
297
- id: event.id
298
- };
299
- case "tool-input-start": return {
300
- type: "tool-input-start",
301
- id: event.id,
302
- toolName: event.toolName,
303
- providerExecuted: true,
304
- dynamic: true
305
- };
306
- case "tool-input-delta": return {
307
- type: "tool-input-delta",
308
- id: event.id,
309
- delta: event.delta
310
- };
311
- case "tool-input-end": return {
312
- type: "tool-input-end",
313
- id: event.id
314
- };
315
- case "tool-call": return {
282
+ }];
283
+ case "handler-complete": return [];
284
+ case "text-start":
285
+ if (trackedParts.text.open.has(event.id)) return [];
286
+ trackedParts.text.open.add(event.id);
287
+ return [{
288
+ type: "text-start",
289
+ id: event.id
290
+ }];
291
+ case "text-delta": {
292
+ const deltaPart = {
293
+ type: "text-delta",
294
+ id: event.id,
295
+ delta: event.text
296
+ };
297
+ if (trackedParts.text.open.has(event.id)) return [deltaPart];
298
+ if (trackedParts.text.open.size > 0) return [];
299
+ trackedParts.text.open.add(event.id);
300
+ return [{
301
+ type: "text-start",
302
+ id: event.id
303
+ }, deltaPart];
304
+ }
305
+ case "text-end":
306
+ if (!trackedParts.text.open.has(event.id)) return [];
307
+ trackedParts.text.open.delete(event.id);
308
+ return [{
309
+ type: "text-end",
310
+ id: event.id
311
+ }];
312
+ case "reasoning-start":
313
+ if (trackedParts.reasoning.open.has(event.id)) return [];
314
+ trackedParts.reasoning.open.add(event.id);
315
+ return [{
316
+ type: "reasoning-start",
317
+ id: event.id
318
+ }];
319
+ case "reasoning-delta": {
320
+ const deltaPart = {
321
+ type: "reasoning-delta",
322
+ id: event.id,
323
+ delta: event.text
324
+ };
325
+ if (trackedParts.reasoning.open.has(event.id)) return [deltaPart];
326
+ if (trackedParts.reasoning.open.size > 0) return [];
327
+ trackedParts.reasoning.open.add(event.id);
328
+ return [{
329
+ type: "reasoning-start",
330
+ id: event.id
331
+ }, deltaPart];
332
+ }
333
+ case "reasoning-end":
334
+ if (!trackedParts.reasoning.open.has(event.id)) return [];
335
+ trackedParts.reasoning.open.delete(event.id);
336
+ return [{
337
+ type: "reasoning-end",
338
+ id: event.id
339
+ }];
340
+ case "tool-input-start":
341
+ if (trackedParts.toolInput.open.has(event.id)) return [];
342
+ trackedParts.toolInput.open.add(event.id);
343
+ return [{
344
+ type: "tool-input-start",
345
+ id: event.id,
346
+ toolName: event.toolName,
347
+ providerExecuted: true,
348
+ dynamic: true
349
+ }];
350
+ case "tool-input-delta":
351
+ if (!trackedParts.toolInput.open.has(event.id)) return [];
352
+ return [{
353
+ type: "tool-input-delta",
354
+ id: event.id,
355
+ delta: event.delta
356
+ }];
357
+ case "tool-input-end":
358
+ if (!trackedParts.toolInput.open.has(event.id)) return [];
359
+ trackedParts.toolInput.open.delete(event.id);
360
+ return [{
361
+ type: "tool-input-end",
362
+ id: event.id
363
+ }];
364
+ case "tool-call": return [{
316
365
  type: "tool-call",
317
366
  toolCallId: event.toolCallId,
318
367
  toolName: event.toolName,
319
368
  input: JSON.stringify(event.input),
320
369
  providerExecuted: true,
321
370
  dynamic: true
322
- };
371
+ }];
323
372
  case "tool-result": {
324
373
  const result = event.output ?? "";
325
- return {
374
+ return [{
326
375
  type: "tool-result",
327
376
  toolCallId: event.toolCallId,
328
377
  toolName: event.toolName,
329
378
  result
330
- };
379
+ }];
331
380
  }
332
- case "error": return {
381
+ case "error": return [{
333
382
  type: "error",
334
383
  error: event.error
335
- };
336
- default: return null;
384
+ }];
385
+ default: return [];
337
386
  }
338
387
  }
388
+ function createStreamedPartTracker() {
389
+ return {
390
+ text: createSegmentTracker(),
391
+ reasoning: createSegmentTracker(),
392
+ toolInput: createSegmentTracker()
393
+ };
394
+ }
395
+ function createSegmentTracker() {
396
+ return { open: /* @__PURE__ */ new Set() };
397
+ }
339
398
  function shouldCloseStream(event, closeConfig) {
340
399
  if (event.type === "error") return true;
341
400
  if (closeConfig.closeMode === "legacy") return event.type === "finish";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@terminaluse/vercel-ai-sdk-provider",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Vercel AI SDK provider for TerminalUse agents",
5
5
  "repository": {
6
6
  "type": "git",