deprecate gemini 2 flash and lite (#3581)

* deprecate gemini 2 flash and lite

* fix test
This commit is contained in:
Reynaldi Chernando
2026-08-14 17:27:48 -04:00
committed by GitHub
parent efa2cb4441
commit 6254714484
3 changed files with 45 additions and 93 deletions
@@ -20,7 +20,7 @@
/**
* Integration test for the Gemini chat provider.
*
* Hits the real Google Gemini API with `gemini-2.0-flash-lite` (one
* Hits the real Google Gemini API with `gemini-2.5-flash-lite` (one
* of the cheapest variants). Skipped when `PUTER_TEST_AI_GEMINI_API_KEY`
* is unset.
*/
@@ -40,14 +40,14 @@ const ENV_VAR = 'PUTER_TEST_AI_GEMINI_API_KEY';
describe.skipIf(skipUnlessEnv(ENV_VAR))(
'GeminiChatProvider (integration)',
() => {
it('returns a non-empty completion from gemini-2.0-flash-lite', { timeout: INTEGRATION_TEST_TIMEOUT_MS }, async () => {
it('returns a non-empty completion from gemini-2.5-flash-lite', { timeout: INTEGRATION_TEST_TIMEOUT_MS }, async () => {
const provider = new GeminiChatProvider(makeMeteringStub(), {
apiKey: optionalEnv(ENV_VAR)!,
});
const result = await withTestActor(() =>
provider.complete({
model: 'gemini-2.0-flash-lite',
model: 'gemini-2.5-flash-lite',
messages: [
{ role: 'user', content: 'Say hi in one word.' },
],
@@ -400,46 +400,51 @@ describe('GeminiChatProvider.complete non-stream output', () => {
});
it('bills cached tokens at the input rate when the model prices no cache read', async () => {
// gemini-2.0-flash-lite's catalogue entry has no cached_tokens rate.
// Cached tokens are subtracted out of prompt_tokens, so pricing them
// at zero bills them nowhere.
// Every shipped entry currently prices cache reads, so drop the rate
// off one for this call. Cached tokens are subtracted out of
// prompt_tokens, so pricing them at zero bills them nowhere.
const lite = GEMINI_MODELS.find(
(m) => m.id === 'gemini-2.0-flash-lite',
(m) => m.id === 'gemini-3.1-flash-lite',
)!;
expect(lite.costs.cached_tokens).toBeUndefined();
const cachedRate = lite.costs.cached_tokens;
delete lite.costs.cached_tokens;
const { provider } = makeProvider();
createMock.mockResolvedValueOnce({
choices: [
{
message: { content: 'cached', role: 'assistant' },
finish_reason: 'stop',
try {
const { provider } = makeProvider();
createMock.mockResolvedValueOnce({
choices: [
{
message: { content: 'cached', role: 'assistant' },
finish_reason: 'stop',
},
],
usage: {
prompt_tokens: 3000,
completion_tokens: 40,
prompt_tokens_details: { cached_tokens: 2900 },
},
],
usage: {
prompt_tokens: 3000,
completion_tokens: 40,
prompt_tokens_details: { cached_tokens: 2900 },
},
});
});
await withTestActor(() =>
provider.complete({
model: 'gemini-2.0-flash-lite',
messages: [{ role: 'user', content: 'hi' }],
}),
);
await withTestActor(() =>
provider.complete({
model: 'gemini-3.1-flash-lite',
messages: [{ role: 'user', content: 'hi' }],
}),
);
const [, , , overrides] = recordSpy.mock.calls[0]!;
const inputRate = Number(lite.costs.prompt_tokens);
expect(overrides).toMatchObject({
prompt_tokens: (3000 - 2900) * inputRate,
completion_tokens: 40 * Number(lite.costs.completion_tokens),
cached_tokens: 2900 * inputRate,
});
expect(
(overrides as Record<string, number>).cached_tokens,
).toBeGreaterThan(0);
const [, , , overrides] = recordSpy.mock.calls[0]!;
const inputRate = Number(lite.costs.prompt_tokens);
expect(overrides).toMatchObject({
prompt_tokens: (3000 - 2900) * inputRate,
completion_tokens: 40 * Number(lite.costs.completion_tokens),
cached_tokens: 2900 * inputRate,
});
expect(
(overrides as Record<string, number>).cached_tokens,
).toBeGreaterThan(0);
} finally {
lite.costs.cached_tokens = cachedRate;
}
});
it('zeroes cached_tokens when prompt_tokens_details is missing', async () => {
@@ -643,9 +648,9 @@ describe('GeminiChatProvider.complete grounding request metering', () => {
// generation; without its own rate the fee fell through to the input
// token rate, which is several orders of magnitude below list.
const lite = GEMINI_MODELS.find(
(m) => m.id === 'gemini-2.0-flash-lite',
(m) => m.id === 'gemini-3.1-flash-lite',
)!;
expect(lite.costs.grounding_requests).toBe(3_500_000);
expect(lite.costs.grounding_requests).toBe(1_400_000);
const { provider } = makeProvider();
createMock.mockResolvedValueOnce({
@@ -666,7 +671,7 @@ describe('GeminiChatProvider.complete grounding request metering', () => {
await withTestActor(() =>
provider.complete({
model: 'gemini-2.0-flash-lite',
model: 'gemini-3.1-flash-lite',
messages: [{ role: 'user', content: 'search for foo' }],
}),
);
@@ -49,59 +49,6 @@ export const GEMINI_MODELS: IChatModel[] = [
grounding_requests: 1_400_000,
},
},
{
puterId: 'google:google/gemini-2.0-flash',
id: 'gemini-2.0-flash',
modalities: {
input: ['text', 'image', 'audio', 'video', 'pdf'],
output: ['text'],
},
open_weights: false,
tool_call: true,
knowledge: '2024-06',
release_date: '2024-12-11',
name: 'Gemini 2.0 Flash',
aliases: ['google/gemini-2.0-flash'],
context: 131072,
costs_currency: 'usd-cents',
input_cost_key: 'prompt_tokens',
output_cost_key: 'completion_tokens',
costs: {
tokens: 1_000_000,
prompt_tokens: 10,
completion_tokens: 40,
cached_tokens: 3,
// Gemini 2.x grounding is $35 / 1,000 requests
grounding_requests: 3_500_000,
},
max_tokens: 8192,
},
{
puterId: 'google:google/gemini-2.0-flash-lite',
id: 'gemini-2.0-flash-lite',
modalities: {
input: ['text', 'image', 'audio', 'video', 'pdf'],
output: ['text'],
},
open_weights: false,
tool_call: true,
knowledge: '2024-06',
release_date: '2024-12-11',
name: 'Gemini 2.0 Flash-Lite',
aliases: ['google/gemini-2.0-flash-lite'],
context: 1_048_576,
costs_currency: 'usd-cents',
input_cost_key: 'prompt_tokens',
output_cost_key: 'completion_tokens',
costs: {
tokens: 1_000_000,
prompt_tokens: 8,
completion_tokens: 30,
// Gemini 2.x grounding is $35 / 1,000 requests
grounding_requests: 3_500_000,
},
max_tokens: 8192,
},
{
puterId: 'google:google/gemini-2.5-flash',
id: 'gemini-2.5-flash',