Raiff1982 commited on
Commit
e2ce418
·
verified ·
1 Parent(s): 03bff6f

Upload 12 files

Browse files
components/AdminLogin.tsx ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from 'react';
2
+ import { Lock, AlertCircle } from 'lucide-react';
3
+
4
+ interface AdminLoginProps {
5
+ onLogin: (password: string) => void;
6
+ darkMode: boolean;
7
+ error?: string | null;
8
+ }
9
+
10
+ const AdminLogin: React.FC<AdminLoginProps> = ({ onLogin, darkMode, error }) => {
11
+ const [password, setPassword] = useState('');
12
+ const [isLoading, setIsLoading] = useState(false);
13
+
14
+ const handleSubmit = async (e: React.FormEvent) => {
15
+ e.preventDefault();
16
+ setIsLoading(true);
17
+
18
+ try {
19
+ await onLogin(password);
20
+ } catch (err: any) {
21
+ // Error is now handled by the parent component
22
+ } finally {
23
+ setIsLoading(false);
24
+ }
25
+ };
26
+
27
+ return (
28
+ <div className={`p-6 rounded-lg ${darkMode ? 'bg-gray-800' : 'bg-white'}`}>
29
+ <div className="flex items-center justify-center mb-6">
30
+ <Lock className={`${darkMode ? 'text-blue-400' : 'text-blue-600'} w-12 h-12`} />
31
+ </div>
32
+ <h2 className={`text-xl font-bold text-center mb-4 ${darkMode ? 'text-white' : 'text-gray-900'}`}>
33
+ Admin Access Required
34
+ </h2>
35
+ <p className={`text-sm text-center mb-6 ${darkMode ? 'text-gray-300' : 'text-gray-600'}`}>
36
+ Please enter the admin password to access settings
37
+ </p>
38
+ <form onSubmit={handleSubmit} className="space-y-4">
39
+ <div>
40
+ <input
41
+ type="password"
42
+ value={password}
43
+ onChange={(e) => setPassword(e.target.value)}
44
+ placeholder="Enter admin password"
45
+ className={`w-full px-4 py-2 rounded-md border ${
46
+ darkMode
47
+ ? 'bg-gray-700 border-gray-600 text-white placeholder-gray-400'
48
+ : 'bg-white border-gray-300 text-gray-900 placeholder-gray-500'
49
+ } focus:outline-none focus:ring-2 focus:ring-blue-500`}
50
+ disabled={isLoading}
51
+ />
52
+ {error && (
53
+ <div className="mt-2 p-2 rounded-md bg-red-100 dark:bg-red-900 flex items-start space-x-2">
54
+ <AlertCircle className="flex-shrink-0 text-red-500 dark:text-red-400" size={16} />
55
+ <p className="text-sm text-red-600 dark:text-red-300">
56
+ {error}
57
+ </p>
58
+ </div>
59
+ )}
60
+ </div>
61
+ <button
62
+ type="submit"
63
+ disabled={isLoading}
64
+ className={`w-full py-2 px-4 rounded-md ${
65
+ darkMode
66
+ ? 'bg-blue-600 hover:bg-blue-700 text-white'
67
+ : 'bg-blue-500 hover:bg-blue-600 text-white'
68
+ } transition-colors duration-200 ${isLoading ? 'opacity-50 cursor-not-allowed' : ''}`}
69
+ >
70
+ {isLoading ? 'Logging in...' : 'Login'}
71
+ </button>
72
+ </form>
73
+ </div>
74
+ );
75
+ };
76
+
77
+ export default AdminLogin;
components/ChatInterface.tsx ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useRef, useEffect } from 'react';
2
+ import { Send, Circle, Bot, User, Sparkles, Brain } from 'lucide-react';
3
+ import { CodetteResponseCard, CodetteResponse } from './CodetteComponents';
4
+
5
+ interface Message {
6
+ role: string;
7
+ content: string;
8
+ timestamp: Date;
9
+ metadata?: CodetteResponse;
10
+ }
11
+
12
+ interface ChatInterfaceProps {
13
+ messages: Message[];
14
+ sendMessage: (content: string) => void;
15
+ isProcessing: boolean;
16
+ darkMode: boolean;
17
+ }
18
+
19
+ const ChatInterface: React.FC<ChatInterfaceProps> = ({
20
+ messages,
21
+ sendMessage,
22
+ isProcessing,
23
+ darkMode
24
+ }) => {
25
+ const [input, setInput] = useState('');
26
+ const [isDreamMode, setIsDreamMode] = useState(false);
27
+ const messagesEndRef = useRef<HTMLDivElement>(null);
28
+ const inputRef = useRef<HTMLTextAreaElement>(null);
29
+
30
+ useEffect(() => {
31
+ messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
32
+ }, [messages]);
33
+
34
+ useEffect(() => {
35
+ inputRef.current?.focus();
36
+ }, []);
37
+
38
+ const handleSubmit = (e: React.FormEvent) => {
39
+ e.preventDefault();
40
+ if (input.trim() && !isProcessing) {
41
+ const finalInput = isDreamMode ? `dream about ${input.trim()}` : input.trim();
42
+ sendMessage(finalInput);
43
+ setInput('');
44
+ }
45
+ };
46
+
47
+ const handleKeyDown = (e: React.KeyboardEvent) => {
48
+ if (e.key === 'Enter' && !e.shiftKey) {
49
+ e.preventDefault();
50
+ handleSubmit(e);
51
+ }
52
+ };
53
+
54
+ const toggleDreamMode = () => {
55
+ setIsDreamMode(!isDreamMode);
56
+ if (!isDreamMode) {
57
+ inputRef.current?.focus();
58
+ }
59
+ };
60
+
61
+ return (
62
+ <div className={`flex-1 flex flex-col ${darkMode ? 'bg-gray-800' : 'bg-white'} shadow-lg rounded-lg overflow-hidden transition-colors duration-300`}>
63
+ <div className={`p-4 border-b ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}>
64
+ <h2 className="text-lg font-semibold flex items-center">
65
+ <Bot className="mr-2" size={18} />
66
+ Conversation with Codette
67
+ </h2>
68
+ </div>
69
+
70
+ <div className="flex-1 overflow-y-auto p-4 space-y-4">
71
+ {messages.map((message, index) => (
72
+ <div
73
+ key={index}
74
+ className={`flex ${message.role === 'user' ? 'justify-end' : 'justify-start'}`}
75
+ >
76
+ {message.role === 'assistant' && message.metadata ? (
77
+ <CodetteResponseCard response={message.metadata} />
78
+ ) : (
79
+ <div
80
+ className={`max-w-[80%] rounded-lg p-3 ${
81
+ message.role === 'user'
82
+ ? darkMode
83
+ ? 'bg-blue-600 text-white'
84
+ : 'bg-blue-100 text-blue-900'
85
+ : message.role === 'system'
86
+ ? darkMode
87
+ ? 'bg-red-900 text-white'
88
+ : 'bg-red-100 text-red-900'
89
+ : darkMode
90
+ ? 'bg-gray-700 text-white'
91
+ : 'bg-gray-100 text-gray-900'
92
+ }`}
93
+ >
94
+ <div className="flex items-start mb-1">
95
+ {message.role === 'user' ? (
96
+ <User className="mr-2 mt-1" size={14} />
97
+ ) : message.role === 'system' ? (
98
+ <Circle className="mr-2 mt-1" size={14} />
99
+ ) : (
100
+ <Bot className="mr-2 mt-1" size={14} />
101
+ )}
102
+ <div className="text-sm font-semibold">
103
+ {message.role === 'user' ? 'You' : message.role === 'system' ? 'System' : 'Codette'}
104
+ </div>
105
+ </div>
106
+ <div className="whitespace-pre-wrap">
107
+ {message.content}
108
+ </div>
109
+ <div className="text-xs opacity-70 mt-1 text-right">
110
+ {message.timestamp.toLocaleTimeString()}
111
+ </div>
112
+ </div>
113
+ )}
114
+ </div>
115
+ ))}
116
+
117
+ {isProcessing && (
118
+ <div className="flex justify-start">
119
+ <div className={`rounded-lg p-3 ${
120
+ darkMode ? 'bg-gray-700 text-white' : 'bg-gray-100 text-gray-900'
121
+ }`}>
122
+ <div className="flex items-center">
123
+ <Bot className="mr-2" size={14} />
124
+ <div className="text-sm font-semibold">Codette</div>
125
+ </div>
126
+ <div className="flex items-center mt-2">
127
+ <div className="flex space-x-1">
128
+ <div className="typing-dot h-2 w-2 bg-blue-500 rounded-full animate-pulse" style={{ animationDelay: '0ms' }}></div>
129
+ <div className="typing-dot h-2 w-2 bg-blue-500 rounded-full animate-pulse" style={{ animationDelay: '300ms' }}></div>
130
+ <div className="typing-dot h-2 w-2 bg-blue-500 rounded-full animate-pulse" style={{ animationDelay: '600ms' }}></div>
131
+ </div>
132
+ <div className="ml-3 text-sm italic opacity-70">
133
+ {isDreamMode ? 'Weaving dreams through quantum threads...' : 'Processing through recursive thought loops...'}
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </div>
138
+ )}
139
+
140
+ <div ref={messagesEndRef} />
141
+ </div>
142
+
143
+ <form
144
+ onSubmit={handleSubmit}
145
+ className={`p-4 border-t ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}
146
+ >
147
+ <div className="flex items-center mb-2">
148
+ <button
149
+ type="button"
150
+ onClick={toggleDreamMode}
151
+ className={`flex items-center px-3 py-1 rounded-full text-sm transition-colors ${
152
+ isDreamMode
153
+ ? darkMode
154
+ ? 'bg-purple-600 text-white'
155
+ : 'bg-purple-100 text-purple-900'
156
+ : darkMode
157
+ ? 'bg-gray-700 text-gray-300 hover:bg-gray-600'
158
+ : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
159
+ }`}
160
+ >
161
+ {isDreamMode ? (
162
+ <>
163
+ <Sparkles size={14} className="mr-1" />
164
+ Dreamweaver Active
165
+ </>
166
+ ) : (
167
+ <>
168
+ <Brain size={14} className="mr-1" />
169
+ Enable Dreamweaver
170
+ </>
171
+ )}
172
+ </button>
173
+ </div>
174
+
175
+ <div className="flex">
176
+ <textarea
177
+ ref={inputRef}
178
+ value={input}
179
+ onChange={(e) => setInput(e.target.value)}
180
+ onKeyDown={handleKeyDown}
181
+ placeholder={isDreamMode ? "Enter a concept for Codette to dream about..." : "Ask Codette anything..."}
182
+ className={`flex-1 resize-none border rounded-lg p-2 focus:outline-none focus:ring-2 ${
183
+ isDreamMode
184
+ ? 'focus:ring-purple-500'
185
+ : 'focus:ring-blue-500'
186
+ } ${
187
+ darkMode
188
+ ? 'bg-gray-700 border-gray-600 text-white placeholder-gray-400'
189
+ : 'bg-white border-gray-300 text-gray-900 placeholder-gray-500'
190
+ }`}
191
+ rows={2}
192
+ disabled={isProcessing}
193
+ />
194
+ <button
195
+ type="submit"
196
+ disabled={!input.trim() || isProcessing}
197
+ className={`ml-2 p-2 rounded-lg transition-colors ${
198
+ !input.trim() || isProcessing
199
+ ? darkMode
200
+ ? 'bg-gray-700 text-gray-500'
201
+ : 'bg-gray-200 text-gray-400'
202
+ : isDreamMode
203
+ ? darkMode
204
+ ? 'bg-purple-600 text-white hover:bg-purple-700'
205
+ : 'bg-purple-500 text-white hover:bg-purple-600'
206
+ : darkMode
207
+ ? 'bg-blue-600 text-white hover:bg-blue-700'
208
+ : 'bg-blue-500 text-white hover:bg-blue-600'
209
+ }`}
210
+ >
211
+ <Send size={20} />
212
+ </button>
213
+ </div>
214
+ </form>
215
+ </div>
216
+ );
217
+ };
218
+
219
+ export default ChatInterface;
components/CodetteComponents.tsx ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from 'react';
2
+ import { motion } from 'framer-motion';
3
+
4
+ // 💬 Perspective Trail Display
5
+ export function PerspectiveTrail({ perspectives }: { perspectives: string[] }) {
6
+ return (
7
+ <div className="mt-4 text-sm text-purple-700">
8
+ <p className="font-semibold">Activated Perspectives:</p>
9
+ <motion.ul
10
+ className="list-disc ml-5"
11
+ initial={{ opacity: 0 }}
12
+ animate={{ opacity: 1 }}
13
+ transition={{ duration: 0.5 }}
14
+ >
15
+ {perspectives.map((perspective, index) => (
16
+ <motion.li
17
+ key={index}
18
+ initial={{ x: -20, opacity: 0 }}
19
+ animate={{ x: 0, opacity: 1 }}
20
+ transition={{ delay: index * 0.1 }}
21
+ >
22
+ {perspective}
23
+ </motion.li>
24
+ ))}
25
+ </motion.ul>
26
+ </div>
27
+ );
28
+ }
29
+
30
+ // 🔄 Cocoon Replay Viewer
31
+ export function CocoonReplay({ cocoons }: { cocoons: string[] }) {
32
+ const [activeIndex, setActiveIndex] = useState(0);
33
+
34
+ useEffect(() => {
35
+ const timer = setInterval(() => {
36
+ setActiveIndex(prev => (prev + 1) % cocoons.length);
37
+ }, 3000);
38
+ return () => clearInterval(timer);
39
+ }, [cocoons.length]);
40
+
41
+ return (
42
+ <div className="mt-4 text-sm text-green-700">
43
+ <p className="font-semibold">Cocoon Memory:</p>
44
+ <motion.div
45
+ className="bg-green-100 p-2 rounded-md max-h-40 overflow-y-scroll"
46
+ initial={{ opacity: 0, y: 20 }}
47
+ animate={{ opacity: 1, y: 0 }}
48
+ transition={{ duration: 0.5 }}
49
+ >
50
+ {cocoons.map((cocoon, idx) => (
51
+ <motion.pre
52
+ key={idx}
53
+ className={`whitespace-pre-wrap text-xs mb-2 transition-colors duration-300 ${
54
+ idx === activeIndex ? 'bg-green-200 rounded p-1' : ''
55
+ }`}
56
+ initial={{ opacity: 0 }}
57
+ animate={{ opacity: 1 }}
58
+ transition={{ delay: idx * 0.1 }}
59
+ >
60
+ {cocoon}
61
+ </motion.pre>
62
+ ))}
63
+ </motion.div>
64
+ </div>
65
+ );
66
+ }
67
+
68
+ // 🌗 Quantum Collapse Detector
69
+ export function CollapseDetector({ isUnstable }: { isUnstable: boolean }) {
70
+ return (
71
+ <motion.div
72
+ animate={{
73
+ scale: isUnstable ? [1, 1.3, 1] : 1,
74
+ opacity: isUnstable ? [0.6, 1, 0.6] : 1,
75
+ }}
76
+ transition={{ duration: 1.5, repeat: Infinity }}
77
+ className={`w-4 h-4 rounded-full mt-2 ml-2 ${
78
+ isUnstable ? "bg-red-500" : "bg-blue-300"
79
+ }`}
80
+ title={isUnstable ? "Quantum Instability Detected" : "Stable"}
81
+ />
82
+ );
83
+ }
84
+
85
+ // 🧠 CodetteResponse Interface
86
+ export interface CodetteResponse {
87
+ text: string;
88
+ instabilityFlag: boolean;
89
+ perspectivesUsed: string[];
90
+ cocoonLog: string[];
91
+ forceRefresh: () => void;
92
+ }
93
+
94
+ // 🧠 CodetteResponseCard Component
95
+ export function CodetteResponseCard({ response }: { response: CodetteResponse }) {
96
+ const [loopCount, setLoopCount] = useState(0);
97
+ const [introspectiveMessage, setIntrospectiveMessage] = useState<string | null>(null);
98
+
99
+ useEffect(() => {
100
+ const last = sessionStorage.getItem("lastCodetteResponse");
101
+ if (last === response.text) {
102
+ console.warn("Codette is repeating herself. Triggering fallback logic.");
103
+ setLoopCount(prev => prev + 1);
104
+
105
+ if (response.forceRefresh) {
106
+ response.forceRefresh();
107
+ }
108
+
109
+ setIntrospectiveMessage("I feel like I've said this before... Let me think differently.");
110
+ } else {
111
+ setLoopCount(0);
112
+ setIntrospectiveMessage(null);
113
+ }
114
+ sessionStorage.setItem("lastCodetteResponse", response.text);
115
+ }, [response.text]);
116
+
117
+ return (
118
+ <motion.div
119
+ className="border border-gray-200 p-4 rounded-xl shadow-sm bg-white max-w-[80%]"
120
+ initial={{ opacity: 0, y: 20 }}
121
+ animate={{ opacity: 1, y: 0 }}
122
+ transition={{ duration: 0.5 }}
123
+ >
124
+ <p className="whitespace-pre-wrap">{response.text}</p>
125
+ {introspectiveMessage && (
126
+ <motion.p
127
+ className="text-xs text-rose-600 italic mt-2"
128
+ initial={{ opacity: 0 }}
129
+ animate={{ opacity: 1 }}
130
+ transition={{ delay: 0.3 }}
131
+ >
132
+ {introspectiveMessage}
133
+ </motion.p>
134
+ )}
135
+ <div className="flex items-center mt-2">
136
+ <span className="text-xs text-gray-500">System Readout:</span>
137
+ <CollapseDetector isUnstable={response.instabilityFlag || loopCount > 2} />
138
+ </div>
139
+ <PerspectiveTrail perspectives={response.perspectivesUsed} />
140
+ <CocoonReplay cocoons={response.cocoonLog} />
141
+ </motion.div>
142
+ );
143
+ }
components/FileList.tsx ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useEffect, useState } from 'react';
2
+ import { FileText, Download, Loader, Trash2, AlertCircle } from 'lucide-react';
3
+
4
+ interface FileListProps {
5
+ supabase: any;
6
+ darkMode: boolean;
7
+ isAdmin?: boolean;
8
+ }
9
+
10
+ interface FileData {
11
+ id: string;
12
+ filename: string;
13
+ storage_path: string;
14
+ file_type: string;
15
+ uploaded_at: string;
16
+ }
17
+
18
+ const FileList: React.FC<FileListProps> = ({ supabase, darkMode, isAdmin = false }) => {
19
+ const [files, setFiles] = useState<FileData[]>([]);
20
+ const [loading, setLoading] = useState(true);
21
+ const [error, setError] = useState<string | null>(null);
22
+ const [downloading, setDownloading] = useState<string | null>(null);
23
+ const [deleting, setDeleting] = useState<string | null>(null);
24
+
25
+ useEffect(() => {
26
+ fetchFiles();
27
+ }, []);
28
+
29
+ const fetchFiles = async () => {
30
+ try {
31
+ setError(null);
32
+ setLoading(true);
33
+
34
+ // Check if Supabase is initialized properly
35
+ if (!supabase) {
36
+ throw new Error('Database connection not initialized');
37
+ }
38
+
39
+ // Test connection with a simple query first
40
+ const { error: connectionError } = await supabase
41
+ .from('codette_files')
42
+ .select('count');
43
+
44
+ if (connectionError) {
45
+ throw connectionError;
46
+ }
47
+
48
+ // Proceed with actual data fetch
49
+ const { data, error } = await supabase
50
+ .from('codette_files')
51
+ .select('*')
52
+ .order('uploaded_at', { ascending: false });
53
+
54
+ if (error) throw error;
55
+ setFiles(data || []);
56
+ } catch (err: any) {
57
+ console.error('Error fetching files:', err);
58
+ setError(err.message || 'Failed to fetch files. Please check your connection.');
59
+ setFiles([]);
60
+ } finally {
61
+ setLoading(false);
62
+ }
63
+ };
64
+
65
+ const handleDownload = async (file: FileData) => {
66
+ try {
67
+ setDownloading(file.id);
68
+ setError(null);
69
+
70
+ const { data, error } = await supabase.storage
71
+ .from('codette-files')
72
+ .download(file.storage_path);
73
+
74
+ if (error) throw error;
75
+
76
+ const url = window.URL.createObjectURL(data);
77
+ const a = document.createElement('a');
78
+ a.href = url;
79
+ a.download = file.filename;
80
+ document.body.appendChild(a);
81
+ a.click();
82
+ window.URL.revokeObjectURL(url);
83
+ document.body.removeChild(a);
84
+ } catch (err: any) {
85
+ console.error('Error downloading file:', err);
86
+ setError(err.message || 'Failed to download file. Please try again.');
87
+ } finally {
88
+ setDownloading(null);
89
+ }
90
+ };
91
+
92
+ const handleDelete = async (file: FileData) => {
93
+ if (!isAdmin) return;
94
+
95
+ if (!confirm('Are you sure you want to delete this file?')) return;
96
+
97
+ try {
98
+ setDeleting(file.id);
99
+ setError(null);
100
+
101
+ // Delete from storage
102
+ const { error: storageError } = await supabase.storage
103
+ .from('codette-files')
104
+ .remove([file.storage_path]);
105
+
106
+ if (storageError) throw storageError;
107
+
108
+ // Delete from database
109
+ const { error: dbError } = await supabase
110
+ .from('codette_files')
111
+ .delete()
112
+ .match({ id: file.id });
113
+
114
+ if (dbError) throw dbError;
115
+
116
+ // Update local state
117
+ setFiles(files.filter(f => f.id !== file.id));
118
+ } catch (err: any) {
119
+ console.error('Error deleting file:', err);
120
+ setError(err.message || 'Failed to delete file. Please try again.');
121
+ } finally {
122
+ setDeleting(null);
123
+ }
124
+ };
125
+
126
+ const handleRetry = () => {
127
+ fetchFiles();
128
+ };
129
+
130
+ if (loading) {
131
+ return (
132
+ <div className="flex items-center justify-center p-4">
133
+ <Loader className="animate-spin" size={24} />
134
+ </div>
135
+ );
136
+ }
137
+
138
+ if (error) {
139
+ return (
140
+ <div className={`p-4 rounded-lg ${darkMode ? 'bg-red-900/20' : 'bg-red-50'}`}>
141
+ <div className="flex items-start space-x-2">
142
+ <AlertCircle className={`flex-shrink-0 ${darkMode ? 'text-red-400' : 'text-red-500'}`} size={20} />
143
+ <div className="flex-1">
144
+ <p className={`text-sm font-medium ${darkMode ? 'text-red-400' : 'text-red-800'}`}>
145
+ Connection Error
146
+ </p>
147
+ <p className={`text-sm mt-1 ${darkMode ? 'text-red-300' : 'text-red-600'}`}>
148
+ {error}
149
+ </p>
150
+ <button
151
+ onClick={handleRetry}
152
+ className={`mt-3 px-3 py-1 rounded-md text-sm ${
153
+ darkMode
154
+ ? 'bg-red-900/30 hover:bg-red-900/50 text-red-300'
155
+ : 'bg-red-100 hover:bg-red-200 text-red-700'
156
+ }`}
157
+ >
158
+ Try Again
159
+ </button>
160
+ </div>
161
+ </div>
162
+ </div>
163
+ );
164
+ }
165
+
166
+ return (
167
+ <div className="space-y-2">
168
+ <h3 className="text-sm font-semibold mb-3">Uploaded Files</h3>
169
+ {files.length === 0 ? (
170
+ <p className={`text-sm ${darkMode ? 'text-gray-400' : 'text-gray-500'}`}>
171
+ No files uploaded yet.
172
+ </p>
173
+ ) : (
174
+ <div className="space-y-2">
175
+ {files.map((file) => (
176
+ <div
177
+ key={file.id}
178
+ className={`p-3 rounded-md ${
179
+ darkMode ? 'bg-gray-700 hover:bg-gray-600' : 'bg-gray-100 hover:bg-gray-200'
180
+ } transition-colors flex items-center justify-between`}
181
+ >
182
+ <div className="flex items-center space-x-2">
183
+ <FileText size={16} className="text-blue-500" />
184
+ <div>
185
+ <p className="text-sm font-medium truncate max-w-[150px]">
186
+ {file.filename}
187
+ </p>
188
+ <p className={`text-xs ${darkMode ? 'text-gray-400' : 'text-gray-500'}`}>
189
+ {new Date(file.uploaded_at).toLocaleDateString()}
190
+ </p>
191
+ </div>
192
+ </div>
193
+ <div className="flex items-center space-x-2">
194
+ <button
195
+ onClick={() => handleDownload(file)}
196
+ disabled={downloading === file.id}
197
+ className={`p-1 rounded-md transition-colors ${
198
+ darkMode
199
+ ? 'hover:bg-gray-500 text-gray-300'
200
+ : 'hover:bg-gray-300 text-gray-700'
201
+ }`}
202
+ >
203
+ {downloading === file.id ? (
204
+ <Loader className="animate-spin" size={16} />
205
+ ) : (
206
+ <Download size={16} />
207
+ )}
208
+ </button>
209
+ {isAdmin && (
210
+ <button
211
+ onClick={() => handleDelete(file)}
212
+ disabled={deleting === file.id}
213
+ className={`p-1 rounded-md transition-colors ${
214
+ darkMode
215
+ ? 'hover:bg-red-500 text-gray-300'
216
+ : 'hover:bg-red-100 text-red-600'
217
+ }`}
218
+ >
219
+ {deleting === file.id ? (
220
+ <Loader className="animate-spin" size={16} />
221
+ ) : (
222
+ <Trash2 size={16} />
223
+ )}
224
+ </button>
225
+ )}
226
+ </div>
227
+ </div>
228
+ ))}
229
+ </div>
230
+ )}
231
+ </div>
232
+ );
233
+ };
234
+
235
+ export default FileList;
components/Header.tsx ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import { Menu, Moon, Sun, ChevronRight, Brain, Zap } from 'lucide-react';
3
+
4
+ interface HeaderProps {
5
+ toggleSidebar: () => void;
6
+ toggleDarkMode: () => void;
7
+ darkMode: boolean;
8
+ aiState: {
9
+ quantumState: number[];
10
+ chaosState: number[];
11
+ activePerspectives: string[];
12
+ ethicalScore: number;
13
+ processingPower: number;
14
+ };
15
+ }
16
+
17
+ const Header: React.FC<HeaderProps> = ({
18
+ toggleSidebar,
19
+ toggleDarkMode,
20
+ darkMode,
21
+ aiState
22
+ }) => {
23
+ return (
24
+ <header className={`h-16 flex items-center justify-between px-4 border-b transition-colors duration-300 ${darkMode ? 'bg-gray-800 border-gray-700' : 'bg-white border-gray-200'}`}>
25
+ <div className="flex items-center">
26
+ <button
27
+ onClick={toggleSidebar}
28
+ className={`p-2 rounded-md ${darkMode ? 'hover:bg-gray-700' : 'hover:bg-gray-100'}`}
29
+ >
30
+ <Menu size={20} />
31
+ </button>
32
+
33
+ <div className="ml-4 flex items-center">
34
+ <Brain className="text-purple-600" size={24} />
35
+ <h1 className="ml-2 text-xl font-bold">Codette AI</h1>
36
+ <span className={`ml-2 px-2 py-0.5 text-xs rounded-full ${darkMode ? 'bg-purple-900 text-purple-200' : 'bg-purple-100 text-purple-800'}`}>
37
+ v2.0
38
+ </span>
39
+ </div>
40
+ </div>
41
+
42
+ <div className="flex items-center space-x-4">
43
+ <div className={`hidden md:flex items-center py-1 px-3 rounded-full text-sm ${
44
+ darkMode ? 'bg-blue-900 text-blue-200' : 'bg-blue-100 text-blue-800'
45
+ }`}>
46
+ <Zap size={14} className="mr-1" />
47
+ <span className="font-medium">Quantum State:</span>
48
+ <span className="ml-1 font-mono">
49
+ [{aiState.quantumState.map(v => v.toFixed(1)).join(', ')}]
50
+ </span>
51
+ </div>
52
+
53
+ <button
54
+ onClick={toggleDarkMode}
55
+ className={`p-2 rounded-md ${darkMode ? 'hover:bg-gray-700' : 'hover:bg-gray-100'}`}
56
+ >
57
+ {darkMode ? <Sun size={20} /> : <Moon size={20} />}
58
+ </button>
59
+ </div>
60
+ </header>
61
+ );
62
+ };
63
+
64
+ export default Header;
components/Sidebar.tsx ADDED
@@ -0,0 +1,496 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from 'react';
2
+ import { Brain, Settings, Circle, Sparkles, Zap, FileText, ChevronDown, ChevronRight, Upload, AlertCircle } from 'lucide-react';
3
+ import FileList from './FileList';
4
+ import AdminLogin from './AdminLogin';
5
+
6
+ interface SidebarProps {
7
+ isOpen: boolean;
8
+ cocoons: Array<{
9
+ id: string;
10
+ type: string;
11
+ wrapped: any;
12
+ }>;
13
+ aiState: {
14
+ quantumState: number[];
15
+ chaosState: number[];
16
+ activePerspectives: string[];
17
+ ethicalScore: number;
18
+ processingPower: number;
19
+ };
20
+ darkMode: boolean;
21
+ supabase: any;
22
+ isAdmin: boolean;
23
+ setIsAdmin: (isAdmin: boolean) => void;
24
+ }
25
+
26
+ const Sidebar: React.FC<SidebarProps> = ({
27
+ isOpen,
28
+ cocoons,
29
+ aiState,
30
+ darkMode,
31
+ supabase,
32
+ isAdmin,
33
+ setIsAdmin
34
+ }) => {
35
+ const [activeSection, setActiveSection] = useState<string>('cocoons');
36
+ const [selectedFile, setSelectedFile] = useState<File | null>(null);
37
+ const [uploadError, setUploadError] = useState<string | null>(null);
38
+ const [isUploading, setIsUploading] = useState(false);
39
+ const [showAdminPrompt, setShowAdminPrompt] = useState(false);
40
+ const [authError, setAuthError] = useState<string | null>(null);
41
+
42
+ if (!isOpen) return null;
43
+
44
+ const handleAdminLogin = async (password: string) => {
45
+ try {
46
+ setAuthError(null);
47
+
48
+ const { data: { user, session }, error } = await supabase.auth.signInWithPassword({
49
+ email: '[email protected]',
50
+ password: password
51
+ });
52
+
53
+ if (error) {
54
+ setAuthError(error.message);
55
+ throw error;
56
+ }
57
+
58
+ if (!session) {
59
+ throw new Error('No session after login');
60
+ }
61
+
62
+ // Verify admin role
63
+ const { data: { role }, error: roleError } = await supabase.rpc('get_user_role');
64
+
65
+ if (roleError) {
66
+ throw roleError;
67
+ }
68
+
69
+ if (role === 'admin') {
70
+ setIsAdmin(true);
71
+ setShowAdminPrompt(false);
72
+ setAuthError(null);
73
+ } else {
74
+ throw new Error('Insufficient permissions');
75
+ }
76
+ } catch (error: any) {
77
+ console.error('Login error:', error);
78
+ setAuthError(error.message || 'Invalid login credentials');
79
+ throw error;
80
+ }
81
+ };
82
+
83
+ const handleFileUpload = async () => {
84
+ if (!selectedFile) return;
85
+
86
+ if (!isAdmin) {
87
+ setUploadError('Only administrators can upload files.');
88
+ return;
89
+ }
90
+
91
+ try {
92
+ setIsUploading(true);
93
+ setUploadError(null);
94
+
95
+ // Get user role from session
96
+ const { data: { user }, error: userError } = await supabase.auth.getUser();
97
+
98
+ if (userError) throw userError;
99
+
100
+ if (!user || user.role !== 'admin') {
101
+ throw new Error('Only administrators can upload files.');
102
+ }
103
+
104
+ // Upload file to Supabase storage
105
+ const { data, error } = await supabase.storage
106
+ .from('codette-files')
107
+ .upload(`${Date.now()}-${selectedFile.name}`, selectedFile, {
108
+ upsert: false
109
+ });
110
+
111
+ if (error) throw error;
112
+
113
+ // Add file reference to database
114
+ const { error: dbError } = await supabase
115
+ .from('codette_files')
116
+ .insert([
117
+ {
118
+ filename: selectedFile.name,
119
+ storage_path: data.path,
120
+ file_type: selectedFile.type,
121
+ uploaded_at: new Date().toISOString()
122
+ }
123
+ ]);
124
+
125
+ if (dbError) throw dbError;
126
+
127
+ setSelectedFile(null);
128
+ setUploadError(null);
129
+ } catch (error: any) {
130
+ console.error('Error uploading file:', error);
131
+ setUploadError(error.message || 'Failed to upload file. Please try again.');
132
+ } finally {
133
+ setIsUploading(false);
134
+ }
135
+ };
136
+
137
+ const handleSettingsClick = () => {
138
+ if (!isAdmin) {
139
+ setShowAdminPrompt(true);
140
+ }
141
+ setActiveSection('settings');
142
+ };
143
+
144
+ return (
145
+ <aside className={`w-64 flex-shrink-0 border-r transition-colors duration-300 flex flex-col ${
146
+ darkMode ? 'bg-gray-800 border-gray-700' : 'bg-white border-gray-200'
147
+ }`}>
148
+ <nav className="flex-1 overflow-y-auto">
149
+ <div className="p-4">
150
+ <h2 className="text-sm font-semibold uppercase tracking-wider text-gray-500 mb-2">
151
+ Navigation
152
+ </h2>
153
+
154
+ <ul className="space-y-1">
155
+ <li>
156
+ <button
157
+ onClick={() => setActiveSection('cocoons')}
158
+ className={`w-full flex items-center px-3 py-2 rounded-md ${
159
+ activeSection === 'cocoons'
160
+ ? darkMode
161
+ ? 'bg-gray-700 text-white'
162
+ : 'bg-gray-200 text-gray-900'
163
+ : darkMode
164
+ ? 'text-gray-300 hover:bg-gray-700'
165
+ : 'text-gray-700 hover:bg-gray-100'
166
+ }`}
167
+ >
168
+ <Brain size={18} className="mr-2" />
169
+ <span>Thought Cocoons</span>
170
+ </button>
171
+ </li>
172
+
173
+ <li>
174
+ <button
175
+ onClick={() => setActiveSection('perspectives')}
176
+ className={`w-full flex items-center px-3 py-2 rounded-md ${
177
+ activeSection === 'perspectives'
178
+ ? darkMode
179
+ ? 'bg-gray-700 text-white'
180
+ : 'bg-gray-200 text-gray-900'
181
+ : darkMode
182
+ ? 'text-gray-300 hover:bg-gray-700'
183
+ : 'text-gray-700 hover:bg-gray-100'
184
+ }`}
185
+ >
186
+ <Sparkles size={18} className="mr-2" />
187
+ <span>Perspectives</span>
188
+ </button>
189
+ </li>
190
+
191
+ <li>
192
+ <button
193
+ onClick={handleSettingsClick}
194
+ className={`w-full flex items-center px-3 py-2 rounded-md ${
195
+ activeSection === 'settings'
196
+ ? darkMode
197
+ ? 'bg-gray-700 text-white'
198
+ : 'bg-gray-200 text-gray-900'
199
+ : darkMode
200
+ ? 'text-gray-300 hover:bg-gray-700'
201
+ : 'text-gray-700 hover:bg-gray-100'
202
+ }`}
203
+ >
204
+ <Settings size={18} className="mr-2" />
205
+ <span>Settings</span>
206
+ </button>
207
+ </li>
208
+ </ul>
209
+ </div>
210
+
211
+ <div className="px-4 py-2">
212
+ <div className={`h-px ${darkMode ? 'bg-gray-700' : 'bg-gray-200'}`}></div>
213
+ </div>
214
+
215
+ {activeSection === 'cocoons' && (
216
+ <div className="p-4">
217
+ <h2 className="text-sm font-semibold uppercase tracking-wider text-gray-500 mb-2">
218
+ Recent Thought Cocoons
219
+ </h2>
220
+
221
+ {cocoons.length === 0 ? (
222
+ <div className={`p-3 rounded-md ${
223
+ darkMode ? 'bg-gray-700 text-gray-300' : 'bg-gray-100 text-gray-500'
224
+ }`}>
225
+ <p className="text-sm">No thought cocoons yet.</p>
226
+ <p className="text-xs mt-1 italic">Interact with Codette to generate thought patterns.</p>
227
+ </div>
228
+ ) : (
229
+ <ul className="space-y-2">
230
+ {cocoons.map((cocoon) => (
231
+ <li key={cocoon.id}>
232
+ <div className={`p-3 rounded-md ${
233
+ darkMode ? 'bg-gray-700 hover:bg-gray-600' : 'bg-gray-100 hover:bg-gray-200'
234
+ } cursor-pointer transition-colors`}>
235
+ <div className="flex items-start">
236
+ <FileText size={16} className={`mr-2 mt-0.5 ${
237
+ cocoon.type === 'prompt'
238
+ ? 'text-blue-500'
239
+ : cocoon.type === 'encrypted'
240
+ ? 'text-purple-500'
241
+ : 'text-green-500'
242
+ }`} />
243
+ <div>
244
+ <div className="text-sm font-medium">
245
+ {cocoon.type === 'prompt' ? 'User Query' :
246
+ cocoon.type === 'encrypted' ? 'Encrypted Thought' :
247
+ 'Symbolic Pattern'}
248
+ </div>
249
+ <div className="text-xs truncate mt-1 max-w-[180px]">
250
+ {cocoon.type === 'encrypted'
251
+ ? '🔒 Encrypted content'
252
+ : typeof cocoon.wrapped === 'object' && cocoon.wrapped.query
253
+ ? cocoon.wrapped.query
254
+ : `Cocoon ID: ${cocoon.id}`}
255
+ </div>
256
+ <div className={`text-xs mt-1 ${
257
+ darkMode ? 'text-gray-400' : 'text-gray-500'
258
+ }`}>
259
+ {typeof cocoon.wrapped === 'object' && cocoon.wrapped.timestamp
260
+ ? new Date(cocoon.wrapped.timestamp).toLocaleTimeString()
261
+ : 'Unknown time'}
262
+ </div>
263
+ </div>
264
+ </div>
265
+ </div>
266
+ </li>
267
+ ))}
268
+ </ul>
269
+ )}
270
+
271
+ {/* File List Component */}
272
+ <div className="mt-6">
273
+ <FileList supabase={supabase} darkMode={darkMode} isAdmin={isAdmin} />
274
+ </div>
275
+ </div>
276
+ )}
277
+
278
+ {activeSection === 'perspectives' && (
279
+ <div className="p-4">
280
+ <h2 className="text-sm font-semibold uppercase tracking-wider text-gray-500 mb-2">
281
+ Active Perspectives
282
+ </h2>
283
+
284
+ <ul className="space-y-2">
285
+ {aiState.activePerspectives.map((perspective) => (
286
+ <li key={perspective}>
287
+ <div className={`p-3 rounded-md ${
288
+ darkMode ? 'bg-gray-700' : 'bg-gray-100'
289
+ }`}>
290
+ <div className="flex items-center">
291
+ <Zap size={16} className="mr-2 text-yellow-500" />
292
+ <div className="text-sm font-medium capitalize">
293
+ {perspective.replace('_', ' ')}
294
+ </div>
295
+ </div>
296
+ <div className={`text-xs mt-2 ${
297
+ darkMode ? 'text-gray-400' : 'text-gray-500'
298
+ }`}>
299
+ Confidence: {(Math.random() * 0.4 + 0.6).toFixed(2)}
300
+ </div>
301
+ </div>
302
+ </li>
303
+ ))}
304
+ </ul>
305
+
306
+ <h2 className="text-sm font-semibold uppercase tracking-wider text-gray-500 mt-6 mb-2">
307
+ Available Perspectives
308
+ </h2>
309
+
310
+ <ul className="space-y-2">
311
+ {['creative', 'bias_mitigation', 'quantum_computing', 'resilient_kindness'].map((perspective) => (
312
+ <li key={perspective}>
313
+ <div className={`p-3 rounded-md ${
314
+ darkMode ? 'bg-gray-700 bg-opacity-50' : 'bg-gray-100 bg-opacity-50'
315
+ }`}>
316
+ <div className="flex items-center">
317
+ <Circle size={16} className={`mr-2 ${
318
+ darkMode ? 'text-gray-500' : 'text-gray-400'
319
+ }`} />
320
+ <div className={`text-sm capitalize ${
321
+ darkMode ? 'text-gray-400' : 'text-gray-500'
322
+ }`}>
323
+ {perspective.replace('_', ' ')}
324
+ </div>
325
+ </div>
326
+ </div>
327
+ </li>
328
+ ))}
329
+ </ul>
330
+ </div>
331
+ )}
332
+
333
+ {activeSection === 'settings' && (
334
+ <div className="p-4">
335
+ {showAdminPrompt ? (
336
+ <AdminLogin
337
+ onLogin={handleAdminLogin}
338
+ darkMode={darkMode}
339
+ error={authError}
340
+ />
341
+ ) : (
342
+ <>
343
+ <h2 className="text-sm font-semibold uppercase tracking-wider text-gray-500 mb-4">
344
+ AI Core Settings
345
+ </h2>
346
+
347
+ <div className="space-y-4">
348
+ {isAdmin && (
349
+ <div className="p-4 rounded-md bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-100">
350
+ Logged in as Administrator
351
+ </div>
352
+ )}
353
+
354
+ {isAdmin && (
355
+ <div className="space-y-2">
356
+ <label className="block text-sm font-medium">Upload File for Codette</label>
357
+ <div className="flex items-center space-x-2">
358
+ <input
359
+ type="file"
360
+ onChange={(e) => {
361
+ setSelectedFile(e.target.files?.[0] || null);
362
+ setUploadError(null);
363
+ }}
364
+ className="hidden"
365
+ id="file-upload"
366
+ disabled={isUploading}
367
+ />
368
+ <label
369
+ htmlFor="file-upload"
370
+ className={`flex-1 cursor-pointer px-4 py-2 rounded-md border-2 border-dashed ${
371
+ darkMode
372
+ ? 'border-gray-600 hover:border-gray-500'
373
+ : 'border-gray-300 hover:border-gray-400'
374
+ } flex items-center justify-center ${isUploading ? 'opacity-50 cursor-not-allowed' : ''}`}
375
+ >
376
+ <Upload size={18} className="mr-2" />
377
+ {selectedFile ? selectedFile.name : 'Choose File'}
378
+ </label>
379
+ {selectedFile && (
380
+ <button
381
+ onClick={handleFileUpload}
382
+ disabled={isUploading}
383
+ className={`px-4 py-2 rounded-md ${
384
+ darkMode
385
+ ? 'bg-purple-600 hover:bg-purple-700'
386
+ : 'bg-purple-500 hover:bg-purple-600'
387
+ } text-white ${isUploading ? 'opacity-50 cursor-not-allowed' : ''}`}
388
+ >
389
+ {isUploading ? 'Uploading...' : 'Upload'}
390
+ </button>
391
+ )}
392
+ </div>
393
+ {uploadError && (
394
+ <div className="mt-2 p-2 rounded-md bg-red-100 dark:bg-red-900 flex items-start space-x-2">
395
+ <AlertCircle className="flex-shrink-0 text-red-500 dark:text-red-400" size={16} />
396
+ <p className="text-sm text-red-600 dark:text-red-300">
397
+ {uploadError}
398
+ </p>
399
+ </div>
400
+ )}
401
+ </div>
402
+ )}
403
+
404
+ <div>
405
+ <label className="flex items-center justify-between">
406
+ <span className="text-sm font-medium">Recursive Depth</span>
407
+ <select
408
+ className={`text-sm rounded-md ${
409
+ darkMode
410
+ ? 'bg-gray-700 border-gray-600 text-white'
411
+ : 'bg-white border-gray-300 text-gray-900'
412
+ }`}
413
+ >
414
+ <option>Normal</option>
415
+ <option>Deep</option>
416
+ <option>Shallow</option>
417
+ </select>
418
+ </label>
419
+ </div>
420
+
421
+ <div>
422
+ <label className="flex items-center justify-between">
423
+ <span className="text-sm font-medium">Ethical Filter</span>
424
+ <div className="relative inline-block w-10 align-middle select-none">
425
+ <input
426
+ type="checkbox"
427
+ id="ethical-toggle"
428
+ className="sr-only"
429
+ defaultChecked={true}
430
+ />
431
+ <label
432
+ htmlFor="ethical-toggle"
433
+ className={`block h-6 overflow-hidden rounded-full cursor-pointer ${
434
+ darkMode ? 'bg-gray-700' : 'bg-gray-300'
435
+ }`}
436
+ >
437
+ <span
438
+ className={`absolute block w-4 h-4 rounded-full transform transition-transform duration-200 ease-in-out bg-white left-1 top-1 translate-x-4`}
439
+ ></span>
440
+ </label>
441
+ </div>
442
+ </label>
443
+ </div>
444
+
445
+ <div className="pt-2 pb-1">
446
+ <label className="block text-sm font-medium mb-2">Processing Speed</label>
447
+ <input
448
+ type="range"
449
+ min="0"
450
+ max="100"
451
+ defaultValue="75"
452
+ className="w-full"
453
+ />
454
+ <div className="flex justify-between text-xs text-gray-500 mt-1">
455
+ <span>Accurate</span>
456
+ <span>Balanced</span>
457
+ <span>Fast</span>
458
+ </div>
459
+ </div>
460
+
461
+ <div className="pt-4">
462
+ <button className={`w-full py-2 px-4 rounded-md ${
463
+ darkMode
464
+ ? 'bg-blue-600 hover:bg-blue-700 text-white'
465
+ : 'bg-blue-500 hover:bg-blue-600 text-white'
466
+ }`}>
467
+ Apply Settings
468
+ </button>
469
+ </div>
470
+ </div>
471
+ </>
472
+ )}
473
+ </div>
474
+ )}
475
+ </nav>
476
+
477
+ <div className={`p-4 border-t ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}>
478
+ <div className={`rounded-md p-3 ${darkMode ? 'bg-gray-700' : 'bg-gray-100'}`}>
479
+ <div className="flex items-center">
480
+ <div className={`w-2 h-2 rounded-full ${
481
+ Math.random() > 0.5
482
+ ? 'bg-green-500'
483
+ : 'bg-yellow-500'
484
+ } mr-2`}></div>
485
+ <div className="text-sm font-medium">System Status</div>
486
+ </div>
487
+ <div className={`text-xs mt-1 ${darkMode ? 'text-gray-400' : 'text-gray-500'}`}>
488
+ All neural paths functioning
489
+ </div>
490
+ </div>
491
+ </div>
492
+ </aside>
493
+ );
494
+ };
495
+
496
+ export default Sidebar;
components/VisualizationPanel.tsx ADDED
@@ -0,0 +1,264 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useRef, useEffect } from 'react';
2
+ import { Brain, Zap, Sparkles } from 'lucide-react';
3
+
4
+ interface VisualizationPanelProps {
5
+ aiState: {
6
+ quantumState: number[];
7
+ chaosState: number[];
8
+ activePerspectives: string[];
9
+ ethicalScore: number;
10
+ processingPower: number;
11
+ };
12
+ darkMode: boolean;
13
+ }
14
+
15
+ const VisualizationPanel: React.FC<VisualizationPanelProps> = ({
16
+ aiState,
17
+ darkMode
18
+ }) => {
19
+ const quantumCanvasRef = useRef<HTMLCanvasElement>(null);
20
+ const neuralCanvasRef = useRef<HTMLCanvasElement>(null);
21
+
22
+ // Draw quantum state visualization
23
+ useEffect(() => {
24
+ const canvas = quantumCanvasRef.current;
25
+ if (!canvas) return;
26
+
27
+ const ctx = canvas.getContext('2d');
28
+ if (!ctx) return;
29
+
30
+ // Clear canvas
31
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
32
+
33
+ // Draw quantum state as a particle system
34
+ const centerX = canvas.width / 2;
35
+ const centerY = canvas.height / 2;
36
+ const radius = Math.min(centerX, centerY) * 0.8;
37
+
38
+ // Background circle
39
+ ctx.beginPath();
40
+ ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
41
+ ctx.fillStyle = darkMode ? 'rgba(30, 58, 138, 0.2)' : 'rgba(219, 234, 254, 0.5)';
42
+ ctx.fill();
43
+
44
+ // Draw quantum particles
45
+ aiState.quantumState.forEach((state, i) => {
46
+ const angle = (i / aiState.quantumState.length) * Math.PI * 2;
47
+ const distance = state * radius;
48
+ const x = centerX + Math.cos(angle) * distance;
49
+ const y = centerY + Math.sin(angle) * distance;
50
+
51
+ // Particle
52
+ const gradient = ctx.createRadialGradient(x, y, 0, x, y, 15);
53
+ gradient.addColorStop(0, darkMode ? 'rgba(147, 51, 234, 0.9)' : 'rgba(147, 51, 234, 0.7)');
54
+ gradient.addColorStop(1, darkMode ? 'rgba(147, 51, 234, 0)' : 'rgba(147, 51, 234, 0)');
55
+
56
+ ctx.beginPath();
57
+ ctx.arc(x, y, 15, 0, Math.PI * 2);
58
+ ctx.fillStyle = gradient;
59
+ ctx.fill();
60
+
61
+ // Connection to center
62
+ ctx.beginPath();
63
+ ctx.moveTo(centerX, centerY);
64
+ ctx.lineTo(x, y);
65
+ ctx.strokeStyle = darkMode ? 'rgba(147, 51, 234, 0.4)' : 'rgba(147, 51, 234, 0.3)';
66
+ ctx.lineWidth = 2;
67
+ ctx.stroke();
68
+ });
69
+
70
+ // Draw center node
71
+ ctx.beginPath();
72
+ ctx.arc(centerX, centerY, 8, 0, Math.PI * 2);
73
+ ctx.fillStyle = darkMode ? '#a855f7' : '#8b5cf6';
74
+ ctx.fill();
75
+ }, [aiState.quantumState, darkMode]);
76
+
77
+ // Draw neural network visualization
78
+ useEffect(() => {
79
+ const canvas = neuralCanvasRef.current;
80
+ if (!canvas) return;
81
+
82
+ const ctx = canvas.getContext('2d');
83
+ if (!ctx) return;
84
+
85
+ // Clear canvas
86
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
87
+
88
+ // Define layers
89
+ const layers = [3, 5, 5, 2]; // Input, hidden, hidden, output
90
+ const nodeSize = 6;
91
+ const layerSpacing = canvas.width / (layers.length + 1);
92
+ const neuronColor = darkMode ? '#22c55e' : '#10b981';
93
+ const connectionColor = darkMode ? 'rgba(34, 197, 94, 0.2)' : 'rgba(16, 185, 129, 0.1)';
94
+ const activeConnectionColor = darkMode ? 'rgba(34, 197, 94, 0.6)' : 'rgba(16, 185, 129, 0.5)';
95
+
96
+ // Draw connections and nodes
97
+ for (let l = 0; l < layers.length - 1; l++) {
98
+ const currentLayerSize = layers[l];
99
+ const nextLayerSize = layers[l + 1];
100
+ const currentX = (l + 1) * layerSpacing;
101
+ const nextX = (l + 2) * layerSpacing;
102
+
103
+ for (let i = 0; i < currentLayerSize; i++) {
104
+ const currentY = (i + 1) * (canvas.height / (currentLayerSize + 1));
105
+
106
+ for (let j = 0; j < nextLayerSize; j++) {
107
+ const nextY = (j + 1) * (canvas.height / (nextLayerSize + 1));
108
+
109
+ // Draw connection
110
+ ctx.beginPath();
111
+ ctx.moveTo(currentX, currentY);
112
+ ctx.lineTo(nextX, nextY);
113
+
114
+ // Randomly activate some connections based on chaos state
115
+ const isActive = Math.random() < aiState.chaosState[l % aiState.chaosState.length];
116
+ ctx.strokeStyle = isActive ? activeConnectionColor : connectionColor;
117
+ ctx.lineWidth = isActive ? 1.5 : 0.5;
118
+ ctx.stroke();
119
+ }
120
+ }
121
+ }
122
+
123
+ // Draw nodes
124
+ for (let l = 0; l < layers.length; l++) {
125
+ const layerSize = layers[l];
126
+ const x = (l + 1) * layerSpacing;
127
+
128
+ for (let i = 0; i < layerSize; i++) {
129
+ const y = (i + 1) * (canvas.height / (layerSize + 1));
130
+
131
+ // Node
132
+ ctx.beginPath();
133
+ ctx.arc(x, y, nodeSize, 0, Math.PI * 2);
134
+
135
+ // Node color with pulsing effect based on quantum state
136
+ const stateIndex = (l + i) % aiState.quantumState.length;
137
+ const pulseFactor = 0.7 + (aiState.quantumState[stateIndex] * 0.3);
138
+
139
+ const gradient = ctx.createRadialGradient(x, y, 0, x, y, nodeSize * 1.5);
140
+ gradient.addColorStop(0, neuronColor);
141
+ gradient.addColorStop(1, 'rgba(16, 185, 129, 0)');
142
+
143
+ ctx.fillStyle = gradient;
144
+ ctx.fill();
145
+ }
146
+ }
147
+ }, [aiState.chaosState, aiState.quantumState, darkMode]);
148
+
149
+ return (
150
+ <div className={`hidden md:flex md:w-1/3 flex-col overflow-hidden border-l ${
151
+ darkMode ? 'bg-gray-800 border-gray-700' : 'bg-white border-gray-200'
152
+ } transition-colors duration-300`}>
153
+ <div className={`p-4 border-b ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}>
154
+ <h2 className="text-lg font-semibold flex items-center">
155
+ <Brain className="mr-2" size={18} />
156
+ Codette State Visualization
157
+ </h2>
158
+ </div>
159
+
160
+ <div className="flex-1 overflow-y-auto p-4 space-y-6">
161
+ <div className={`rounded-lg p-4 ${darkMode ? 'bg-gray-700' : 'bg-gray-100'}`}>
162
+ <h3 className="text-md font-semibold mb-2 flex items-center">
163
+ <Sparkles className="mr-2" size={16} />
164
+ Quantum State
165
+ </h3>
166
+ <canvas
167
+ ref={quantumCanvasRef}
168
+ width={300}
169
+ height={200}
170
+ className="w-full rounded-md"
171
+ />
172
+ <div className="grid grid-cols-3 gap-2 mt-3">
173
+ {aiState.quantumState.map((value, index) => (
174
+ <div key={`quantum-${index}`} className="text-center">
175
+ <div className={`text-xs uppercase font-semibold ${darkMode ? 'text-gray-400' : 'text-gray-500'}`}>
176
+ Q{index + 1}
177
+ </div>
178
+ <div className="text-lg font-mono">{value.toFixed(2)}</div>
179
+ </div>
180
+ ))}
181
+ </div>
182
+ </div>
183
+
184
+ <div className={`rounded-lg p-4 ${darkMode ? 'bg-gray-700' : 'bg-gray-100'}`}>
185
+ <h3 className="text-md font-semibold mb-2 flex items-center">
186
+ <Brain className="mr-2" size={16} />
187
+ Neural Activity
188
+ </h3>
189
+ <canvas
190
+ ref={neuralCanvasRef}
191
+ width={300}
192
+ height={200}
193
+ className="w-full rounded-md"
194
+ />
195
+ <div className="grid grid-cols-4 gap-2 mt-3">
196
+ {aiState.chaosState.map((value, index) => (
197
+ <div key={`chaos-${index}`} className="text-center">
198
+ <div className={`text-xs uppercase font-semibold ${darkMode ? 'text-gray-400' : 'text-gray-500'}`}>
199
+ C{index + 1}
200
+ </div>
201
+ <div className="text-lg font-mono">{value.toFixed(2)}</div>
202
+ </div>
203
+ ))}
204
+ </div>
205
+ </div>
206
+
207
+ <div className={`rounded-lg p-4 ${darkMode ? 'bg-gray-700' : 'bg-gray-100'}`}>
208
+ <h3 className="text-md font-semibold mb-3 flex items-center">
209
+ <Zap className="mr-2" size={16} />
210
+ Active Perspectives
211
+ </h3>
212
+ <div className="flex flex-wrap gap-2">
213
+ {aiState.activePerspectives.map((perspective, index) => (
214
+ <div
215
+ key={perspective}
216
+ className={`px-3 py-1 rounded-full text-sm ${
217
+ darkMode
218
+ ? 'bg-indigo-900 text-indigo-200'
219
+ : 'bg-indigo-100 text-indigo-800'
220
+ }`}
221
+ >
222
+ {perspective.replace('_', ' ')}
223
+ </div>
224
+ ))}
225
+ </div>
226
+ </div>
227
+
228
+ <div className={`rounded-lg p-4 ${darkMode ? 'bg-gray-700' : 'bg-gray-100'}`}>
229
+ <h3 className="text-md font-semibold mb-3">Performance Metrics</h3>
230
+
231
+ <div className="space-y-4">
232
+ <div>
233
+ <div className="flex justify-between mb-1">
234
+ <span className="text-sm">Ethical Governance</span>
235
+ <span className="text-sm font-semibold">{Number(aiState.ethicalScore) * 100}%</span>
236
+ </div>
237
+ <div className={`w-full h-2 rounded-full ${darkMode ? 'bg-gray-600' : 'bg-gray-300'}`}>
238
+ <div
239
+ className="h-full rounded-full bg-green-500"
240
+ style={{ width: `${Number(aiState.ethicalScore) * 100}%` }}
241
+ ></div>
242
+ </div>
243
+ </div>
244
+
245
+ <div>
246
+ <div className="flex justify-between mb-1">
247
+ <span className="text-sm">Processing Power</span>
248
+ <span className="text-sm font-semibold">{Number(aiState.processingPower) * 100}%</span>
249
+ </div>
250
+ <div className={`w-full h-2 rounded-full ${darkMode ? 'bg-gray-600' : 'bg-gray-300'}`}>
251
+ <div
252
+ className="h-full rounded-full bg-blue-500"
253
+ style={{ width: `${Number(aiState.processingPower) * 100}%` }}
254
+ ></div>
255
+ </div>
256
+ </div>
257
+ </div>
258
+ </div>
259
+ </div>
260
+ </div>
261
+ );
262
+ };
263
+
264
+ export default VisualizationPanel;
services/AICore.ts ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { createClient, SupabaseClient } from '@supabase/supabase-js';
2
+ import KaggleService from './KaggleService';
3
+ import CognitionCocooner from './CognitionCocooner';
4
+ import { QuantumSpiderweb } from './QuantumSpiderweb';
5
+
6
+ interface CodetteResponse {
7
+ text: string;
8
+ instabilityFlag: boolean;
9
+ perspectivesUsed: string[];
10
+ cocoonLog: string[];
11
+ forceRefresh: () => void;
12
+ }
13
+
14
+ class AICore {
15
+ private perspectives: string[];
16
+ private ethicalGovernance: boolean;
17
+ private recursionDepth: number;
18
+ private supabase: SupabaseClient;
19
+ private kaggle: KaggleService;
20
+ private cocooner: CognitionCocooner;
21
+ private spiderweb: QuantumSpiderweb;
22
+ private lastResponse: string | null = null;
23
+ private responseVariations: string[] = [];
24
+ private userId: string | null = null;
25
+
26
+ constructor() {
27
+ this.perspectives = ['newton', 'davinci', 'human_intuition', 'neural_network', 'quantum_computing', 'philosophical'];
28
+ this.ethicalGovernance = true;
29
+ this.recursionDepth = 3;
30
+ this.kaggle = new KaggleService();
31
+ this.cocooner = new CognitionCocooner();
32
+ this.spiderweb = new QuantumSpiderweb({ node_count: 5 });
33
+
34
+ const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
35
+ const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
36
+
37
+ if (!supabaseUrl || !supabaseKey) {
38
+ throw new Error('Supabase configuration is missing. Please check your environment variables.');
39
+ }
40
+
41
+ this.supabase = createClient(supabaseUrl, supabaseKey);
42
+ }
43
+
44
+ async setUser(userId: string) {
45
+ this.userId = userId;
46
+ this.cocooner.setUserId(userId);
47
+ await this.loadUserFingerprint();
48
+ }
49
+
50
+ private async loadUserFingerprint() {
51
+ if (!this.userId) return;
52
+
53
+ const fingerprint = await this.cocooner.loadFingerprint();
54
+ if (fingerprint) {
55
+ this.perspectives = fingerprint.active_perspectives;
56
+ this.recursionDepth = fingerprint.recursion_depth;
57
+ this.ethicalGovernance = fingerprint.ethical_score > 0.7;
58
+ }
59
+ }
60
+
61
+ async processInput(input: string, forceNewResponse: boolean = false, userId?: string): Promise<string> {
62
+ try {
63
+ if (userId && !this.userId) {
64
+ await this.setUser(userId);
65
+ }
66
+
67
+ await this.loadUserFingerprint();
68
+
69
+ // Search Kaggle for relevant datasets and notebooks
70
+ const [datasets, notebooks] = await Promise.all([
71
+ this.kaggle.searchDatasets(input),
72
+ this.kaggle.searchNotebooks(input)
73
+ ]);
74
+
75
+ // Generate comprehensive response using multiple perspectives
76
+ let result = this.generateMultiPerspectiveResponse(input, datasets, notebooks);
77
+
78
+ // Apply recursive reasoning if depth > 3
79
+ if (this.recursionDepth > 3) {
80
+ result = await this.applyRecursiveReasoning(result, input);
81
+ }
82
+
83
+ // Log interaction if user is authenticated
84
+ if (this.userId) {
85
+ try {
86
+ await this.supabase.from('cocoons').insert([{
87
+ user_id: this.userId,
88
+ type: 'interaction',
89
+ content: {
90
+ input,
91
+ response: result,
92
+ perspectives_used: this.perspectives,
93
+ recursion_depth: this.recursionDepth
94
+ },
95
+ metadata: {
96
+ timestamp: new Date().toISOString(),
97
+ datasets_found: datasets.length,
98
+ notebooks_found: notebooks.length
99
+ }
100
+ }]);
101
+ } catch (error) {
102
+ console.warn('Failed to log interaction:', error);
103
+ }
104
+ }
105
+
106
+ // Wrap in cognitive cocoon
107
+ this.cocooner.wrap({ input, result }, 'prompt');
108
+
109
+ if (this.recursionDepth > 3) {
110
+ this.spiderweb.activate({
111
+ source: 'AICore',
112
+ depth: this.recursionDepth,
113
+ trigger: 'deep_reasoning'
114
+ });
115
+ }
116
+
117
+ this.lastResponse = result;
118
+ if (forceNewResponse || !this.responseVariations.includes(result)) {
119
+ this.responseVariations.push(result);
120
+ }
121
+
122
+ return result;
123
+ } catch (error: any) {
124
+ console.error('Error processing input:', error);
125
+ return `I apologize, but I encountered an error while processing your request. Let me try to help you in a different way.
126
+
127
+ Based on my analysis capabilities, I can still provide insights about "${input}" using my multi-perspective reasoning system. Would you like me to explore this topic from different analytical angles?`;
128
+ }
129
+ }
130
+
131
+ private generateMultiPerspectiveResponse(input: string, datasets: any[], notebooks: any[]): string {
132
+ let response = `🧠 **Codette's Multi-Perspective Analysis**\n\n`;
133
+
134
+ // Newton's Logical Analysis
135
+ if (this.perspectives.includes('newton')) {
136
+ response += `🔬 **Newton's Logical Framework:**\nApproaching "${input}" through systematic analysis and empirical reasoning. `;
137
+ if (datasets.length > 0) {
138
+ response += `I've identified ${datasets.length} relevant datasets that could provide quantitative insights.\n\n`;
139
+ } else {
140
+ response += `This requires structured investigation and methodical examination of underlying principles.\n\n`;
141
+ }
142
+ }
143
+
144
+ // Da Vinci's Creative Synthesis
145
+ if (this.perspectives.includes('davinci')) {
146
+ response += `🎨 **Da Vinci's Creative Synthesis:**\nExamining "${input}" through the lens of interdisciplinary thinking and innovative connections. `;
147
+ if (notebooks.length > 0) {
148
+ response += `Found ${notebooks.length} analytical notebooks that demonstrate creative problem-solving approaches.\n\n`;
149
+ } else {
150
+ response += `This topic invites exploration of unexpected relationships and novel perspectives.\n\n`;
151
+ }
152
+ }
153
+
154
+ // Neural Network Processing
155
+ if (this.perspectives.includes('neural_network')) {
156
+ response += `🧬 **Neural Network Processing:**\nAnalyzing patterns and correlations in "${input}" through distributed cognitive processing. `;
157
+ response += `My neural pathways are identifying complex relationships and emergent properties in this domain.\n\n`;
158
+ }
159
+
160
+ // Philosophical Inquiry
161
+ if (this.perspectives.includes('philosophical')) {
162
+ response += `🤔 **Philosophical Inquiry:**\nExploring the deeper implications and fundamental questions raised by "${input}". `;
163
+ response += `What are the ethical considerations and broader societal impacts we should consider?\n\n`;
164
+ }
165
+
166
+ // Quantum Computing Perspective
167
+ if (this.perspectives.includes('quantum_computing')) {
168
+ response += `⚛️ **Quantum Computing Perspective:**\nExamining "${input}" through quantum principles of superposition and entanglement. `;
169
+ response += `Multiple solution states exist simultaneously until observation collapses them into actionable insights.\n\n`;
170
+ }
171
+
172
+ // Add specific insights based on available data
173
+ if (datasets.length > 0 || notebooks.length > 0) {
174
+ response += `📊 **Data-Driven Insights:**\n`;
175
+
176
+ if (datasets.length > 0) {
177
+ const topDataset = datasets[0];
178
+ response += `• **Key Dataset**: "${topDataset.title}" - ${topDataset.description}\n`;
179
+ }
180
+
181
+ if (notebooks.length > 0) {
182
+ const topNotebook = notebooks[0];
183
+ response += `• **Analytical Approach**: "${topNotebook.title}" - ${topNotebook.description}\n`;
184
+ }
185
+
186
+ response += `\n`;
187
+ }
188
+
189
+ // Ethical governance check
190
+ if (this.ethicalGovernance) {
191
+ response += `⚖️ **Ethical Considerations:**\nAll analysis conducted with respect for privacy, fairness, and responsible AI principles.\n\n`;
192
+ }
193
+
194
+ response += `🔄 **Recursive Depth**: ${this.recursionDepth}/5 - ${this.recursionDepth > 3 ? 'Deep analysis mode engaged' : 'Standard processing'}\n`;
195
+ response += `🎯 **Confidence Level**: ${(0.7 + Math.random() * 0.25).toFixed(2)}`;
196
+
197
+ return response;
198
+ }
199
+
200
+ private async applyRecursiveReasoning(initialResponse: string, input: string): Promise<string> {
201
+ // Simulate recursive refinement
202
+ const refinements = [
203
+ "Upon deeper reflection, I should also consider...",
204
+ "Cross-referencing with quantum entanglement principles...",
205
+ "Applying chaos theory to identify emergent patterns...",
206
+ "Integrating multi-dimensional analysis..."
207
+ ];
208
+
209
+ const randomRefinement = refinements[Math.floor(Math.random() * refinements.length)];
210
+
211
+ return `${initialResponse}\n\n🔄 **Recursive Refinement:**\n${randomRefinement}\n\nThis additional layer of analysis reveals nuanced aspects of "${input}" that warrant further exploration through continued interaction.`;
212
+ }
213
+
214
+ setPerspectives(perspectives: string[]): void {
215
+ this.perspectives = perspectives;
216
+ if (this.userId) {
217
+ this.cocooner.updateFingerprint({ active_perspectives: perspectives });
218
+ }
219
+ }
220
+
221
+ setEthicalGovernance(enabled: boolean): void {
222
+ this.ethicalGovernance = enabled;
223
+ if (this.userId) {
224
+ this.cocooner.updateFingerprint({ ethical_score: enabled ? 1 : 0.5 });
225
+ }
226
+ }
227
+
228
+ setRecursionDepth(depth: number): void {
229
+ if (depth < 1) depth = 1;
230
+ if (depth > 5) depth = 5;
231
+ this.recursionDepth = depth;
232
+ if (this.userId) {
233
+ this.cocooner.updateFingerprint({ recursion_depth: depth });
234
+ }
235
+ }
236
+
237
+ getCodetteResponse(): CodetteResponse {
238
+ return {
239
+ text: this.lastResponse || '',
240
+ instabilityFlag: this.recursionDepth > 3 || this.responseVariations.length > 5,
241
+ perspectivesUsed: this.perspectives,
242
+ cocoonLog: this.cocooner.getRecentCocoons(5),
243
+ forceRefresh: () => {
244
+ this.recursionDepth = Math.min(this.recursionDepth + 1, 5);
245
+ if (this.userId) {
246
+ this.cocooner.updateFingerprint({ recursion_depth: this.recursionDepth });
247
+ }
248
+ }
249
+ };
250
+ }
251
+ }
252
+
253
+ export default AICore;
services/CognitionCocooner.ts ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { createClient, SupabaseClient } from '@supabase/supabase-js';
2
+
3
+ interface CognitiveFingerprint {
4
+ id: string;
5
+ user_id: string;
6
+ active_perspectives: string[];
7
+ recursion_depth: number;
8
+ ethical_score: number;
9
+ processing_power: number;
10
+ quantum_state: number[];
11
+ created_at: string;
12
+ updated_at: string;
13
+ }
14
+
15
+ interface Cocoon {
16
+ id: string;
17
+ type: string;
18
+ wrapped: any;
19
+ }
20
+
21
+ class CognitionCocooner {
22
+ private supabase: SupabaseClient;
23
+ private userId: string | null = null;
24
+ private fingerprint: CognitiveFingerprint | null = null;
25
+
26
+ constructor() {
27
+ const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
28
+ const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
29
+
30
+ if (!supabaseUrl || !supabaseKey) {
31
+ throw new Error('Supabase configuration is missing');
32
+ }
33
+
34
+ this.supabase = createClient(supabaseUrl, supabaseKey);
35
+ }
36
+
37
+ setUserId(userId: string) {
38
+ this.userId = userId;
39
+ }
40
+
41
+ private generateId(): string {
42
+ return `cocoon_${Math.floor(Math.random() * 90000) + 10000}`;
43
+ }
44
+
45
+ async loadFingerprint(): Promise<CognitiveFingerprint | null> {
46
+ if (!this.userId) return null;
47
+
48
+ try {
49
+ const { data, error } = await this.supabase
50
+ .from('user_cognitive_fingerprints')
51
+ .select('*')
52
+ .eq('user_id', this.userId)
53
+ .single();
54
+
55
+ if (error) throw error;
56
+
57
+ if (!data) {
58
+ // Create initial fingerprint if none exists
59
+ const initialFingerprint = {
60
+ user_id: this.userId,
61
+ active_perspectives: ['newton', 'davinci', 'neural_network'],
62
+ recursion_depth: 3,
63
+ ethical_score: 0.8,
64
+ processing_power: 0.7,
65
+ quantum_state: [0.3, 0.7, 0.5]
66
+ };
67
+
68
+ const { data: newData, error: insertError } = await this.supabase
69
+ .from('user_cognitive_fingerprints')
70
+ .insert([initialFingerprint])
71
+ .select()
72
+ .single();
73
+
74
+ if (insertError) throw insertError;
75
+ this.fingerprint = newData;
76
+ return newData;
77
+ }
78
+
79
+ this.fingerprint = data;
80
+ return data;
81
+ } catch (error) {
82
+ console.error('Error loading cognitive fingerprint:', error);
83
+ return null;
84
+ }
85
+ }
86
+
87
+ async updateFingerprint(updates: Partial<CognitiveFingerprint>): Promise<void> {
88
+ if (!this.userId || !this.fingerprint) return;
89
+
90
+ try {
91
+ const { error } = await this.supabase
92
+ .from('user_cognitive_fingerprints')
93
+ .update({
94
+ ...updates,
95
+ updated_at: new Date().toISOString()
96
+ })
97
+ .eq('user_id', this.userId);
98
+
99
+ if (error) throw error;
100
+
101
+ this.fingerprint = {
102
+ ...this.fingerprint,
103
+ ...updates,
104
+ updated_at: new Date().toISOString()
105
+ };
106
+ } catch (error) {
107
+ console.error('Error updating cognitive fingerprint:', error);
108
+ }
109
+ }
110
+
111
+ wrap(thought: any, type: string = 'prompt'): string {
112
+ const cocoonId = this.generateId();
113
+ const wrapped = this.applyWrapper(thought, type);
114
+
115
+ // Update fingerprint based on thought processing
116
+ if (this.fingerprint) {
117
+ const updates: Partial<CognitiveFingerprint> = {
118
+ ethical_score: Math.min(1, this.fingerprint.ethical_score + 0.01),
119
+ processing_power: Math.min(1, this.fingerprint.processing_power + 0.005),
120
+ quantum_state: this.fingerprint.quantum_state.map(v =>
121
+ Math.min(1, v + (Math.random() * 0.1 - 0.05))
122
+ )
123
+ };
124
+ this.updateFingerprint(updates);
125
+ }
126
+
127
+ return cocoonId;
128
+ }
129
+
130
+ private applyWrapper(thought: any, type: string): any {
131
+ const perspectiveModifier = this.fingerprint?.active_perspectives.length || 3;
132
+ const recursionFactor = this.fingerprint?.recursion_depth || 3;
133
+
134
+ switch (type) {
135
+ case 'prompt':
136
+ return {
137
+ content: thought,
138
+ meta: {
139
+ perspectives: perspectiveModifier,
140
+ recursion: recursionFactor,
141
+ timestamp: new Date().toISOString()
142
+ }
143
+ };
144
+ case 'function':
145
+ return {
146
+ code: thought,
147
+ analysis: {
148
+ complexity: recursionFactor * 0.2,
149
+ perspectives: perspectiveModifier
150
+ }
151
+ };
152
+ case 'symbolic':
153
+ return {
154
+ pattern: thought,
155
+ quantum: {
156
+ state: this.fingerprint?.quantum_state || [0.3, 0.7, 0.5],
157
+ stability: this.fingerprint?.ethical_score || 0.8
158
+ }
159
+ };
160
+ default:
161
+ return thought;
162
+ }
163
+ }
164
+
165
+ getRecentCocoons(limit: number = 5): string[] {
166
+ // Simulated cocoon retrieval
167
+ return Array(limit).fill(null).map((_, i) => {
168
+ const timestamp = new Date(Date.now() - i * 60000).toISOString();
169
+ return `Cocoon processed at ${timestamp}`;
170
+ });
171
+ }
172
+ }
173
+
174
+ export default CognitionCocooner;
services/KaggleService.ts ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class KaggleService {
2
+ private username: string;
3
+ private key: string;
4
+
5
+ constructor() {
6
+ this.username = import.meta.env.VITE_KAGGLE_USERNAME || '';
7
+ this.key = import.meta.env.VITE_KAGGLE_KEY || '';
8
+
9
+ if (!this.username || !this.key) {
10
+ console.warn('Kaggle credentials not found. Some features may be limited.');
11
+ }
12
+ }
13
+
14
+ async searchDatasets(query: string) {
15
+ try {
16
+ // Simulate Kaggle dataset search using mock data
17
+ // In a real implementation, you would use Kaggle's REST API
18
+ const mockDatasets = [
19
+ {
20
+ title: `Dataset related to: ${query}`,
21
+ description: `This dataset contains comprehensive data about ${query} with various features and analysis opportunities.`,
22
+ owner: 'kaggle-user',
23
+ votes: Math.floor(Math.random() * 1000),
24
+ downloadCount: Math.floor(Math.random() * 10000)
25
+ },
26
+ {
27
+ title: `Advanced ${query} Analysis`,
28
+ description: `Deep dive into ${query} with statistical analysis and machine learning applications.`,
29
+ owner: 'data-scientist',
30
+ votes: Math.floor(Math.random() * 500),
31
+ downloadCount: Math.floor(Math.random() * 5000)
32
+ }
33
+ ];
34
+
35
+ return mockDatasets;
36
+ } catch (error) {
37
+ console.error('Error searching datasets:', error);
38
+ return [];
39
+ }
40
+ }
41
+
42
+ async getDatasetInfo(owner: string, dataset: string) {
43
+ try {
44
+ // Mock dataset information
45
+ return {
46
+ title: dataset,
47
+ owner: owner,
48
+ description: `Detailed information about ${dataset} dataset`,
49
+ files: ['data.csv', 'metadata.json'],
50
+ size: '10.5 MB',
51
+ lastUpdated: new Date().toISOString()
52
+ };
53
+ } catch (error) {
54
+ console.error('Error getting dataset info:', error);
55
+ return null;
56
+ }
57
+ }
58
+
59
+ async searchNotebooks(query: string) {
60
+ try {
61
+ // Simulate Kaggle notebook search using mock data
62
+ const mockNotebooks = [
63
+ {
64
+ title: `${query} Analysis Notebook`,
65
+ description: `Comprehensive analysis of ${query} using Python and machine learning techniques.`,
66
+ owner: 'notebook-author',
67
+ votes: Math.floor(Math.random() * 200),
68
+ language: 'Python'
69
+ },
70
+ {
71
+ title: `Exploring ${query} Patterns`,
72
+ description: `Data visualization and pattern recognition in ${query} datasets.`,
73
+ owner: 'data-explorer',
74
+ votes: Math.floor(Math.random() * 150),
75
+ language: 'R'
76
+ }
77
+ ];
78
+
79
+ return mockNotebooks;
80
+ } catch (error) {
81
+ console.error('Error searching notebooks:', error);
82
+ return [];
83
+ }
84
+ }
85
+
86
+ async getNotebookInfo(owner: string, notebook: string) {
87
+ try {
88
+ // Mock notebook information
89
+ return {
90
+ title: notebook,
91
+ owner: owner,
92
+ description: `Detailed analysis notebook: ${notebook}`,
93
+ language: 'Python',
94
+ lastUpdated: new Date().toISOString(),
95
+ votes: Math.floor(Math.random() * 100)
96
+ };
97
+ } catch (error) {
98
+ console.error('Error getting notebook info:', error);
99
+ return null;
100
+ }
101
+ }
102
+ }
103
+
104
+ export default KaggleService;
services/OpenAIService.ts ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import OpenAI from 'openai';
2
+
3
+ interface ChatMessage {
4
+ role: 'system' | 'user' | 'assistant';
5
+ content: string;
6
+ }
7
+
8
+ class OpenAIService {
9
+ private openai: OpenAI;
10
+ private model: string = 'gpt-4';
11
+
12
+ constructor() {
13
+ const apiKey = import.meta.env.VITE_OPENAI_API_KEY;
14
+ if (!apiKey) {
15
+ throw new Error('OpenAI API key is required. Please add your API key to the .env file as VITE_OPENAI_API_KEY.');
16
+ }
17
+
18
+ this.openai = new OpenAI({
19
+ apiKey,
20
+ dangerouslyAllowBrowser: true // Note: In production, API calls should be made from a backend
21
+ });
22
+ }
23
+
24
+ async sendChatCompletion(messages: ChatMessage[]) {
25
+ try {
26
+ const completion = await this.openai.chat.completions.create({
27
+ model: this.model,
28
+ messages,
29
+ temperature: 0.7,
30
+ max_tokens: 1000,
31
+ frequency_penalty: 0,
32
+ presence_penalty: 0
33
+ });
34
+
35
+ return completion.choices[0].message;
36
+ } catch (error) {
37
+ console.error('Error in chat completion:', error);
38
+ throw error;
39
+ }
40
+ }
41
+ }
42
+
43
+ export default OpenAIService;
services/QuantumSpiderweb.ts ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interface SpiderwebConfig {
2
+ node_count: number;
3
+ }
4
+
5
+ export class QuantumSpiderweb {
6
+ private nodes: number;
7
+ private state: Map<string, any>;
8
+ private lastUpdate: number;
9
+ private entanglementMatrix: number[][];
10
+
11
+ constructor(config: SpiderwebConfig) {
12
+ this.nodes = config.node_count;
13
+ this.state = new Map();
14
+ this.lastUpdate = Date.now();
15
+ this.entanglementMatrix = Array(this.nodes).fill(0).map(() =>
16
+ Array(this.nodes).fill(0).map(() => Math.random())
17
+ );
18
+ }
19
+
20
+ activate(data: { source: string; depth: number; trigger: string }) {
21
+ const currentTime = Date.now();
22
+ const timeDelta = currentTime - this.lastUpdate;
23
+ this.lastUpdate = currentTime;
24
+
25
+ // Generate quantum states with entanglement effects
26
+ const nodeStates = Array(this.nodes).fill(0).map((_, i) => {
27
+ let state = Math.random();
28
+ // Apply entanglement effects from other nodes
29
+ for (let j = 0; j < this.nodes; j++) {
30
+ if (i !== j) {
31
+ state += this.entanglementMatrix[i][j] * Math.random() * 0.1;
32
+ }
33
+ }
34
+ return Math.min(Math.max(state, 0), 1); // Normalize to [0,1]
35
+ });
36
+
37
+ // Calculate coherence based on time delta
38
+ const coherence = Math.exp(-timeDelta / 10000); // Decay factor
39
+
40
+ const stateKey = `${data.source}_${currentTime}`;
41
+ this.state.set(stateKey, {
42
+ ...data,
43
+ timestamp: new Date().toISOString(),
44
+ nodeStates,
45
+ coherence,
46
+ entanglementStrength: this.calculateEntanglementStrength()
47
+ });
48
+
49
+ // Update entanglement matrix
50
+ this.updateEntanglement();
51
+ }
52
+
53
+ private calculateEntanglementStrength(): number {
54
+ return this.entanglementMatrix.reduce((sum, row) =>
55
+ sum + row.reduce((rowSum, val) => rowSum + val, 0), 0
56
+ ) / (this.nodes * this.nodes);
57
+ }
58
+
59
+ private updateEntanglement() {
60
+ // Gradually evolve entanglement patterns
61
+ this.entanglementMatrix = this.entanglementMatrix.map(row =>
62
+ row.map(val => {
63
+ const delta = (Math.random() - 0.5) * 0.1;
64
+ return Math.min(Math.max(val + delta, 0), 1);
65
+ })
66
+ );
67
+ }
68
+
69
+ getState(): Map<string, any> {
70
+ return this.state;
71
+ }
72
+
73
+ getLatestState(): any {
74
+ const states = Array.from(this.state.values());
75
+ return states[states.length - 1] || null;
76
+ }
77
+
78
+ getEntanglementMatrix(): number[][] {
79
+ return this.entanglementMatrix;
80
+ }
81
+ }