AI Explain Feature: Anonymous Access with Streaming Response
Parent Epic: #166
Depends on: #169 (Search Results Component)
The Feature
When a user clicks "Explain This" on any search result, they get an AI-generated explanation of the code. This works without login. This is a key differentiator - competitors gate this behind signup.
User Flow
- User sees search result
- Clicks "Explain This" button
- Button transforms to loading state
- AI explanation streams in character-by-character
- Full explanation visible, can be copied or dismissed
UI Specification
Button States
[Explain This] <- Idle
[Explaining...] <- Loading (spinner)
[Close Explanation] <- Showing explanation
Explanation Panel
Appears below the code snippet, within the same card:
┌──────────────────────────────────────────────────────────────────┐
│ flask/src/flask/app.py 98% match │
│ ───────────────────────────────────────────────────────────────│
│ [code snippet...] │
│ ───────────────────────────────────────────────────────────────│
│ │
│ Explanation [Copy] [X] │
│ ─────────────────────────────────────────────────────────────── │
│ │
│ This decorator registers a function to run before each │
│ incoming request. Common use cases include: │
│ │
│ - Opening database connections │
│ - Loading the current user from session │
│ - Setting up request-specific context │
│ │
│ The decorated function receives no arguments. If it returns │
│ a value, that value is used as the response and the actual │
│ view function is never called. │
│ │
│ ───────────────────────────────────────────────────────────────│
│ [Copy Code] [View Full File] [GitHub] │
└──────────────────────────────────────────────────────────────────┘
Streaming Response
The explanation should stream in character-by-character, like ChatGPT. This creates anticipation and feels more natural than a sudden wall of text.
// Typewriter effect
const TypewriterText = ({ text, speed = 20 }) => {
const [displayed, setDisplayed] = useState('');
useEffect(() => {
let i = 0;
const interval = setInterval(() => {
if (i < text.length) {
setDisplayed(prev => prev + text[i]);
i++;
} else {
clearInterval(interval);
}
}, speed);
return () => clearInterval(interval);
}, [text]);
return <span>{displayed}<span className="cursor">|</span></span>;
};
If the backend supports true streaming (SSE or WebSocket), use that instead of simulated typewriter.
Backend Integration
Endpoint
POST /api/v2/explain
{
"repo_id": "flask",
"file_path": "src/flask/app.py",
"line_start": 847,
"line_end": 858,
"code_snippet": "...",
"query_context": "authentication middleware patterns"
}
Response (Streaming)
data: {"chunk": "This decorator "}
data: {"chunk": "registers a function "}
data: {"chunk": "to run before each..."}
data: {"done": true}
Anonymous Access
This endpoint must work without authentication. Rate limit by IP/session to prevent abuse:
- 10 explanations per hour for anonymous users
- Show remaining count subtly
Animation Specifications
Button Click -> Explanation Panel
1. Button text changes to "Explaining..."
2. Sparkle icon starts rotating
3. Card expands smoothly (height animation)
4. Explanation header fades in
5. Text streams in character by character
6. When done, cursor blinks then disappears
Collapse Explanation
1. Click X or "Close Explanation"
2. Text fades out quickly (150ms)
3. Card height collapses (300ms)
4. Button returns to "Explain This"
Rate Limiting UI
When approaching limit:
[Explain This] (7 remaining)
When limit reached:
[Sign up for unlimited explains]
This is how we convert anonymous users - give them value, then ask for signup when they want more.
Implementation Tasks
Acceptance Criteria
Technical Notes
Use OpenAI or Claude API for explanations. Prompt should include:
- The code snippet
- The search query (for context)
- The file path (for additional context)
Keep explanations concise - 3-5 sentences max. Developers don't want essays.
AI Explain Feature: Anonymous Access with Streaming Response
Parent Epic: #166
Depends on: #169 (Search Results Component)
The Feature
When a user clicks "Explain This" on any search result, they get an AI-generated explanation of the code. This works without login. This is a key differentiator - competitors gate this behind signup.
User Flow
UI Specification
Button States
Explanation Panel
Appears below the code snippet, within the same card:
Streaming Response
The explanation should stream in character-by-character, like ChatGPT. This creates anticipation and feels more natural than a sudden wall of text.
If the backend supports true streaming (SSE or WebSocket), use that instead of simulated typewriter.
Backend Integration
Endpoint
Response (Streaming)
Anonymous Access
This endpoint must work without authentication. Rate limit by IP/session to prevent abuse:
Animation Specifications
Button Click -> Explanation Panel
Collapse Explanation
Rate Limiting UI
When approaching limit:
When limit reached:
This is how we convert anonymous users - give them value, then ask for signup when they want more.
Implementation Tasks
components/search/ExplanationPanel.tsxcomponents/ui/TypewriterText.tsxhooks/useExplainCode.ts- manages API call and streamingSearchResult.tsxto include expandable explanationPOST /api/v2/explainAcceptance Criteria
Technical Notes
Use OpenAI or Claude API for explanations. Prompt should include:
Keep explanations concise - 3-5 sentences max. Developers don't want essays.