@ai-sdk/anthropic 4.0.85 → 4.0.87

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/anthropic",
3
- "version": "4.0.85",
3
+ "version": "4.0.87",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -35,8 +35,8 @@
35
35
  }
36
36
  },
37
37
  "dependencies": {
38
- "@ai-sdk/provider": "4.0.31",
39
- "@ai-sdk/provider-utils": "5.0.65"
38
+ "@ai-sdk/provider": "4.0.33",
39
+ "@ai-sdk/provider-utils": "5.0.67"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@ai-sdk/test-server": "2.0.4",
@@ -3203,8 +3203,71 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
3203
3203
  }),
3204
3204
  );
3205
3205
 
3206
+ let hasOutput = false;
3207
+ let hasStreamError = false;
3208
+ let lastFinish:
3209
+ | Extract<LanguageModelV4StreamPart, { type: 'finish' }>
3210
+ | undefined;
3211
+ const streamWithFinishReason = transformedStream.pipeThrough(
3212
+ new TransformStream<LanguageModelV4StreamPart, LanguageModelV4StreamPart>(
3213
+ {
3214
+ transform(chunk, controller) {
3215
+ switch (chunk.type) {
3216
+ case 'response-metadata':
3217
+ hasOutput = false;
3218
+ break;
3219
+ case 'finish':
3220
+ hasOutput = false;
3221
+ lastFinish = chunk;
3222
+ break;
3223
+ case 'error':
3224
+ hasStreamError = true;
3225
+ break;
3226
+ case 'text-delta':
3227
+ case 'reasoning-delta':
3228
+ case 'tool-input-delta':
3229
+ hasOutput ||= chunk.delta.length > 0;
3230
+ break;
3231
+ case 'tool-call':
3232
+ hasOutput = true;
3233
+ break;
3234
+ }
3235
+ controller.enqueue(chunk);
3236
+ },
3237
+ flush(controller) {
3238
+ // Preserve the existing no-output error path. Only partial output
3239
+ // without a finish chunk receives an interrupted finish reason.
3240
+ if (hasOutput && !hasStreamError) {
3241
+ controller.enqueue({
3242
+ type: 'finish',
3243
+ finishReason: { unified: 'interrupted', raw: undefined },
3244
+ // Keep the usage and metadata core already had before the cutoff.
3245
+ usage: lastFinish?.usage ?? {
3246
+ inputTokens: {
3247
+ total: undefined,
3248
+ noCache: undefined,
3249
+ cacheRead: undefined,
3250
+ cacheWrite: undefined,
3251
+ },
3252
+ outputTokens: {
3253
+ total: undefined,
3254
+ text: undefined,
3255
+ reasoning: undefined,
3256
+ },
3257
+ },
3258
+ ...(lastFinish?.providerMetadata != null
3259
+ ? { providerMetadata: lastFinish.providerMetadata }
3260
+ : {}),
3261
+ });
3262
+ }
3263
+ },
3264
+ },
3265
+ ),
3266
+ );
3267
+
3206
3268
  // The first chunk needs to be pulled immediately to check if it is an error
3207
- const [streamForFirstChunk, streamForConsumer] = transformedStream.tee();
3269
+ const [streamForFirstChunk, streamForConsumer] =
3270
+ streamWithFinishReason.tee();
3208
3271
 
3209
3272
  const firstChunkReader = streamForFirstChunk.getReader();
3210
3273
  try {