search
search is SABLE's document semantic search Edge Function — the same retrieval layer
/api/chat and /api/search (the web routes) ultimately call through to for scoped answers with
citations.
Contract
POST { query, as }
- Embed the query with Voyage (
voyage-4, 1024-dim output, truncated to 4,000 characters,input_type: "query"). - Resolve the verified caller from their Supabase JWT.
- Scope retrieval to the caller's org/project boundary —
asselects a view-as scope for a lead, never a client-supplied override of whose data is visible. - Retrieve production knowledge chunks via the
match_knowledge_chunks_scopedRPC.
Why this runs as an Edge Function, not web code
VOYAGE_API_KEY is a Supabase secret; SUPABASE_URL/SUPABASE_SERVICE_ROLE_KEY are
auto-injected into the Edge runtime. This is the general "secrets live in Edge Functions" pattern
this repository follows — the browser never sees the Voyage key or a service-role database key,
even indirectly through a web API response.
Scope resolution
logic.ts's resolveSearchScope is the shared function that turns a verified caller plus a
requested as value into the actual project/org boundary a query is allowed to search — the same
scope-resolution shape used across chat, the spine, and the API routes described in
Security Scoping.
Where the code lives
sable-agents-demo/supabase/functions/search/index.ts,logic.tssable-agents-demo/web/api/search.js,_rag.jssable-agents-demo/docs-site/docs/reference/search-indexing.md— the ingestion/embedding side this function retrieves from