@ai-sdk/google 4.0.102 → 4.0.103
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/CHANGELOG.md +16 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -5
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +22 -4
- package/dist/internal/index.js.map +1 -1
- package/package.json +3 -3
- package/src/continue-google-stream.ts +11 -3
- package/src/google-language-model.ts +17 -4
- package/src/interactions/build-google-interactions-stream-transform.ts +12 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/google",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.103",
|
|
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.
|
|
39
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
38
|
+
"@ai-sdk/provider": "4.0.32",
|
|
39
|
+
"@ai-sdk/provider-utils": "5.0.66"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@ai-sdk/test-server": "2.0.4",
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { ParseResult } from '@ai-sdk/provider-utils';
|
|
2
2
|
|
|
3
|
+
export type GoogleStreamPart<T> =
|
|
4
|
+
| ParseResult<T>
|
|
5
|
+
| { type: 'continuation-start' };
|
|
6
|
+
|
|
3
7
|
/**
|
|
4
8
|
* Concatenates the event streams of a long decode response that spans several
|
|
5
9
|
* requests (Gemini 4 long decode).
|
|
@@ -7,7 +11,9 @@ import type { ParseResult } from '@ai-sdk/provider-utils';
|
|
|
7
11
|
* Events of the current stream are passed through unchanged. When an event
|
|
8
12
|
* signals that the per-request cap was reached while budget remains
|
|
9
13
|
* (`getContinuationToken` returns a token), the next request is sent with that
|
|
10
|
-
* token once the current stream ends, and its events are appended
|
|
14
|
+
* token once the current stream ends, and its events are appended after a
|
|
15
|
+
* `continuation-start` marker. The marker orders per-response state changes
|
|
16
|
+
* with buffered events, including when the new stream is empty. If the
|
|
11
17
|
* continuation request fails, the error is emitted as a failed parse result
|
|
12
18
|
* and the stream ends.
|
|
13
19
|
*/
|
|
@@ -21,11 +27,11 @@ export function continueGoogleStream<T>({
|
|
|
21
27
|
continueStream: (
|
|
22
28
|
continuationToken: string,
|
|
23
29
|
) => Promise<ReadableStream<ParseResult<T>>>;
|
|
24
|
-
}): ReadableStream<
|
|
30
|
+
}): ReadableStream<GoogleStreamPart<T>> {
|
|
25
31
|
let reader = stream.getReader();
|
|
26
32
|
let pendingContinuationToken: string | undefined;
|
|
27
33
|
|
|
28
|
-
return new ReadableStream<
|
|
34
|
+
return new ReadableStream<GoogleStreamPart<T>>({
|
|
29
35
|
async pull(controller) {
|
|
30
36
|
while (true) {
|
|
31
37
|
const { done, value } = await reader.read();
|
|
@@ -51,6 +57,8 @@ export function continueGoogleStream<T>({
|
|
|
51
57
|
|
|
52
58
|
try {
|
|
53
59
|
reader = (await continueStream(continuationToken)).getReader();
|
|
60
|
+
controller.enqueue({ type: 'continuation-start' });
|
|
61
|
+
return;
|
|
54
62
|
} catch (error) {
|
|
55
63
|
// Surfaced as an `error` stream part, followed by the `finish` part
|
|
56
64
|
// with the last continuation token so the caller can resume.
|
|
@@ -33,11 +33,13 @@ import {
|
|
|
33
33
|
zodSchema,
|
|
34
34
|
type FetchFunction,
|
|
35
35
|
type InferSchema,
|
|
36
|
-
type ParseResult,
|
|
37
36
|
type Resolvable,
|
|
38
37
|
} from '@ai-sdk/provider-utils';
|
|
39
38
|
import { z } from 'zod/v4';
|
|
40
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
continueGoogleStream,
|
|
41
|
+
type GoogleStreamPart,
|
|
42
|
+
} from './continue-google-stream';
|
|
41
43
|
import {
|
|
42
44
|
addGoogleUsageMetadata,
|
|
43
45
|
convertGoogleUsage,
|
|
@@ -926,8 +928,9 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
926
928
|
},
|
|
927
929
|
});
|
|
928
930
|
|
|
931
|
+
// A clean end without the provider's completion signal is interrupted.
|
|
929
932
|
let finishReason: LanguageModelV4FinishReason = {
|
|
930
|
-
unified: '
|
|
933
|
+
unified: 'interrupted',
|
|
931
934
|
raw: undefined,
|
|
932
935
|
};
|
|
933
936
|
let usage: GoogleUsageMetadata | undefined = undefined;
|
|
@@ -1005,7 +1008,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
1005
1008
|
const result = {
|
|
1006
1009
|
stream: response.pipeThrough(
|
|
1007
1010
|
new TransformStream<
|
|
1008
|
-
|
|
1011
|
+
GoogleStreamPart<ChunkSchema>,
|
|
1009
1012
|
LanguageModelV4StreamPart
|
|
1010
1013
|
>({
|
|
1011
1014
|
start(controller) {
|
|
@@ -1013,11 +1016,21 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
1013
1016
|
},
|
|
1014
1017
|
|
|
1015
1018
|
transform(chunk, controller) {
|
|
1019
|
+
if ('type' in chunk) {
|
|
1020
|
+
// Reset in stream order, after the prior response's buffered
|
|
1021
|
+
// CONTINUATION chunk, rather than when the request starts.
|
|
1022
|
+
finishReason = { unified: 'interrupted', raw: undefined };
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1016
1026
|
if (options.includeRawChunks) {
|
|
1017
1027
|
controller.enqueue({ type: 'raw', rawValue: chunk.rawValue });
|
|
1018
1028
|
}
|
|
1019
1029
|
|
|
1020
1030
|
if (!chunk.success) {
|
|
1031
|
+
if (finishReason.unified === 'interrupted') {
|
|
1032
|
+
finishReason = { unified: 'error', raw: undefined };
|
|
1033
|
+
}
|
|
1021
1034
|
controller.enqueue({ type: 'error', error: chunk.error });
|
|
1022
1035
|
return;
|
|
1023
1036
|
}
|
|
@@ -152,6 +152,7 @@ export function buildGoogleInteractionsStreamTransform({
|
|
|
152
152
|
let serviceTier: string | undefined = headerServiceTier;
|
|
153
153
|
let finishStatus: GoogleInteractionsStatus | string | undefined;
|
|
154
154
|
let hasFunctionCall = false;
|
|
155
|
+
let hasCompletionEvent = false;
|
|
155
156
|
|
|
156
157
|
/*
|
|
157
158
|
* Per-index open step slots. The Interactions API frames concurrent steps
|
|
@@ -838,6 +839,7 @@ export function buildGoogleInteractionsStreamTransform({
|
|
|
838
839
|
}
|
|
839
840
|
|
|
840
841
|
case 'interaction.completed': {
|
|
842
|
+
hasCompletionEvent = true;
|
|
841
843
|
const event = value as Extract<
|
|
842
844
|
GoogleInteractionsEvent,
|
|
843
845
|
{ event_type: 'interaction.completed' }
|
|
@@ -893,12 +895,17 @@ export function buildGoogleInteractionsStreamTransform({
|
|
|
893
895
|
},
|
|
894
896
|
|
|
895
897
|
flush(controller) {
|
|
898
|
+
const isInterrupted =
|
|
899
|
+
!hasCompletionEvent &&
|
|
900
|
+
(finishStatus == null || finishStatus === 'in_progress');
|
|
896
901
|
const finishReason: LanguageModelV4FinishReason = {
|
|
897
|
-
unified:
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
+
unified: isInterrupted
|
|
903
|
+
? 'interrupted'
|
|
904
|
+
: mapGoogleInteractionsFinishReason({
|
|
905
|
+
status: finishStatus,
|
|
906
|
+
hasFunctionCall,
|
|
907
|
+
}),
|
|
908
|
+
raw: isInterrupted ? undefined : finishStatus,
|
|
902
909
|
};
|
|
903
910
|
|
|
904
911
|
const outputTokensByModality =
|