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 & Architecture

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:

┌────────────────────────┐ ┌─────────────────────────┐ ┌───────────────────────┐ │ Caller/User │ │ Vite Frontend (React) │ │ Twilio Webhook │ │ Telephony/Audio Stream │ │ Dashboard + Testing │ │ Incoming Calls / SMS │ └───────────┬────────────┘ └────────────┬────────────┘ └───────────┬───────────┘ │ │ │ │ (Twilio Stream WebSockets) │ (REST API & Auth) │ ▼ ▼ │ ┌────────────────────────────────────────────────────────────────────┐ │ │ Fastify Voice Desk Server │ │ (TwiML Stream) │ (railway-backend-index-FIXED.js) │◄────────────┘ └─────────────────────────────────┬──────────────────────────────────┘ │ ┌────────────────────────┼────────────────────────┐ │ (OpenAI WS Relay) │ (Supabase client RLS) │ (Hume API Access) ▼ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ ┌───────────────────┐ │ OpenAI API │ │ Supabase Database│ │ Hume AI API │ │ Realtime Audio │ │ Vector Embed & │ │ Emotion Analytics │ │ + GPT-4o RAG │ │ Edge Functions │ │ Webhook Logs │ └──────────────────┘ └──────────────────┘ └───────────────────┘

Lifecycle Flow

The step-by-step lifecycle flow of an incoming call through the voice agent workspace:

  1. Twilio incoming call matches webhook configuration, querying Supabase settings before executing a TwiML WebSocket stream response.
  2. WebSocket handshake opens media relays to Fastify which launches a parallel connection to api.openai.com/v1/realtime.
  3. Audio payload relays process PCM input, passing real-time Voice Activity Detection (VAD) updates. Output stream packets are converted back for Twilio playback.
  4. Active tool calls intercept semantic inquiries, querying matching documents or updating databases via Edge API triggers.
  5. Post-call closure records duration, saves call transcripts, and runs background LLM extractions to format final summary notes.
Server Integration

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.
Database & Schema

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-embedding creates vectors using text-embedding-3-small; semantic-knowledge-search handles similarity inquiries.
  • CRM Hooks: push-lead-to-cms pushes data to Clio or Lawmatics; process-cms-push-queue processes queued tasks.
  • Outreach Automation: trigger-chase-protocol schedules SMS templates; execute-scheduled-actions manages messaging timeouts.
  • Telephony: twilio-webhook handles incoming calls; make-outbound-call starts outbound calls.
Frontend Web Client

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.
Setup & Deployment

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:

  1. Install packages for the workspace dependencies:
    npm install
  2. Create environment config: Copy and populate the values in your local .env file.
  3. Run the Fastify server:
    node railway-backend-index-FIXED.js
  4. Run the Vite frontend:
    npm run dev
  5. 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);
}
References

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.3 in 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.
Copied to clipboard!