Install
npm install @fluxgate/sdk @fluxgate/gemini @google/generative-ai
One-time setup
Unlike the OpenAI and Anthropic wrappers, createGeminiCostTracker wraps a model instance, not the top-level client. Create one tracked model per model ID you use.
// lib/gemini.ts
import { GoogleGenerativeAI } from "@google/generative-ai";
import { FluxGate } from "@fluxgate/sdk";
import { createGeminiCostTracker } from "@fluxgate/gemini";
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);
const fg = new FluxGate({ apiKey: process.env.FLUXGATE_API_KEY! });
// Create one tracked model per model ID you use
export const geminiPro = createGeminiCostTracker(
genAI.getGenerativeModel({ model: "gemini-1.5-pro" }),
fg,
);
export const geminiFlash = createGeminiCostTracker(
genAI.getGenerativeModel({ model: "gemini-1.5-flash" }),
fg,
);
Text generation
import { geminiPro } from "@/lib/gemini";
const result = await geminiPro
.withContext({
feature: "content-generation",
user: { id: session.user.id },
sessionId: session.id,
})
.generateContent(prompt);
const text = result.response.text();
const { cost, trackingId } = result.fluxGateCostTrackingResponse;
Streaming
const result = await geminiPro
.withContext({ feature: "streaming-gen" })
.generateContentStream(longPrompt);
for await (const chunk of result.stream) {
process.stdout.write(chunk.text());
}
// Tracking is finalised once the stream is consumed
const response = await result.response;
console.log(result.fluxGateCostTrackingResponse);
Multi-turn chat sessions
startChat returns a TrackedChatSession. Each sendMessage and sendMessageStream call is tracked individually and attributed to the same context.
const chat = geminiPro
.withContext({ feature: "chatbot", user: session.user.id })
.startChat({
history: [
{ role: "user", parts: [{ text: "Hello" }] },
{ role: "model", parts: [{ text: "Hi! How can I help?" }] },
],
});
const result1 = await chat.sendMessage("What is FluxGate?");
console.log(result1.response.text());
const result2 = await chat.sendMessage("How do I install it?");
console.log(result2.response.text());
Mid-conversation context upgrade
Use .withTracking() on an existing TrackedChatSession to merge additional metadata — useful when a user authenticates mid-session or moves to a paid feature tier.
const premiumChat = chat.withTracking({
feature: "premium-chatbot",
user: {
id: currentUser.id,
monthlyRevenue: currentUser.mrr,
},
});
const result = await premiumChat.sendMessage("I need a detailed analysis");
New context keys override matching keys; unmatched keys are preserved from the original context.
Multimodal (vision)
import { GoogleGenerativeAI } from "@google/generative-ai";
import { createGeminiCostTracker } from "@fluxgate/gemini";
import { FluxGate } from "@fluxgate/sdk";
import fs from "fs";
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);
const fg = new FluxGate({ apiKey: process.env.FLUXGATE_API_KEY! });
const vision = createGeminiCostTracker(
genAI.getGenerativeModel({ model: "gemini-pro-vision" }),
fg,
);
const imageBytes = fs.readFileSync("./screenshot.jpg").toString("base64");
const result = await vision
.withContext({ feature: "image-analysis" })
.generateContent([
{ text: "Describe the UI and identify any accessibility issues." },
{ inlineData: { mimeType: "image/jpeg", data: imageBytes } },
]);
Embeddings
const result = await geminiPro
.withContext({ feature: "vector-search" })
.embedContent(document);
const vector = result.embedding.values;
Safety settings
Safety-blocked responses are automatically recorded with status: "BLOCKED".
import { HarmCategory, HarmBlockThreshold } from "@google/generative-ai";
const safeModel = createGeminiCostTracker(
genAI.getGenerativeModel({
model: "gemini-1.5-pro",
safetySettings: [
{
category: HarmCategory.HARM_CATEGORY_HARASSMENT,
threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
},
],
}),
fg,
);
FluxGateCostTrackingResponse shape
interface FluxGateCostTrackingResponse {
status:
| "SUCCESS"
| "ERROR"
| "BLOCKED"
| "MAX_TOKENS"
| "CONTENT_FILTER"
| "RECITATION"
| "MALFORMED_REQUEST";
cost: number | null; // USD
trackingId: string | null;
createdAt: string | null; // ISO 8601
errorMessage?: string;
}
Tracked automatically: input tokens, output tokens, cached content tokens, model name, latency (ms), stream duration, and finish reason (stop, max_tokens, safety, recitation).
Supported methods
| Method | Non-streaming | Streaming |
|---|---|---|
generateContent | ✅ | — |
generateContentStream | — | ✅ |
startChat → sendMessage | ✅ | — |
startChat → sendMessageStream | — | ✅ |
embedContent | ✅ | — |
Supported models
gemini-pro, gemini-pro-vision, gemini-ultra, gemini-1.5-pro, gemini-1.5-flash, and any future models supported by @google/generative-ai.