|
1 | | -import React, { useState, useEffect } from 'react'; |
2 | | -import PromptInputArea from './components/PromptInputArea'; |
3 | | -import PromptVersioningPanel from './components/PromptVersioningPanel'; |
4 | | -import { PromptPlayground } from './components/PromptPlayground'; // Named import |
5 | | -import PromptOptimizationSettings from './components/PromptOptimizationSettings'; |
6 | | -import Button from '../../components/ui/Button'; |
7 | | -import Input from '../../components/ui/Input'; |
8 | | -import { Prompt, PromptCategory, PromptVersion } from '../../types/prompt'; // Import PromptCategory and PromptVersion |
| 1 | +import { useState } from 'react'; |
| 2 | +import { useParams } from 'react-router-dom'; |
9 | 3 | import { usePromptManagement } from '../../hooks/usePromptManagement'; |
10 | | - |
11 | | -const PromptEditorPage: React.FC = () => { |
12 | | - const [newPromptName, setNewPromptName] = useState<string>(''); |
13 | | - const [newPromptCategory, setNewPromptCategory] = useState<PromptCategory>('general'); // Use PromptCategory type |
14 | | - const [newPromptDomain, setNewPromptDomain] = useState<string>(''); |
15 | | - |
16 | | - const { prompts, selectedPrompt, isLoading, error, fetchAllPrompts, fetchPrompt, createPrompt, addVersion, rollbackToVersion } = usePromptManagement(); // Destructure correctly |
17 | | - const [promptContent, setPromptContent] = useState<string>(''); |
18 | | - |
19 | | - // Effect to fetch all prompts on initial load and when a prompt is created/updated/deleted |
20 | | - useEffect(() => { |
21 | | - fetchAllPrompts(); |
22 | | - }, [fetchAllPrompts]); // Removed selectedPrompt from dependency to avoid unnecessary re-fetches |
23 | | - |
24 | | - // Effect to update promptContent when selectedPrompt changes |
25 | | - useEffect(() => { |
26 | | - if (selectedPrompt) { |
27 | | - const currentVersionData = selectedPrompt.versions.find(v => v.version === selectedPrompt.currentVersion); |
28 | | - setPromptContent(currentVersionData?.content || ''); |
29 | | - } else { |
30 | | - setPromptContent(''); // Clear content for new prompt creation |
31 | | - setNewPromptName(''); // Reset new prompt fields when no prompt is selected |
32 | | - setNewPromptCategory('general'); |
33 | | - setNewPromptDomain(''); |
34 | | - } |
35 | | - }, [selectedPrompt]); |
36 | | - |
37 | | - const handlePromptSelect = async (promptId: string) => { |
38 | | - await fetchPrompt(promptId); |
| 4 | +import { PromptInputArea } from './components/PromptInputArea'; |
| 5 | +import { PromptVersioningPanel } from './components/PromptVersioningPanel'; |
| 6 | + |
| 7 | +export function PromptEditorPage() { |
| 8 | + const { promptId } = useParams<{ promptId: string }>(); |
| 9 | + const { activePrompt, isLoading, error } = usePromptManagement(promptId || null); |
| 10 | + const [isSaving, setIsSaving] = useState(false); |
| 11 | + |
| 12 | + const handleSave = async (newContent: string) => { |
| 13 | + if (!activePrompt) return; |
| 14 | + setIsSaving(true); |
| 15 | + // Add save logic here |
| 16 | + console.log('Saving content:', newContent); |
| 17 | + setIsSaving(false); |
39 | 18 | }; |
40 | 19 |
|
41 | | - const handleSavePrompt = async () => { |
42 | | - if (isLoading) return; // Prevent multiple saves |
| 20 | + if (isLoading) { |
| 21 | + return <div>Loading prompt...</div>; |
| 22 | + } |
43 | 23 |
|
44 | | - if (selectedPrompt) { |
45 | | - const currentVersionData = selectedPrompt.versions.find(v => v.version === selectedPrompt.currentVersion); |
46 | | - const currentContent = currentVersionData?.content; |
| 24 | + if (error) { |
| 25 | + return <div style={{ color: 'red' }}>Error: {error}</div>; |
| 26 | + } |
47 | 27 |
|
48 | | - if (promptContent === currentContent) { |
49 | | - alert('No changes detected in prompt content. Not creating a new version.'); |
50 | | - return; |
51 | | - } |
52 | | - // Add a new version |
53 | | - await addVersion(selectedPrompt.id, promptContent, { |
54 | | - expectedOutcome: currentVersionData?.metadata.expectedOutcome || '', // Preserve previous metadata or prompt for new |
55 | | - rationale: 'Manual edit from editor, new version created', |
56 | | - author: 'current_user' // Replace with actual user info |
57 | | - }); |
58 | | - |
59 | | - } else { // Create a new prompt |
60 | | - if (!newPromptName.trim() || !promptContent.trim()) { |
61 | | - alert('Please provide a name, category, domain and initial content for the new prompt.'); |
62 | | - return; |
63 | | - } |
64 | | - await createPrompt(newPromptName, promptContent, newPromptCategory, newPromptDomain); |
65 | | - // Reset new prompt fields after creation is handled by the useEffect for selectedPrompt change |
66 | | - } |
67 | | - }; |
68 | | - |
69 | | - const handleRollback = async (version: string) => { |
70 | | - if (selectedPrompt) { |
71 | | - await rollbackToVersion(selectedPrompt.id, version); |
72 | | - } |
73 | | - }; |
74 | | - |
75 | | - const handleCreateNewPromptClick = () => { |
76 | | - // Clear selected prompt and reset form for new prompt creation |
77 | | - fetchPrompt(''); // This will set selectedPrompt to null, triggering the useEffect to clear fields |
78 | | - }; |
| 28 | + if (!activePrompt) { |
| 29 | + return <div>Select a prompt to begin.</div>; |
| 30 | + } |
79 | 31 |
|
80 | 32 | return ( |
81 | | - <div className="prompt-editor-page"> |
82 | | - <h2>Master Prompt Editor</h2> |
83 | | - <p>This is the central nervous system for sophisticated AI interactions, offering robust prompt management, advanced engineering techniques, automated optimization, and collaborative workflows. (Section 2)</p> |
84 | | - |
85 | | - <div style={{ display: 'flex', gap: '20px', marginTop: '20px' }}> |
86 | | - <div style={{ flex: 1, border: '1px solid #e9ecef', padding: '20px', borderRadius: '8px', backgroundColor: 'white' }}> |
87 | | - <h3>Prompt Repository</h3> |
88 | | - <p>Centralized repository for all your prompts, categorized by purpose and domain. (2.1)</p> |
89 | | - <ul style={{ listStyle: 'none', padding: 0 }}> |
90 | | - {prompts.length === 0 && !isLoading && !error ? ( |
91 | | - <p>No prompts found. Create one!</p> |
92 | | - ) : isLoading ? ( |
93 | | - <p>Loading prompts...</p> |
94 | | - ) : error ? ( |
95 | | - <p style={{ color: 'red' }}>Error loading prompts: {error}</p> |
96 | | - ) : ( |
97 | | - prompts.map(p => ( |
98 | | - <li key={p.id} style={{ marginBottom: '5px' }}> |
99 | | - <a href="#" onClick={(e) => { e.preventDefault(); handlePromptSelect(p.id); }}> |
100 | | - {p.name} (v{p.currentVersion}) |
101 | | - </a> |
102 | | - </li> |
103 | | - )) |
104 | | - )} |
105 | | - <li><Button onClick={handleCreateNewPromptClick} style={{ marginTop: '10px' }}>Create New Prompt</Button></li> |
106 | | - </ul> |
107 | | - </div> |
108 | | - |
109 | | - <div style={{ flex: 2, display: 'flex', flexDirection: 'column', gap: '20px' }}> |
110 | | - <div style={{ border: '1px solid #e9ecef', padding: '20px', borderRadius: '8px', backgroundColor: 'white' }}> |
111 | | - <h3>Prompt Design Area {selectedPrompt ? `(${selectedPrompt.name})` : '(New Prompt)'}</h3> |
112 | | - {!selectedPrompt && ( |
113 | | - <> |
114 | | - <Input label="New Prompt Name" value={newPromptName} onChange={(e) => setNewPromptName(e.target.value)} placeholder="e.g., 'marketing-email-draft'" /> |
115 | | - <div style={{marginBottom: '15px'}}> |
116 | | - <label htmlFor="new-prompt-category">Category:</label> |
117 | | - <select id="new-prompt-category" value={newPromptCategory} onChange={(e) => setNewPromptCategory(e.target.value as PromptCategory)} style={{ padding: '8px', borderRadius: '4px', border: '1px solid #ccc', width: '100%' }}> |
118 | | - <option value="general">General</option> |
119 | | - <option value="marketing">Marketing</option> |
120 | | - <option value="human-resources">Human Resources</option> |
121 | | - <option value="software-development">Software Development</option> |
122 | | - </select> |
123 | | - </div> |
124 | | - <Input label="Domain" value={newPromptDomain} onChange={(e) => setNewPromptDomain(e.target.value)} placeholder="e.g., 'customer-support'" /> |
125 | | - </> |
126 | | - )} |
127 | | - <PromptInputArea |
128 | | - promptContent={promptContent} |
129 | | - onPromptContentChange={setPromptContent} |
130 | | - /> |
131 | | - {isLoading && <p>Processing...</p>} |
132 | | - {error && <p style={{color: 'red'}}>Error: {error}</p>} |
133 | | - <Button onClick={handleSavePrompt} style={{ marginTop: '10px' }}> |
134 | | - {selectedPrompt ? 'Save New Version' : 'Create Prompt'} |
135 | | - </Button> |
136 | | - </div> |
137 | | - |
138 | | - <div style={{ border: '1px solid #e9ecef', padding: '20px', borderRadius: '8px', backgroundColor: 'white' }}> |
139 | | - <h3>Prompt Playground</h3> |
140 | | - <PromptPlayground promptContent={promptContent} /> |
141 | | - <p>Intuitive graphical user interfaces allow non-technical users to interact with, modify, and test prompts in a safe, controlled environment. (2.1)</p> |
142 | | - </div> |
143 | | - |
144 | | - <div style={{ border: '1px solid #e9ecef', padding: '20px', borderRadius: '8px', backgroundColor: 'white' }}> |
145 | | - <h3>Automated Optimization & Evaluation</h3> |
146 | | - <PromptOptimizationSettings promptId={selectedPrompt?.id || ''} /> |
147 | | - <p>Systematically test different prompt variations and compare their outputs and performance, leveraging meta-learning, gradient-based optimization, and DSPy integration. (2.3)</p> |
148 | | - </div> |
149 | | - </div> |
150 | | - |
151 | | - <div style={{ flex: 1, border: '1px solid #e9ecef', padding: '20px', borderRadius: '8px', backgroundColor: 'white' }}> |
152 | | - <h3>Prompt Versioning & History</h3> |
153 | | - {selectedPrompt ? ( |
154 | | - <PromptVersioningPanel |
155 | | - currentVersion={selectedPrompt.currentVersion} |
156 | | - versionHistory={selectedPrompt.versions.map(v => ({ version: v.version, date: v.metadata.lastModified, rationale: v.metadata.rationale }))} |
157 | | - onRollback={handleRollback} |
158 | | - /> |
159 | | - ) : ( |
160 | | - <p>Select a prompt to view its version history.</p> |
161 | | - )} |
162 | | - <p style={{ fontSize: '0.9em', color: '#666', marginTop: '15px' }}> |
163 | | - Robust prompt management and versioning system with semantic versioning and rollback capabilities. (2.1) |
164 | | - </p> |
165 | | - <p style={{ fontSize: '0.9em', color: '#666' }}> |
166 | | - Comprehensive metadata and documentation tracked for each prompt version. (2.1) |
167 | | - </p> |
168 | | - </div> |
| 33 | + <div> |
| 34 | + <h2>{activePrompt.name}</h2> |
| 35 | + <p>{activePrompt.description}</p> |
| 36 | + <div> |
| 37 | + <PromptInputArea onSave={handleSave} initialContent={activePrompt.content} /> |
| 38 | + <PromptVersioningPanel versions={activePrompt.versions} /> |
169 | 39 | </div> |
170 | 40 | </div> |
171 | 41 | ); |
172 | | -}; |
173 | | - |
174 | | -export default PromptEditorPage; |
| 42 | +} |
0 commit comments