@ai-sdk/google 3.0.67 → 3.0.68
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 +6 -0
- package/dist/index.d.mts +90 -1
- package/dist/index.d.ts +90 -1
- package/dist/index.js +2383 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2353 -1
- package/dist/index.mjs.map +1 -1
- package/docs/15-google-generative-ai.mdx +396 -0
- package/package.json +3 -3
- package/src/google-provider.ts +34 -0
- package/src/index.ts +6 -0
- package/src/interactions/build-google-interactions-stream-transform.ts +711 -0
- package/src/interactions/convert-google-interactions-usage.ts +47 -0
- package/src/interactions/convert-to-google-interactions-input.ts +630 -0
- package/src/interactions/extract-google-interactions-sources.ts +245 -0
- package/src/interactions/google-interactions-agent.ts +16 -0
- package/src/interactions/google-interactions-api.ts +466 -0
- package/src/interactions/google-interactions-language-model-options.ts +136 -0
- package/src/interactions/google-interactions-language-model.ts +609 -0
- package/src/interactions/google-interactions-prompt.ts +457 -0
- package/src/interactions/google-interactions-provider-metadata.ts +23 -0
- package/src/interactions/map-google-interactions-finish-reason.ts +33 -0
- package/src/interactions/parse-google-interactions-outputs.ts +257 -0
- package/src/interactions/poll-google-interactions.ts +110 -0
- package/src/interactions/prepare-google-interactions-tools.ts +245 -0
- package/src/interactions/synthesize-google-interactions-agent-stream.ts +185 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import type { LanguageModelV3Source } from '@ai-sdk/provider';
|
|
2
|
+
import type {
|
|
3
|
+
GoogleInteractionsAnnotation,
|
|
4
|
+
GoogleInteractionsBuiltinToolResultContent,
|
|
5
|
+
GoogleInteractionsFileCitation,
|
|
6
|
+
GoogleInteractionsGoogleMapsResultContent,
|
|
7
|
+
GoogleInteractionsGoogleSearchResultContent,
|
|
8
|
+
GoogleInteractionsPlaceCitation,
|
|
9
|
+
GoogleInteractionsURLCitation,
|
|
10
|
+
GoogleInteractionsURLContextResultContent,
|
|
11
|
+
} from './google-interactions-prompt';
|
|
12
|
+
|
|
13
|
+
const KNOWN_DOC_EXTENSIONS: Record<string, string> = {
|
|
14
|
+
pdf: 'application/pdf',
|
|
15
|
+
txt: 'text/plain',
|
|
16
|
+
md: 'text/markdown',
|
|
17
|
+
markdown: 'text/markdown',
|
|
18
|
+
doc: 'application/msword',
|
|
19
|
+
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function inferDocMediaType(uriOrName: string): string {
|
|
23
|
+
const lower = uriOrName.toLowerCase();
|
|
24
|
+
for (const [ext, media] of Object.entries(KNOWN_DOC_EXTENSIONS)) {
|
|
25
|
+
if (lower.endsWith(`.${ext}`)) return media;
|
|
26
|
+
}
|
|
27
|
+
return 'application/octet-stream';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function basename(uriOrName: string): string | undefined {
|
|
31
|
+
const parts = uriOrName.split('/');
|
|
32
|
+
const last = parts[parts.length - 1];
|
|
33
|
+
return last && last.length > 0 ? last : undefined;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Maps a single text-block annotation (`url_citation` / `file_citation` /
|
|
38
|
+
* `place_citation`) onto a `LanguageModelV3Source`. Returns `undefined` when
|
|
39
|
+
* the annotation lacks the minimum payload to form a source (e.g. a URL
|
|
40
|
+
* citation without a `url`).
|
|
41
|
+
*/
|
|
42
|
+
export function annotationToSource({
|
|
43
|
+
annotation,
|
|
44
|
+
generateId,
|
|
45
|
+
}: {
|
|
46
|
+
annotation: GoogleInteractionsAnnotation | { type: string };
|
|
47
|
+
generateId: () => string;
|
|
48
|
+
}): LanguageModelV3Source | undefined {
|
|
49
|
+
switch (annotation.type) {
|
|
50
|
+
case 'url_citation': {
|
|
51
|
+
const a = annotation as GoogleInteractionsURLCitation;
|
|
52
|
+
if (a.url == null || a.url.length === 0) return undefined;
|
|
53
|
+
return {
|
|
54
|
+
type: 'source',
|
|
55
|
+
sourceType: 'url',
|
|
56
|
+
id: generateId(),
|
|
57
|
+
url: a.url,
|
|
58
|
+
...(a.title != null ? { title: a.title } : {}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
case 'file_citation': {
|
|
62
|
+
const a = annotation as GoogleInteractionsFileCitation;
|
|
63
|
+
const uri = a.document_uri ?? a.source ?? a.file_name;
|
|
64
|
+
if (uri == null || uri.length === 0) return undefined;
|
|
65
|
+
if (uri.startsWith('http://') || uri.startsWith('https://')) {
|
|
66
|
+
return {
|
|
67
|
+
type: 'source',
|
|
68
|
+
sourceType: 'url',
|
|
69
|
+
id: generateId(),
|
|
70
|
+
url: uri,
|
|
71
|
+
...(a.file_name != null ? { title: a.file_name } : {}),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const filename = a.file_name ?? basename(uri);
|
|
75
|
+
const mediaType = inferDocMediaType(uri);
|
|
76
|
+
return {
|
|
77
|
+
type: 'source',
|
|
78
|
+
sourceType: 'document',
|
|
79
|
+
id: generateId(),
|
|
80
|
+
mediaType,
|
|
81
|
+
title: a.file_name ?? filename ?? uri,
|
|
82
|
+
...(filename != null ? { filename } : {}),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
case 'place_citation': {
|
|
86
|
+
const a = annotation as GoogleInteractionsPlaceCitation;
|
|
87
|
+
if (a.url == null || a.url.length === 0) return undefined;
|
|
88
|
+
return {
|
|
89
|
+
type: 'source',
|
|
90
|
+
sourceType: 'url',
|
|
91
|
+
id: generateId(),
|
|
92
|
+
url: a.url,
|
|
93
|
+
...(a.name != null ? { title: a.name } : {}),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
default:
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Maps a built-in tool *result* content block to zero or more
|
|
103
|
+
* `LanguageModelV3Source` parts. The Interactions API exposes grounding
|
|
104
|
+
* sources both inline (via `text_annotation` deltas) and via tool-result
|
|
105
|
+
* content blocks; the latter is what this function consumes.
|
|
106
|
+
*
|
|
107
|
+
* Supported result kinds:
|
|
108
|
+
* - `url_context_result` -> URL sources for each fetched URL with `status: 'success'`
|
|
109
|
+
* - `google_search_result` -> URL sources (when `url` is present), search-suggestion
|
|
110
|
+
* entries are skipped (they are HTML widgets, not citations)
|
|
111
|
+
* - `google_maps_result` -> URL sources for each place with a `url`
|
|
112
|
+
* - `file_search_result` -> document sources (best-effort -- `result[]` is loosely typed)
|
|
113
|
+
*/
|
|
114
|
+
export function builtinToolResultToSources({
|
|
115
|
+
block,
|
|
116
|
+
generateId,
|
|
117
|
+
}: {
|
|
118
|
+
block: GoogleInteractionsBuiltinToolResultContent;
|
|
119
|
+
generateId: () => string;
|
|
120
|
+
}): Array<LanguageModelV3Source> {
|
|
121
|
+
const sources: Array<LanguageModelV3Source> = [];
|
|
122
|
+
|
|
123
|
+
switch (block.type) {
|
|
124
|
+
case 'url_context_result': {
|
|
125
|
+
const result =
|
|
126
|
+
(block as GoogleInteractionsURLContextResultContent).result ?? [];
|
|
127
|
+
for (const entry of result) {
|
|
128
|
+
if (entry?.url == null || entry.url.length === 0) continue;
|
|
129
|
+
if (entry.status != null && entry.status !== 'success') continue;
|
|
130
|
+
sources.push({
|
|
131
|
+
type: 'source',
|
|
132
|
+
sourceType: 'url',
|
|
133
|
+
id: generateId(),
|
|
134
|
+
url: entry.url,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
case 'google_search_result': {
|
|
140
|
+
const result =
|
|
141
|
+
(block as GoogleInteractionsGoogleSearchResultContent).result ?? [];
|
|
142
|
+
for (const entry of result) {
|
|
143
|
+
const url = entry?.url;
|
|
144
|
+
if (url == null || url.length === 0) continue;
|
|
145
|
+
sources.push({
|
|
146
|
+
type: 'source',
|
|
147
|
+
sourceType: 'url',
|
|
148
|
+
id: generateId(),
|
|
149
|
+
url,
|
|
150
|
+
...(entry.title != null ? { title: entry.title } : {}),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case 'google_maps_result': {
|
|
156
|
+
const result =
|
|
157
|
+
(block as GoogleInteractionsGoogleMapsResultContent).result ?? [];
|
|
158
|
+
for (const entry of result) {
|
|
159
|
+
for (const place of entry.places ?? []) {
|
|
160
|
+
if (place.url == null || place.url.length === 0) continue;
|
|
161
|
+
sources.push({
|
|
162
|
+
type: 'source',
|
|
163
|
+
sourceType: 'url',
|
|
164
|
+
id: generateId(),
|
|
165
|
+
url: place.url,
|
|
166
|
+
...(place.name != null ? { title: place.name } : {}),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
case 'file_search_result': {
|
|
173
|
+
const result = (block as { result?: Array<unknown> }).result ?? [];
|
|
174
|
+
for (const raw of result) {
|
|
175
|
+
if (raw == null || typeof raw !== 'object') continue;
|
|
176
|
+
const entry = raw as {
|
|
177
|
+
file_name?: string;
|
|
178
|
+
document_uri?: string;
|
|
179
|
+
source?: string;
|
|
180
|
+
title?: string;
|
|
181
|
+
};
|
|
182
|
+
const uri = entry.document_uri ?? entry.source ?? entry.file_name;
|
|
183
|
+
if (uri == null || uri.length === 0) continue;
|
|
184
|
+
if (uri.startsWith('http://') || uri.startsWith('https://')) {
|
|
185
|
+
sources.push({
|
|
186
|
+
type: 'source',
|
|
187
|
+
sourceType: 'url',
|
|
188
|
+
id: generateId(),
|
|
189
|
+
url: uri,
|
|
190
|
+
...(entry.title != null ? { title: entry.title } : {}),
|
|
191
|
+
});
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
const filename = entry.file_name ?? basename(uri);
|
|
195
|
+
const mediaType = inferDocMediaType(uri);
|
|
196
|
+
sources.push({
|
|
197
|
+
type: 'source',
|
|
198
|
+
sourceType: 'document',
|
|
199
|
+
id: generateId(),
|
|
200
|
+
mediaType,
|
|
201
|
+
title: entry.title ?? entry.file_name ?? filename ?? uri,
|
|
202
|
+
...(filename != null ? { filename } : {}),
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
default:
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return sources;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Given a list of annotations attached to a single `text` content block,
|
|
216
|
+
* returns the corresponding `LanguageModelV3Source` parts (de-duplicated by
|
|
217
|
+
* URL/filename to avoid double-counting when the same citation reappears
|
|
218
|
+
* across deltas).
|
|
219
|
+
*/
|
|
220
|
+
export function annotationsToSources({
|
|
221
|
+
annotations,
|
|
222
|
+
generateId,
|
|
223
|
+
}: {
|
|
224
|
+
annotations:
|
|
225
|
+
| Array<GoogleInteractionsAnnotation | { type: string }>
|
|
226
|
+
| null
|
|
227
|
+
| undefined;
|
|
228
|
+
generateId: () => string;
|
|
229
|
+
}): Array<LanguageModelV3Source> {
|
|
230
|
+
if (annotations == null) return [];
|
|
231
|
+
const seen = new Set<string>();
|
|
232
|
+
const sources: Array<LanguageModelV3Source> = [];
|
|
233
|
+
for (const annotation of annotations) {
|
|
234
|
+
const source = annotationToSource({ annotation, generateId });
|
|
235
|
+
if (source == null) continue;
|
|
236
|
+
const key =
|
|
237
|
+
source.sourceType === 'url'
|
|
238
|
+
? `url:${source.url}`
|
|
239
|
+
: `doc:${source.filename ?? source.title}`;
|
|
240
|
+
if (seen.has(key)) continue;
|
|
241
|
+
seen.add(key);
|
|
242
|
+
sources.push(source);
|
|
243
|
+
}
|
|
244
|
+
return sources;
|
|
245
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-only module: declares the union of supported Gemini Interactions agent
|
|
3
|
+
* names. Used by the `google.interactions({ agent })` factory branch.
|
|
4
|
+
*
|
|
5
|
+
* Sourced from `googleapis/js-genai` `src/interactions/resources/interactions.ts`
|
|
6
|
+
* (`Interaction.agent` enum). Subject to expansion as Google adds new agents.
|
|
7
|
+
*
|
|
8
|
+
* This is a strict string-literal union (no `string` escape hatch) so that
|
|
9
|
+
* passing an unknown agent name is a compile-time error. Add new agents here
|
|
10
|
+
* as Google publishes them.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export type GoogleInteractionsAgentName =
|
|
14
|
+
| 'deep-research-pro-preview-12-2025'
|
|
15
|
+
| 'deep-research-preview-04-2026'
|
|
16
|
+
| 'deep-research-max-preview-04-2026';
|