ak-gemini 2.3.0 → 2.4.1
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/base.js +22 -4
- package/chat.js +13 -0
- package/index.cjs +30 -4
- package/package.json +2 -2
- package/transformer.js +2 -1
- package/types.d.ts +8 -0
package/base.js
CHANGED
|
@@ -37,11 +37,13 @@ const THINKING_SUPPORTED_MODELS = [
|
|
|
37
37
|
];
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* Model pricing per million tokens (Paid Tier Standard, base rate, as of
|
|
40
|
+
* Model pricing per million tokens (Paid Tier Standard, base rate, as of July 2026).
|
|
41
41
|
* Source: https://ai.google.dev/gemini-api/docs/pricing
|
|
42
42
|
*
|
|
43
43
|
* NOTES:
|
|
44
44
|
* - Pro models use tiered pricing (≤200k vs >200k context). Listed rate is ≤200k base tier.
|
|
45
|
+
* - Gemma models (e.g. Gemma 4) are intentionally excluded — they are open models with
|
|
46
|
+
* no paid per-token tier on the Gemini API (Vertex deployments bill by compute).
|
|
45
47
|
* - Image-output tokens on Nano Banana models bill at $60/M (1.5 Flash Image) or $120/M (3 Pro Image).
|
|
46
48
|
* Only text-input/text-output rates are modelled here; image-output cost is NOT included in estimateCost().
|
|
47
49
|
* - Audio input is more expensive on most models — listed rate covers text/image/video input.
|
|
@@ -52,6 +54,7 @@ const MODEL_PRICING = {
|
|
|
52
54
|
'gemini-3.1-flash-lite': { input: 0.25, output: 1.50 },
|
|
53
55
|
// Gemini 3.x preview
|
|
54
56
|
'gemini-3.1-pro-preview': { input: 2.00, output: 12.00 }, // ≤200k tier
|
|
57
|
+
'gemini-3-pro-preview': { input: 2.00, output: 12.00 }, // ≤200k tier; launch rate (superseded by 3.1, off the pricing page)
|
|
55
58
|
'gemini-3-flash-preview': { input: 0.50, output: 3.00 },
|
|
56
59
|
'gemini-3.1-flash-lite-preview': { input: 0.25, output: 1.50 },
|
|
57
60
|
'gemini-3.1-flash-image-preview': { input: 0.50, output: 3.00 }, // text-only; image-output is $60/M
|
|
@@ -155,6 +158,13 @@ class BaseGemini {
|
|
|
155
158
|
if (this.serviceTier) this.chatConfig['serviceTier'] = this.serviceTier;
|
|
156
159
|
if (this.includeServerSideToolInvocations) this.chatConfig['includeServerSideToolInvocations'] = true;
|
|
157
160
|
|
|
161
|
+
// ── Sampling Shortcuts ──
|
|
162
|
+
// Top-level sugar for chatConfig sampling knobs; wins over chatConfig
|
|
163
|
+
// (same precedence as the maxOutputTokens promotion below)
|
|
164
|
+
for (const key of ['temperature', 'topP', 'topK']) {
|
|
165
|
+
if (options[key] !== undefined) this.chatConfig[key] = options[key];
|
|
166
|
+
}
|
|
167
|
+
|
|
158
168
|
// Apply systemPrompt to chatConfig
|
|
159
169
|
if (this.systemPrompt) {
|
|
160
170
|
this.chatConfig.systemInstruction = this.systemPrompt;
|
|
@@ -321,6 +331,7 @@ class BaseGemini {
|
|
|
321
331
|
* @param {string} [opts.contextKey='CONTEXT'] - Key for optional context
|
|
322
332
|
* @param {string} [opts.explanationKey='EXPLANATION'] - Key for optional explanations
|
|
323
333
|
* @param {string} [opts.systemPromptKey='SYSTEM'] - Key for system prompt overrides in examples
|
|
334
|
+
* @param {'json'|'text'} [opts.format='json'] - Model-turn format: 'json' wraps answers in a {data} envelope (Transformer protocol); 'text' stores ANSWER verbatim (prose agents like Chat)
|
|
324
335
|
* @returns {Promise<Array>} The updated chat history
|
|
325
336
|
*/
|
|
326
337
|
async seed(examples, opts = {}) {
|
|
@@ -336,6 +347,7 @@ class BaseGemini {
|
|
|
336
347
|
const contextKey = opts.contextKey || 'CONTEXT';
|
|
337
348
|
const explanationKey = opts.explanationKey || 'EXPLANATION';
|
|
338
349
|
const systemPromptKey = opts.systemPromptKey || 'SYSTEM';
|
|
350
|
+
const format = opts.format || 'json';
|
|
339
351
|
|
|
340
352
|
// Check for system prompt override in examples
|
|
341
353
|
const instructionExample = examples.find(ex => ex[systemPromptKey]);
|
|
@@ -367,9 +379,15 @@ class BaseGemini {
|
|
|
367
379
|
userText += promptText;
|
|
368
380
|
}
|
|
369
381
|
|
|
370
|
-
|
|
371
|
-
if (
|
|
372
|
-
|
|
382
|
+
let modelText;
|
|
383
|
+
if (format === 'text') {
|
|
384
|
+
modelText = isJSON(answerValue) ? JSON.stringify(answerValue, null, 2) : String(answerValue || '');
|
|
385
|
+
if (explanationValue) log.warn('seed(): EXPLANATION has no representation in text format; ignored.');
|
|
386
|
+
} else {
|
|
387
|
+
if (answerValue) modelResponse.data = answerValue;
|
|
388
|
+
if (explanationValue) modelResponse.explanation = explanationValue;
|
|
389
|
+
modelText = JSON.stringify(modelResponse, null, 2);
|
|
390
|
+
}
|
|
373
391
|
|
|
374
392
|
if (userText.trim().length && modelText.trim().length > 0) {
|
|
375
393
|
historyToAdd.push({ role: 'user', parts: [{ text: userText.trim() }] });
|
package/chat.js
CHANGED
|
@@ -47,6 +47,19 @@ class Chat extends BaseGemini {
|
|
|
47
47
|
log.debug(`Chat created with model: ${this.modelName}`);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Seeds the conversation with example pairs stored as plain prose turns.
|
|
52
|
+
* Chat is a prose agent — model turns are stored verbatim, not wrapped in
|
|
53
|
+
* Transformer's {data} JSON envelope.
|
|
54
|
+
*
|
|
55
|
+
* @param {import('./types').TransformationExample[]} [examples]
|
|
56
|
+
* @param {import('./types').SeedOptions} [opts={}]
|
|
57
|
+
* @returns {Promise<Array>} The updated chat history
|
|
58
|
+
*/
|
|
59
|
+
async seed(examples, opts = {}) {
|
|
60
|
+
return super.seed(examples, { format: 'text', ...opts });
|
|
61
|
+
}
|
|
62
|
+
|
|
50
63
|
/**
|
|
51
64
|
* Send a text message and get a response. Adds to conversation history.
|
|
52
65
|
*
|
package/index.cjs
CHANGED
|
@@ -338,6 +338,8 @@ var MODEL_PRICING = {
|
|
|
338
338
|
// Gemini 3.x preview
|
|
339
339
|
"gemini-3.1-pro-preview": { input: 2, output: 12 },
|
|
340
340
|
// ≤200k tier
|
|
341
|
+
"gemini-3-pro-preview": { input: 2, output: 12 },
|
|
342
|
+
// ≤200k tier; launch rate (superseded by 3.1, off the pricing page)
|
|
341
343
|
"gemini-3-flash-preview": { input: 0.5, output: 3 },
|
|
342
344
|
"gemini-3.1-flash-lite-preview": { input: 0.25, output: 1.5 },
|
|
343
345
|
"gemini-3.1-flash-image-preview": { input: 0.5, output: 3 },
|
|
@@ -398,6 +400,9 @@ var BaseGemini = class {
|
|
|
398
400
|
};
|
|
399
401
|
if (this.serviceTier) this.chatConfig["serviceTier"] = this.serviceTier;
|
|
400
402
|
if (this.includeServerSideToolInvocations) this.chatConfig["includeServerSideToolInvocations"] = true;
|
|
403
|
+
for (const key of ["temperature", "topP", "topK"]) {
|
|
404
|
+
if (options[key] !== void 0) this.chatConfig[key] = options[key];
|
|
405
|
+
}
|
|
401
406
|
if (this.systemPrompt) {
|
|
402
407
|
this.chatConfig.systemInstruction = this.systemPrompt;
|
|
403
408
|
} else if (this.systemPrompt === null && options.systemPrompt === void 0) {
|
|
@@ -531,6 +536,7 @@ var BaseGemini = class {
|
|
|
531
536
|
* @param {string} [opts.contextKey='CONTEXT'] - Key for optional context
|
|
532
537
|
* @param {string} [opts.explanationKey='EXPLANATION'] - Key for optional explanations
|
|
533
538
|
* @param {string} [opts.systemPromptKey='SYSTEM'] - Key for system prompt overrides in examples
|
|
539
|
+
* @param {'json'|'text'} [opts.format='json'] - Model-turn format: 'json' wraps answers in a {data} envelope (Transformer protocol); 'text' stores ANSWER verbatim (prose agents like Chat)
|
|
534
540
|
* @returns {Promise<Array>} The updated chat history
|
|
535
541
|
*/
|
|
536
542
|
async seed(examples, opts = {}) {
|
|
@@ -544,6 +550,7 @@ var BaseGemini = class {
|
|
|
544
550
|
const contextKey = opts.contextKey || "CONTEXT";
|
|
545
551
|
const explanationKey = opts.explanationKey || "EXPLANATION";
|
|
546
552
|
const systemPromptKey = opts.systemPromptKey || "SYSTEM";
|
|
553
|
+
const format = opts.format || "json";
|
|
547
554
|
const instructionExample = examples.find((ex) => ex[systemPromptKey]);
|
|
548
555
|
if (instructionExample) {
|
|
549
556
|
logger_default.debug(`Found system prompt in examples; reinitializing chat.`);
|
|
@@ -572,9 +579,15 @@ ${contextText}
|
|
|
572
579
|
let promptText = isJSON(promptValue) ? JSON.stringify(promptValue, null, 2) : promptValue;
|
|
573
580
|
userText += promptText;
|
|
574
581
|
}
|
|
575
|
-
|
|
576
|
-
if (
|
|
577
|
-
|
|
582
|
+
let modelText;
|
|
583
|
+
if (format === "text") {
|
|
584
|
+
modelText = isJSON(answerValue) ? JSON.stringify(answerValue, null, 2) : String(answerValue || "");
|
|
585
|
+
if (explanationValue) logger_default.warn("seed(): EXPLANATION has no representation in text format; ignored.");
|
|
586
|
+
} else {
|
|
587
|
+
if (answerValue) modelResponse.data = answerValue;
|
|
588
|
+
if (explanationValue) modelResponse.explanation = explanationValue;
|
|
589
|
+
modelText = JSON.stringify(modelResponse, null, 2);
|
|
590
|
+
}
|
|
578
591
|
if (userText.trim().length && modelText.trim().length > 0) {
|
|
579
592
|
historyToAdd.push({ role: "user", parts: [{ text: userText.trim() }] });
|
|
580
593
|
historyToAdd.push({ role: "model", parts: [{ text: modelText.trim() }] });
|
|
@@ -938,7 +951,8 @@ var Transformer = class extends base_default {
|
|
|
938
951
|
answerKey: this.answerKey,
|
|
939
952
|
contextKey: this.contextKey,
|
|
940
953
|
explanationKey: this.explanationKey,
|
|
941
|
-
systemPromptKey: this.systemPromptKey
|
|
954
|
+
systemPromptKey: this.systemPromptKey,
|
|
955
|
+
format: "json"
|
|
942
956
|
});
|
|
943
957
|
}
|
|
944
958
|
// ── Primary Send Method ──────────────────────────────────────────────────
|
|
@@ -1216,6 +1230,18 @@ var Chat = class extends base_default {
|
|
|
1216
1230
|
super(options);
|
|
1217
1231
|
logger_default.debug(`Chat created with model: ${this.modelName}`);
|
|
1218
1232
|
}
|
|
1233
|
+
/**
|
|
1234
|
+
* Seeds the conversation with example pairs stored as plain prose turns.
|
|
1235
|
+
* Chat is a prose agent — model turns are stored verbatim, not wrapped in
|
|
1236
|
+
* Transformer's {data} JSON envelope.
|
|
1237
|
+
*
|
|
1238
|
+
* @param {import('./types').TransformationExample[]} [examples]
|
|
1239
|
+
* @param {import('./types').SeedOptions} [opts={}]
|
|
1240
|
+
* @returns {Promise<Array>} The updated chat history
|
|
1241
|
+
*/
|
|
1242
|
+
async seed(examples, opts = {}) {
|
|
1243
|
+
return super.seed(examples, { format: "text", ...opts });
|
|
1244
|
+
}
|
|
1219
1245
|
/**
|
|
1220
1246
|
* Send a text message and get a response. Adds to conversation history.
|
|
1221
1247
|
*
|
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.4.1",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"files": [
|
|
8
8
|
"index.js",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
],
|
|
66
66
|
"license": "ISC",
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@google/genai": "^2.
|
|
68
|
+
"@google/genai": "^2.10.0",
|
|
69
69
|
"dotenv": "^17.3.1",
|
|
70
70
|
"pino": "^10.3.1",
|
|
71
71
|
"pino-pretty": "^13.1.3"
|
package/transformer.js
CHANGED
|
@@ -141,7 +141,8 @@ class Transformer extends BaseGemini {
|
|
|
141
141
|
answerKey: this.answerKey,
|
|
142
142
|
contextKey: this.contextKey,
|
|
143
143
|
explanationKey: this.explanationKey,
|
|
144
|
-
systemPromptKey: this.systemPromptKey
|
|
144
|
+
systemPromptKey: this.systemPromptKey,
|
|
145
|
+
format: 'json'
|
|
145
146
|
});
|
|
146
147
|
}
|
|
147
148
|
|
package/types.d.ts
CHANGED
|
@@ -147,6 +147,12 @@ export interface BaseGeminiOptions {
|
|
|
147
147
|
thinkingConfig?: ThinkingConfig | null;
|
|
148
148
|
/** Maximum output tokens (default: 50000, null removes limit) */
|
|
149
149
|
maxOutputTokens?: number | null;
|
|
150
|
+
/** Sampling temperature (shorthand for chatConfig.temperature; wins over chatConfig) */
|
|
151
|
+
temperature?: number;
|
|
152
|
+
/** Nucleus sampling (shorthand for chatConfig.topP; wins over chatConfig) */
|
|
153
|
+
topP?: number;
|
|
154
|
+
/** Top-k sampling (shorthand for chatConfig.topK; wins over chatConfig) */
|
|
155
|
+
topK?: number;
|
|
150
156
|
/** Log level (default: based on NODE_ENV) */
|
|
151
157
|
logLevel?: LogLevel;
|
|
152
158
|
|
|
@@ -563,6 +569,8 @@ export interface SeedOptions {
|
|
|
563
569
|
contextKey?: string;
|
|
564
570
|
explanationKey?: string;
|
|
565
571
|
systemPromptKey?: string;
|
|
572
|
+
/** Model-turn format: 'json' wraps answers in a {data} envelope (Transformer protocol); 'text' stores ANSWER verbatim (prose agents like Chat). Default: 'json' */
|
|
573
|
+
format?: 'json' | 'text';
|
|
566
574
|
}
|
|
567
575
|
|
|
568
576
|
// ── Class Declarations ───────────────────────────────────────────────────────
|