ak-gemini 2.4.1 → 2.6.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 +111 -0
- package/GUIDE.md +11 -1
- package/README.md +56 -4
- package/UPGRADING.md +111 -0
- package/base.js +292 -34
- package/chat.js +2 -0
- package/code-agent.js +2 -0
- package/embedding.js +4 -6
- package/image-generator.js +10 -7
- package/index.cjs +319 -57
- package/index.js +2 -1
- package/json-helpers.js +105 -0
- package/message.js +20 -7
- package/package.json +5 -3
- package/rag-agent.js +2 -0
- package/tool-agent.js +2 -0
- package/transformer.js +6 -2
- package/types.d.ts +87 -4
package/json-helpers.js
CHANGED
|
@@ -267,6 +267,111 @@ function findCompleteJSONStructures(text) {
|
|
|
267
267
|
return results;
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Validates a parsed value against a (subset of) JSON Schema. Dependency-light —
|
|
272
|
+
* intended to guard fallback structured-output paths where the model isn't forced
|
|
273
|
+
* to emit schema-valid JSON.
|
|
274
|
+
*
|
|
275
|
+
* Supported keywords: `type` (string or array of strings; 'integer' checks for
|
|
276
|
+
* whole numbers), `required`, `properties`, `additionalProperties: false`,
|
|
277
|
+
* `items` (single schema), `enum`. Unknown keywords are ignored (lenient).
|
|
278
|
+
*
|
|
279
|
+
* @param {*} data - The parsed value to validate
|
|
280
|
+
* @param {Object} schema - JSON Schema object
|
|
281
|
+
* @param {string} [path='$'] - Internal: JSON path prefix for error messages
|
|
282
|
+
* @returns {string[]} Array of human-readable error strings; empty means valid.
|
|
283
|
+
*/
|
|
284
|
+
export function validateSchema(data, schema, path = '$') {
|
|
285
|
+
// NOTE: ak-gemini enforces structured output natively (responseSchema), so this
|
|
286
|
+
// validator has no runtime call site here — it exists for cross-package API
|
|
287
|
+
// symmetry with ak-claude (whose Vertex fallback path relies on it). Keep this
|
|
288
|
+
// implementation byte-identical to ak-claude/json-helpers.js; apply fixes to both.
|
|
289
|
+
const errors = [];
|
|
290
|
+
if (!schema || typeof schema !== 'object') return errors;
|
|
291
|
+
|
|
292
|
+
// ── nullable (OpenAPI-style) ── a null value is valid on a nullable node.
|
|
293
|
+
if (data === null && schema.nullable === true) return errors;
|
|
294
|
+
|
|
295
|
+
// ── enum ── strict equality first, then deep-equal for object/array members.
|
|
296
|
+
if (Array.isArray(schema.enum)) {
|
|
297
|
+
const target = JSON.stringify(data);
|
|
298
|
+
const ok = schema.enum.some(v => v === data || JSON.stringify(v) === target);
|
|
299
|
+
if (!ok) errors.push(`${path}: value ${JSON.stringify(data)} is not one of allowed enum values ${JSON.stringify(schema.enum)}`);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// ── type ──
|
|
303
|
+
if (schema.type !== undefined) {
|
|
304
|
+
const types = Array.isArray(schema.type) ? schema.type : [schema.type];
|
|
305
|
+
if (schema.nullable === true) types.push('null');
|
|
306
|
+
if (!types.some(t => matchesType(data, t))) {
|
|
307
|
+
errors.push(`${path}: expected type ${types.join('|')} but got ${describeType(data)}`);
|
|
308
|
+
// If the type is wrong, deeper checks are meaningless — stop here for this node.
|
|
309
|
+
return errors;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// ── object ── (Object.hasOwn avoids prototype-chain keys like 'toString')
|
|
314
|
+
const isObject = data !== null && typeof data === 'object' && !Array.isArray(data);
|
|
315
|
+
if (isObject && (schema.properties || schema.required || schema.additionalProperties === false)) {
|
|
316
|
+
const props = schema.properties || {};
|
|
317
|
+
|
|
318
|
+
if (Array.isArray(schema.required)) {
|
|
319
|
+
for (const key of schema.required) {
|
|
320
|
+
if (!Object.hasOwn(data, key)) errors.push(`${path}: missing required property "${key}"`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (schema.additionalProperties === false) {
|
|
325
|
+
for (const key of Object.keys(data)) {
|
|
326
|
+
if (!Object.hasOwn(props, key)) errors.push(`${path}: unexpected property "${key}" (additionalProperties is false)`);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
for (const [key, subSchema] of Object.entries(props)) {
|
|
331
|
+
if (Object.hasOwn(data, key)) {
|
|
332
|
+
errors.push(...validateSchema(data[key], /** @type {any} */ (subSchema), `${path}.${key}`));
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// ── array ──
|
|
338
|
+
if (Array.isArray(data) && schema.items && typeof schema.items === 'object' && !Array.isArray(schema.items)) {
|
|
339
|
+
data.forEach((item, i) => {
|
|
340
|
+
errors.push(...validateSchema(item, schema.items, `${path}[${i}]`));
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return errors;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* @param {*} value
|
|
349
|
+
* @param {string} type - JSON Schema type name
|
|
350
|
+
* @returns {boolean}
|
|
351
|
+
*/
|
|
352
|
+
function matchesType(value, type) {
|
|
353
|
+
switch (type) {
|
|
354
|
+
case 'string': return typeof value === 'string';
|
|
355
|
+
case 'number': return typeof value === 'number' && !Number.isNaN(value);
|
|
356
|
+
case 'integer': return typeof value === 'number' && Number.isInteger(value);
|
|
357
|
+
case 'boolean': return typeof value === 'boolean';
|
|
358
|
+
case 'object': return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
359
|
+
case 'array': return Array.isArray(value);
|
|
360
|
+
case 'null': return value === null;
|
|
361
|
+
default: return true; // unknown type keyword — be lenient
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* @param {*} value
|
|
367
|
+
* @returns {string}
|
|
368
|
+
*/
|
|
369
|
+
function describeType(value) {
|
|
370
|
+
if (value === null) return 'null';
|
|
371
|
+
if (Array.isArray(value)) return 'array';
|
|
372
|
+
return typeof value;
|
|
373
|
+
}
|
|
374
|
+
|
|
270
375
|
/**
|
|
271
376
|
* Extracts valid JSON from model response text using multiple strategies.
|
|
272
377
|
* @param {string} text - The model response text
|
package/message.js
CHANGED
|
@@ -53,6 +53,13 @@ class Message extends BaseGemini {
|
|
|
53
53
|
}
|
|
54
54
|
if (options.responseMimeType) {
|
|
55
55
|
this.chatConfig.responseMimeType = options.responseMimeType;
|
|
56
|
+
} else if (options.responseSchema) {
|
|
57
|
+
// Google's @google/genai requires response_mime_type: 'application/json'
|
|
58
|
+
// whenever a responseSchema is set — it does NOT add it automatically.
|
|
59
|
+
// Passing a schema without the mime type yields a 400 INVALID_ARGUMENT
|
|
60
|
+
// (Vertex) or prose output that fails JSON extraction. Auto-pair them.
|
|
61
|
+
this.chatConfig.responseMimeType = 'application/json';
|
|
62
|
+
log.debug("responseSchema set without responseMimeType — defaulting responseMimeType to 'application/json'.");
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
this._isStructured = !!(options.responseSchema || options.responseMimeType === 'application/json');
|
|
@@ -71,12 +78,11 @@ class Message extends BaseGemini {
|
|
|
71
78
|
|
|
72
79
|
log.debug(`Initializing ${this.constructor.name} with model: ${this.modelName}...`);
|
|
73
80
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
81
|
+
// Connectivity check is opt-in (healthCheck: true). models.list() is a
|
|
82
|
+
// different IAM surface than generateContent — a service account allowed to
|
|
83
|
+
// generate but not list publisher models would fail here misleadingly — and
|
|
84
|
+
// it adds a round-trip per instance. The first send() is a fine error signal.
|
|
85
|
+
await this._healthCheckPing();
|
|
80
86
|
|
|
81
87
|
this._initialized = true;
|
|
82
88
|
log.debug(`${this.constructor.name}: Initialized (stateless mode).`);
|
|
@@ -111,11 +117,18 @@ class Message extends BaseGemini {
|
|
|
111
117
|
}
|
|
112
118
|
}));
|
|
113
119
|
|
|
120
|
+
// Compute per-call usage synchronously from THIS response before any other
|
|
121
|
+
// concurrent send() can mutate instance state. result.usage is safe under
|
|
122
|
+
// concurrency; getLastUsage() (instance state, updated below) is not.
|
|
123
|
+
const usage = this._usageFromResponse(result);
|
|
124
|
+
|
|
114
125
|
this._captureMetadata(result);
|
|
115
126
|
|
|
116
127
|
this._cumulativeUsage = {
|
|
117
128
|
promptTokens: this.lastResponseMetadata.promptTokens,
|
|
118
129
|
responseTokens: this.lastResponseMetadata.responseTokens,
|
|
130
|
+
thoughtsTokens: this.lastResponseMetadata.thoughtsTokens,
|
|
131
|
+
cachedTokens: this.lastResponseMetadata.cachedTokens,
|
|
119
132
|
totalTokens: this.lastResponseMetadata.totalTokens,
|
|
120
133
|
attempts: 1
|
|
121
134
|
};
|
|
@@ -127,7 +140,7 @@ class Message extends BaseGemini {
|
|
|
127
140
|
const text = result.text || '';
|
|
128
141
|
const response = {
|
|
129
142
|
text,
|
|
130
|
-
usage
|
|
143
|
+
usage
|
|
131
144
|
};
|
|
132
145
|
|
|
133
146
|
// Parse structured data if configured
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "ak-gemini",
|
|
3
3
|
"author": "ak@mixpanel.com",
|
|
4
4
|
"description": "AK's Generative AI Helper for doing... everything",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.6.0",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"files": [
|
|
8
8
|
"index.js",
|
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
"json-helpers.js",
|
|
20
20
|
"types.d.ts",
|
|
21
21
|
"logger.js",
|
|
22
|
-
"GUIDE.md"
|
|
22
|
+
"GUIDE.md",
|
|
23
|
+
"UPGRADING.md",
|
|
24
|
+
"CHANGELOG.md"
|
|
23
25
|
],
|
|
24
26
|
"types": "types.d.ts",
|
|
25
27
|
"exports": {
|
|
@@ -65,7 +67,7 @@
|
|
|
65
67
|
],
|
|
66
68
|
"license": "ISC",
|
|
67
69
|
"dependencies": {
|
|
68
|
-
"@google/genai": "^2.
|
|
70
|
+
"@google/genai": "^2.12.0",
|
|
69
71
|
"dotenv": "^17.3.1",
|
|
70
72
|
"pino": "^10.3.1",
|
|
71
73
|
"pino-pretty": "^13.1.3"
|
package/rag-agent.js
CHANGED
|
@@ -213,6 +213,8 @@ class RagAgent extends BaseGemini {
|
|
|
213
213
|
this._cumulativeUsage = {
|
|
214
214
|
promptTokens: this.lastResponseMetadata.promptTokens,
|
|
215
215
|
responseTokens: this.lastResponseMetadata.responseTokens,
|
|
216
|
+
thoughtsTokens: this.lastResponseMetadata.thoughtsTokens,
|
|
217
|
+
cachedTokens: this.lastResponseMetadata.cachedTokens,
|
|
216
218
|
totalTokens: this.lastResponseMetadata.totalTokens,
|
|
217
219
|
attempts: 1
|
|
218
220
|
};
|
package/tool-agent.js
CHANGED
|
@@ -200,6 +200,8 @@ class ToolAgent extends BaseGemini {
|
|
|
200
200
|
this._cumulativeUsage = {
|
|
201
201
|
promptTokens: this.lastResponseMetadata.promptTokens,
|
|
202
202
|
responseTokens: this.lastResponseMetadata.responseTokens,
|
|
203
|
+
thoughtsTokens: this.lastResponseMetadata.thoughtsTokens,
|
|
204
|
+
cachedTokens: this.lastResponseMetadata.cachedTokens,
|
|
203
205
|
totalTokens: this.lastResponseMetadata.totalTokens,
|
|
204
206
|
attempts: 1
|
|
205
207
|
};
|
package/transformer.js
CHANGED
|
@@ -201,7 +201,7 @@ class Transformer extends BaseGemini {
|
|
|
201
201
|
if (opts.labels) messageOptions.labels = opts.labels;
|
|
202
202
|
|
|
203
203
|
// Reset cumulative usage tracking
|
|
204
|
-
this._cumulativeUsage = { promptTokens: 0, responseTokens: 0, totalTokens: 0, attempts: 0 };
|
|
204
|
+
this._cumulativeUsage = { promptTokens: 0, responseTokens: 0, thoughtsTokens: 0, cachedTokens: 0, totalTokens: 0, attempts: 0 };
|
|
205
205
|
|
|
206
206
|
let lastError = null;
|
|
207
207
|
|
|
@@ -215,6 +215,8 @@ class Transformer extends BaseGemini {
|
|
|
215
215
|
if (this.lastResponseMetadata) {
|
|
216
216
|
this._cumulativeUsage.promptTokens += this.lastResponseMetadata.promptTokens || 0;
|
|
217
217
|
this._cumulativeUsage.responseTokens += this.lastResponseMetadata.responseTokens || 0;
|
|
218
|
+
this._cumulativeUsage.thoughtsTokens += this.lastResponseMetadata.thoughtsTokens || 0;
|
|
219
|
+
this._cumulativeUsage.cachedTokens += this.lastResponseMetadata.cachedTokens || 0;
|
|
218
220
|
this._cumulativeUsage.totalTokens += this.lastResponseMetadata.totalTokens || 0;
|
|
219
221
|
this._cumulativeUsage.attempts = attempt + 1;
|
|
220
222
|
}
|
|
@@ -389,6 +391,8 @@ Respond with JSON only – no comments or explanations.
|
|
|
389
391
|
this._cumulativeUsage = {
|
|
390
392
|
promptTokens: this.lastResponseMetadata.promptTokens,
|
|
391
393
|
responseTokens: this.lastResponseMetadata.responseTokens,
|
|
394
|
+
thoughtsTokens: this.lastResponseMetadata.thoughtsTokens,
|
|
395
|
+
cachedTokens: this.lastResponseMetadata.cachedTokens,
|
|
392
396
|
totalTokens: this.lastResponseMetadata.totalTokens,
|
|
393
397
|
attempts: 1
|
|
394
398
|
};
|
|
@@ -422,7 +426,7 @@ Respond with JSON only – no comments or explanations.
|
|
|
422
426
|
this.chatSession = this._createChatSession(exampleHistory);
|
|
423
427
|
|
|
424
428
|
this.lastResponseMetadata = null;
|
|
425
|
-
this._cumulativeUsage = { promptTokens: 0, responseTokens: 0, totalTokens: 0, attempts: 0 };
|
|
429
|
+
this._cumulativeUsage = { promptTokens: 0, responseTokens: 0, thoughtsTokens: 0, cachedTokens: 0, totalTokens: 0, attempts: 0 };
|
|
426
430
|
|
|
427
431
|
log.debug(`Conversation cleared. Preserved ${exampleHistory.length} example items.`);
|
|
428
432
|
}
|
package/types.d.ts
CHANGED
|
@@ -6,11 +6,38 @@ export { ThinkingLevel, HarmCategory, HarmBlockThreshold };
|
|
|
6
6
|
|
|
7
7
|
export interface ThinkingConfig {
|
|
8
8
|
includeThoughts?: boolean;
|
|
9
|
-
/** Token budget for thinking. 0 = disabled, -1 = automatic. */
|
|
9
|
+
/** Token budget for thinking. 0 = disabled, -1 = automatic. Mutually exclusive with thinkingLevel. */
|
|
10
10
|
thinkingBudget?: number;
|
|
11
11
|
thinkingLevel?: ThinkingLevel;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Cross-package reasoning-effort levels (same option name in ak-claude).
|
|
16
|
+
* Gemini's wire field is `thinkingConfig.thinkingLevel`; `xhigh` and `max` are
|
|
17
|
+
* ak-claude-only levels and clamp to `high` here.
|
|
18
|
+
*/
|
|
19
|
+
export type EffortLevel = 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
20
|
+
|
|
21
|
+
/** Per-million-token rates for a single model. */
|
|
22
|
+
export interface ModelPricing {
|
|
23
|
+
input: number;
|
|
24
|
+
output: number;
|
|
25
|
+
/** Rate for tokens served from a context cache. Absent when Google publishes none — cost then falls back to `input` (overestimate). */
|
|
26
|
+
cachedInput?: number;
|
|
27
|
+
/** >200k-context tier rates, present only on tiered (Pro) models. */
|
|
28
|
+
inputAbove200k?: number;
|
|
29
|
+
outputAbove200k?: number;
|
|
30
|
+
cachedInputAbove200k?: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** ModelPricing decorated with the tier threshold and the table's verification date. */
|
|
34
|
+
export interface ResolvedPricing extends ModelPricing {
|
|
35
|
+
/** Prompt-token count above which the *Above200k rates apply. */
|
|
36
|
+
tierThreshold: number;
|
|
37
|
+
/** ISO date the pricing table was last verified against Google's pricing page. */
|
|
38
|
+
asOf: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
14
41
|
export interface SafetySetting {
|
|
15
42
|
category: HarmCategory;
|
|
16
43
|
threshold: HarmBlockThreshold;
|
|
@@ -54,6 +81,9 @@ export interface ResponseMetadata {
|
|
|
54
81
|
requestedModel: string;
|
|
55
82
|
promptTokens: number;
|
|
56
83
|
responseTokens: number;
|
|
84
|
+
thoughtsTokens?: number;
|
|
85
|
+
/** Cached-content tokens. A SUBSET of promptTokens, not an addition to it. */
|
|
86
|
+
cachedTokens?: number;
|
|
57
87
|
totalTokens: number;
|
|
58
88
|
timestamp: number;
|
|
59
89
|
groundingMetadata?: GroundingMetadata | null;
|
|
@@ -64,7 +94,17 @@ export interface UsageData {
|
|
|
64
94
|
promptTokens: number;
|
|
65
95
|
/** CUMULATIVE output tokens across all retry attempts */
|
|
66
96
|
responseTokens: number;
|
|
67
|
-
/** CUMULATIVE
|
|
97
|
+
/** CUMULATIVE thinking ("thoughts") tokens; billed at the output rate. Included in totalTokens and estimatedCost. */
|
|
98
|
+
thoughtsTokens?: number;
|
|
99
|
+
/**
|
|
100
|
+
* CUMULATIVE cached-content tokens (`usageMetadata.cachedContentTokenCount`).
|
|
101
|
+
* NOTE: Gemini INCLUDES these in promptTokens — they are a subset, not an
|
|
102
|
+
* addition. `estimatedCost` subtracts them from promptTokens and re-bills them
|
|
103
|
+
* at the discounted cached rate. (ak-claude is the opposite: Anthropic's cache
|
|
104
|
+
* tokens are excluded from input_tokens and added on top.)
|
|
105
|
+
*/
|
|
106
|
+
cachedTokens?: number;
|
|
107
|
+
/** CUMULATIVE total tokens across all retry attempts (includes thoughtsTokens) */
|
|
68
108
|
totalTokens: number;
|
|
69
109
|
/** Number of attempts (1 = first try success, 2+ = retries needed) */
|
|
70
110
|
attempts: number;
|
|
@@ -76,6 +116,12 @@ export interface UsageData {
|
|
|
76
116
|
groundingMetadata?: GroundingMetadata | null;
|
|
77
117
|
/** Model lifecycle status from Google (e.g., 'DEPRECATED'). Surfaced from @google/genai 1.47+. */
|
|
78
118
|
modelStatus?: string | null;
|
|
119
|
+
/**
|
|
120
|
+
* Estimated USD cost from MODEL_PRICING (input + cached input + output + thoughts).
|
|
121
|
+
* `null` means the model's pricing is UNKNOWN — it does NOT mean the call was free.
|
|
122
|
+
* Cache STORAGE (per token-hour) and image-output tokens are not modelled.
|
|
123
|
+
*/
|
|
124
|
+
estimatedCost?: number | null;
|
|
79
125
|
}
|
|
80
126
|
|
|
81
127
|
export interface TransformationExample {
|
|
@@ -145,6 +191,12 @@ export interface BaseGeminiOptions {
|
|
|
145
191
|
chatConfig?: Partial<ChatConfig>;
|
|
146
192
|
/** Thinking features configuration */
|
|
147
193
|
thinkingConfig?: ThinkingConfig | null;
|
|
194
|
+
/**
|
|
195
|
+
* Reasoning effort (cross-package option; same name in ak-claude). Maps to
|
|
196
|
+
* `thinkingConfig.thinkingLevel` and wins over an explicit thinkingLevel /
|
|
197
|
+
* thinkingBudget. Throws on an unrecognized level.
|
|
198
|
+
*/
|
|
199
|
+
effort?: EffortLevel | null;
|
|
148
200
|
/** Maximum output tokens (default: 50000, null removes limit) */
|
|
149
201
|
maxOutputTokens?: number | null;
|
|
150
202
|
/** Sampling temperature (shorthand for chatConfig.temperature; wins over chatConfig) */
|
|
@@ -592,6 +644,8 @@ export declare class BaseGemini {
|
|
|
592
644
|
cachedContent: string | null;
|
|
593
645
|
serviceTier: ServiceTier | null;
|
|
594
646
|
includeServerSideToolInvocations: boolean;
|
|
647
|
+
/** Normalized `effort` option; null when unset. */
|
|
648
|
+
effort: EffortLevel | null;
|
|
595
649
|
|
|
596
650
|
init(force?: boolean): Promise<void>;
|
|
597
651
|
seed(examples?: TransformationExample[], opts?: SeedOptions): Promise<any[]>;
|
|
@@ -602,11 +656,14 @@ export declare class BaseGemini {
|
|
|
602
656
|
estimateCost(nextPayload: Record<string, unknown> | string): Promise<{
|
|
603
657
|
inputTokens: number;
|
|
604
658
|
model: string;
|
|
605
|
-
pricing:
|
|
606
|
-
estimatedInputCost: number;
|
|
659
|
+
pricing: ResolvedPricing | null;
|
|
660
|
+
estimatedInputCost: number | null;
|
|
607
661
|
note: string;
|
|
608
662
|
}>;
|
|
609
663
|
|
|
664
|
+
/** @internal Validates the `effort` option; throws on an unknown level. */
|
|
665
|
+
protected _normalizeEffort(effort?: string | null): EffortLevel | null;
|
|
666
|
+
|
|
610
667
|
// Context Caching
|
|
611
668
|
createCache(config?: CacheConfig): Promise<CachedContentInfo>;
|
|
612
669
|
getCache(cacheName: string): Promise<CachedContentInfo>;
|
|
@@ -757,6 +814,32 @@ export declare class ImageGenerator extends BaseGemini {
|
|
|
757
814
|
|
|
758
815
|
export declare function extractJSON(text: string): any;
|
|
759
816
|
export declare function attemptJSONRecovery(text: string, maxAttempts?: number): any | null;
|
|
817
|
+
/** Validates a parsed value against a subset of JSON Schema. Returns error strings ([] means valid). */
|
|
818
|
+
export declare function validateSchema(data: any, schema: Record<string, any>, path?: string): string[];
|
|
819
|
+
|
|
820
|
+
/** Per-million-token pricing keyed by model id. */
|
|
821
|
+
export declare const MODEL_PRICING: Record<string, ModelPricing>;
|
|
822
|
+
/** ISO date the pricing table was last verified against Google's published rates. */
|
|
823
|
+
export declare const MODEL_PRICING_AS_OF: string;
|
|
824
|
+
/** Floating `-latest` alias → canonical model id, for pricing resolution. */
|
|
825
|
+
export declare const MODEL_ALIASES: Record<string, string>;
|
|
826
|
+
/** Valid values for the `effort` option. */
|
|
827
|
+
export declare const EFFORT_LEVELS: readonly EffortLevel[];
|
|
828
|
+
/** Resolves pricing for a model id (follows -latest aliases). `null` means UNKNOWN, not free. */
|
|
829
|
+
export declare function resolvePricing(modelId: string | null | undefined): ResolvedPricing | null;
|
|
830
|
+
/**
|
|
831
|
+
* Estimated USD cost from token counts. `null` means UNKNOWN, not free.
|
|
832
|
+
* `cachedTokens` is a SUBSET of `promptTokens` (Gemini includes them) and is
|
|
833
|
+
* subtracted before billing at the cached rate. Thinking tokens bill at the
|
|
834
|
+
* output rate. Tier is selected from `promptTokens` vs 200k.
|
|
835
|
+
*/
|
|
836
|
+
export declare function computeCost(
|
|
837
|
+
modelId: string | null | undefined,
|
|
838
|
+
promptTokens: number,
|
|
839
|
+
responseTokens: number,
|
|
840
|
+
thoughtsTokens?: number,
|
|
841
|
+
cachedTokens?: number
|
|
842
|
+
): number | null;
|
|
760
843
|
|
|
761
844
|
declare const _default: {
|
|
762
845
|
Transformer: typeof Transformer;
|