Files
nexu-io__open-design/apps/daemon/tests/memory-google-default.test.ts
open-design-crew[bot] 66e4061274 fix(memory): retire chat auto-extraction and clean up its artifacts (#5708)
- chatExtractionEnabled now defaults OFF (explicit opt-in only); it gates
  the regex pack, chat-form profile capture, and LLM extractor together
  while leaving memory injection untouched
- add a one-time boot migration (memory-cleanup.ts) that deletes regex-pack
  artifacts by name+template fingerprint, prunes user_profile to the
  canonical field set the settings editor writes, and forces the legacy
  config flag off once; marker-gated so a conscious re-opt-in sticks
- persist writer provenance (frontmatter source:) on every new entry so
  future audits can tell auto-extracted facts from hand-written ones
- LLM-extracted entries are deliberately kept: on-disk they are
  indistinguishable from hand-written prose, and they are the least
  harmful of the retired pipelines' output

Co-authored-by: NJUHua <113895241+NJUHua@users.noreply.github.com>
2026-07-16 02:53:44 +00:00

65 lines
2.2 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, writeMemoryConfig } 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();
// Chat auto-extraction defaults OFF product-wide; this spec covers the
// provider auto-pick inside the extractor, so opt in explicitly.
await writeMemoryConfig(dataDir, { chatExtractionEnabled: true });
});
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');
});
});