djmuted commited on
Commit
bff1373
1 Parent(s): fd1c59b

Add streaming support

Browse files
Files changed (2) hide show
  1. src/openai.js +43 -15
  2. src/slack.js +4 -2
src/openai.js CHANGED
@@ -39,7 +39,7 @@ openaiRouter.post("/chat/completions", jsonParser, async (req, res) => {
39
  return;
40
  }
41
 
42
- const { messages } = req.body;
43
  if (!messages || !(await messageArraySchema.isValid(messages))) {
44
  res.status(400).json({ error: "Bad request" });
45
  return;
@@ -50,21 +50,49 @@ openaiRouter.post("/chat/completions", jsonParser, async (req, res) => {
50
 
51
  const messagesSplit = splitJsonArray(messages, 12000);
52
 
53
- const result = await myq.run(() => slack.waitForWebSocketResponse(messagesSplit));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
- res.json({
56
- id, created,
57
- object: 'chat.completion',
58
- model: spoofModelName,
59
- choices: [{
60
- message: {
61
- role: 'assistant',
62
- content: result.trimStart(),
63
- },
64
- finish_reason: 'stop',
65
- index: 0,
66
- }]
67
- });
 
 
 
 
 
 
68
  } catch (error) {
69
  console.error(error);
70
  res.status(500).json({ error: "Internal server error" });
 
39
  return;
40
  }
41
 
42
+ const { messages, stream } = req.body;
43
  if (!messages || !(await messageArraySchema.isValid(messages))) {
44
  res.status(400).json({ error: "Bad request" });
45
  return;
 
50
 
51
  const messagesSplit = splitJsonArray(messages, 12000);
52
 
53
+ if (stream) {
54
+ res.writeHead(200, {
55
+ 'Content-Type': 'text/event-stream',
56
+ 'Cache-Control': 'no-cache',
57
+ Connection: 'keep-alive',
58
+ });
59
+ }
60
+
61
+ const generateResponse = (content) => {
62
+ return {
63
+ id, created,
64
+ object: 'chat.completion',
65
+ model: spoofModelName,
66
+ choices: [{
67
+ message: {
68
+ role: 'assistant',
69
+ content,
70
+ },
71
+ finish_reason: 'stop',
72
+ index: 0,
73
+ }]
74
+ };
75
+ }
76
 
77
+ let currentContent = '';
78
+ const onData = (newContent) => {
79
+ if (stream) {
80
+ const chunk = newContent.slice(currentContent.length);
81
+ currentContent = newContent;
82
+ res.write('event: data\n');
83
+ res.write(`data: ${JSON.stringify(chunk)}\n\n`);
84
+ }
85
+ };
86
+
87
+ const result = await myq.run(() => slack.waitForWebSocketResponse(messagesSplit, onData));
88
+
89
+ if (stream) {
90
+ res.write('event: data\n');
91
+ res.write(`data: ${generateResponse(currentContent)}\n\n`);
92
+ res.write('data: [DONE]\n\n');
93
+ } else {
94
+ res.json(generateResponse(result));
95
+ }
96
  } catch (error) {
97
  console.error(error);
98
  res.status(500).json({ error: "Internal server error" });
src/slack.js CHANGED
@@ -74,7 +74,7 @@ async function sendChatReset() {
74
  form.pipe(req);
75
  }
76
 
77
- async function waitForWebSocketResponse(messages) {
78
  return new Promise(async (resolve, reject) => {
79
  const websocketURL = `wss://wss-primary.slack.com/?token=${TOKEN}`;
80
 
@@ -114,8 +114,10 @@ async function waitForWebSocketResponse(messages) {
114
  resolve(data.message.text);
115
  }
116
  } else {
117
- //yield data.message.text;
118
  console.log(`${currentTime()} fetched ${data.message.text.length} characters...`);
 
 
 
119
  }
120
  }
121
  } catch (error) {
 
74
  form.pipe(req);
75
  }
76
 
77
+ async function waitForWebSocketResponse(messages, onData) {
78
  return new Promise(async (resolve, reject) => {
79
  const websocketURL = `wss://wss-primary.slack.com/?token=${TOKEN}`;
80
 
 
114
  resolve(data.message.text);
115
  }
116
  } else {
 
117
  console.log(`${currentTime()} fetched ${data.message.text.length} characters...`);
118
+ if (onData) {
119
+ onData(data.message.text);
120
+ }
121
  }
122
  }
123
  } catch (error) {