File size: 5,275 Bytes
7211e95 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
import React, { useState, useCallback } from 'react';
import { Zap } from 'lucide-react';
// Import sub-components for each step
import Header from './Header';
import SetupScreen from './SetupScreen';
import InputScreen from './InputScreen';
import GeneratingScreen from './GeneratingScreen';
import PreviewScreen from './PreviewScreen';
// Import the API services
import { callAnthropicAPI } from '../services/anthropic';
import { callHuggingFaceAPI } from '../services/huggingface'; // New service
import { getPrompts } from '../services/prompts';
const WorkshopGenerator = () => {
const [currentStep, setCurrentStep] = useState('setup');
const [apiKey, setApiKey] = useState({ anthropic: '', huggingface: '' });
const [apiProvider, setApiProvider] = useState('anthropic'); // 'anthropic' or 'huggingface'
const [workshopData, setWorkshopData] = useState({
topic: '',
audience: '',
duration: '90',
difficulty: 'intermediate'
});
const [generatedContent, setGeneratedContent] = useState(null);
const [isGenerating, setIsGenerating] = useState(false);
const [activeAgent, setActiveAgent] = useState('');
const [error, setError] = useState('');
const getApiCallFunction = useCallback(() => {
if (apiProvider === 'huggingface') {
return (prompt, maxTokens) => callHuggingFaceAPI(prompt, apiKey.huggingface, maxTokens);
}
// Default to Anthropic
return (prompt, maxTokens) => callAnthropicAPI(prompt, apiKey.anthropic, maxTokens);
}, [apiProvider, apiKey]);
const generateWorkshop = async () => {
setIsGenerating(true);
setCurrentStep('generating');
setError('');
const callAPI = getApiCallFunction();
const prompts = getPrompts(workshopData);
try {
const runAgent = async (agentName, prompt, maxTokens) => {
setActiveAgent(agentName);
const response = await callAPI(prompt, maxTokens);
const cleanResponse = response.replace(/```json\n?/, "").replace(/```\n?/, "").trim();
try {
return JSON.parse(cleanResponse);
} catch (parseError) {
console.error(`Error parsing JSON from ${agentName}:`, parseError, "Raw response:", response);
throw new Error(`Agent "${agentName}" returned invalid data. Please try again.`);
}
};
// Run the agent pipeline
const topicData = await runAgent('topic', prompts.topic, 1500);
const contentData = await runAgent('content', prompts.content(JSON.stringify(topicData)), 3000);
const slideData = await runAgent('slide', prompts.slide(JSON.stringify(contentData)), 4000);
const codeData = await runAgent('code', prompts.code(JSON.stringify(topicData)), 3000);
// Combine results
setGeneratedContent({
topic: topicData,
content: contentData,
slides: slideData,
code: codeData,
metadata: {
title: topicData.title || workshopData.topic,
modules: topicData.modules?.length || 0,
slideCount: slideData.slide_count || slideData.slides?.length || 0,
exercises: codeData.exercises?.length || 0,
generatedAt: new Date().toISOString(),
provider: apiProvider
}
});
setCurrentStep('preview');
} catch (err) {
console.error("Workshop generation error:", err);
setError(err.message);
setCurrentStep('input');
} finally {
setIsGenerating(false);
setActiveAgent('');
}
};
const resetGenerator = () => {
setCurrentStep('input');
setGeneratedContent(null);
setWorkshopData({ topic: '', audience: '', duration: '90', difficulty: 'intermediate' });
setError('');
};
const renderStep = () => {
switch (currentStep) {
case 'setup':
return <SetupScreen
apiKey={apiKey}
setApiKey={setApiKey}
apiProvider={apiProvider}
setApiProvider={setApiProvider}
setCurrentStep={setCurrentStep}
setError={setError}
getApiCallFunction={getApiCallFunction}
/>;
case 'input':
return <InputScreen
workshopData={workshopData}
setWorkshopData={setWorkshopData}
isGenerating={isGenerating}
generateWorkshop={generateWorkshop}
setCurrentStep={setCurrentStep}
/>;
case 'generating':
return <GeneratingScreen activeAgent={activeAgent} />;
case 'preview':
return <PreviewScreen
generatedContent={generatedContent}
workshopData={workshopData}
resetGenerator={resetGenerator}
/>;
default:
return <SetupScreen />;
}
};
return (
<div className="min-h-screen bg-gray-900 text-white font-sans">
<Header />
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
{error && (
<div className="max-w-2xl mx-auto mb-6 bg-red-500/20 border border-red-400 rounded-lg p-4 flex items-center space-x-3">
<AlertCircle className="w-5 h-5 text-red-400" />
<span className="text-red-200">{error}</span>
</div>
)}
{renderStep()}
</main>
</div>
);
};
export default WorkshopGenerator; |