Merge pull request #67 from matrixgpt/optional-threads

Optional threads
This commit is contained in:
bertybuttface 2023-01-27 18:24:41 +00:00 committed by GitHub
commit 2a5845c954
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 16 additions and 6 deletions

View File

@ -68,6 +68,8 @@ MATRIX_WHITELIST=
# Matrix Feature Flags (optional)
MATRIX_AUTOJOIN=true
MATRIX_ENCRYPTION=true
# If you turn threads off you will have problems if you don't set CHATGPT_CONTEXT=room
MATRIX_THREADS=true
MATRIX_PREFIX_DM=false
MATRIX_RICH_TEXT=true
```

View File

@ -13,6 +13,7 @@ export const {
/** Matrix Bot Features */
MATRIX_AUTOJOIN,
MATRIX_ENCRYPTION,
MATRIX_THREADS,
MATRIX_PREFIX_DM,
MATRIX_RICH_TEXT,
/** Matrix Access Control */
@ -38,6 +39,7 @@ export const {
/** Matrix Bot Features */
MATRIX_AUTOJOIN: { schema: z.boolean().default(true), description: "Set to true if you want the bot to autojoin when invited" },
MATRIX_ENCRYPTION: { schema: z.boolean().default(true), description: "Set to true if you want the bot to support encrypted channels" },
MATRIX_THREADS: { schema: z.boolean().default(true), description: "Set to true if you want the bot to answer always in a new thread/conversation" },
MATRIX_PREFIX_DM: { schema: z.boolean().default(false), description: "Set to false if you want the bot to answer to all messages in a one-to-one room" },
MATRIX_RICH_TEXT: { schema: z.boolean().default(true), description: "Set to true if you want the bot to answer with enriched text" },
/** Matrix Access Control */

View File

@ -1,8 +1,8 @@
import { ChatGPTAPIBrowser } from "chatgpt";
import { LogService, MatrixClient, UserID } from "matrix-bot-sdk";
import { CHATGPT_CONTEXT, CHATGPT_TIMEOUT, MATRIX_DEFAULT_PREFIX_REPLY, MATRIX_DEFAULT_PREFIX, MATRIX_BLACKLIST, MATRIX_WHITELIST, MATRIX_RICH_TEXT, MATRIX_PREFIX_DM } from "./env.js";
import { CHATGPT_CONTEXT, CHATGPT_TIMEOUT, MATRIX_DEFAULT_PREFIX_REPLY, MATRIX_DEFAULT_PREFIX, MATRIX_BLACKLIST, MATRIX_WHITELIST, MATRIX_RICH_TEXT, MATRIX_PREFIX_DM, MATRIX_THREADS } from "./env.js";
import { RelatesTo, MessageEvent, StoredConversation, StoredConversationConfig } from "./interfaces.js";
import { sendChatGPTMessage, sendError, sendThreadReply } from "./utils.js";
import { sendChatGPTMessage, sendError, sendReply } from "./utils.js";
export default class CommandHandler {
@ -124,7 +124,7 @@ export default class CommandHandler {
const result = await sendChatGPTMessage(this.chatGPT, await bodyWithoutPrefix, storedConversation);
await Promise.all([
this.client.setTyping(roomId, false, 500),
sendThreadReply(this.client, roomId, this.getRootEventId(event), `${result.response}`, MATRIX_RICH_TEXT)
sendReply(this.client, roomId, this.getRootEventId(event), `${result.response}`, MATRIX_THREADS, MATRIX_RICH_TEXT)
]);
const storedConfig = ((storedConversation !== undefined && storedConversation.config !== undefined) ? storedConversation.config : {})

View File

@ -7,7 +7,7 @@ import {
} from "matrix-bot-sdk";
import * as path from "path";
import { DATA_PATH, OPENAI_EMAIL, OPENAI_PASSWORD, OPENAI_LOGIN_TYPE, OPENAI_PRO, MATRIX_HOMESERVER_URL, MATRIX_ACCESS_TOKEN, MATRIX_AUTOJOIN, MATRIX_BOT_PASSWORD, MATRIX_BOT_USERNAME, MATRIX_ENCRYPTION } from './env.js'
import { DATA_PATH, OPENAI_EMAIL, OPENAI_PASSWORD, OPENAI_LOGIN_TYPE, OPENAI_PRO, MATRIX_HOMESERVER_URL, MATRIX_ACCESS_TOKEN, MATRIX_AUTOJOIN, MATRIX_BOT_PASSWORD, MATRIX_BOT_USERNAME, MATRIX_ENCRYPTION, MATRIX_THREADS, CHATGPT_CONTEXT } from './env.js'
import { parseMatrixUsernamePretty } from './utils.js';
import CommandHandler from "./handlers.js"
import { ChatGPTAPIBrowser } from 'chatgpt'
@ -38,6 +38,7 @@ async function main() {
console.log("Set MATRIX_ACCESS_TOKEN to above token, MATRIX_BOT_PASSWORD can now be blank")
return;
}
if (!MATRIX_THREADS && CHATGPT_CONTEXT !== "room") throw Error("You must set CHATGPT_CONTEXT to 'room' if you set MATRIX_THREADS to false")
const client: MatrixClient = new MatrixClient(MATRIX_HOMESERVER_URL, MATRIX_ACCESS_TOKEN, storage, cryptoStore);
// use puppeteer to bypass cloudflare (headful because of captchas)

View File

@ -28,13 +28,17 @@ export async function sendError(client: MatrixClient, text: string, roomId: stri
* @param {string} roomId the room ID the event being replied to resides in
* @param {string} rootEventId the root event of the thread
* @param {string} text the plain text to reply with
* @param {boolean} thread reply as a thread
* @param {boolean} rich should the plain text be rendered to html using markdown?
*/
export async function sendThreadReply(client: MatrixClient, roomId: string, rootEventId: string, text: string, rich:boolean = false): Promise<void> {
export async function sendReply(client: MatrixClient, roomId: string, rootEventId: string, text: string, thread: boolean = false, rich:boolean = false): Promise<void> {
const contentCommon = {
body: text,
msgtype: "m.text",
}
const contentThreadOnly = {
"m.relates_to": {
event_id: rootEventId,
is_falling_back: true,
@ -67,8 +71,9 @@ export async function sendThreadReply(client: MatrixClient, roomId: string, root
}
const content = rich ? { ...contentCommon, ...contentRichOnly } : { ...contentCommon, ...contentTextOnly };
const finalContent = thread ? { ...content, ...contentThreadOnly } : content
await client.sendEvent(roomId, "m.room.message", content);
await client.sendEvent(roomId, "m.room.message", finalContent);
}
export async function sendChatGPTMessage(chatGPT: ChatGPTAPIBrowser, question: string, storedConversation: StoredConversation) {