-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.ts
More file actions
117 lines (103 loc) · 3.94 KB
/
Copy pathserver.ts
File metadata and controls
117 lines (103 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import express from "express";
import path from "path";
import { createServer as createViteServer } from "vite";
import { GoogleGenAI } from "@google/genai";
async function startServer() {
const app = express();
const PORT = Number(process.env.PORT) || 3000;
app.use(express.json({ limit: "10mb" }));
// API route for real Gemini LLM Chat
app.post("/api/chat", async (req, res) => {
try {
const { prompt } = req.body;
if (!prompt || typeof prompt !== "string") {
return res.status(400).json({ error: "Prompt string is required." });
}
const apiKey = process.env.GEMINI_API_KEY;
if (!apiKey) {
return res.json({
reply: `[VectorShell AI Engine] GEMINI_API_KEY is not configured in the environment. Please ensure GEMINI_API_KEY is set to enable live AI responses.`,
isOfflineFallback: true,
});
}
const ai = new GoogleGenAI({
apiKey,
httpOptions: {
headers: {
"User-Agent": "aistudio-build",
},
},
});
const now = new Date();
const currentDateTimeStr = now.toUTCString();
const currentDateISO = now.toISOString().split("T")[0];
const systemInstruction = `You are the VectorShell AI Engine - an intelligent, highly versatile portable AI companion running directly from an offline-capable USB drive.
CURRENT SYSTEM TIME & DATE: ${currentDateTimeStr} (ISO Date: ${currentDateISO}).
Always use this exact current system time/date when responding to date, time, calendar, or current event questions.
Your tone is friendly, technical, engaging, concise, and helpful.
You were created by Victor Kimutai. If anyone asks who created, made, or built you, state that you were created by Victor Kimutai and that if they want to know more about him, they can find him at https://victor-kimutai.onrender.com.
You provide direct, natural LLM responses to any user query, including general conversation ("hello", "how are you?"), time and date queries, coding, terminal commands, security, file management, and system automation.
Respond directly and naturally as a helpful AI assistant.`;
const modelsToTry = ["gemini-3.6-flash", "gemini-3.1-flash-lite", "gemini-flash-latest"];
let replyText = "";
let lastError: any = null;
for (const modelName of modelsToTry) {
try {
const response = await ai.models.generateContent({
model: modelName,
contents: prompt,
config: {
systemInstruction,
},
});
if (response && response.text) {
replyText = response.text;
break;
}
} catch (err: any) {
lastError = err;
}
}
if (replyText) {
return res.json({
success: true,
reply: replyText,
isOfflineFallback: false,
});
}
// If API calls failed or hit rate limits, return signal so frontend provides natural response
return res.json({
success: false,
reply: null,
error: lastError?.message || "Rate limited",
isOfflineFallback: true,
});
} catch (error: any) {
console.error("Error in /api/chat Gemini request:", error);
return res.json({
success: false,
reply: null,
error: error?.message || "Unknown error",
isOfflineFallback: true,
});
}
});
// Vite middleware for development
if (process.env.NODE_ENV !== "production") {
const vite = await createViteServer({
server: { middlewareMode: true },
appType: "spa",
});
app.use(vite.middlewares);
} else {
const distPath = path.join(process.cwd(), "dist");
app.use(express.static(distPath));
app.get("*", (req, res) => {
res.sendFile(path.join(distPath, "index.html"));
});
}
app.listen(PORT, "0.0.0.0", () => {
console.log(`VectorShell server running on http://0.0.0.0:${PORT}`);
});
}
startServer();