# AI Assistant - Development Status & Roadmap

**Last Updated:** October 7, 2025
**Status:** Core Features Complete ✅ | AI Research Display Fixed ✅

---

## 🎉 Completed Features

### 1. **Admin Access Fix** ✅
- **Issue:** Admins couldn't access documents across all companies
- **Fix:** Updated `find_document_by_filename()` to check `user.is_admin()` before applying filters
- **Location:** `assistant_routes.py:85-107`

### 2. **Document Summarization Linking** ✅
- **Issue:** Summarizations weren't being linked back to CaseDocuments
- **Fix:** Modified `process_summarization_job()` to set `case_doc.summarization_job_id`
- **Benefit:** Assistant now retrieves existing summaries instead of asking to create new ones
- **Location:** `summarization_routes.py:287-296`

### 3. **Clickable Action Links** ✅
- **Feature:** Replaced numbered options with clickable markdown links
- **Actions:** Create Summary, Analyze Document, View Case Dashboard
- **Benefit:** One-click access to features directly from assistant responses
- **Location:** `assistant_routes.py:467-478`

### 4. **Dual Copy Buttons** ✅
- **Feature:** Copy buttons at both top AND bottom of assistant responses
- **CSS Classes:** `.copy-btn-top` and `.copy-btn-bottom`
- **Benefit:** Easy copying for long responses
- **Location:** `base_layout.html:1102-1143`

### 5. **Quick Case Edits** ✅
- **Add Notes:** `"add note to case 123: Client called today"`
- **Update Status:** `"update case 456 status to settled"`
- **Valid Statuses:** active, pending, closed, settled, dismissed, on_hold
- **Functions:** `add_case_note()`, `update_case_status()`
- **Location:** `assistant_routes.py:444-511`

### 6. **Context Memory** ✅
- **Feature:** Remembers last 5 entities (cases/documents) discussed
- **Follow-up Commands:**
  - After discussing case 1: `"add another note: Client approved"` (no case number needed!)
  - After discussing case 1: `"update status to settled"` (remembers case 1)
- **Implementation:**
  - `get_conversation_context()` - Retrieves last entities from conversation
  - `parse_user_intent()` - Enhanced with context hints for GPT-4o
  - Metadata storage: case_number saved in `AssistantMessage.msg_metadata`
- **Location:** `assistant_routes.py:145-186`, `assistant_routes.py:651-662`

### 7. **AI Research Display Fix** ✅ (October 7, 2025)
- **Issue:** AI Research page wasn't displaying responses despite API returning data
- **Root Cause:** Global `addMessage()` function in `base_layout.html` (for assistant chat) was conflicting with AI Research page's `addMessage()` function
- **Symptoms:**
  - API returned data successfully (visible in console logs)
  - User queries displayed correctly
  - AI responses silently failed to render
  - No JavaScript errors shown
- **Solution:** Renamed AI Research function to `addAIMessage()` to avoid namespace collision
- **Impact:** AI Research page now properly displays all conversations
- **Files Modified:** `templates/ai_legal_research.html`
- **Lesson Learned:** Always use unique function names for page-specific JavaScript; global functions can silently override local implementations
- **Location:** `templates/ai_legal_research.html:509-576`

---

## 🚀 Next Features to Implement

### **Priority 1: Multi-Document Search** (HIGH VALUE)
**Command:** `"Find all mentions of 'negligence' in case 123"`

**Implementation Plan:**
```python
def search_documents_in_case(user, case, search_term):
    """Search across all documents in a case"""
    # Get all documents in the case
    docs = CaseDocument.query.filter_by(case_id=case.id).all()

    results = []
    for doc in docs:
        # Search in summarization results
        if doc.summarization_job_id:
            summ = SummarizationResult.query...
            if search_term.lower() in summ.summary.lower():
                results.append({
                    'document': doc,
                    'snippet': extract_context(summ.summary, search_term)
                })

        # Search in analysis results
        if doc.analysis_job_id:
            analysis = AnalysisResult.query...
            # Similar search logic

    return format_search_results(results)
```

**New Intent:** `search_case_documents`
**Example Responses:**
- Found 3 mentions of "negligence" across 2 documents
- Links to specific documents with context snippets

---

### **Priority 2: Batch Operations** (TIME SAVER)
**Commands:**
- `"Summarize all documents in case 123"`
- `"Analyze all PDFs in case 456"`

**Implementation Plan:**
```python
def batch_summarize_documents(user, case):
    """Queue summarization for multiple documents"""
    docs = CaseDocument.query.filter_by(case_id=case.id).all()

    # Filter unsummarized documents
    to_summarize = [d for d in docs if not d.has_summarization()]

    if not to_summarize:
        return "All documents already summarized!"

    # Queue jobs
    job_ids = []
    for doc in to_summarize:
        job_id = queue_summarization_job(doc, user)
        job_ids.append(job_id)

    return f"Started summarization for {len(to_summarize)} documents. Job IDs: {job_ids}"
```

**New Intents:** `batch_summarize`, `batch_analyze`
**UI Enhancement:** Progress tracker showing "2/5 documents completed"

---

### **Priority 3: Smart Document Suggestions** (PROACTIVE)
**Behavior:** When user asks about a case, assistant checks for unanalyzed documents

**Implementation:**
```python
def get_case_summary(case, user):
    """Enhanced with proactive suggestions"""
    summary = build_case_summary(case)

    # Check for unanalyzed documents
    unanalyzed = [d for d in case.documents if not d.has_analysis()]

    if unanalyzed:
        summary += f"\n\n💡 **Suggestion:** You have {len(unanalyzed)} documents that haven't been analyzed yet."
        summary += "\n   Say 'analyze all documents' to process them."

    return summary
```

---

### **Priority 4: Additional Quick Edits** (EXPANDING CAPABILITIES)

**Set Lead Attorney:**
```python
# "Set lead attorney for case 123 to John Doe"
def set_case_lead_attorney(user, case, attorney_name):
    attorney = User.query.filter(
        User.company_id == case.company_id,
        or_(
            User.first_name.ilike(f'%{attorney_name}%'),
            User.last_name.ilike(f'%{attorney_name}%')
        )
    ).first()

    if attorney:
        case.lead_attorney_id = attorney.id
        db.session.commit()
        return f"Set {attorney.get_full_name()} as lead attorney"
```

**Add Team Members:**
```python
# "Add Sarah to case 123 team"
def add_team_member(user, case, member_name):
    member = find_user_by_name(member_name, case.company_id)
    if member and member not in case.team_members:
        case.team_members.append(member)
        db.session.commit()
```

**Schedule Events:**
```python
# "Schedule hearing for case 123 on 10/15/2025"
# Future enhancement - requires calendar integration
```

---

### **Priority 5: Document Timeline Generator** (ANALYSIS TOOL)

**Command:** `"Create timeline for case 123"`

**Implementation:**
```python
def generate_case_timeline(case):
    """Extract dates from documents and create chronological timeline"""
    events = []

    # Case creation
    events.append({
        'date': case.created_at,
        'event': f'Case opened: {case.case_name}',
        'source': 'Case record'
    })

    # Document uploads
    for doc in case.documents:
        events.append({
            'date': doc.uploaded_at,
            'event': f'Document uploaded: {doc.original_filename}',
            'source': 'Document'
        })

    # Extract dates from summaries/analyses
    for doc in case.documents:
        if doc.has_summarization():
            dates = extract_dates_from_text(doc.summarization.summary)
            for date in dates:
                events.append({
                    'date': date,
                    'event': f'Date mentioned in {doc.original_filename}',
                    'source': doc.original_filename
                })

    # Sort chronologically
    events.sort(key=lambda x: x['date'])

    return format_timeline(events)
```

---

## 📊 Technical Details

### Intent Classification
- **Model:** GPT-4o
- **Temperature:** 0.3
- **Max Tokens:** 200
- **Context Window:** Last 5 assistant messages with entity info

### Supported Intents
1. `summarize_case` - Case summary
2. `analyze_document` - Document analysis
3. `analyze_image` - Image analysis
4. `summarize_document` - Document summarization
5. `find_case` - Case search
6. `list_cases` - List user's cases
7. `list_documents` - List all documents
8. `get_case_info` - Case information
9. `search_documents` - Document search
10. `add_case_note` - Add case note ✨ NEW
11. `update_case_status` - Update case status ✨ NEW
12. `general_help` - Help information

### Context Tracking
```python
context = {
    'last_case_id': '5',           # Database ID
    'last_case_number': '1',       # User-facing case number
    'last_document_id': '14',      # Database ID
    'recent_entities': [
        {'type': 'case', 'id': '5', 'action': 'summarize_case'},
        {'type': 'case', 'id': '5', 'action': 'add_note'}
    ]
}
```

---

## 🐛 Known Issues & Future Fixes

### 1. **OpenAI API Key Configuration**
- **Issue:** API key must be loaded from Flask `app.config`
- **Current Solution:** Using `current_app.config.get('OPENAI_API_KEY')`
- **Future:** Consider caching the client instance

### 2. **Context Persistence**
- **Current:** Context only within single conversation
- **Future:** Cross-conversation memory ("Remember last case I discussed yesterday")

### 3. **Error Handling**
- **Current:** Fallback to "unknown" intent on OpenAI errors
- **Future:** Retry logic, rate limiting awareness

---

## 📝 Testing Checklist for Tomorrow

### Quick Edits
- [ ] Add note without case context (should ask for case)
- [ ] Add note with case context (should use remembered case)
- [ ] Update status with invalid status (should show error)
- [ ] Update status with context (should work seamlessly)

### Context Memory
- [ ] Discuss case 1, then add note (should remember)
- [ ] Discuss case 1, then case 2, then add note (should use case 2)
- [ ] New conversation - context should be empty

### Document Operations
- [ ] Summarize existing summary (should return cached)
- [ ] Summarize new document (should show action links)
- [ ] Analyze document with existing analysis (should return it)

---

## 🎯 Success Metrics

- **Response Time:** < 2 seconds for intent parsing
- **Context Accuracy:** 95%+ correct case/document from context
- **User Satisfaction:** Reduced clicks (from 3-4 to 1 for common tasks)
- **Adoption:** Track usage of context-based commands vs explicit commands

---

## 🔧 Development Notes

### File Locations
- **Main Route:** `/var/www/lawbot/assistant_routes.py`
- **Templates:** `/var/www/lawbot/templates/base_layout.html`
- **Models:** `/var/www/lawbot/models.py`
- **Summarization:** `/var/www/lawbot/summarization_routes.py`
- **TODO List:** `/var/www/lawbot/ASSISTANT_TODO.md` ⭐ Quick reference for pending tasks
- **Project Guide:** `/var/www/lawbot/CLAUDE.md`

### Service Management
```bash
# Restart after changes
systemctl restart epolaw

# Check logs
journalctl -u epolaw -f
tail -f /var/log/epolaw/error.log

# Test in Python
/var/www/lawbot/venv/bin/python3 -c "from app import app; ..."
```

### Database Queries
```python
# Get conversation context
context = get_conversation_context(conversation.id, limit=5)

# Find case by number or ID
case = find_case_by_number_or_id(user, case_identifier)

# Find document by filename
doc = find_document_by_filename(user, filename, case_id=None)
```

---

## 💡 Ideas for Future Enhancements

1. **Voice Commands:** Integration with speech-to-text
2. **Email Integration:** "Email case summary to client"
3. **Calendar Sync:** Google Calendar/Outlook integration
4. **Document Comparison:** "Compare draft1.docx with draft2.docx"
5. **Legal Citation Extraction:** Auto-detect case citations
6. **Billing Integration:** "Bill 2.5 hours to case 123"
7. **Client Portal Links:** "Generate client-facing link for case 123"
8. **Smart Notifications:** "Notify me when case 123 status changes"

---

**Ready to continue building tomorrow! 🚀**
