Analyzer
The analyzer module runs LLM-powered analysis on call transcriptions after a call ends. Two types of analyzers process every call: org analyzers (custom, user-defined) and system analyzers (platform-wide, hidden from users). Both use GPT-5 with a custom prompt to extract insights from the transcription.
How It Works
Section titled “How It Works”Call ends → Transcription saved → analyze_call(call_id) │ ├─ Org Analyzers (assigned to the phone number) │ For each: prompt + transcription → GPT-5 → save to call_analysis │ └─ System Analyzers (run on every call) For each: prompt + transcription → GPT-5 → save to system_call_analysisTwo Types of Analyzers
Section titled “Two Types of Analyzers”Org Analyzers
Section titled “Org Analyzers”Created and managed by the organization through the UI and API. Each analyzer has a custom prompt and is assigned to specific phone numbers via the phone_number_analyzer join table.
pub struct Analyzer { pub id: Uuid, pub name: String, pub prompt: String, // LLM instruction for analysis pub phone_ids: Vec<Uuid>, // Phone numbers this analyzer runs on pub default: bool, // Auto-assign to new phone numbers}Example use cases: sentiment analysis, lead qualification, compliance checks, call summary generation.
Results are stored in the call_analysis table and visible in the call details UI.
System Analyzers
Section titled “System Analyzers”Platform-level analyzers stored in the system_analyzer table. They run on every call automatically, regardless of phone number assignments. Organizations don’t see or manage these.
Results are stored in a separate system_call_analysis table.
Analysis Pipeline
Section titled “Analysis Pipeline”analyze_call is the main entry point, called after a transcription is saved:
- Load the call record and its
phone_number_id - Find all org analyzers assigned to that phone number (
phone_number_analyzertable) - Run each org analyzer sequentially:
- Load the analyzer’s
prompt - Send
prompt(system) +transcription(user) to GPT-5 - Save result to
call_analysiswithcall_id,analyzer_id,analysis_text
- Load the analyzer’s
- Run all system analyzers (from
system_analyzertable):- Same flow but results go to
system_call_analysiswithsystem_analyzer_id
- Same flow but results go to
LLM Execution
Section titled “LLM Execution”All analysis goes through analyze_call_text:
pub async fn analyze_call_text( prompt: String, // Analyzer instruction (system message) transcription: String, // Call transcript (user message)) -> Result<String, AppError>Model: GPT-5 via aisdk OpenAI provider. Returns raw text output.
Storage
Section titled “Storage”| Table | Analyzer Type | Key Fields |
|---|---|---|
call_analysis | Org | call_id, analyzer_id, analysis_text, created_at |
system_call_analysis | System | call_id, system_analyzer_id, analysis_text, created_at |
API Endpoints
Section titled “API Endpoints”All endpoints require an authenticated session and scope to the org.
| Route | Method | Description |
|---|---|---|
/api/analyzers | GET | List all org analyzers (phone assignments not loaded) |
/api/analyzers/{id} | GET | Get an analyzer with phone assignments |
/api/analyzers | POST | Create an analyzer with phone assignments |
/api/analyzers/{id} | PUT | Update name, prompt, default flag, and phone assignments |
/api/analyzers/{id} | DELETE | Delete an analyzer |
Create and update accept AnalyzerData:
pub struct AnalyzerData { pub name: String, pub prompt: String, pub phone_ids: Vec<Uuid>, pub default: bool,}Phone assignment updates use a delete-all-then-reinsert strategy on phone_number_analyzer.
AI Builder Integration
Section titled “AI Builder Integration”The create and edit forms for org analyzers use the AI Builder to generate and refine the prompt field. Instead of writing analysis instructions manually, you describe what you want in plain English and the AI produces a structured prompt.
Supported actions:
- Generate — describe the analysis you need (e.g., “Extract sentiment, key issues, and resolution status”) and get a complete prompt with categories, output format, and edge cases
- Edit — refine the generated prompt with 8 predefined actions (Improve, Make Concise, Add Examples, Strengthen Safety, etc.) plus free-text custom edits
- Undo — revert the last edit
The AI Builder components (AiGenerateInstructions, InstructionPreview, AiInstructionToolbar) replace the plain textarea in both CreateAnalyzer and AnalyzerDetails components. The AiBuilderArea::Analyzer variant routes requests to 10 analyzer-specific prompt templates in src/shared/ai_builder/prompts/analyzer/.
Permission: AnalyzerCollectionPermission::Create is required to use the AI Builder for analyzers.
Phone Number Assignment
Section titled “Phone Number Assignment”Analyzers are linked to phone numbers, not agents. When a call comes in on a phone number, all analyzers assigned to that number run on the transcription.
The default flag on an analyzer means it gets auto-assigned to newly purchased phone numbers (handled during the phone purchase flow in the twilio module).
Module Structure
Section titled “Module Structure”src/mods/analyzer/├── api/ # CRUD for org analyzers├── components/ # UI: analyzer list, card, details, create form├── types/ # Analyzer, AnalyzerData├── utils/ # analyze_call, analyze_call_one_analyzer, analyze_call_system_analyzers, analyze_call_text└── views/ # AnalyzerListView, AnalyzerDetailsView, CreateAnalyzerView