Spaces:
Sleeping
Sleeping
| import "dotenv/config"; | |
| import express from "express"; | |
| import { fileURLToPath } from "url"; | |
| import { dirname, join } from "path"; | |
| const __dirname = dirname(fileURLToPath(import.meta.url)); | |
| const app = express(); | |
| app.use(express.json()); | |
| // ββ Serve static files ββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| app.use(express.static(__dirname)); | |
| // ββ Root β redirect to the simulator ββββββββββββββββββββββββββββββββββββββ | |
| app.get("/", (req, res) => { | |
| res.sendFile(join(__dirname, "smart_glove_simulator.html")); | |
| }); | |
| // ββ Gemini 2.5 Flash proxy βββββββββββββββββββββββββββββββββββββββββββββββββ | |
| app.post("/api/grammar", async (req, res) => { | |
| const { words, tense } = req.body; | |
| const targetTense = tense || "present simple"; | |
| if (!Array.isArray(words) || words.length === 0) { | |
| return res.status(400).json({ error: "No words provided" }); | |
| } | |
| const apiKey = process.env.GEMINI_API_KEY; | |
| const model = process.env.GEMINI_MODEL || "gemini-2.5-flash"; | |
| if (!apiKey) { | |
| return res.status(500).json({ error: "GEMINI_API_KEY not configured on server" }); | |
| } | |
| const prompt = | |
| `You are an AI assistant for a sign language glove system. The user is non-verbal and uses gestures to communicate.` + | |
| `\nWords captured from hand gestures: [${words.map(w => `"${w}"`).join(", ")}].` + | |
| `\nTask: Expand these fragmented words into exactly ONE natural, grammatically correct, and conversational English sentence that expresses the user's intent. The sentence must be in the ${targetTense} tense.` + | |
| `\nRules:` + | |
| `\n- The words provided are shorthand sign language. You must infer missing pronouns (like "I" or "You"), articles, prepositions, and context (e.g., "walk, me" might mean "I want to walk with you" or "Please walk with me").` + | |
| `\n- Make the sentence polite, natural, and suitable for everyday human communication.` + | |
| `\n- Strictly output ONLY the final spoken sentence. No quotes, no explanations, no introductory text.`; | |
| try { | |
| const endpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`; | |
| const geminiRes = await fetch(endpoint, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| contents: [{ parts: [{ text: prompt }] }], | |
| generationConfig: { maxOutputTokens: 256, temperature: 0.3 }, | |
| }), | |
| }); | |
| const data = await geminiRes.json(); | |
| if (data.error) { | |
| console.error("Gemini error:", data.error); | |
| return res.status(502).json({ error: data.error.message }); | |
| } | |
| const sentence = data.candidates[0].content.parts[0].text.trim(); | |
| return res.json({ sentence }); | |
| } catch (err) { | |
| console.error("Proxy error:", err); | |
| return res.status(500).json({ error: err.message }); | |
| } | |
| }); | |
| // ββ Start ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| const PORT = process.env.PORT || 3000; | |
| app.listen(PORT, () => console.log(`π§€ Smart Glove Simulator running on port ${PORT}`)); | |