gabbi-law-voice-nexus-dev
Developer reference documentation hub for the MeetGabbi legal CRM, real-time voice system, and vector-backed knowledge base search framework.
Overview
The system establishes a multi-tenant voice and chat automation workspace running on top of Deno Edge Functions and Fastify middleware:
- Voice Desk Relays connect raw Twilio media streams bidirectionally to OpenAI Realtime socket interfaces.
- RAG Legal Brain matches customer inquiries semantically using cosine distance vector parameters in Postgres.
- CRM Pipeline Integrations push intake records directly to Clio, Lawmatics, Hubspot, and Salesforce.
- Chase Outreach campaigns automate follow-up emails, text messages, and call scheduling for intake conversion.
System Diagram
The core system boundaries and client-server interactions are illustrated below:
Lifecycle Flow
The step-by-step lifecycle flow of an incoming call through the voice agent workspace:
- Twilio incoming call matches webhook configuration, querying Supabase settings before executing a TwiML WebSocket stream response.
- WebSocket handshake opens media relays to Fastify which launches a parallel connection to
api.openai.com/v1/realtime. - Audio payload relays process PCM input, passing real-time Voice Activity Detection (VAD) updates. Output stream packets are converted back for Twilio playback.
- Active tool calls intercept semantic inquiries, querying matching documents or updating databases via Edge API triggers.
- Post-call closure records duration, saves call transcripts, and runs background LLM extractions to format final summary notes.
Fastify Routes
The Fastify backend (running on Railway) manages webhooks and routes. Filter endpoints using the box below. For detailed backend routing and relay logic documentation, see the railway-backend-index-FIXED developer document.
| Route | Method | Description |
|---|---|---|
/incoming-call/:agentId? |
POST | Triggered by Twilio calls. Queries Supabase for agent details and replies with TwiML routing audio to media streams. |
/media-stream/:agentId/:userId? |
GET (WS) | Bidirectional WebSocket handler. Channels Twilio voice payloads to OpenAI and manages assistant audio interruptions. |
/api/phone-numbers |
GET | Fetches phone number lines linked to the user's dashboard along with active agent IDs. |
/api/assign-agent |
POST | Maps a specific agent prompt configuration to a purchased Twilio phone number SID. |
/api/update-prompt/:agentId? |
POST/PUT | Modifies prompt instructions, greetings, and active speaking configurations for an agent. |
/api/calls |
GET | Retrieves historical logging details, duration intervals, and transcript summaries. |
Helper Logic
Key internal functions running inside railway-backend-index-FIXED.js:
| Function | Scope & Operational Logic |
|---|---|
safeSupabaseOperation(operation, name, retries) |
Runs database calls with exponential backoff retries to guarantee persistence during network fluctuations. |
extractContactFromTranscript(callId, userId, callerNumber) |
Queries GPT-4o post-call to parse caller names, email addresses, and notes from transcripts, updating profiles. |
reconnectConversationWs(attempt, maxAttempts) |
Reconnects active sockets to the OpenAI Realtime API without dropping the caller stream session. |
getUserAgent(userId, agentId) |
Loads prompts, greetings, VAD calibrated attributes, and Hume parameters from Supabase cache stores. |
Supabase Tables
Standard Postgres relational tables configured inside Supabase. Use the search filter below to browse the schema:
| Table Name | Primary Columns | Description |
|---|---|---|
organizations |
id (uuid), name (text) |
Handles tenant structures for law firm accounts, separating dashboard items. |
profiles |
id (uuid), user_id (uuid), email (text) |
Links system user information to Supabase Auth tables. |
phone_numbers |
id (uuid), phone_number (text), twilio_sid (text) |
Maps purchased Twilio numbers to agent prompts. |
agent_prompts |
id (uuid), agent_id (uuid), prompt_text (text) |
Stores the system prompts, greetings, and VAD attributes for the agent. |
knowledge_bases |
id (uuid), rag_enabled (boolean) |
Tracks document collections designated for semantic lookup. |
knowledge_base_items |
id (uuid), content (text), embedding (vector) |
Stores document chunks alongside 1536-dimension pgvector embeddings. |
contacts |
id (uuid), phone_number (text), name (text) |
Client profiles captured by the voice agent during calls. |
leads |
id (uuid), status (text), practice_type (text) |
Intake pipeline records tracked in the CRM. |
chase_protocols |
id (uuid), trigger_tags (text[]), actions (jsonb) |
Defines automated follow-up sequences. |
call_activities |
id (uuid), duration (interval), summary (text) |
Stores call metrics, transcripts, and emotional indexes. |
pgvector Matching Function
Cosine similarity matching for the RAG search pipeline is handled via a Postgres database function:
CREATE OR REPLACE FUNCTION match_knowledge_base_items(
query_embedding vector(1536),
match_knowledge_base_id uuid,
match_threshold float DEFAULT 0.3,
match_count int DEFAULT 5
) RETURNS TABLE (
id uuid,
title text,
content text,
type text,
similarity float
) LANGUAGE plpgsql AS $$
BEGIN
RETURN QUERY
SELECT
kbi.id,
kbi.title,
kbi.content,
kbi.type,
1 - (kbi.embedding <=> query_embedding) AS similarity
FROM knowledge_base_items kbi
WHERE kbi.knowledge_base_id = match_knowledge_base_id
AND 1 - (kbi.embedding <=> query_embedding) > match_threshold
ORDER BY kbi.embedding <=> query_embedding
LIMIT match_count;
END;
$$;
Edge Modules
Categorized layout of core Deno Edge Functions deployed on Supabase:
- RAG Processing:
generate-knowledge-embeddingcreates vectors usingtext-embedding-3-small;semantic-knowledge-searchhandles similarity inquiries. - CRM Hooks:
push-lead-to-cmspushes data to Clio or Lawmatics;process-cms-push-queueprocesses queued tasks. - Outreach Automation:
trigger-chase-protocolschedules SMS templates;execute-scheduled-actionsmanages messaging timeouts. - Telephony:
twilio-webhookhandles incoming calls;make-outbound-callstarts outbound calls.
React Architecture
The client side uses React, Vite, and TypeScript. Structure overview:
- Page Router (`App.tsx`): Integrates React Router DOM, managing authentication states, layouts, and redirects.
- State Contexts (`src/contexts`): Provides global hooks for authentication, Supabase client sessions, and active organizations.
- UI Components (`src/components/ui`): Reusable UI primitives styled with Vanilla CSS and Tailwind CSS classes.
Dashboard Pages
Primary configuration views within the web client:
| Dashboard View | Source File | Key Functionality |
|---|---|---|
| Voice Desk Panel | VoiceAgentSettings.tsx |
Allows editing prompts, greetings, selecting voice models, and configuring VAD thresholds. |
| RAG Semantic Admin | BrainRAG.tsx |
Supports document uploading, manual chunk indexing, cosine distance threshold tweaks, and search evaluations. |
| Outreach Drips | ChaseProtocol.tsx |
A visual builder used to configure automated drip campaigns (SMS and Email delays) triggered by status updates. |
| Intake Pipeline | Pipeline.tsx |
A Kanban board displaying lead cards, estimated values, and conversion pipelines. |
| Developer Sandbox | QATestingDashboard.tsx |
Allows running automated test calls, auditing LLM evaluations, and verifying prompt behaviors. |
Env Variables
Required environment configuration settings in your local .env file:
| Variable Name | Type | Default | Description |
|---|---|---|---|
PORT |
number |
3000 |
The network port where Fastify listens for incoming webhook requests. |
OPENAI_API_KEY |
string |
Required | API credential for OpenAI. Enables Realtime WebSockets, text embeddings, and GPT-4o extractions. |
SUPABASE_URL |
string |
Required | URL endpoint pointing to your Supabase instance. |
SUPABASE_ANON_KEY |
string |
Required | Client-side key used for standard authenticated requests. |
SUPABASE_SERVICE_ROLE_KEY |
string |
Required | Admin credential used by background server threads to bypass Row Level Security. |
TWILIO_ACCOUNT_SID |
string |
Required | Developer account identifier used to initialize the Twilio API client. |
TWILIO_AUTH_TOKEN |
string |
Required | Auth token for standard REST verification headers in Twilio API requests. |
Local Installation
Steps to run the client and backend servers locally:
- Install packages for the workspace dependencies:
npm install - Create environment config: Copy and populate the values in your local
.envfile. - Run the Fastify server:
node railway-backend-index-FIXED.js - Run the Vite frontend:
npm run dev - Expose your local port to Twilio for incoming webhook routing:
ngrok http 3000
Code Snippets
Example: Querying semantic knowledge from the RAG search endpoint
async function performVectorSearch(supabaseUrl, anonKey, kbId, query) {
const endpoint = `${supabaseUrl}/functions/v1/semantic-knowledge-search`;
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${anonKey}`
},
body: JSON.stringify({
knowledge_base_id: kbId,
query: query,
top_k: 3,
similarity_threshold: 0.3
})
});
const result = await response.json();
if (result.success) {
return result.results;
}
throw new Error(result.error);
}
Dependencies
Core dependencies mapped by their operational scope:
- Voice Stream Relays:
ws(OpenAI realtime sockets),twilio(REST SDK). - Backend Framework:
fastify,@fastify/websocket,@fastify/formbody. - Database Clients:
@supabase/supabase-js. - Frontend Engine:
react,typescript,vite,react-router-dom. - Expression Analytics:
@humeai/voice-react(Hume SDK connection modules).
Best Practices
- PostgREST Null Filtering: When mapping team identifiers in DB helpers, always run a null check filter:
.filter(id => !!id)prior to querying integrations with.in("user_id", ...)to prevent query parser crashes. - Vector Cosine Thresholds: Maintain RAG similarity limits around
0.3in matching queries. This prevents empty results while filtering out irrelevant contexts. - Non-blocking Sockets: Defer database writes, OpenAI post-call transcriptions, and CRM queue pushes to asynchronous promises. Do not block active VoIP audio packages.
- Interruption Control: When a user starts speaking during AI output, immediately clear the Twilio audio output buffers and send a truncate command to the OpenAI realtime socket.