# Investigation Report: Copilot Not Loading Data During Call

**Date:** 2026-01-17
**Status:** Investigation Complete

---

## Summary

The LiveCopilot shows during calls but displays:
1. "No script for this lead type/stage"
2. "No intel available for this lead"
3. "Starting transcription..." (stuck, never starts)
4. CALL button still visible during active call

---

## Problem 1: "No script for this lead type/stage"

### Root Cause
The ScriptPanel (`admin/src/components/ScriptPanel.jsx:267`) calls `scriptsApi.getForLead(leadId)` which hits `/api/scripts/for-lead/:leadId`.

The backend route (`src/routes/scripts.js:280-328`) requires:
1. **Lead must have `lead_type` and `platform_stage` populated** (lines 285-289)
2. **Scripts must exist** in the `scripts` table matching:
   - `is_active = true`
   - `target_type` matches lead's `lead_type` OR 'both'
   - `target_stage` matches lead's `platform_stage`

```javascript
// src/routes/scripts.js:285-311
const { data: lead } = await supabase
  .from('leads')
  .select('lead_type, platform_stage')  // These fields must be populated
  .eq('id', leadId)
  .single();

// Then filters scripts by:
query = query.or(`target_type.eq.${lead.lead_type},target_type.eq.both`);
query = query.eq('target_stage', lead.platform_stage);
```

If `lead_type` or `platform_stage` is null, or no scripts match, `recommendedScripts` returns empty.

### Fix Options
1. **Data Fix**: Ensure leads have `lead_type` and `platform_stage` populated via platform sync
2. **Code Fix**: Modify ScriptPanel to show a default/generic script when none found
3. **Database Fix**: Create scripts for all stage combinations

---

## Problem 2: "No intel available for this lead"

### Root Cause
The LiveIntelPanel (`admin/src/components/LiveIntelPanel.jsx:24`) calls `aiApi.getLiveIntel(leadId)` which hits `/api/ai/live-intel/:leadId`.

The condition at line 54 shows "No intel" when:
```javascript
if (!intel || (!intel.company && !intel.person && intel.similar_wins?.length === 0))
```

This means the endpoint returns either:
- An error/null response
- Empty data (no company, person, or similar_wins)

The live-intel endpoint (`src/routes/ai.js`) queries the `lead_intel` table. If no intel has been generated/stored for this lead, it returns empty data.

### Fix Options
1. **Data Fix**: Run intel generation for leads (via company/person research endpoints)
2. **Code Fix**: Generate intel on-the-fly if not found
3. **UI Fix**: Show "Intel loading..." or offer a "Generate Intel" button

---

## Problem 3: "Starting transcription..." stuck forever

### Root Cause
Looking at `admin/src/components/LiveCopilot.jsx:778`:
```javascript
{transcript || (isListening ? 'Listening...' : 'Starting transcription...')}
```

The text shows "Starting transcription..." when:
- `isListening` is `false`
- `transcript` is empty

`isListening` only becomes true when:
1. **Deepgram WebSocket** connects (line 497) - requires `DEEPGRAM_API_KEY` env var
2. **Web Speech API** starts (line 643) - fallback if Deepgram not configured

The flow at lines 480-655:
1. Request microphone access
2. Check if Deepgram credentials exist (`creds?.url && creds?.apiKey`)
3. If yes: Connect WebSocket to Deepgram
4. If no: Fall back to Web Speech API

**Likely Cause**: `DEEPGRAM_API_KEY` is not set in Railway, AND the Web Speech API fallback fails silently.

The deepgram-credentials endpoint (`src/routes/ai.js:911-926`) returns:
```javascript
if (!config.configured) {
  return res.status(503).json({
    success: false,
    error: 'Live transcription not configured'
  });
}
```

If this returns 503, the frontend falls back to Web Speech API. But Web Speech API may:
- Not be supported (non-Chrome browsers)
- Require HTTPS
- Fail without proper error display

### Fix Options
1. **Config Fix**: Add `DEEPGRAM_API_KEY` to Railway environment variables
2. **Code Fix**: Improve error handling to show why transcription failed
3. **UI Fix**: Show explicit status when Web Speech API is being used vs Deepgram

---

## Problem 4: CALL button visible during active call

### Root Cause
The LeadActionBar (`admin/src/components/LeadActionBar.jsx`) is rendered at:
- `admin/src/pages/LeadProfile.jsx:364-371`

It's styled as:
```jsx
<div className="fixed bottom-0 left-0 right-0 ... z-30">
```

TwilioCall is styled as:
```jsx
<div className="fixed bottom-0 inset-x-0 z-[60] ...">
```

Both occupy the bottom of the screen. While TwilioCall has higher z-index (60 > 30), if TwilioCall is now a compact bottom bar, there may be visual stacking issues.

### Fix
**Hide LeadActionBar when a call is active:**

In `LeadProfile.jsx`, use `useCall()` to check `activeLead`:

```jsx
const { startCall, activeLead } = useCall();

// In render, conditionally show LeadActionBar:
{!activeLead && (
  <LeadActionBar
    lead={lead}
    actionLabel={lead.metadata?.action_label}
    onCall={handleCall}
    onSms={() => setShowAIWriter(true)}
    onCallback={() => setShowCallbackModal(true)}
    calling={calling}
  />
)}
```

---

## Fix Tasks

### Immediate Fixes (Code)

1. **LeadActionBar visibility** - Hide when call is active
   - File: `admin/src/pages/LeadProfile.jsx`
   - Change: Wrap LeadActionBar in `{!activeLead && ...}`

2. **Transcription error display** - Show why transcription failed
   - File: `admin/src/components/LiveCopilot.jsx`
   - Change: Add status text when credentials fail or Web Speech unsupported

### Configuration Fixes (Railway)

3. **Add DEEPGRAM_API_KEY** to Railway environment
   - Get API key from Deepgram dashboard
   - Add to Railway project environment variables

### Data Fixes (Database)

4. **Populate lead_type and platform_stage** on leads
   - Run platform sync: `POST /api/sync/platform`
   - Or manually update leads in Supabase

5. **Create default scripts** for common scenarios
   - Use scripts admin UI or direct database insert
   - Minimum: one script for each lead_type/stage combination

6. **Generate intel for leads**
   - Call `/api/ai/company-research/:companyName` for company intel
   - Call `/api/ai/person-research/:leadId` for person intel

---

## Verification Steps

After fixes:
1. Start a call → Copilot should show
2. Transcript should show "Listening..." not "Starting transcription..."
3. Script panel should show a script (or clear "no script" reason)
4. Intel panel should show data (or "Generate Intel" button)
5. CALL button should NOT be visible during active call

---

## Files Referenced

| File | Lines | Description |
|------|-------|-------------|
| `admin/src/components/ScriptPanel.jsx` | 267, 315-323 | Script fetch and "no script" display |
| `admin/src/components/LiveIntelPanel.jsx` | 24, 54-61 | Intel fetch and "no intel" display |
| `admin/src/components/LiveCopilot.jsx` | 480-655, 778 | Transcription init and status display |
| `admin/src/components/LeadActionBar.jsx` | 30 | Fixed bottom position |
| `admin/src/pages/LeadProfile.jsx` | 364-371 | LeadActionBar usage |
| `src/routes/scripts.js` | 280-328 | For-lead endpoint |
| `src/routes/ai.js` | 911-926 | Deepgram credentials endpoint |
| `src/services/deepgram.js` | 19-43 | Deepgram config check |
