@warlock.js/ai-google 5.31.0 → 5.33.0
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 +20 -0
- package/cjs/index.cjs +85 -8
- package/cjs/index.cjs.map +1 -1
- package/esm/config.type.d.mts +4 -6
- package/esm/config.type.d.mts.map +1 -1
- package/esm/gemini-image.d.mts +1 -3
- package/esm/gemini-image.d.mts.map +1 -1
- package/esm/gemini-image.mjs +1 -1
- package/esm/gemini-image.mjs.map +1 -1
- package/esm/image.d.mts +1 -3
- package/esm/image.d.mts.map +1 -1
- package/esm/index.d.mts +2 -2
- package/esm/index.mjs +2 -2
- package/esm/known-pricing.d.mts +8 -4
- package/esm/known-pricing.d.mts.map +1 -1
- package/esm/known-pricing.mjs +5 -1
- package/esm/known-pricing.mjs.map +1 -1
- package/esm/model.mjs +51 -6
- package/esm/model.mjs.map +1 -1
- package/esm/provider-options.d.mts +2 -2
- package/esm/provider-options.d.mts.map +1 -1
- package/esm/provider-options.mjs +1 -1
- package/esm/provider-options.mjs.map +1 -1
- package/esm/sdk.d.mts +1 -3
- package/esm/sdk.d.mts.map +1 -1
- package/esm/utils/grounding.mjs +30 -0
- package/esm/utils/grounding.mjs.map +1 -0
- package/esm/utils/index.mjs +1 -1
- package/llms-full.txt +60 -11
- package/package.json +3 -3
- package/skills/setup-google/SKILL.md +60 -11
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,26 @@ All notable changes to `@warlock.js/ai-google` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
|
|
6
6
|
|
|
7
|
+
## 5.33.0 - 2026-10-19
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Lockstep release; package APIs are unchanged.
|
|
12
|
+
|
|
13
|
+
## 5.32.0 - 2026-10-18
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Pin the package development compiler to TypeScript 7.0.2 and use explicit Node types and source roots with supported module resolution.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Gemini Developer API token counting sends the full `generateContentRequest`, including system instructions, tools and generation settings, through the existing SDK transport with cancellation and error mapping. Vertex counting is unchanged; unsupported cached-content counts carry the typed signal used by `countInputTokens` to estimate.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Preserve raw candidate grounding metadata and normalize unique nonempty search queries in completions and streams. Export opt-in Gemini 3+ request prices as `GOOGLE_SERVER_TOOL_PRICING`; document older models’ per-prompt billing.
|
|
26
|
+
|
|
7
27
|
## 5.31.0 - 2026-10-18
|
|
8
28
|
|
|
9
29
|
### Fixed
|
package/cjs/index.cjs
CHANGED
|
@@ -499,7 +499,7 @@ const DEFAULT_RESPONSE_MODALITIES = ["TEXT", "IMAGE"];
|
|
|
499
499
|
* or image generation being "stopped" for safety, prohibited content,
|
|
500
500
|
* recitation, blocklist, or SPII.
|
|
501
501
|
*/
|
|
502
|
-
const FILTERED_FINISH_REASONS = new Set([
|
|
502
|
+
const FILTERED_FINISH_REASONS = /* @__PURE__ */ new Set([
|
|
503
503
|
"SAFETY",
|
|
504
504
|
"IMAGE_SAFETY",
|
|
505
505
|
"PROHIBITED_CONTENT",
|
|
@@ -832,10 +832,42 @@ const GOOGLE_MODEL_PRICING = { "gemini-3.5-flash-lite": {
|
|
|
832
832
|
function googlePricingFor(modelName) {
|
|
833
833
|
return GOOGLE_MODEL_PRICING[modelName];
|
|
834
834
|
}
|
|
835
|
+
/** USD per nonempty unique query for Gemini 3+, before free monthly allowances.
|
|
836
|
+
* Gemini 2.5 and older bill per grounded prompt; do not use this rate for them.
|
|
837
|
+
* https://ai.google.dev/gemini-api/docs/google-search#pricing — verified 2026-10-18. */
|
|
838
|
+
const GOOGLE_SERVER_TOOL_PRICING = { webSearch: .014 };
|
|
839
|
+
|
|
840
|
+
//#endregion
|
|
841
|
+
//#region ../../packages/ai-google/src/utils/grounding.ts
|
|
842
|
+
/** Candidate snapshots are replaced, not added: streamed metadata may repeat.
|
|
843
|
+
* Installed @google/genai 2.19.0 GroundingMetadata.webSearchQueries; REST schema:
|
|
844
|
+
* https://ai.google.dev/api/generate-content#GroundingMetadata
|
|
845
|
+
* Billing ignores empty queries and counts unique queries for Gemini 3+:
|
|
846
|
+
* https://ai.google.dev/gemini-api/docs/google-search#pricing
|
|
847
|
+
* Gemini 2.5 and older bill per grounded prompt; this counter is NOT that unit. */
|
|
848
|
+
function applyGrounding(usage, snapshots, response) {
|
|
849
|
+
for (const [position, candidate] of (response.candidates ?? []).entries()) if (candidate.groundingMetadata) snapshots.set(candidate.index ?? position, candidate.groundingMetadata);
|
|
850
|
+
const reported = [...snapshots.values()].filter((metadata) => metadata.webSearchQueries !== void 0);
|
|
851
|
+
if (reported.length > 0) {
|
|
852
|
+
const queries = reported.flatMap((metadata) => metadata.webSearchQueries ?? []);
|
|
853
|
+
usage.serverToolUse = {
|
|
854
|
+
...usage.serverToolUse,
|
|
855
|
+
webSearchRequests: new Set(queries.filter((query) => query !== "")).size,
|
|
856
|
+
googleWebSearchQueries: queries.length
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
/** Retain chunks, supports, search entry point and queries without flattening them. */
|
|
861
|
+
function groundingMetadata(snapshots) {
|
|
862
|
+
return snapshots.size ? { google: { groundingMetadata: [...snapshots].map(([index, metadata]) => ({
|
|
863
|
+
index,
|
|
864
|
+
...metadata
|
|
865
|
+
})) } } : void 0;
|
|
866
|
+
}
|
|
835
867
|
|
|
836
868
|
//#endregion
|
|
837
869
|
//#region ../../packages/ai-google/src/provider-options.ts
|
|
838
|
-
const RESERVED_FIELDS = new Set([
|
|
870
|
+
const RESERVED_FIELDS = /* @__PURE__ */ new Set([
|
|
839
871
|
"systemInstruction",
|
|
840
872
|
"tools",
|
|
841
873
|
"abortSignal",
|
|
@@ -1000,12 +1032,17 @@ var GoogleModel = class {
|
|
|
1000
1032
|
}
|
|
1001
1033
|
const toolCalls = this.extractToolCalls(response);
|
|
1002
1034
|
const finishReason = toolCalls ? "tool_calls" : mapFinishReason(response.candidates?.[0]?.finishReason);
|
|
1003
|
-
const usage =
|
|
1035
|
+
const usage = this.extractUsage(response);
|
|
1036
|
+
const grounding = /* @__PURE__ */ new Map();
|
|
1037
|
+
applyGrounding(usage, grounding, response);
|
|
1038
|
+
const providerMetadata = groundingMetadata(grounding);
|
|
1039
|
+
(0, _warlock_js_ai.attachCost)(usage, this.pricing);
|
|
1004
1040
|
this.logger.debug(LOG_MODULE, "response", "generateContent call succeeded", {
|
|
1005
1041
|
finishReason,
|
|
1006
1042
|
usage
|
|
1007
1043
|
});
|
|
1008
1044
|
return {
|
|
1045
|
+
...providerMetadata ? { providerMetadata } : {},
|
|
1009
1046
|
content: response.text ?? "",
|
|
1010
1047
|
finishReason,
|
|
1011
1048
|
usage,
|
|
@@ -1016,10 +1053,9 @@ var GoogleModel = class {
|
|
|
1016
1053
|
async countTokens(messages, options) {
|
|
1017
1054
|
const { systemInstruction, contents } = toGoogleContents(messages);
|
|
1018
1055
|
const config = this.buildConfig(systemInstruction, options);
|
|
1019
|
-
if (
|
|
1020
|
-
if (config.cachedContent !== void 0) throw new _warlock_js_ai.InvalidRequestError("The Google SDK countTokens endpoint cannot count a cachedContent reference.");
|
|
1056
|
+
if (config.cachedContent !== void 0) throw new _warlock_js_ai.InvalidRequestError("The Google SDK countTokens endpoint cannot count a cachedContent reference.", { reason: "count-unsupported" });
|
|
1021
1057
|
try {
|
|
1022
|
-
const response = await this.ai.models.countTokens({
|
|
1058
|
+
const response = this.ai.vertexai ? await this.ai.models.countTokens({
|
|
1023
1059
|
model: this.name,
|
|
1024
1060
|
contents,
|
|
1025
1061
|
config: {
|
|
@@ -1028,7 +1064,7 @@ var GoogleModel = class {
|
|
|
1028
1064
|
...config.abortSignal ? { abortSignal: config.abortSignal } : {},
|
|
1029
1065
|
...config.httpOptions ? { httpOptions: config.httpOptions } : {}
|
|
1030
1066
|
}
|
|
1031
|
-
});
|
|
1067
|
+
}) : await this.countDeveloperTokens(contents, config);
|
|
1032
1068
|
if (response.totalTokens === void 0) throw new _warlock_js_ai.InvalidRequestError("Google countTokens returned no totalTokens.");
|
|
1033
1069
|
return response.totalTokens;
|
|
1034
1070
|
} catch (thrown) {
|
|
@@ -1036,6 +1072,42 @@ var GoogleModel = class {
|
|
|
1036
1072
|
}
|
|
1037
1073
|
}
|
|
1038
1074
|
/**
|
|
1075
|
+
* REST counts the full generation request, unlike the typed Developer API
|
|
1076
|
+
* converter in @google/genai 2.19.0. See https://ai.google.dev/api/tokens.
|
|
1077
|
+
* extraBody keeps the SDK's auth, fetch, base URL, retries and cancellation.
|
|
1078
|
+
*/
|
|
1079
|
+
countDeveloperTokens(contents, config) {
|
|
1080
|
+
config.abortSignal?.throwIfAborted();
|
|
1081
|
+
const { systemInstruction, serviceTier, tools, toolConfig, safetySettings, cachedContent, abortSignal, httpOptions, ...generationConfig } = config;
|
|
1082
|
+
delete generationConfig.automaticFunctionCalling;
|
|
1083
|
+
const model = this.name.startsWith("models/") ? this.name : `models/${this.name}`;
|
|
1084
|
+
return this.ai.models.countTokens({
|
|
1085
|
+
model: this.name,
|
|
1086
|
+
contents,
|
|
1087
|
+
config: {
|
|
1088
|
+
abortSignal,
|
|
1089
|
+
httpOptions: {
|
|
1090
|
+
...httpOptions,
|
|
1091
|
+
extraBody: {
|
|
1092
|
+
...httpOptions?.extraBody,
|
|
1093
|
+
contents: void 0,
|
|
1094
|
+
generateContentRequest: {
|
|
1095
|
+
model,
|
|
1096
|
+
contents,
|
|
1097
|
+
...serviceTier !== void 0 ? { serviceTier } : {},
|
|
1098
|
+
...systemInstruction !== void 0 ? { systemInstruction: { parts: [{ text: systemInstruction }] } } : {},
|
|
1099
|
+
...tools !== void 0 ? { tools } : {},
|
|
1100
|
+
...toolConfig !== void 0 ? { toolConfig } : {},
|
|
1101
|
+
...safetySettings !== void 0 ? { safetySettings } : {},
|
|
1102
|
+
...cachedContent !== void 0 ? { cachedContent } : {},
|
|
1103
|
+
...Object.keys(generationConfig).length > 0 ? { generationConfig } : {}
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1039
1111
|
* Incremental streaming completion via `generateContentStream`.
|
|
1040
1112
|
* Yields neutral `ModelStreamChunk`s — `delta` for text, `tool-call`
|
|
1041
1113
|
* per function call (Gemini emits a fully-formed call, not partial
|
|
@@ -1072,8 +1144,10 @@ var GoogleModel = class {
|
|
|
1072
1144
|
total: 0
|
|
1073
1145
|
};
|
|
1074
1146
|
const want = (0, _warlock_js_ai.resolveStreamChunks)(options);
|
|
1147
|
+
const grounding = /* @__PURE__ */ new Map();
|
|
1075
1148
|
try {
|
|
1076
1149
|
for await (const chunk of iterable) {
|
|
1150
|
+
applyGrounding(usage, grounding, chunk);
|
|
1077
1151
|
if (want.reasoning) {
|
|
1078
1152
|
for (const part of chunk.candidates?.[0]?.content?.parts ?? []) if (part.thought === true && typeof part.text === "string" && part.text !== "") yield {
|
|
1079
1153
|
type: "reasoning",
|
|
@@ -1116,10 +1190,12 @@ var GoogleModel = class {
|
|
|
1116
1190
|
finishReason,
|
|
1117
1191
|
usage
|
|
1118
1192
|
});
|
|
1193
|
+
const providerMetadata = groundingMetadata(grounding);
|
|
1119
1194
|
yield {
|
|
1120
1195
|
type: "done",
|
|
1121
1196
|
finishReason,
|
|
1122
|
-
usage
|
|
1197
|
+
usage,
|
|
1198
|
+
...providerMetadata ? { providerMetadata } : {}
|
|
1123
1199
|
};
|
|
1124
1200
|
}
|
|
1125
1201
|
/**
|
|
@@ -1393,6 +1469,7 @@ var GoogleSDK = class {
|
|
|
1393
1469
|
|
|
1394
1470
|
//#endregion
|
|
1395
1471
|
exports.GOOGLE_MODEL_PRICING = GOOGLE_MODEL_PRICING;
|
|
1472
|
+
exports.GOOGLE_SERVER_TOOL_PRICING = GOOGLE_SERVER_TOOL_PRICING;
|
|
1396
1473
|
exports.GeminiImageModel = GeminiImageModel;
|
|
1397
1474
|
exports.GoogleImageModel = GoogleImageModel;
|
|
1398
1475
|
exports.GoogleSDK = GoogleSDK;
|