78 lines
2.7 KiB
JavaScript
78 lines
2.7 KiB
JavaScript
#!/usr/bin/env node
|
|
//IRC bot that responds to !chat, queries the chatgpt api, and prints the response line by line
|
|
const irc = require('irc');
|
|
const axios = require('axios');
|
|
const config = require('./config.json');
|
|
const client = new irc.Client(config.server, config.nick, {
|
|
channels: config.channels,
|
|
});
|
|
|
|
// listen for messages that start with !chat and call the chatgpt api with a callback that prints the response line by line
|
|
client.addListener('message', async (from, to, message) => {
|
|
if (message.startsWith('!chat')) {
|
|
const query = message.slice(6);
|
|
chatgpt(query, (line) => {
|
|
client.say(to, line);
|
|
});
|
|
}
|
|
});
|
|
|
|
// function that calls the chatgpt streaming api (with server send events) and calls the callback function for each line
|
|
function chatgpt(query, callback) {
|
|
const apiUrl = 'https://api.openai.com/v1/chat/completions';
|
|
|
|
const response = await axios.post(apiUrl, {
|
|
messages: [{ role: 'user', content: query }],
|
|
model: 'gpt-3.5-turbo',
|
|
stream: true,
|
|
}, {
|
|
headers: {
|
|
Authorization: `Bearer ${config.openaiApiKey}`,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
responseType: 'stream',
|
|
});
|
|
|
|
let line = '';
|
|
response.data.on('data', (event) => {
|
|
let data = event.toString();
|
|
let parts = data.split('\n');
|
|
// parse if starts with data:
|
|
for(part of parts) {
|
|
if(part === 'data: [DONE]') {
|
|
process.stdout.write('\n');
|
|
} else if(part.startsWith('data: ')) {
|
|
let jsonString = part.slice(part.indexOf('{'), part.lastIndexOf('}') + 1);
|
|
try {
|
|
let json = JSON.parse(jsonString);
|
|
let chunk = json.choices[0].delta.content;
|
|
//split the chunk into lines leaving the delimiter in the array
|
|
const lines = str.split(/\r?\n/); // split by new lines
|
|
|
|
let hasStartNewline = str.startsWith("\n");
|
|
let hasEndNewline = str.endsWith("\n");
|
|
|
|
if(hasStartNewline) {
|
|
callback(line);
|
|
line = '';
|
|
}
|
|
|
|
for (let i = 0; i < lines.length - 1; i++) {
|
|
callback(lines[i]);
|
|
line = '';
|
|
}
|
|
|
|
line += lines[lines.length - 1];
|
|
|
|
if(hasEndNewline) {
|
|
callback(line);
|
|
line = '';
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
console.log(part);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
} |