feat(05-03): Implement API fallback handling for research display
- Enhanced exaSearch service with Exa API + fallback tier system * Tier 1: Exa API (primary) * Tier 2: Synthetic results with suggested web sources * Improved error handling with graceful degradation - Updated backend exerciseResearch route to return provider info * Returns 'provider' field identifying which API was used * Returns 'status' field (success/degraded) for UI feedback * Better error messages for debugging - Enhanced ResearchDisplay component with fallback feedback * New ResearchProviderBadge shows which provider was used * Visual indicators for fallback results (Suggested badge) * Support for multiple provider types (exa, fallback, gemini, etc.) * Improved error handling and recovery flows - Updated ExerciseResearchPanel with better error handling * Proper response parsing from backend * Forwards provider and status info to display component * Improved accessibility with tooltip hints - Added comprehensive Research Display styling * Responsive layout for mobile and desktop * Visual hierarchy for summaries and sources * Provider badge styling with color-coding * Fallback state indicators for user awareness
This commit is contained in:
@@ -45,7 +45,8 @@ const createExerciseResearchRouter = ({ pool, exaSearch }) => {
|
||||
? Math.min(requestedResults, 10)
|
||||
: 5;
|
||||
|
||||
const { summary, results } = await exaSearch({ query, numResults });
|
||||
// Fetch research with fallback support
|
||||
const { summary, results, provider, status } = await exaSearch({ query, numResults });
|
||||
|
||||
let researchRecord = null;
|
||||
try {
|
||||
@@ -53,7 +54,7 @@ const createExerciseResearchRouter = ({ pool, exaSearch }) => {
|
||||
`INSERT INTO research_results (exercise_id, query, summary, results, provider)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id, created_at`,
|
||||
[exerciseId, query, summary, JSON.stringify(results), 'exa']
|
||||
[exerciseId, query, summary, JSON.stringify(results), provider || 'exa']
|
||||
);
|
||||
researchRecord = insertResult.rows[0] || null;
|
||||
} catch (err) {
|
||||
@@ -65,11 +66,16 @@ const createExerciseResearchRouter = ({ pool, exaSearch }) => {
|
||||
query,
|
||||
summary,
|
||||
results,
|
||||
stored: researchRecord
|
||||
stored: researchRecord,
|
||||
provider: provider || 'exa',
|
||||
status: status || 'success'
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Error running exercise research:', err);
|
||||
res.status(500).json({ error: 'Failed to fetch research' });
|
||||
res.status(500).json({
|
||||
error: 'Failed to fetch research',
|
||||
message: err.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user