# Research Execution Flow - Code Walkthrough ## Overview This document traces the complete flow from when a user clicks "Start Research" to when they see the results on the UI. --- ## 1. User Clicks "Start Research" Button ### Location: `ActionButtons.tsx` (Line 104-119) ```typescript : } onClick={onExecute} // ← This is the entry point disabled={isExecuting || !canExecute} > {isExecuting ? 'Researching...' : 'Start Research'} ``` **What happens:** - Button shows loading spinner when `isExecuting` is true - Calls `onExecute` callback - Button is disabled if no queries are selected (`canExecute` must be true) --- ## 2. IntentConfirmationPanel Handles Execution ### Location: `IntentConfirmationPanel.tsx` (Line 106-122) ```typescript const handleExecute = () => { const updatedIntent = { ...intent }; // Pass wizard state to onConfirm for draft saving onConfirm(updatedIntent, wizardState); // Get selected queries (sorted by priority) const queriesToUse = Array.from(selectedQueries) .sort((a, b) => a - b) .map(idx => editedQueries[idx]) .filter(q => q && q.query.trim().length > 0); // Store updated trends config if (editedTrendsConfig && intentAnalysis) { intentAnalysis.trends_config = editedTrendsConfig; } onExecute(queriesToUse); // ← Passes queries to ResearchInput }; ``` **What happens:** 1. Confirms the intent (saves draft) 2. Extracts selected queries from the UI 3. Updates trends configuration if modified 4. Calls `onExecute` with the selected queries --- ## 3. ResearchInput Passes to Execution Hook ### Location: `ResearchInput.tsx` (Line 580-586) ```typescript onExecute={async (selectedQueries) => { const result = await execution.executeIntentResearch(state, selectedQueries); if (result?.success) { // Skip to results step onUpdate({ currentStep: 3 }); } }} ``` **What happens:** 1. Calls `execution.executeIntentResearch()` with wizard state and selected queries 2. If successful, automatically navigates to Step 3 (Results) --- ## 4. Execution Hook Processes Research ### Location: `useResearchExecution.ts` (Line 284-378) ```typescript const executeIntentResearch = useCallback(async ( state: WizardState, selectedQueries?: ResearchQuery[] ): Promise => { // 1. Ensure intent is available let intent = confirmedIntent; if (!intent) { const analysis = await analyzeIntent(state); if (!analysis?.success) { return null; } intent = analysis.intent; } // 2. Set loading state setIsExecuting(true); setError(null); try { // 3. Prepare queries (use provided or fall back to suggested) const queriesToUse = selectedQueries || intentAnalysis?.suggested_queries?.slice(0, 5) || []; // 4. Make API call const response = await intentResearchApi.executeIntentResearch({ user_input: state.keywords.join(' '), confirmed_intent: intent, selected_queries: queriesToUse.map(q => ({ query: q.query, purpose: q.purpose, provider: q.provider, priority: q.priority, expected_results: q.expected_results, })), max_sources: state.config.max_sources || 10, include_domains: state.config.exa_include_domains || state.config.tavily_include_domains || [], exclude_domains: state.config.exa_exclude_domains || state.config.tavily_exclude_domains || [], trends_config: intentAnalysis?.trends_config, skip_inference: true, }); // 5. Handle response if (!response.success) { setError(response.error_message || 'Research failed'); setIsExecuting(false); return null; } // 6. Store results setIntentResult(response); // 7. Save draft to database autoSaveDraft(state, { intentAnalysis: intentAnalysis || undefined, confirmedIntent: intent, intentResult: response, }).catch(error => { console.warn('[useResearchExecution] Failed to save draft:', error); }); // 8. Transform to legacy format for backward compatibility const legacyResult = { success: true, sources: response.sources.map(s => ({ title: s.title, url: s.url, excerpt: s.excerpt ?? undefined, credibility_score: s.credibility_score, })), keyword_analysis: { primary_keywords: state.keywords, secondary: response.suggested_outline, }, competitor_analysis: {}, suggested_angles: response.key_takeaways, search_queries: [], intent_result: response, }; setResult(legacyResult); setIsExecuting(false); // 9. Cache result researchCache.cacheResult( state.keywords, state.industry, state.targetAudience, legacyResult ); return response; } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Research failed'; setError(errorMessage); setIsExecuting(false); return null; } }, [confirmedIntent, intentAnalysis, analyzeIntent]); ``` **What happens:** 1. ✅ Validates intent is available 2. ✅ Sets `isExecuting = true` (shows loading state) 3. ✅ Prepares queries from selection or defaults 4. ✅ Makes API call to `/api/research/intent/research` 5. ✅ Handles success/error responses 6. ✅ Saves draft to database 7. ✅ Transforms result to legacy format 8. ✅ Caches result for future use 9. ✅ Sets `isExecuting = false` (hides loading state) --- ## 5. API Call to Backend ### Location: `intentResearchApi.ts` (Line 50-114) ```typescript export const executeIntentResearch = async ( request: IntentDrivenResearchRequest ): Promise => { try { const response = await axios.post( '/api/research/intent/research', request, { headers: { 'Content-Type': 'application/json', }, timeout: 300000, // 5 minutes } ); return response.data; } catch (error: any) { // Error handling... } }; ``` **Backend Endpoint:** `POST /api/research/intent/research` **Backend Handler:** `backend/api/research/handlers/intent.py` (Line 619-809) **What backend does:** 1. Validates authentication 2. Gets research persona 3. Determines intent (from confirmed or infers) 4. Generates queries if not provided 5. Executes research using Research Engine 6. Runs Google Trends analysis in parallel (if enabled) 7. Analyzes results using IntentAwareAnalyzer 8. Merges trends data 9. Returns structured response --- ## 6. UI Updates During Execution ### Loading State Changes: 1. **Button State** (`ActionButtons.tsx`): - Text changes: "Start Research" → "Researching..." - Shows spinner icon - Button is disabled 2. **Execution Hook State** (`useResearchExecution.ts`): - `isExecuting = true` → triggers re-renders - `error = null` → clears any previous errors 3. **ResearchInput Component** (`ResearchInput.tsx`): - `execution.isExecuting` prop updates - IntentConfirmationPanel shows loading state --- ## 7. Navigation to Results Step ### Location: `ResearchInput.tsx` (Line 580-586) ```typescript onExecute={async (selectedQueries) => { const result = await execution.executeIntentResearch(state, selectedQueries); if (result?.success) { // Skip to results step onUpdate({ currentStep: 3 }); // ← Navigates to Step 3 } }} ``` **What happens:** - After successful research, automatically updates wizard state - `currentStep` changes from `1` to `3` - ResearchWizard re-renders and shows `StepResults` component --- ## 8. Results Display - StepResults Component ### Location: `StepResults.tsx` (Line 15-405) ### Initial Check (Line 19-35): ```typescript // Check if we have intent-driven results const intentResult: IntentDrivenResearchResponse | null = execution?.intentResult || (state.results as any)?.intent_result || null; // Determine if we have both types of results const hasIntentResults = !!intentResult; const hasTraditionalResults = !!state.results && !intentResult; const hasAnyResults = hasIntentResults || hasTraditionalResults; if (!hasAnyResults) { return ( No results available ); } ``` ### Header Section (Line 73-134): **What user sees:** - **Title:** "Research Results" - **Action Buttons:** - ← Back (returns to previous step) - 📥 Export JSON (downloads results) - 🔄 Start New Research (resets to step 1) ### Tab Navigation (Line 144-210): **Tabs available:** 1. **📋 Summary** - Executive summary and key takeaways 2. **📊 Deliverables** - Statistics, quotes, case studies, trends 3. **🔗 Sources** - All research sources with links 4. **📈 Analysis** - Detailed analysis and insights **Tab badges show counts:** - Deliverables tab: Total count of all deliverables - Sources tab: Number of sources found ### Summary Tab Content (Line 217-232): **What user sees:** 1. **Executive Summary** (if available): ```typescript {intentResult.executive_summary && ( Executive Summary {intentResult.executive_summary} )} ``` 2. **Direct Answer** (if available): ```typescript {intentResult.primary_answer && ( Direct Answer {intentResult.primary_answer} )} ``` 3. **Key Takeaways** (if available): - List of bullet points - Styled as cards or list items ### Deliverables Tab Content (Line 250-280): **What user sees:** 1. **Statistics** (`intentResult.statistics`): - Data points with labels - Formatted as cards or tables - May include charts/graphs 2. **Expert Quotes** (`intentResult.expert_quotes`): - Quote text - Source attribution - Credibility score 3. **Case Studies** (`intentResult.case_studies`): - Case study title - Description - Key findings - Source link 4. **Trends** (`intentResult.trends`): - Trend description - Google Trends data (if available) - Charts showing interest over time - Regional interest data 5. **Best Practices** (`intentResult.best_practices`): - List of actionable recommendations 6. **Comparisons** (`intentResult.comparisons`): - Side-by-side comparisons - Pros/cons tables ### Sources Tab Content (Line 290-320): **What user sees:** ```typescript {intentResult.sources.map((source, idx) => ( {source.title} {source.excerpt && {source.excerpt}} Credibility: {source.credibility_score} Domain: {new URL(source.url).hostname} ))} ``` **Each source shows:** - Title (clickable link) - Excerpt/preview - Credibility score - Domain name - Published date (if available) ### Analysis Tab Content (Line 330-360): **What user sees:** 1. **Confidence Score:** - Visual indicator (progress bar or badge) - Percentage or rating 2. **Gaps Identified:** - List of areas needing more research - Suggestions for follow-up 3. **Follow-up Queries:** - Suggested next research questions - Clickable to start new research 4. **Suggested Outline:** - Content structure based on research - Organized by sections --- ## 9. IntentResultsDisplay Component ### Location: `IntentResultsDisplay.tsx` **Used when:** Intent-driven results are available **Features:** - Tabbed interface for different deliverable types - Interactive charts for trends - Expandable sections for detailed views - Export functionality for trends data **Tabs:** 1. **Summary** - Overview and primary answer 2. **Statistics** - Data points and metrics 3. **Expert Quotes** - Quotations with sources 4. **Case Studies** - Real-world examples 5. **Trends** - Trend analysis with charts 6. **Sources** - All research sources --- ## 10. State Management After Completion ### Draft Saving (Line 330-337): ```typescript // Save draft with research results autoSaveDraft(state, { intentAnalysis: intentAnalysis || undefined, confirmedIntent: intent, intentResult: response, }).catch(error => { console.warn('[useResearchExecution] Failed to save draft:', error); }); ``` **What happens:** - Saves complete research state to: 1. **localStorage** (for browser persistence) 2. **Database** (via `/api/research/projects/save`) **Saved data includes:** - Keywords - Intent analysis - Confirmed intent - Research results - Configuration - Current step (3 = completed) ### Result Caching (Line 363-369): ```typescript researchCache.cacheResult( state.keywords, state.industry, state.targetAudience, legacyResult ); ``` **Purpose:** Allows quick retrieval of results for similar queries --- ## 11. User Actions After Results ### Available Actions: 1. **← Back Button:** - Returns to Step 1 (Research Input) - Preserves all data 2. **📥 Export JSON:** - Downloads complete results as JSON file - Includes all deliverables, sources, and metadata 3. **🔄 Start New Research:** - Resets wizard to Step 1 - Clears all results - Starts fresh research 4. **Tab Navigation:** - Switch between Summary, Deliverables, Sources, Analysis - Each tab shows different aspect of results --- ## 12. Error Handling ### If Research Fails: 1. **API Error:** - `setError(errorMessage)` in execution hook - Error displayed in UI - Button re-enabled for retry 2. **Network Error:** - Timeout after 5 minutes - User sees "Network error" message - Can retry the request 3. **Validation Error:** - If no queries selected: Warning alert shown - Button remains disabled until valid --- ## Summary Flow Diagram ``` User clicks "Start Research" ↓ ActionButtons.onExecute() ↓ IntentConfirmationPanel.handleExecute() ↓ ResearchInput.onExecute(selectedQueries) ↓ execution.executeIntentResearch(state, queries) ↓ [Loading State: isExecuting = true] ↓ intentResearchApi.executeIntentResearch(request) ↓ POST /api/research/intent/research ↓ Backend: Research Engine + Intent Analyzer ↓ Response: IntentDrivenResearchResponse ↓ [Save draft to database] ↓ [Cache result] ↓ [Loading State: isExecuting = false] ↓ onUpdate({ currentStep: 3 }) ↓ StepResults Component Renders ↓ User sees: - Executive Summary - Direct Answer - Key Takeaways - Deliverables (Statistics, Quotes, Case Studies, Trends) - Sources (with links) - Analysis (Confidence, Gaps, Follow-ups) ``` --- ## Key Files Reference 1. **Frontend Components:** - `ActionButtons.tsx` - Start Research button - `IntentConfirmationPanel.tsx` - Intent confirmation UI - `ResearchInput.tsx` - Step 1 component - `StepResults.tsx` - Step 3 results display - `IntentResultsDisplay.tsx` - Intent-driven results renderer 2. **Hooks:** - `useResearchExecution.ts` - Research execution logic - `useResearchWizard.ts` - Wizard state management 3. **API:** - `intentResearchApi.ts` - API client for research endpoints 4. **Backend:** - `handlers/intent.py` - Intent research endpoint handler - `services/research/intent/` - Intent analysis services - `services/research/core/` - Research engine --- ## UI States Summary | State | Button Text | Button State | UI Feedback | |-------|------------|--------------|-------------| | **Ready** | "Start Research" | Enabled | Info alert: "Ready to start research!" | | **No Queries** | "Start Research" | Disabled | Warning: "Please select at least one query" | | **Executing** | "Researching..." | Disabled + Spinner | Loading indicator | | **Success** | N/A (on Results page) | N/A | Results displayed in tabs | | **Error** | "Start Research" | Enabled | Error message displayed | --- This completes the code walkthrough from button click to results display! 🎉
No results available
{intentResult.executive_summary}
{intentResult.primary_answer}
{source.excerpt}