Files
nexu-io-open-design/apps/daemon/tests/memory-google-default.test.ts
Muhsin Mustapha c965aa7687 fix: update Google Gemini BYOK models to current API (remove shut-down 2.0 models, add 3.x) (#3821)
* fix: update Google Gemini BYOK models to current API (remove shut-down 2.0 models, add 3.x)

gemini-2.0-flash and gemini-2.0-flash-lite are now shut down by Google (404 NOT_FOUND). Replace the default model and suggested model list in the Google Gemini BYOK provider with the current live API lineup per https://ai.google.dev/gemini-api/docs/models (last updated 2026-06-01).

New default: gemini-3.5-flash (Stable, May 2026).

Full model list: gemini-3.5-flash, gemini-3.1-pro-preview, gemini-3-flash-preview, gemini-3.1-flash-lite, gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite.

* fix: update FAST_MODEL_BY_PROTOCOL.google to live gemini-3.5-flash

The SUGGESTED_MODELS list was migrated from 2.0 to 3.x in the previous
commit but FAST_MODEL_BY_PROTOCOL.google was missed, leaving the shared
fast-pick default (used by the memory extractor auto-mode and other
one-pick consumers) pointing at the shut-down gemini-2.0-flash endpoint.

Also adds a test in tests/state/api-protocols.test.ts that asserts the
Google fast default is contained in the live suggested-models list, so
the two tables cannot drift apart silently in future updates.

* fix: update daemon PROVIDER_DEFAULTS.google.model to gemini-3.5-flash

The memory extractor's PROVIDER_DEFAULTS table in memory-llm.ts still
had gemini-2.0-flash as the Google fast-pick fallback. The env-key path
and the BYOK chatProvider path both read this table when no explicit
model is set, so memory extraction against a Google key would still hit
the shut-down endpoint even after the BYOK Settings defaults were fixed.

Also fixes the stale gemini-2.0-flash assertion in
SettingsDialog.test.ts that was keeping CI red after the previous
commit updated the expected default.

Adds apps/daemon/tests/memory-google-default.test.ts: a focused
regression test that calls extractWithLLM with a Google chatProvider
carrying no model and asserts the outbound URL contains gemini-3.5-flash
so the daemon and web tables cannot drift silently in future updates.

* chore: normalize CRLF to LF on three files modified in this PR
2026-06-11 17:28:04 +00:00

62 lines
2.0 KiB
TypeScript

import { promises as fsp } from 'node:fs';
import path from 'node:path';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { extractWithLLM } from '../src/memory-llm.js';
import { memoryDir } from '../src/memory.js';
import { __resetExtractionsForTests } from '../src/memory-extractions.js';
const dataDir = path.join(process.env.OD_DATA_DIR as string, 'memory-google-default-test');
const originalFetch = globalThis.fetch;
beforeEach(async () => {
await fsp.rm(memoryDir(dataDir), { recursive: true, force: true });
__resetExtractionsForTests();
});
afterEach(() => {
globalThis.fetch = originalFetch;
});
describe('memory-llm Google fast-model default', () => {
it('uses gemini-3.5-flash (not a shut-down 2.0 model) when chatProvider omits a model', async () => {
let capturedUrl: string | null = null;
globalThis.fetch = async (input: Parameters<typeof fetch>[0]) => {
const url =
typeof input === 'string'
? input
: input instanceof URL
? input.toString()
: (input as Request).url;
capturedUrl = url;
// Return a valid Google Gemini response shape so extractWithLLM can parse it.
return new Response(
JSON.stringify({
candidates: [{ content: { parts: [{ text: '{"entries":[]}' }] } }],
}),
{ status: 200, headers: { 'content-type': 'application/json' } },
);
};
await extractWithLLM(
dataDir,
{ userMessage: 'I prefer dark mode.', assistantMessage: 'Noted.' },
{
projectRoot: null,
chatAgentId: null,
chatProvider: {
provider: 'google',
apiKey: 'AQ.TestKeyForUnitTests01234567890123456789012',
baseUrl: 'https://generativelanguage.googleapis.com',
apiVersion: '',
model: '',
},
},
);
expect(capturedUrl).not.toBeNull();
expect(capturedUrl).toContain('gemini-3.5-flash');
expect(capturedUrl).not.toContain('gemini-2.0-flash');
});
});