Test #2
@@ -0,0 +1,83 @@
|
|||||||
|
const continueThread = require('./openai-thread-completion').continueThread
|
||||||
|
const { Log } = require('debug-level')
|
||||||
|
|
||||||
|
require('babel-polyfill');
|
||||||
|
require('isomorphic-fetch');
|
||||||
|
const { mmClient, wsClient } = require('./mm-client')
|
||||||
|
|
||||||
|
// the mattermost library uses FormData - so here is a polyfill
|
||||||
|
if (!global.FormData) {
|
||||||
|
global.FormData = require('form-data');
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.options({ json: true, colors: true })
|
||||||
|
Log.wrapConsole('bot-ws', { level4log: 'INFO' })
|
||||||
|
const log = new Log('bot')
|
||||||
|
|
||||||
|
let meId = null;
|
||||||
|
mmClient.getMe().then(me => meId = me.id)
|
||||||
|
|
||||||
|
const name = process.env['MATTERMOST_BOTNAME'] || '@dall-e'
|
||||||
|
|
||||||
|
wsClient.addMessageListener(async function (event) {
|
||||||
|
if (['posted'].includes(event.event) && meId) {
|
||||||
|
const post = JSON.parse(event.data.post);
|
||||||
|
if (post.root_id === "" && (!event.data.mentions || (!JSON.parse(event.data.mentions).includes(meId)))) {
|
||||||
|
// we're not in a thread and we are not mentioned - ignore the message
|
||||||
|
} else {
|
||||||
|
if (post.user_id !== meId) {
|
||||||
|
const chatmessages = [
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": `You are a helpful assistant named ${name} who provides succinct answers in Markdown format.`
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
let appendDiagramInstructions = false
|
||||||
|
|
||||||
|
const thread = await mmClient.getPostThread(post.id, true, false, true)
|
||||||
|
|
||||||
|
const posts = [...new Set(thread.order)].map(id => thread.posts[id])
|
||||||
|
.filter(a => a.create_at > Date.now() - 1000 * 60 * 60 * 24 * 1)
|
||||||
|
.sort((a, b) => a.create_at - b.create_at)
|
||||||
|
|
||||||
|
let assistantCount = 0;
|
||||||
|
posts.forEach(threadPost => {
|
||||||
|
log.trace({msg: threadPost})
|
||||||
|
if (threadPost.user_id === meId) {
|
||||||
|
chatmessages.push({role: "assistant", content: threadPost.props.originalMessage ?? threadPost.message})
|
||||||
|
assistantCount++
|
||||||
|
} else {
|
||||||
|
if (threadPost.message.includes(name)){
|
||||||
|
assistantCount++;
|
||||||
|
}
|
||||||
|
chatmessages.push({role: "user", content: threadPost.message})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// see if we are actually part of the conversation -
|
||||||
|
// ignore conversations where we were never mentioned or participated.
|
||||||
|
if (assistantCount > 0){
|
||||||
|
wsClient.userTyping(post.channel_id, post.id ?? "")
|
||||||
|
log.trace({chatmessages})
|
||||||
|
const answer = await continueThread(chatmessages)
|
||||||
|
log.trace({answer})
|
||||||
|
wsClient.userTyping(post.channel_id, post.id ?? "")
|
||||||
|
const newPost = await mmClient.createPost({
|
||||||
|
message: message,
|
||||||
|
channel_id: post.channel_id,
|
||||||
|
props,
|
||||||
|
root_id: post.root_id || post.id,
|
||||||
|
file_ids: fileId ? [fileId] : undefined
|
||||||
|
})
|
||||||
|
log.trace({msg: newPost})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.debug({msg: event})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
const Client4 = require('@mattermost/client').Client4
|
||||||
|
const WebSocketClient = require('@mattermost/client').WebSocketClient
|
||||||
|
const { Log } = require('debug-level')
|
||||||
|
const log = new Log('bot')
|
||||||
|
|
||||||
|
if (!global.WebSocket) {
|
||||||
|
global.WebSocket = require('ws');
|
||||||
|
}
|
||||||
|
|
||||||
|
const mattermostToken = process.env['MATTERMOST_TOKEN']
|
||||||
|
const matterMostURLString = process.env['MATTERMOST_URL']
|
||||||
|
|
||||||
|
const client = new Client4()
|
||||||
|
client.setUrl(matterMostURLString)
|
||||||
|
client.setToken(mattermostToken)
|
||||||
|
|
||||||
|
const wsClient = new WebSocketClient();
|
||||||
|
let matterMostURL = new URL(matterMostURLString);
|
||||||
|
const wsUrl = `${matterMostURL.protocol === 'https:' ? 'wss' : 'ws'}://${matterMostURL.host}/api/v4/websocket`
|
||||||
|
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
wsClient.addCloseListener(connectFailCount => reject())
|
||||||
|
wsClient.addErrorListener(event => { reject(event) })
|
||||||
|
}).then(() => process.exit(0)).catch(reason => { log.error(reason); process.exit(-1)})
|
||||||
|
|
||||||
|
wsClient.initialize(wsUrl, mattermostToken)
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mmClient: client,
|
||||||
|
wsClient
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
const { Configuration, OpenAIApi } = require("openai");
|
||||||
|
const configuration = new Configuration({
|
||||||
|
apiKey: process.env["OPENAI_API_KEY"]
|
||||||
|
});
|
||||||
|
const openai = new OpenAIApi(configuration);
|
||||||
|
|
||||||
|
const model = process.env["OPENAI_MODEL_NAME"] ?? 'image-alpha-001'
|
||||||
|
const max_tokens = Number(process.env["OPENAI_MAX_TOKENS"] ?? 2000)
|
||||||
|
|
||||||
|
async function continueThread(messages) {
|
||||||
|
const response = await openai.generateImage({
|
||||||
|
prompt: messages,
|
||||||
|
model,
|
||||||
|
n: 1,
|
||||||
|
size: "512x512",
|
||||||
|
response_format: "b64_json",
|
||||||
|
});
|
||||||
|
return response.json?.data?.choices?.[0]?.message?.content
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { continueThread }
|
||||||
Reference in New Issue
Block a user