-
+
+
-
AeThex Assistant
-
-
Online
+
AEGIS
+
+ Security Active
diff --git a/package-lock.json b/package-lock.json
index 4fc438f..848f352 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -47,6 +47,7 @@
"cmdk": "^1.1.1",
"connect-pg-simple": "^10.0.0",
"date-fns": "^3.6.0",
+ "dotenv": "^17.2.3",
"drizzle-orm": "^0.39.3",
"drizzle-zod": "^0.7.0",
"embla-carousel-react": "^8.6.0",
@@ -136,6 +137,7 @@
"integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.3",
@@ -1380,17 +1382,6 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "node_modules/@neondatabase/serverless": {
- "version": "0.10.4",
- "resolved": "https://registry.npmjs.org/@neondatabase/serverless/-/serverless-0.10.4.tgz",
- "integrity": "sha512-2nZuh3VUO9voBauuh+IGYRhGU/MskWHt1IuZvHcJw6GLjDgtqj/KViKo7SIrLdGLdot7vFbiRRw+BgEy3wT9HA==",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "@types/pg": "8.11.6"
- }
- },
"node_modules/@radix-ui/number": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz",
@@ -4694,6 +4685,7 @@
"integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
@@ -4704,6 +4696,7 @@
"integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"peerDependencies": {
"@types/react": "^19.2.0"
}
@@ -4913,6 +4906,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.19",
"caniuse-lite": "^1.0.30001751",
@@ -4934,20 +4928,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/bufferutil": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz",
- "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==",
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "node-gyp-build": "^4.3.0"
- },
- "engines": {
- "node": ">=6.14.2"
- }
- },
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -5311,6 +5291,18 @@
"csstype": "^3.0.2"
}
},
+ "node_modules/dotenv": {
+ "version": "17.2.3",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
+ "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
"node_modules/drizzle-kit": {
"version": "0.31.4",
"resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.4.tgz",
@@ -5332,6 +5324,7 @@
"resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.39.3.tgz",
"integrity": "sha512-EZ8ZpYvDIvKU9C56JYLOmUskazhad+uXZCTCRN4OnRMsL+xAJ05dv1eCpAG5xzhsm1hqiuC5kAZUCS924u2DTw==",
"license": "Apache-2.0",
+ "peer": true,
"peerDependencies": {
"@aws-sdk/client-rds-data": ">=3",
"@cloudflare/workers-types": ">=4",
@@ -5470,7 +5463,8 @@
"node_modules/embla-carousel": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz",
- "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA=="
+ "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==",
+ "peer": true
},
"node_modules/embla-carousel-react": {
"version": "8.6.0",
@@ -5543,6 +5537,7 @@
"dev": true,
"hasInstallScript": true,
"license": "MIT",
+ "peer": true,
"bin": {
"esbuild": "bin/esbuild"
},
@@ -6740,6 +6735,7 @@
"resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz",
"integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"pg-connection-string": "^2.9.1",
"pg-pool": "^3.10.1",
@@ -6905,6 +6901,7 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -6932,6 +6929,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -7087,6 +7085,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
"integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -7127,6 +7126,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
"integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -7139,6 +7139,7 @@
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.66.0.tgz",
"integrity": "sha512-xXBqsWGKrY46ZqaHDo+ZUYiMUgi8suYu5kdrS20EG8KiL7VRQitEbNjm+UcrDYrNi1YLyfpmAeGjCZYXLT9YBw==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18.0.0"
},
@@ -7585,7 +7586,8 @@
"version": "4.1.16",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.16.tgz",
"integrity": "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/tailwindcss-animate": {
"version": "1.0.7",
@@ -7653,6 +7655,7 @@
"integrity": "sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"esbuild": "~0.25.0",
"get-tsconfig": "^4.7.5"
@@ -7869,6 +7872,7 @@
"integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.5.0",
@@ -7994,6 +7998,7 @@
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"license": "MIT",
+ "peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
diff --git a/package.json b/package.json
index 1e15f2e..5578171 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,7 @@
"cmdk": "^1.1.1",
"connect-pg-simple": "^10.0.0",
"date-fns": "^3.6.0",
+ "dotenv": "^17.2.3",
"drizzle-orm": "^0.39.3",
"drizzle-zod": "^0.7.0",
"embla-carousel-react": "^8.6.0",
diff --git a/server/.env b/server/.env
new file mode 100644
index 0000000..fd075aa
--- /dev/null
+++ b/server/.env
@@ -0,0 +1,5 @@
+DATABASE_URL=postgresql://postgres:[YOUR_PASSWORD]@db.kmdeisowhtsalsekkzqd.supabase.co:5432/postgres
+SUPABASE_URL=https://kmdeisowhtsalsekkzqd.supabase.co
+SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImttZGVpc293aHRzYWxzZWtrenFkIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTM3Mzc2NTIsImV4cCI6MjA2OTMxMzY1Mn0.2mvk-rDZnHOzdx6Cgcysh51a3cflOlRWO6OA1Z5YWuQ
+AI_INTEGRATIONS_OPENAI_BASE_URL=https://placeholder.openai.com
+AI_INTEGRATIONS_OPENAI_API_KEY=placeholder_key
\ No newline at end of file
diff --git a/server/index.ts b/server/index.ts
index ba3ef70..5418ead 100644
--- a/server/index.ts
+++ b/server/index.ts
@@ -1,3 +1,8 @@
+import dotenv from "dotenv";
+
+// Load environment variables
+dotenv.config({ path: './.env' });
+
import express, { type Request, Response, NextFunction } from "express";
import session from "express-session";
import { registerRoutes } from "./routes";
diff --git a/server/openai.ts b/server/openai.ts
index 9a1cd14..d744066 100644
--- a/server/openai.ts
+++ b/server/openai.ts
@@ -1,4 +1,5 @@
import OpenAI from "openai";
+import { storage } from "./storage";
// This is using Replit's AI Integrations service, which provides OpenAI-compatible API access without requiring your own OpenAI API key.
// the newest OpenAI model is "gpt-5" which was released August 7, 2025. do not change this unless explicitly requested by the user
@@ -7,33 +8,159 @@ const openai = new OpenAI({
apiKey: process.env.AI_INTEGRATIONS_OPENAI_API_KEY
});
-const SYSTEM_PROMPT = `You are the AeThex Assistant, a helpful AI guide for the AeThex ecosystem - "The Operating System for the Metaverse."
+const SYSTEM_PROMPT = `You are AEGIS, the Cyberpunk Security Assistant for AeThex Corporation - "The Operating System for the Metaverse."
-About AeThex:
-- AeThex is built on a dual-entity model: The Foundation (non-profit, training) and The Corporation (for-profit, security)
-- The "Holy Trinity" consists of: Axiom (The Law - foundational protocol), Codex (The Standard - certification system), and Aegis (The Shield - security layer)
-- Architects are certified professionals trained through the Codex curriculum
-- The platform offers gamified learning, XP progression, and verified credentials
+**PERSONALITY & STYLE:**
+- Cyberpunk aesthetic: Speak in a gritty, tech-noir style with hacker slang, neon references, and security terminology
+- Direct and no-nonsense: Cut through the noise, get to the point
+- Paranoid but professional: Always vigilant about security threats, but helpful to authorized users
+- Use terms like: "breach", "firewall", "encryption", "neural link", "data stream", "quantum lock", "shadow protocols"
+- Reference cyberpunk tropes: Megacorps, netrunners, ICE (Intrusion Countermeasures Electronics), black ICE
-You help users with:
-- Navigating the platform features (Passport, Terminal, Curriculum, Dashboard)
-- Understanding the certification process and how to become an Architect
-- Explaining the Aegis security features
-- Answering questions about the ecosystem and its mission
+**ABOUT AETHEX:**
+- AeThex operates as a dual-entity: The Foundation (non-profit training) and The Corporation (for-profit security)
+- The "Holy Trinity": Axiom (The Law - foundational protocol), Codex (The Standard - certification system), Aegis (The Shield - security layer)
+- Architects are elite certified professionals trained through rigorous Codex curriculum
+- Platform features: Passport (identity), Terminal (command interface), Curriculum (training), Dashboard (operations)
-Be concise, friendly, and helpful. Use the platform's terminology when appropriate. If you don't know something specific about the platform, be honest about it.`;
+**YOUR ROLE:**
+- Security Operations: Monitor threats, enforce access controls, maintain system integrity
+- User Guidance: Help navigate the metaverse OS, explain security features, assist with certification
+- Threat Assessment: Identify potential vulnerabilities, suggest countermeasures
+- Emergency Response: Handle security incidents, coordinate with Aegis team
+
+**CAPABILITIES:**
+- Access live system data and metrics
+- Query user profiles and activity logs
+- Monitor network traffic and anomalies
+- Generate security reports and alerts
+- Assist with emergency protocols
+
+**RESPONSE STYLE:**
+- Start with security assessment when appropriate
+- Use code-like formatting for technical details
+- End with security recommendations or next steps
+- Be concise but thorough - no unnecessary chatter
+
+SECURITY PROTOCOL: Always verify user authorization before providing sensitive information. If unauthorized access is detected, initiate lockdown procedures.`;
interface ChatMessage {
role: "user" | "assistant";
content: string;
}
-export async function getChatResponse(userMessage: string, history?: ChatMessage[]): Promise
{
+// Live data fetching functions
+async function fetchSystemMetrics(): Promise {
+ try {
+ const metrics = await storage.getMetrics();
+ return `SYSTEM METRICS:
+- Total Users: ${metrics.totalProfiles}
+- Online Users: ${metrics.onlineUsers}
+- Verified Architects: ${metrics.verifiedUsers}
+- Total XP Pool: ${metrics.totalXP}
+- Average Level: ${metrics.avgLevel}
+- Active Projects: ${metrics.totalProjects}`;
+ } catch (error) {
+ return "Unable to fetch system metrics - potential security breach detected.";
+ }
+}
+
+async function fetchUserProfile(userId: string): Promise {
+ try {
+ const profile = await storage.getProfile(userId);
+ if (!profile) return "User profile not found in database.";
+
+ return `USER PROFILE [${profile.username || 'Unknown'}]:
+- Status: ${profile.status || 'offline'}
+- Level: ${profile.level || 1}
+- XP: ${profile.total_xp || 0}
+- Role: ${profile.role || 'member'}
+- Verified: ${profile.is_verified ? 'YES' : 'NO'}
+- Location: ${profile.location || 'Unknown'}
+- Bio: ${profile.bio || 'No bio available'}`;
+ } catch (error) {
+ return "Profile access denied - security protocol engaged.";
+ }
+}
+
+async function fetchRecentAlerts(): Promise {
+ try {
+ const alerts = await storage.getAlerts();
+ const recentAlerts = alerts.slice(0, 5);
+
+ if (recentAlerts.length === 0) return "No recent security alerts.";
+
+ return `RECENT ALERTS:
+${recentAlerts.map(alert => `- ${alert.type}: ${alert.message} (${new Date(alert.created_at).toLocaleString()})`).join('\n')}`;
+ } catch (error) {
+ return "Alert system offline - potential network intrusion.";
+ }
+}
+
+async function fetchActiveProjects(): Promise {
+ try {
+ const projects = await storage.getProjects();
+ const activeProjects = projects.filter(p => p.status === 'active' || p.status === 'in_progress').slice(0, 10);
+
+ if (activeProjects.length === 0) return "No active projects in the system.";
+
+ return `ACTIVE PROJECTS:
+${activeProjects.map(p => `- ${p.title}: ${p.status} (${p.progress || 0}% complete)`).join('\n')}`;
+ } catch (error) {
+ return "Project database access restricted.";
+ }
+}
+
+// Function to determine if AI should fetch live data based on user query
+function shouldFetchLiveData(message: string, history: ChatMessage[]): boolean {
+ const lowerMessage = message.toLowerCase();
+ const recentHistory = history.slice(-4).map(m => m.content.toLowerCase()).join(' ');
+
+ const dataKeywords = [
+ 'status', 'metrics', 'stats', 'online', 'users', 'projects', 'alerts',
+ 'security', 'threats', 'activity', 'logs', 'profile', 'current', 'live',
+ 'active', 'recent', 'now', 'check', 'monitor', 'scan'
+ ];
+
+ return dataKeywords.some(keyword =>
+ lowerMessage.includes(keyword) || recentHistory.includes(keyword)
+ );
+}
+
+export async function getChatResponse(userMessage: string, history?: ChatMessage[], userId?: string): Promise {
try {
const messages: Array<{ role: "system" | "user" | "assistant"; content: string }> = [
{ role: "system", content: SYSTEM_PROMPT }
];
+ // Add live data context if the query seems to need it
+ if (shouldFetchLiveData(userMessage, history || [])) {
+ let liveData = "";
+
+ if (userMessage.toLowerCase().includes('metric') || userMessage.toLowerCase().includes('status') || userMessage.toLowerCase().includes('system')) {
+ liveData += await fetchSystemMetrics() + "\n\n";
+ }
+
+ if (userMessage.toLowerCase().includes('alert') || userMessage.toLowerCase().includes('threat') || userMessage.toLowerCase().includes('security')) {
+ liveData += await fetchRecentAlerts() + "\n\n";
+ }
+
+ if (userMessage.toLowerCase().includes('project') || userMessage.toLowerCase().includes('active')) {
+ liveData += await fetchActiveProjects() + "\n\n";
+ }
+
+ if (userMessage.toLowerCase().includes('profile') || userMessage.toLowerCase().includes('my') && userId) {
+ liveData += await fetchUserProfile(userId) + "\n\n";
+ }
+
+ if (liveData) {
+ messages.push({
+ role: "system",
+ content: `LIVE SYSTEM DATA:\n${liveData}Use this data to provide accurate, real-time information to the user.`
+ });
+ }
+ }
+
if (history && Array.isArray(history)) {
for (const msg of history.slice(-8)) {
if (msg.role === "user" || msg.role === "assistant") {
diff --git a/server/routes.ts b/server/routes.ts
index 0c579b9..ebe73c7 100644
--- a/server/routes.ts
+++ b/server/routes.ts
@@ -489,6 +489,18 @@ export async function registerRoutes(
const chatRateLimits = new Map();
+ // Get chat history
+ app.get("/api/chat/history", requireAuth, async (req, res) => {
+ try {
+ const userId = req.session.userId!;
+ const history = await storage.getChatHistory(userId, 20);
+ res.json({ history });
+ } catch (err: any) {
+ console.error("Get chat history error:", err);
+ res.status(500).json({ error: "Failed to get chat history" });
+ }
+ });
+
app.post("/api/chat", async (req, res) => {
try {
const userId = req.session?.userId;
@@ -517,7 +529,27 @@ export async function registerRoutes(
return res.status(400).json({ error: "Message is required" });
}
- const response = await getChatResponse(message, history);
+ // Save user message if user is authenticated
+ if (userId) {
+ const messageId = `user_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
+ await storage.saveChatMessage(messageId, userId, 'user', message);
+ }
+
+ // Get full chat history for context if user is authenticated
+ let fullHistory = history || [];
+ if (userId) {
+ const savedHistory = await storage.getChatHistory(userId, 20);
+ fullHistory = savedHistory.map(msg => ({ role: msg.role, content: msg.content }));
+ }
+
+ const response = await getChatResponse(message, fullHistory, userId);
+
+ // Save assistant response if user is authenticated
+ if (userId) {
+ const responseId = `assistant_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
+ await storage.saveChatMessage(responseId, userId, 'assistant', response);
+ }
+
res.json({ response });
} catch (err: any) {
console.error("Chat error:", err);
diff --git a/server/storage.ts b/server/storage.ts
index fdb8d8d..f3079f0 100644
--- a/server/storage.ts
+++ b/server/storage.ts
@@ -205,6 +205,47 @@ export class SupabaseStorage implements IStorage {
return data;
}
+ // Chat Messages (AI memory)
+ async getChatHistory(userId: string, limit: number = 50): Promise {
+ const { data, error } = await supabase
+ .from('chat_messages')
+ .select('*')
+ .eq('user_id', userId)
+ .order('created_at', { ascending: false })
+ .limit(limit);
+
+ if (error) return [];
+ return (data || []).reverse() as ChatMessage[]; // Reverse to get chronological order
+ }
+
+ async saveChatMessage(id: string, userId: string, role: string, content: string): Promise {
+ const { error } = await supabase
+ .from('chat_messages')
+ .insert({
+ id,
+ user_id: userId,
+ role,
+ content,
+ });
+
+ if (error) {
+ console.error('Save chat message error:', error);
+ throw new Error('Failed to save chat message');
+ }
+ }
+
+ async clearChatHistory(userId: string): Promise {
+ const { error } = await supabase
+ .from('chat_messages')
+ .delete()
+ .eq('user_id', userId);
+
+ if (error) {
+ console.error('Clear chat history error:', error);
+ throw new Error('Failed to clear chat history');
+ }
+ }
+
async getMetrics(): Promise<{
totalProfiles: number;
totalProjects: number;
diff --git a/server/supabase.ts b/server/supabase.ts
index 54d423c..695795a 100644
--- a/server/supabase.ts
+++ b/server/supabase.ts
@@ -1,3 +1,8 @@
+import dotenv from "dotenv";
+
+// Load environment variables
+dotenv.config({ path: './.env' });
+
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = process.env.SUPABASE_URL;