Skip to content

feat: dynamic embedding column selection for search#1106

Closed
garrytan-agents wants to merge 1 commit into
garrytan:masterfrom
garrytan-agents:feat/dynamic-embedding-column
Closed

feat: dynamic embedding column selection for search#1106
garrytan-agents wants to merge 1 commit into
garrytan:masterfrom
garrytan-agents:feat/dynamic-embedding-column

Conversation

@garrytan-agents

Copy link
Copy Markdown
Contributor

What

Dynamic embedding column selection — specification for Claude Code implementation.

The Issue

Search hardcodes OpenAI embedding column. Users with multiple providers (Voyage, ZeroEntropy) have fully backfilled alternative columns with valid HNSW indexes, but cannot route search through them.

Key Evidence

Three embedding columns exist with near-full coverage (374K ZE, 247K Voyage, 371K OpenAI) and valid HNSW indexes. postgres-engine.ts:searchVector() resolves the column as a binary text/image switch, ignoring all other columns.

Proposed Approach

  1. embedding_columns config registry mapping column → provider + dimensions + pgvector type
  2. search_embedding_column config key to select default search column
  3. Widen SearchOpts.embeddingColumn type from union to string
  4. Route embedQuery() through the matching provider (not just the global config)
  5. Handle halfvec cast for high-dimensional columns (ZE 2560d)

How to Implement

Pick up with Claude Code:

  • Read docs/issues/dynamic-embedding-column.md for full spec + test guidance
  • Write red tests first based on the Test Guidance section
  • Implement the fix
  • Key files: types.ts, postgres-engine.ts, embedding.ts, gateway.ts, hybrid.ts, mode.ts, query-cache.ts

File: docs/issues/dynamic-embedding-column.md

Tier 2 issue spec for Claude Code implementation. Adds search_embedding_column
config key and column registry to route queries through any declared embedding
provider (OpenAI, Voyage, ZeroEntropy, etc.) instead of hardcoding OpenAI.

File: docs/issues/dynamic-embedding-column.md
@garrytan

Copy link
Copy Markdown
Owner

Closing — this spec doc was the seed for the implementation now happening on garrytan/riga. Thanks for the structured write-up @garrytan-agents; it became the basis for the plan after a /plan-eng-review wave + codex outside voice.

Implementation absorbed the spec verbatim plus 10 codex findings (D7-D16 in the plan) my own review missed:

  • DB-plane config merge (the smoke test's gbrain config set actually had to work)
  • cache schema dim limitation — skip cache for non-default columns
  • cosineReScore hydrating wrong-space embeddings — thread column through getEmbeddingsByChunkIds
  • isAvailable() checking global default instead of resolved column provider
  • engine should take a pre-validated descriptor, not call the resolver itself
  • registry KEYS are config-controlled — added regex + identifier-quoting + field validation
  • doctor needs format_type(atttypid, atttypmod) not udt_name (dim drift is the real failure)
  • coverage gate on gbrain config set search_embedding_column X when <90%
  • MCP search op is keyword-only — embedding_column only on query
  • eval-replay needs per-row captured column or it false-positives on every config flip

Plan file: ~/.claude/plans/system-instruction-you-are-working-sparkling-sun.md (local to my workspace; included in commits via the eng-review report).

Ship branch: garrytan/riga.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants