@ai-sdk/google 3.0.122 → 3.0.124

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/google",
3
- "version": "3.0.122",
3
+ "version": "3.0.124",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -392,10 +392,15 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
392
392
 
393
393
  const candidate = response.candidates?.[0];
394
394
  const promptBlockReason = response.promptFeedback?.blockReason;
395
+ const confirmedPromptBlockReason = isConfirmedPromptBlockReason(
396
+ promptBlockReason,
397
+ )
398
+ ? promptBlockReason
399
+ : undefined;
395
400
  const isPromptBlocked =
396
- candidate?.finishReason == null && promptBlockReason != null;
401
+ candidate?.finishReason == null && confirmedPromptBlockReason != null;
397
402
  const rawFinishReason =
398
- candidate?.finishReason ?? promptBlockReason ?? undefined;
403
+ candidate?.finishReason ?? confirmedPromptBlockReason;
399
404
  const content: Array<LanguageModelV3Content> = [];
400
405
 
401
406
  // map ordered parts to content:
@@ -615,9 +620,12 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
615
620
  raw: undefined,
616
621
  };
617
622
  let usage: GoogleGenerativeAIUsageMetadata | undefined = undefined;
618
- let providerMetadata: SharedV3ProviderMetadata | undefined = undefined;
623
+ let promptFeedback: PromptFeedbackSchema | null = null;
619
624
  let lastGroundingMetadata: GroundingMetadataSchema | null = null;
620
625
  let lastUrlContextMetadata: UrlContextMetadataSchema | null = null;
626
+ let lastSafetyRatings: SafetyRatingSchema[] | null = null;
627
+ let lastFinishMessage: string | null = null;
628
+ let confirmedPromptBlockReason: string | undefined;
621
629
 
622
630
  const generateId = this.config.generateId;
623
631
  let hasToolCalls = false;
@@ -714,40 +722,48 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
714
722
  usage = usageMetadata;
715
723
  }
716
724
 
717
- const candidate = value.candidates?.[0];
725
+ if (
726
+ value.promptFeedback != null &&
727
+ confirmedPromptBlockReason == null
728
+ ) {
729
+ promptFeedback = value.promptFeedback;
718
730
 
719
- // sometimes the API returns an empty candidates array
720
- if (candidate == null) {
721
- const promptBlockReason = value.promptFeedback?.blockReason;
722
- if (promptBlockReason != null) {
731
+ if (
732
+ isConfirmedPromptBlockReason(value.promptFeedback.blockReason)
733
+ ) {
734
+ confirmedPromptBlockReason = value.promptFeedback.blockReason;
723
735
  finishReason = {
724
736
  unified: 'content-filter',
725
- raw: promptBlockReason,
726
- };
727
- providerMetadata = {
728
- [providerOptionsName]: {
729
- promptFeedback: value.promptFeedback ?? null,
730
- groundingMetadata: lastGroundingMetadata,
731
- urlContextMetadata: lastUrlContextMetadata,
732
- safetyRatings: null,
733
- usageMetadata: usageMetadata ?? null,
734
- finishMessage: null,
735
- serviceTier: usage?.serviceTier ?? null,
736
- } satisfies GoogleGenerativeAIProviderMetadata,
737
+ raw: confirmedPromptBlockReason,
737
738
  };
738
739
  }
739
- return;
740
740
  }
741
741
 
742
- const content = candidate.content;
742
+ const candidate = value.candidates?.[0];
743
743
 
744
- if (candidate.groundingMetadata != null) {
745
- lastGroundingMetadata = candidate.groundingMetadata;
744
+ if (candidate != null) {
745
+ if (candidate.groundingMetadata != null) {
746
+ lastGroundingMetadata = candidate.groundingMetadata;
747
+ }
748
+ if (candidate.urlContextMetadata != null) {
749
+ lastUrlContextMetadata = candidate.urlContextMetadata;
750
+ }
751
+ if (candidate.safetyRatings != null) {
752
+ lastSafetyRatings = candidate.safetyRatings;
753
+ }
754
+ if (candidate.finishMessage != null) {
755
+ lastFinishMessage = candidate.finishMessage;
756
+ }
746
757
  }
747
- if (candidate.urlContextMetadata != null) {
748
- lastUrlContextMetadata = candidate.urlContextMetadata;
758
+
759
+ // A confirmed prompt block is terminal for generated content, but
760
+ // later chunks can still contribute usage and provider metadata.
761
+ if (confirmedPromptBlockReason != null || candidate == null) {
762
+ return;
749
763
  }
750
764
 
765
+ const content = candidate.content;
766
+
751
767
  const sources = extractSources({
752
768
  groundingMetadata: candidate.groundingMetadata,
753
769
  generateId,
@@ -1125,33 +1141,13 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
1125
1141
  }
1126
1142
  }
1127
1143
 
1128
- const promptBlockReason = value.promptFeedback?.blockReason;
1129
- const isPromptBlocked =
1130
- candidate.finishReason == null && promptBlockReason != null;
1131
- const rawFinishReason =
1132
- candidate.finishReason ?? promptBlockReason ?? undefined;
1133
-
1134
- if (rawFinishReason != null) {
1144
+ if (candidate.finishReason != null) {
1135
1145
  finishReason = {
1136
- unified: isPromptBlocked
1137
- ? 'content-filter'
1138
- : mapGoogleGenerativeAIFinishReason({
1139
- finishReason: rawFinishReason,
1140
- hasToolCalls,
1141
- }),
1142
- raw: rawFinishReason,
1143
- };
1144
-
1145
- providerMetadata = {
1146
- [providerOptionsName]: {
1147
- promptFeedback: value.promptFeedback ?? null,
1148
- groundingMetadata: lastGroundingMetadata,
1149
- urlContextMetadata: lastUrlContextMetadata,
1150
- safetyRatings: candidate.safetyRatings ?? null,
1151
- usageMetadata: usageMetadata ?? null,
1152
- finishMessage: candidate.finishMessage ?? null,
1153
- serviceTier: usage?.serviceTier ?? null,
1154
- } satisfies GoogleGenerativeAIProviderMetadata,
1146
+ unified: mapGoogleGenerativeAIFinishReason({
1147
+ finishReason: candidate.finishReason,
1148
+ hasToolCalls,
1149
+ }),
1150
+ raw: candidate.finishReason,
1155
1151
  };
1156
1152
  }
1157
1153
  },
@@ -1174,7 +1170,17 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
1174
1170
  type: 'finish',
1175
1171
  finishReason,
1176
1172
  usage: convertGoogleGenerativeAIUsage(usage),
1177
- providerMetadata,
1173
+ providerMetadata: {
1174
+ [providerOptionsName]: {
1175
+ promptFeedback,
1176
+ groundingMetadata: lastGroundingMetadata,
1177
+ urlContextMetadata: lastUrlContextMetadata,
1178
+ safetyRatings: lastSafetyRatings,
1179
+ usageMetadata: usage ?? null,
1180
+ finishMessage: lastFinishMessage,
1181
+ serviceTier: usage?.serviceTier ?? null,
1182
+ } satisfies GoogleGenerativeAIProviderMetadata,
1183
+ },
1178
1184
  });
1179
1185
  },
1180
1186
  }),
@@ -1609,3 +1615,14 @@ const chunkSchema = lazySchema(() =>
1609
1615
  );
1610
1616
 
1611
1617
  type ChunkSchema = InferSchema<typeof chunkSchema>;
1618
+
1619
+ function isConfirmedPromptBlockReason(
1620
+ blockReason: string | null | undefined,
1621
+ ): blockReason is string {
1622
+ return (
1623
+ blockReason != null &&
1624
+ blockReason !== '' &&
1625
+ blockReason !== 'BLOCK_REASON_UNSPECIFIED' &&
1626
+ blockReason !== 'BLOCKED_REASON_UNSPECIFIED'
1627
+ );
1628
+ }