ALwrity AI Blog Writer - Added Google Grounding UI Implementation

This commit is contained in:
ajaysi
2025-09-18 18:45:53 +05:30
parent 9f13daf443
commit 4d153b292d
72 changed files with 11944 additions and 1526 deletions

View File

@@ -1,6 +1,8 @@
import React, { useState } from 'react';
import { useCopilotAction } from '@copilotkit/react-core';
import { blogWriterApi, BlogResearchRequest, BlogResearchResponse } from '../../services/blogWriterApi';
import ResearchPollingHandler from './ResearchPollingHandler';
import { researchCache } from '../../services/researchCache';
const useCopilotActionTyped = useCopilotAction as any;
@@ -139,6 +141,7 @@ const ResearchForm: React.FC<{
};
export const KeywordInputForm: React.FC<KeywordInputFormProps> = ({ onKeywordsReceived, onResearchComplete }) => {
const [currentTaskId, setCurrentTaskId] = useState<string | null>(null);
// Keyword input action with Human-in-the-Loop
useCopilotActionTyped({
@@ -190,7 +193,19 @@ export const KeywordInputForm: React.FC<KeywordInputFormProps> = ({ onKeywordsRe
const keywordList = keywords.includes(',')
? keywords.split(',').map((k: string) => k.trim())
: keywords.split(' ').filter((k: string) => k.length > 2).slice(0, 5);
: [keywords.trim()]; // Preserve single phrases as-is
// Check frontend cache first
const cachedResult = researchCache.getCachedResult(keywordList, 'General', 'General');
if (cachedResult) {
console.log('Frontend cache hit - returning cached result instantly');
onResearchComplete?.(cachedResult);
return {
success: true,
message: `✅ Found cached research for "${keywords}"! Results loaded instantly.`,
cached: true
};
}
const payload: BlogResearchRequest = {
keywords: keywordList,
@@ -199,24 +214,14 @@ export const KeywordInputForm: React.FC<KeywordInputFormProps> = ({ onKeywordsRe
word_count_target: parseInt(blogLength)
};
const res = await blogWriterApi.research(payload);
onResearchComplete?.(res);
const sourcesCount = res.sources?.length || 0;
const queriesCount = res.search_queries?.length || 0;
const anglesCount = res.suggested_angles?.length || 0;
// Start async research
const { task_id } = await blogWriterApi.startResearch(payload);
setCurrentTaskId(task_id);
return {
success: true,
message: `🔍 Research completed for "${keywords}"! Found ${sourcesCount} sources, ${queriesCount} search queries, and ${anglesCount} content angles. The research results are now displayed in the UI.`,
research_summary: {
topic: keywords,
sources: sourcesCount,
queries: queriesCount,
angles: anglesCount,
primary_keywords: res.keyword_analysis?.primary || [],
search_intent: res.keyword_analysis?.search_intent || 'informational'
}
message: `🔍 Research started for "${keywords}"! Task ID: ${task_id}. Progress will be shown below.`,
task_id: task_id
};
} catch (error) {
console.error(`Research failed: ${error}`);
@@ -266,7 +271,22 @@ export const KeywordInputForm: React.FC<KeywordInputFormProps> = ({ onKeywordsRe
}
});
return null; // This component only provides the CopilotKit action, no UI
return (
<>
{/* Polling handler for research progress */}
<ResearchPollingHandler
taskId={currentTaskId}
onResearchComplete={(result) => {
onResearchComplete?.(result);
setCurrentTaskId(null);
}}
onError={(error) => {
console.error('Research error:', error);
setCurrentTaskId(null);
}}
/>
</>
);
};
export default KeywordInputForm;