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; interface KeywordInputFormProps { onKeywordsReceived?: (data: { keywords: string; blogLength: string }) => void; onResearchComplete?: (researchData: BlogResearchResponse) => void; onTaskStart?: (taskId: string) => void; } // Separate component to manage form state const ResearchForm: React.FC<{ prompt?: string; onSubmit: (data: { keywords: string; blogLength: string }) => void; onCancel: () => void; }> = ({ prompt, onSubmit, onCancel }) => { const [keywords, setKeywords] = useState(''); const [blogLength, setBlogLength] = useState('1000'); const hasValidInput = keywords.trim().length > 0; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (hasValidInput) { onSubmit({ keywords: keywords.trim(), blogLength }); } else { window.alert('Please enter keywords or a topic to start research.'); } }; return (

🔍 Let's Research Your Blog Topic

{prompt || 'Please provide the keywords or topic you want to research for your blog:'}

setKeywords(e.target.value)} onFocus={(e) => e.target.select()} placeholder="e.g., artificial intelligence, machine learning, AI trends" style={{ width: '100%', padding: '10px 12px', border: '2px solid #1976d2', borderRadius: '6px', fontSize: '14px', outline: 'none', backgroundColor: 'white', boxSizing: 'border-box' }} autoFocus autoComplete="off" spellCheck="false" />
); }; export const KeywordInputForm: React.FC = ({ onKeywordsReceived, onResearchComplete, onTaskStart }) => { const [currentTaskId, setCurrentTaskId] = useState(null); // Keyword input action with Human-in-the-Loop useCopilotActionTyped({ name: 'getResearchKeywords', description: 'Get keywords from user for blog research', parameters: [ { name: 'prompt', type: 'string', description: 'Prompt to show user', required: false } ], renderAndWaitForResponse: ({ respond, args, status }: { respond?: (value: string) => void; args: { prompt?: string }; status: string }) => { if (status === 'complete') { return (

✅ Research keywords received! Starting research...

); } return ( { onKeywordsReceived?.(formData); respond?.(JSON.stringify(formData)); }} onCancel={() => respond?.('CANCEL')} /> ); } }); // Research action that actually performs the research useCopilotActionTyped({ name: 'performResearch', description: 'Perform research with collected keywords and blog length', parameters: [ { name: 'formData', type: 'string', description: 'JSON string with keywords and blogLength', required: true } ], handler: async ({ formData }: { formData: string }) => { try { const data = JSON.parse(formData); const { keywords, blogLength } = data; const keywordList = keywords.includes(',') ? keywords.split(',').map((k: string) => k.trim()) : [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, industry: 'General', target_audience: 'General', word_count_target: parseInt(blogLength) }; // Store the blog length in localStorage for later use localStorage.setItem('blog_length_target', blogLength); // Start async research const { task_id } = await blogWriterApi.startResearch(payload); setCurrentTaskId(task_id); onTaskStart?.(task_id); // Notify parent component to start polling return { success: true, 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}`); return { success: false, message: `❌ Research failed: ${error}. Please try again with different keywords.` }; } }, render: ({ status }: any) => { if (status === 'inProgress' || status === 'executing') { return (

🔍 Researching Your Topic

• Connecting to Google Search grounding...

• Analyzing keywords and search intent...

• Gathering relevant sources and statistics...

• Generating content angles and search queries...

); } return null; } }); return ( <> {/* Polling handler for research progress */} { onResearchComplete?.(result); setCurrentTaskId(null); }} onError={(error) => { console.error('Research error:', error); setCurrentTaskId(null); }} /> ); }; export default KeywordInputForm;