-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.js
175 lines (152 loc) · 4.88 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
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import 'dotenv/config'
import path from "path";
import express from "express";
import pkg from "@deepgram/sdk";
import { fileURLToPath } from "url";
import { createServer } from "http";
import { Server } from "socket.io";
import { ChatOpenAI } from "langchain/chat_models/openai";
import { HumanChatMessage, SystemChatMessage } from "langchain/schema";
import models from "./models.js";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const { Deepgram } = pkg;
let deepgrams = {};
let socket;
let dgLiveObjs = {};
let globalSockets = {};
let openAIChats = {};
async function promptAI(socketId, model, message){
const response = await openAIChats[socketId].call([
new SystemChatMessage(
models[model]
),
new HumanChatMessage(
message
),
]);
console.log(response);
return response;
}
const app = express();
app.use(express.static("public/"));
app.get("/", function (req, res) {
res.sendFile(__dirname + "/index.html");
});
app.get("/chat", async (req, res) => {
// Respond with error if no API Key set
if(!process.env.OPEN_AI_API_KEY){
res.status(500).send({ err: 'No OpenAI API Key set in the .env file' });
return;
}
let model = req.query.model;
let message = req.query.message;
let socketId = req.query.socketId;
console.log('message',message);
try {
let response = await promptAI(socketId, model, message);
res.send({ response });
} catch (err) {
console.log(err);
res.status(500).send({ err: err.message ? err.message : err });
}
});
const httpServer = createServer(app);
// Pull out connection logic so we can call it outside of the socket connection event
const initDgConnection = (socketId) => {
dgLiveObjs[socketId] = createNewDeepgramLive(deepgrams[socketId]);
addDeepgramTranscriptListener(socketId);
addDeepgramOpenListener(socketId);
addDeepgramCloseListener(socketId);
addDeepgramErrorListener(socketId);
// receive data from client and send to dgLive
globalSockets[socketId].on("packet-sent", async (event) =>
dgPacketResponse(event, socketId)
);
};
const createWebsocket = () => {
if(!socket){
socket = new Server(httpServer, { transports: "websocket",
cors: { }
});
socket.on("connection", (clientSocket) => {
let socketId = clientSocket.id;
console.log(`Connected on server side with ID: ${socketId}`);
globalSockets[socketId] = clientSocket;
if(!deepgrams[socketId]){
deepgrams[socketId] = createNewDeepgram();
}
if(process.env.OPEN_AI_API_KEY){
openAIChats[socketId] = new ChatOpenAI({ openAIApiKey: process.env.OPEN_AI_API_KEY, temperature: 0 });
}
initDgConnection(socketId);
socket.on('disconnect', () => {
console.log('User disconnected.', socketId);
globalSockets[socketId].removeAllListeners();
delete globalSockets[socketId];
dgLiveObjs[socketId].removeAllListeners();
delete dgLiveObjs[socketId];
delete openAIChats[socketId];
});
globalSockets[socketId].emit("socketId", socketId);
});
}
};
const createNewDeepgram = () => {
return new Deepgram(process.env.DEEPGRAM_API_KEY);
};
const createNewDeepgramLive = (dg) => {
return dg.transcription.live({
language: "en",
punctuate: true,
smart_format: true,
model: "nova",
});
};
const addDeepgramTranscriptListener = (socketId) => {
let _socketId = socketId;
dgLiveObjs[socketId].addListener("transcriptReceived", async (dgOutput) => {
let dgJSON = JSON.parse(dgOutput);
let utterance;
try {
utterance = dgJSON.channel.alternatives[0].transcript;
} catch (error) {
console.log(
"WARNING: parsing dgJSON failed. Response from dgLive is:",
error
);
console.log(dgJSON);
}
if (utterance) {
globalSockets[_socketId].emit("print-transcript", utterance);
console.log(`NEW UTTERANCE socketId: ${_socketId}: ${utterance}`);
}
});
};
const addDeepgramOpenListener = (socketId) => {
dgLiveObjs[socketId].addListener("open", async (msg) =>
console.log(`dgLive socketId: ${socketId} WEBSOCKET CONNECTION OPEN!`)
);
};
const addDeepgramCloseListener = (socketId) => {
dgLiveObjs[socketId].addListener("close", async (msg) => {
console.log(`dgLive socketId: ${socketId} CONNECTION CLOSED!`);
console.log(`Reconnecting`);
createWebsocket();
});
};
const addDeepgramErrorListener = (socketId) => {
dgLiveObjs[socketId].addListener("error", async (msg) => {
console.log("ERROR MESG", msg);
console.log(`dgLive socketId: ${socketId} ERROR::Type:${msg.type} / Code:${msg.code}`);
});
};
const dgPacketResponse = (event, socketId) => {
if (dgLiveObjs[socketId].getReadyState() === 1) {
dgLiveObjs[socketId].send(event);
}
};
console.log('Starting Server on Port ', process.env.PORT);
httpServer.listen(process.env.PORT);
createWebsocket();
console.log('Running');