OpenRouter adapter and Voyage AI semantic search added in one commit
Chris-o-O dropped OpenRouter multi-model support and a pgvector semantic search pipeline in a single 925-line commit. Each is gated by its own env var and follows the existing provider abstractions, so they can be adopted independently.
The OpenRouter adapter (backend/src/lib/llm/openrouter.ts) uses the OpenAI SDK pointed at https://openrouter.ai/api/v1 to route to GPT-4o, GPT-4 Turbo, Mistral Large, Llama 3.3 70B, and Gemma 3 27B. It wires into the existing streamChat interface, handles tool-call accumulation across stream chunks, and stores the user's key in a new openrouter_api_key column on user_profiles. The account settings page handles it identically to how Claude and Gemini keys are already handled.
The semantic search pipeline uses Voyage AI's voyage-law-2 model (1024-dimensional embeddings, tuned for legal text). Documents are chunked at 800 characters with 150-character overlap at upload time, fire-and-forget, with [Page N] markers preserved through the chunking. Chunks go into a document_chunks table; a match_document_chunks Supabase RPC does cosine similarity lookup. The search is exposed via a /search/semantic endpoint, a semantic_search chat tool, and a widget on the project page.
Before relying on this in production: indexing has no retry and no backfill, so existing documents won't appear in semantic results until re-uploaded. The pgvector migration requires the extension to be manually enabled in the Supabase dashboard first. The RPC uses security definer and filters by a p_user_id parameter rather than auth.uid(), which is correct for service-role backend usage but means table-level RLS isn't load-bearing here.
Spotted something wrong? Or know the PR text has fresher detail than the writeup above?