From 418357332fb2464ddacb08888c021a8cffc52d63 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Thu, 23 Jul 2026 12:02:36 -0700 Subject: [PATCH] Revert "fix(embed): stamp gateway-resolved model in content_chunks.model, not compiled default (#2846)" This reverts commit 5aa4795c047b9e590229b9b1c0d43b0739f54b95. --- src/core/pglite-engine.ts | 14 +-------- src/core/postgres-engine.ts | 19 +----------- test/e2e/embedding-column-pglite.test.ts | 38 ------------------------ 3 files changed, 2 insertions(+), 69 deletions(-) diff --git a/src/core/pglite-engine.ts b/src/core/pglite-engine.ts index d2f1551c8..b8b23aa0e 100644 --- a/src/core/pglite-engine.ts +++ b/src/core/pglite-engine.ts @@ -2288,18 +2288,6 @@ export class PGLiteEngine implements BrainEngine { const params: unknown[] = []; let paramIdx = 1; - // Provenance fallback for chunks without an explicit `model`: resolve the - // gateway's runtime model, not the compile-time DEFAULT_EMBEDDING_MODEL. - // See postgres-engine.ts _upsertChunksOnce for the full rationale — pglite - // mirrors it for parity. - let resolvedModel: string = DEFAULT_EMBEDDING_MODEL; - try { - const gw = await import('./ai/gateway.ts'); - resolvedModel = gw.getEmbeddingModel() || resolvedModel; - } catch { - // Gateway unconfigured (unit tests / pre-connect): keep the default. - } - for (const chunk of chunks) { const embeddingStr = chunk.embedding ? '[' + Array.from(chunk.embedding).join(',') + ']' @@ -2332,7 +2320,7 @@ export class PGLiteEngine implements BrainEngine { if (embeddingImageStr) params.push(embeddingImageStr); params.push( pageId, chunk.chunk_index, chunk.chunk_text, chunk.chunk_source, - chunk.model || resolvedModel, chunk.token_count || null, + chunk.model || DEFAULT_EMBEDDING_MODEL, chunk.token_count || null, chunk.language || null, chunk.symbol_name || null, chunk.symbol_type || null, chunk.start_line ?? null, chunk.end_line ?? null, parentPath, chunk.doc_comment || null, chunk.symbol_name_qualified || null, diff --git a/src/core/postgres-engine.ts b/src/core/postgres-engine.ts index 13d02994b..b58d748f6 100644 --- a/src/core/postgres-engine.ts +++ b/src/core/postgres-engine.ts @@ -2421,23 +2421,6 @@ export class PostgresEngine implements BrainEngine { const params: unknown[] = []; let paramIdx = 1; - // Provenance fallback for chunks that don't carry an explicit `model`: - // resolve the model the gateway ACTUALLY uses at runtime, not the - // compile-time DEFAULT_EMBEDDING_MODEL constant. Callers like `embed` - // build ChunkInputs without a `model` field (src/commands/embed.ts), so - // the old `chunk.model || DEFAULT_EMBEDDING_MODEL` fallback stamped the - // hardcoded default (e.g. zeroentropyai:zembed-1) onto rows whose vectors - // were produced by a different, config-resolved model — corrupting the - // provenance that signature-drift staleness + dim-migration logic trust. - // Mirrors the resolve-then-fallback pattern used for schema sizing above. - let resolvedModel: string = DEFAULT_EMBEDDING_MODEL; - try { - const gw = await import('./ai/gateway.ts'); - resolvedModel = gw.getEmbeddingModel() || resolvedModel; - } catch { - // Gateway unconfigured (unit tests / pre-connect): keep the default. - } - for (const chunk of chunks) { const embeddingStr = chunk.embedding ? '[' + Array.from(chunk.embedding).join(',') + ']' @@ -2467,7 +2450,7 @@ export class PostgresEngine implements BrainEngine { if (embeddingImageStr) params.push(embeddingImageStr); params.push( pageId, chunk.chunk_index, chunk.chunk_text, chunk.chunk_source, - chunk.model || resolvedModel, chunk.token_count || null, + chunk.model || DEFAULT_EMBEDDING_MODEL, chunk.token_count || null, chunk.language || null, chunk.symbol_name || null, chunk.symbol_type || null, chunk.start_line ?? null, chunk.end_line ?? null, parentPath, chunk.doc_comment || null, chunk.symbol_name_qualified || null, diff --git a/test/e2e/embedding-column-pglite.test.ts b/test/e2e/embedding-column-pglite.test.ts index 7254806cf..86ba41693 100644 --- a/test/e2e/embedding-column-pglite.test.ts +++ b/test/e2e/embedding-column-pglite.test.ts @@ -216,44 +216,6 @@ describe('hybridSearch + resolver — unknown column at entry (D11)', () => { }); }); -describe('upsertChunks — model provenance uses gateway-resolved model, not compiled default', () => { - // Regression (zbrain-rfi): when a caller builds ChunkInputs without an - // explicit `model` (as src/commands/embed.ts does), the engine used to - // stamp the compile-time DEFAULT_EMBEDDING_MODEL ('zeroentropyai:zembed-1') - // onto content_chunks.model — even though the vector was produced by the - // config-resolved model. That corrupted provenance the signature-drift + - // dim-migration logic trusts. The engine must fall back to the model the - // gateway ACTUALLY resolves at write time. - test('unspecified chunk.model records the resolved model, not zeroentropyai:zembed-1', async () => { - configureGateway({ - embedding_model: 'openai:text-embedding-3-large', - embedding_dimensions: 1536, - env: { OPENAI_API_KEY: 'sk-test' }, - }); - - await engine.putPage('docs/provenance-page', { - type: 'concept', - title: 'Provenance test page', - compiled_truth: 'Chunk whose model column must reflect the resolved model.', - }); - // No `model` field on the input — the write-side fallback must fill it. - await engine.upsertChunks('docs/provenance-page', [ - { chunk_index: 0, chunk_text: 'provenance chunk', chunk_source: 'compiled_truth' }, - ]); - - const rows = await engine.executeRaw<{ model: string }>( - `SELECT cc.model FROM content_chunks cc - JOIN pages p ON p.id = cc.page_id - WHERE p.slug = 'docs/provenance-page'`, - ); - expect(rows.length).toBe(1); - expect(rows[0].model).toBe('openai:text-embedding-3-large'); - expect(rows[0].model).not.toBe('zeroentropyai:zembed-1'); - - resetGateway(); - }); -}); - describe('buildVectorCastFragment — engine SQL composer (D3)', () => { test('vector descriptor emits $1::vector', () => { const r: ResolvedColumn = {