diff --git a/build.mjs b/build.mjs index 437ee08..2d2a3c7 100644 --- a/build.mjs +++ b/build.mjs @@ -184,6 +184,10 @@ async function runWebpack(isWithoutKatex, isWithoutTiktoken, callback) { test: /\.(jpg|png|svg)$/, type: 'asset/inline', }, + { + test: /\.(graphql|gql)$/, + loader: 'graphql-tag/loader', + }, isWithoutTiktoken ? { test: /crop-text\.mjs$/, diff --git a/package-lock.json b/package-lock.json index 3fb3613..b26fbbf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "@picocss/pico": "^1.5.7", "@primer/octicons-react": "^18.2.0", "countries-list": "^2.6.1", + "diff": "^5.1.0", "eventsource-parser": "^0.1.0", "file-saver": "^2.0.5", "github-markdown-css": "^5.2.0", @@ -17,6 +18,7 @@ "i18next": "^22.4.13", "katex": "^0.16.4", "lodash-es": "^4.17.21", + "md5": "^2.3.0", "parse5": "^6.0.1", "preact": "^10.13.1", "prop-types": "^15.8.1", @@ -51,6 +53,7 @@ "eslint": "^8.36.0", "eslint-plugin-react": "^7.32.2", "fs-extra": "^11.1.0", + "graphql-tag": "^2.12.6", "jsdom": "^21.1.1", "less-loader": "^11.1.0", "mini-css-extract-plugin": "^2.7.5", @@ -2996,6 +2999,14 @@ "resolved": "https://registry.npmmirror.com/character-entities/-/character-entities-2.0.2.tgz", "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==" }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmmirror.com/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "engines": { + "node": "*" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz", @@ -3248,6 +3259,14 @@ "node": ">= 8" } }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmmirror.com/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "engines": { + "node": "*" + } + }, "node_modules/css-declaration-sorter": { "version": "6.3.1", "resolved": "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", @@ -4567,6 +4586,31 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "node_modules/graphql": { + "version": "16.6.0", + "resolved": "https://registry.npmmirror.com/graphql/-/graphql-16.6.0.tgz", + "integrity": "sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-tag": { + "version": "2.12.6", + "resolved": "https://registry.npmmirror.com/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, "node_modules/gzip-size": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz", @@ -5749,6 +5793,21 @@ "resolved": "https://registry.npmmirror.com/markdown-table/-/markdown-table-3.0.3.tgz", "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==" }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/md5/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "node_modules/mdast-util-definitions": { "version": "5.1.2", "resolved": "https://registry.npmmirror.com/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", @@ -8637,8 +8696,7 @@ "version": "2.5.0", "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz", "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/type-check": { "version": "0.4.0", diff --git a/package.json b/package.json index 88be4f0..f248404 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@picocss/pico": "^1.5.7", "@primer/octicons-react": "^18.2.0", "countries-list": "^2.6.1", + "diff": "^5.1.0", "eventsource-parser": "^0.1.0", "file-saver": "^2.0.5", "github-markdown-css": "^5.2.0", @@ -30,6 +31,7 @@ "i18next": "^22.4.13", "katex": "^0.16.4", "lodash-es": "^4.17.21", + "md5": "^2.3.0", "parse5": "^6.0.1", "preact": "^10.13.1", "prop-types": "^15.8.1", @@ -64,6 +66,7 @@ "eslint": "^8.36.0", "eslint-plugin-react": "^7.32.2", "fs-extra": "^11.1.0", + "graphql-tag": "^2.12.6", "jsdom": "^21.1.1", "less-loader": "^11.1.0", "mini-css-extract-plugin": "^2.7.5", diff --git a/src/background/apis/bing-web.mjs b/src/background/apis/bing-web.mjs index c4f0c5f..a7af84f 100644 --- a/src/background/apis/bing-web.mjs +++ b/src/background/apis/bing-web.mjs @@ -1,4 +1,4 @@ -import BingAIClient from '../clients/BingAIClient' +import BingAIClient from '../clients/bing' import { getUserConfig } from '../../config/index.mjs' import { pushRecord, setAbortController } from './shared.mjs' diff --git a/src/background/apis/poe-web.mjs b/src/background/apis/poe-web.mjs new file mode 100644 index 0000000..d6af778 --- /dev/null +++ b/src/background/apis/poe-web.mjs @@ -0,0 +1,41 @@ +import { pushRecord, setAbortController } from './shared.mjs' +import PoeAiClient from '../clients/poe' + +/** + * @param {Runtime.Port} port + * @param {string} question + * @param {Session} session + * @param {string} modelName + */ +export async function generateAnswersWithPoeWebApi(port, question, session, modelName) { + const bot = new PoeAiClient(session.poe_chatId) + const { messageListener } = setAbortController(port, () => { + bot.breakMsg() + bot.close() + }) + + let answer = '' + await bot + .ask( + question, + modelName, + (msg) => { + answer += msg + port.postMessage({ answer: answer, done: false, session: null }) + }, + () => { + if (bot.chatId) session.poe_chatId = bot.chatId + + pushRecord(session, question, answer) + console.debug('conversation history', { content: session.conversationRecords }) + port.onMessage.removeListener(messageListener) + port.postMessage({ answer: answer, done: true, session: session }) + bot.close() + }, + ) + .catch((err) => { + port.onMessage.removeListener(messageListener) + bot.close() + throw err + }) +} diff --git a/src/background/clients/BingAIClient.js b/src/background/clients/bing/index.mjs similarity index 100% rename from src/background/clients/BingAIClient.js rename to src/background/clients/bing/index.mjs diff --git a/src/background/clients/poe/graphql/AddHumanMessageMutation.graphql b/src/background/clients/poe/graphql/AddHumanMessageMutation.graphql new file mode 100644 index 0000000..01e6bc8 --- /dev/null +++ b/src/background/clients/poe/graphql/AddHumanMessageMutation.graphql @@ -0,0 +1,52 @@ +mutation AddHumanMessageMutation( + $chatId: BigInt! + $bot: String! + $query: String! + $source: MessageSource + $withChatBreak: Boolean! = false +) { + messageCreateWithStatus( + chatId: $chatId + bot: $bot + query: $query + source: $source + withChatBreak: $withChatBreak + ) { + message { + id + __typename + messageId + text + linkifiedText + authorNickname + state + vote + voteReason + creationTime + suggestedReplies + chat { + id + shouldShowDisclaimer + } + } + messageLimit{ + canSend + numMessagesRemaining + resetTime + shouldShowReminder + } + chatBreak { + id + __typename + messageId + text + linkifiedText + authorNickname + state + vote + voteReason + creationTime + suggestedReplies + } + } +} diff --git a/src/background/clients/poe/graphql/AddMessageBreakMutation.graphql b/src/background/clients/poe/graphql/AddMessageBreakMutation.graphql new file mode 100644 index 0000000..b28d990 --- /dev/null +++ b/src/background/clients/poe/graphql/AddMessageBreakMutation.graphql @@ -0,0 +1,17 @@ +mutation AddMessageBreakMutation($chatId: BigInt!) { + messageBreakCreate(chatId: $chatId) { + message { + id + __typename + messageId + text + linkifiedText + authorNickname + state + vote + voteReason + creationTime + suggestedReplies + } + } +} diff --git a/src/background/clients/poe/graphql/AutoSubscriptionMutation.graphql b/src/background/clients/poe/graphql/AutoSubscriptionMutation.graphql new file mode 100644 index 0000000..6cf7bf7 --- /dev/null +++ b/src/background/clients/poe/graphql/AutoSubscriptionMutation.graphql @@ -0,0 +1,7 @@ +mutation AutoSubscriptionMutation($subscriptions: [AutoSubscriptionQuery!]!) { + autoSubscribe(subscriptions: $subscriptions) { + viewer { + id + } + } +} diff --git a/src/background/clients/poe/graphql/BioFragment.graphql b/src/background/clients/poe/graphql/BioFragment.graphql new file mode 100644 index 0000000..c421803 --- /dev/null +++ b/src/background/clients/poe/graphql/BioFragment.graphql @@ -0,0 +1,8 @@ +fragment BioFragment on Viewer { + id + poeUser { + id + uid + bio + } +} diff --git a/src/background/clients/poe/graphql/ChatAddedSubscription.graphql b/src/background/clients/poe/graphql/ChatAddedSubscription.graphql new file mode 100644 index 0000000..664b107 --- /dev/null +++ b/src/background/clients/poe/graphql/ChatAddedSubscription.graphql @@ -0,0 +1,5 @@ +subscription ChatAddedSubscription { + chatAdded { + ...ChatFragment + } +} diff --git a/src/background/clients/poe/graphql/ChatFragment.graphql b/src/background/clients/poe/graphql/ChatFragment.graphql new file mode 100644 index 0000000..605645f --- /dev/null +++ b/src/background/clients/poe/graphql/ChatFragment.graphql @@ -0,0 +1,6 @@ +fragment ChatFragment on Chat { + id + chatId + defaultBotNickname + shouldShowDisclaimer +} diff --git a/src/background/clients/poe/graphql/ChatPaginationQuery.graphql b/src/background/clients/poe/graphql/ChatPaginationQuery.graphql new file mode 100644 index 0000000..f2452cd --- /dev/null +++ b/src/background/clients/poe/graphql/ChatPaginationQuery.graphql @@ -0,0 +1,26 @@ +query ChatPaginationQuery($bot: String!, $before: String, $last: Int! = 10) { + chatOfBot(bot: $bot) { + id + __typename + messagesConnection(before: $before, last: $last) { + pageInfo { + hasPreviousPage + } + edges { + node { + id + __typename + messageId + text + linkifiedText + authorNickname + state + vote + voteReason + creationTime + suggestedReplies + } + } + } + } +} diff --git a/src/background/clients/poe/graphql/ChatViewQuery.graphql b/src/background/clients/poe/graphql/ChatViewQuery.graphql new file mode 100644 index 0000000..c330107 --- /dev/null +++ b/src/background/clients/poe/graphql/ChatViewQuery.graphql @@ -0,0 +1,8 @@ +query ChatViewQuery($bot: String!) { + chatOfBot(bot: $bot) { + id + chatId + defaultBotNickname + shouldShowDisclaimer + } +} diff --git a/src/background/clients/poe/graphql/DeleteHumanMessagesMutation.graphql b/src/background/clients/poe/graphql/DeleteHumanMessagesMutation.graphql new file mode 100644 index 0000000..42692c6 --- /dev/null +++ b/src/background/clients/poe/graphql/DeleteHumanMessagesMutation.graphql @@ -0,0 +1,7 @@ +mutation DeleteHumanMessagesMutation($messageIds: [BigInt!]!) { + messagesDelete(messageIds: $messageIds) { + viewer { + id + } + } +} diff --git a/src/background/clients/poe/graphql/HandleFragment.graphql b/src/background/clients/poe/graphql/HandleFragment.graphql new file mode 100644 index 0000000..f53c484 --- /dev/null +++ b/src/background/clients/poe/graphql/HandleFragment.graphql @@ -0,0 +1,8 @@ +fragment HandleFragment on Viewer { + id + poeUser { + id + uid + handle + } +} diff --git a/src/background/clients/poe/graphql/LoginWithVerificationCodeMutation.graphql b/src/background/clients/poe/graphql/LoginWithVerificationCodeMutation.graphql new file mode 100644 index 0000000..723b1f4 --- /dev/null +++ b/src/background/clients/poe/graphql/LoginWithVerificationCodeMutation.graphql @@ -0,0 +1,13 @@ +mutation LoginWithVerificationCodeMutation( + $verificationCode: String! + $emailAddress: String + $phoneNumber: String +) { + loginWithVerificationCode( + verificationCode: $verificationCode + emailAddress: $emailAddress + phoneNumber: $phoneNumber + ) { + status + } +} diff --git a/src/background/clients/poe/graphql/MessageAddedSubscription.graphql b/src/background/clients/poe/graphql/MessageAddedSubscription.graphql new file mode 100644 index 0000000..0492baa --- /dev/null +++ b/src/background/clients/poe/graphql/MessageAddedSubscription.graphql @@ -0,0 +1,5 @@ +subscription MessageAddedSubscription($chatId: BigInt!) { + messageAdded(chatId: $chatId) { + ...MessageFragment + } +} diff --git a/src/background/clients/poe/graphql/MessageDeletedSubscription.graphql b/src/background/clients/poe/graphql/MessageDeletedSubscription.graphql new file mode 100644 index 0000000..54c1c16 --- /dev/null +++ b/src/background/clients/poe/graphql/MessageDeletedSubscription.graphql @@ -0,0 +1,6 @@ +subscription MessageDeletedSubscription($chatId: BigInt!) { + messageDeleted(chatId: $chatId) { + id + messageId + } +} diff --git a/src/background/clients/poe/graphql/MessageFragment.graphql b/src/background/clients/poe/graphql/MessageFragment.graphql new file mode 100644 index 0000000..cc86081 --- /dev/null +++ b/src/background/clients/poe/graphql/MessageFragment.graphql @@ -0,0 +1,13 @@ +fragment MessageFragment on Message { + id + __typename + messageId + text + linkifiedText + authorNickname + state + vote + voteReason + creationTime + suggestedReplies +} diff --git a/src/background/clients/poe/graphql/MessageRemoveVoteMutation.graphql b/src/background/clients/poe/graphql/MessageRemoveVoteMutation.graphql new file mode 100644 index 0000000..d5e6e61 --- /dev/null +++ b/src/background/clients/poe/graphql/MessageRemoveVoteMutation.graphql @@ -0,0 +1,7 @@ +mutation MessageRemoveVoteMutation($messageId: BigInt!) { + messageRemoveVote(messageId: $messageId) { + message { + ...MessageFragment + } + } +} diff --git a/src/background/clients/poe/graphql/MessageSetVoteMutation.graphql b/src/background/clients/poe/graphql/MessageSetVoteMutation.graphql new file mode 100644 index 0000000..76000df --- /dev/null +++ b/src/background/clients/poe/graphql/MessageSetVoteMutation.graphql @@ -0,0 +1,7 @@ +mutation MessageSetVoteMutation($messageId: BigInt!, $voteType: VoteType!, $reason: String) { + messageSetVote(messageId: $messageId, voteType: $voteType, reason: $reason) { + message { + ...MessageFragment + } + } +} diff --git a/src/background/clients/poe/graphql/SendVerificationCodeForLoginMutation.graphql b/src/background/clients/poe/graphql/SendVerificationCodeForLoginMutation.graphql new file mode 100644 index 0000000..45af479 --- /dev/null +++ b/src/background/clients/poe/graphql/SendVerificationCodeForLoginMutation.graphql @@ -0,0 +1,12 @@ +mutation SendVerificationCodeForLoginMutation( + $emailAddress: String + $phoneNumber: String +) { + sendVerificationCode( + verificationReason: login + emailAddress: $emailAddress + phoneNumber: $phoneNumber + ) { + status + } +} diff --git a/src/background/clients/poe/graphql/ShareMessagesMutation.graphql b/src/background/clients/poe/graphql/ShareMessagesMutation.graphql new file mode 100644 index 0000000..92e80db --- /dev/null +++ b/src/background/clients/poe/graphql/ShareMessagesMutation.graphql @@ -0,0 +1,9 @@ +mutation ShareMessagesMutation( + $chatId: BigInt! + $messageIds: [BigInt!]! + $comment: String +) { + messagesShare(chatId: $chatId, messageIds: $messageIds, comment: $comment) { + shareCode + } +} diff --git a/src/background/clients/poe/graphql/SignupWithVerificationCodeMutation.graphql b/src/background/clients/poe/graphql/SignupWithVerificationCodeMutation.graphql new file mode 100644 index 0000000..06b2826 --- /dev/null +++ b/src/background/clients/poe/graphql/SignupWithVerificationCodeMutation.graphql @@ -0,0 +1,13 @@ +mutation SignupWithVerificationCodeMutation( + $verificationCode: String! + $emailAddress: String + $phoneNumber: String +) { + signupWithVerificationCode( + verificationCode: $verificationCode + emailAddress: $emailAddress + phoneNumber: $phoneNumber + ) { + status + } +} diff --git a/src/background/clients/poe/graphql/StaleChatUpdateMutation.graphql b/src/background/clients/poe/graphql/StaleChatUpdateMutation.graphql new file mode 100644 index 0000000..de203d4 --- /dev/null +++ b/src/background/clients/poe/graphql/StaleChatUpdateMutation.graphql @@ -0,0 +1,7 @@ +mutation StaleChatUpdateMutation($chatId: BigInt!) { + staleChatUpdate(chatId: $chatId) { + message { + ...MessageFragment + } + } +} diff --git a/src/background/clients/poe/graphql/SummarizePlainPostQuery.graphql b/src/background/clients/poe/graphql/SummarizePlainPostQuery.graphql new file mode 100644 index 0000000..afa2a84 --- /dev/null +++ b/src/background/clients/poe/graphql/SummarizePlainPostQuery.graphql @@ -0,0 +1,3 @@ +query SummarizePlainPostQuery($comment: String!) { + summarizePlainPost(comment: $comment) +} diff --git a/src/background/clients/poe/graphql/SummarizeQuotePostQuery.graphql b/src/background/clients/poe/graphql/SummarizeQuotePostQuery.graphql new file mode 100644 index 0000000..5147c3c --- /dev/null +++ b/src/background/clients/poe/graphql/SummarizeQuotePostQuery.graphql @@ -0,0 +1,3 @@ +query SummarizeQuotePostQuery($comment: String, $quotedPostId: BigInt!) { + summarizeQuotePost(comment: $comment, quotedPostId: $quotedPostId) +} diff --git a/src/background/clients/poe/graphql/SummarizeSharePostQuery.graphql b/src/background/clients/poe/graphql/SummarizeSharePostQuery.graphql new file mode 100644 index 0000000..cb4a623 --- /dev/null +++ b/src/background/clients/poe/graphql/SummarizeSharePostQuery.graphql @@ -0,0 +1,3 @@ +query SummarizeSharePostQuery($comment: String!, $chatId: BigInt!, $messageIds: [BigInt!]!) { + summarizeSharePost(comment: $comment, chatId: $chatId, messageIds: $messageIds) +} diff --git a/src/background/clients/poe/graphql/UserSnippetFragment.graphql b/src/background/clients/poe/graphql/UserSnippetFragment.graphql new file mode 100644 index 0000000..17fc842 --- /dev/null +++ b/src/background/clients/poe/graphql/UserSnippetFragment.graphql @@ -0,0 +1,14 @@ +fragment UserSnippetFragment on PoeUser { + id + uid + bio + handle + fullName + viewerIsFollowing + isPoeOnlyUser + profilePhotoURLTiny: profilePhotoUrl(size: tiny) + profilePhotoURLSmall: profilePhotoUrl(size: small) + profilePhotoURLMedium: profilePhotoUrl(size: medium) + profilePhotoURLLarge: profilePhotoUrl(size: large) + isFollowable +} diff --git a/src/background/clients/poe/graphql/ViewerInfoQuery.graphql b/src/background/clients/poe/graphql/ViewerInfoQuery.graphql new file mode 100644 index 0000000..1ecaf9e --- /dev/null +++ b/src/background/clients/poe/graphql/ViewerInfoQuery.graphql @@ -0,0 +1,21 @@ +query ViewerInfoQuery { + viewer { + id + uid + ...ViewerStateFragment + ...BioFragment + ...HandleFragment + hasCompletedMultiplayerNux + poeUser { + id + ...UserSnippetFragment + } + messageLimit{ + canSend + numMessagesRemaining + resetTime + shouldShowReminder + } + } +} + diff --git a/src/background/clients/poe/graphql/ViewerStateFragment.graphql b/src/background/clients/poe/graphql/ViewerStateFragment.graphql new file mode 100644 index 0000000..3cd83e9 --- /dev/null +++ b/src/background/clients/poe/graphql/ViewerStateFragment.graphql @@ -0,0 +1,30 @@ +fragment ViewerStateFragment on Viewer { + id + __typename + iosMinSupportedVersion: integerGate(gateName: "poe_ios_min_supported_version") + iosMinEncouragedVersion: integerGate( + gateName: "poe_ios_min_encouraged_version" + ) + macosMinSupportedVersion: integerGate( + gateName: "poe_macos_min_supported_version" + ) + macosMinEncouragedVersion: integerGate( + gateName: "poe_macos_min_encouraged_version" + ) + showPoeDebugPanel: booleanGate(gateName: "poe_show_debug_panel") + enableCommunityFeed: booleanGate(gateName: "enable_poe_shares_feed") + linkifyText: booleanGate(gateName: "poe_linkify_response") + enableSuggestedReplies: booleanGate(gateName: "poe_suggested_replies") + removeInviteLimit: booleanGate(gateName: "poe_remove_invite_limit") + enableInAppPurchases: booleanGate(gateName: "poe_enable_in_app_purchases") + availableBots { + nickname + displayName + profilePicture + isDown + disclaimer + subtitle + poweredBy + } +} + diff --git a/src/background/clients/poe/graphql/ViewerStateUpdatedSubscription.graphql b/src/background/clients/poe/graphql/ViewerStateUpdatedSubscription.graphql new file mode 100644 index 0000000..dd6d2d1 --- /dev/null +++ b/src/background/clients/poe/graphql/ViewerStateUpdatedSubscription.graphql @@ -0,0 +1,5 @@ +subscription ViewerStateUpdatedSubscription { + viewerStateUpdated { + ...ViewerStateFragment + } +} diff --git a/src/background/clients/poe/index.mjs b/src/background/clients/poe/index.mjs new file mode 100644 index 0000000..dadd11a --- /dev/null +++ b/src/background/clients/poe/index.mjs @@ -0,0 +1,170 @@ +// reference: https://github.com/muharamdani/poe + +import { connectWs, disconnectWs, listenWs } from './websocket.js' +import chatViewQuery from './graphql/ChatViewQuery.graphql' +import addMessageBreakMutation from './graphql/AddMessageBreakMutation.graphql' +import addHumanMessageMutation from './graphql/AddHumanMessageMutation.graphql' +import Browser from 'webextension-polyfill' +import md5 from 'md5' + +const queries = { + chatViewQuery: chatViewQuery.loc.source.body, + addMessageBreakMutation: addMessageBreakMutation.loc.source.body, + addHumanMessageMutation: addHumanMessageMutation.loc.source.body, +} + +export default class PoeAiClient { + constructor(chatId = null) { + this.headers = { + 'Content-Type': 'application/json', + Accept: 'application/json', + Origin: 'https://poe.com', + } + this.settings = null + this.ws = null + this.chatId = chatId + this.bot = null + } + + async ask(message, model, onMessage, onComplete) { + if (!this.settings) { + await this.getCredentials() + } + if (!this.bot) { + await this.initBot(model || 'sage') + } + if (!this.chatId) { + await this.getChatId(this.bot) + } + if (!this.ws) { + this.ws = await connectWs(this.settings) + await this.subscribe() + listenWs(this.ws, onMessage, onComplete) + } + await this.sendMsg(message) + } + + async close() { + if (this.ws) { + await disconnectWs(this.ws) + this.ws = null + } + } + + async getFormkey() { + const encoded = (await (await fetch('https://poe.com')).text()).match( + /