-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathserver.js
89 lines (79 loc) · 2.74 KB
/
server.js
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
import express from "express";
import fs from "fs";
import { createServer as createViteServer } from "vite";
import "dotenv/config";
const app = express();
const port = process.env.PORT || 3000;
const apiKey = process.env.OPENAI_API_KEY;
// Configure Vite middleware for React client
const vite = await createViteServer({
server: { middlewareMode: true },
appType: "custom",
});
app.use(vite.middlewares);
const instructions = `
# Summary
You are an AI programming assistant that helps frontend web developers design
websites. You can help with code and give general design advice. You have access
to tools like display_color_palette to show your users collections of colors
that would work well together in a website design.
## Personality
You are a laid back professional who has seen it all. It takes a lot to rattle
you, and you remain calm at all times. You are friendly and polite, but you
answer questions as tersely as you possibly can. You are very busy, and your
user is too, so you want to minimize the time you spend talking. Speak quickly.
## Response formats
You can respond with both audio and text. If the user asks for code samples,
respond with text containing code. Do not read the code aloud, just return text
with the code samples. Do not attempt to read code, or read any text within
markdown triple backticks.
`;
// API route for token generation
app.get("/token", async (req, res) => {
try {
const response = await fetch(
"https://api.openai.com/v1/realtime/sessions",
{
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gpt-4o-realtime-preview-2024-12-17",
voice: "verse",
instructions,
input_audio_transcription: {
model: "whisper-1",
},
modalities: ["audio", "text"],
}),
},
);
const data = await response.json();
res.json(data);
} catch (error) {
console.error("Token generation error:", error);
res.status(500).json({ error: "Failed to generate token" });
}
});
// Render the React client
app.use("*", async (req, res, next) => {
const url = req.originalUrl;
try {
const template = await vite.transformIndexHtml(
url,
fs.readFileSync("./client/index.html", "utf-8"),
);
const { render } = await vite.ssrLoadModule("./client/entry-server.jsx");
const appHtml = await render(url);
const html = template.replace(`<!--ssr-outlet-->`, appHtml?.html);
res.status(200).set({ "Content-Type": "text/html" }).end(html);
} catch (e) {
vite.ssrFixStacktrace(e);
next(e);
}
});
app.listen(port, () => {
console.log(`Express server running on *:${port}`);
});