diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index b58b603f..00000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
deleted file mode 100644
index a55e7a17..00000000
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 03d9549e..00000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml
deleted file mode 100644
index d23208fb..00000000
--- a/.idea/jsLibraryMappings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/markdown.xml b/.idea/markdown.xml
deleted file mode 100644
index f6d2542c..00000000
--- a/.idea/markdown.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index d3e40546..00000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/node-chatgpt-api.iml b/.idea/node-chatgpt-api.iml
deleted file mode 100644
index 0c8867d7..00000000
--- a/.idea/node-chatgpt-api.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7f..00000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index fbd21f2d..e2a803be 100644
--- a/README.md
+++ b/README.md
@@ -149,6 +149,7 @@ This section will elaborate the parameters that are specific to Bing Chat that a
- `useUserSuffixMessage`: Adds a message by the user reading `Continue the message in the current Context` which will prevent the moderation filter to trigger for user messages, but may confuse the AI
- `plugins`: Enables the plugins in the array with the value `true`. See the `#resolvePlugins` method in the `BingAIClient.js` class for valid plugins
- `persona`: Enables a Microsoft custom GPT. See the `#resolvePersona` method in the `BingAIClient.js` class for valid personas
+- `accountType`: The type of account the cookie is associated with. Valid values are `free` and `pro`. Defaults to `free` if not set.
# ChatGPT API
diff --git a/bin/server.js b/bin/server.js
index de86693d..86e24904 100755
--- a/bin/server.js
+++ b/bin/server.js
@@ -120,6 +120,7 @@ server.post('/conversation', async (request, reply) => {
useUserSuffixMessage,
plugins,
persona,
+ accountType,
} = body;
const messageOptions = {
conversationId: body.conversationId ? body.conversationId.toString() : undefined,
@@ -140,6 +141,7 @@ server.post('/conversation', async (request, reply) => {
...(clientToUseForMessage === 'bing' && { useUserSuffixMessage }),
...(clientToUseForMessage === 'bing' && { plugins }),
...(clientToUseForMessage === 'bing' && { persona }),
+ ...(clientToUseForMessage === 'bing' && { accountType }),
onProgress,
abortController,
};
diff --git a/package-lock.json b/package-lock.json
index c30686e7..af911706 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1309,9 +1309,9 @@
}
},
"node_modules/eslint-config-airbnb-base/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -4371,9 +4371,9 @@
"dev": true
},
"node_modules/undici": {
- "version": "5.25.4",
- "resolved": "https://registry.npmjs.org/undici/-/undici-5.25.4.tgz",
- "integrity": "sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==",
+ "version": "5.28.2",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz",
+ "integrity": "sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==",
"dependencies": {
"@fastify/busboy": "^2.0.0"
},
@@ -5505,9 +5505,9 @@
},
"dependencies": {
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
@@ -7660,9 +7660,9 @@
"dev": true
},
"undici": {
- "version": "5.25.4",
- "resolved": "https://registry.npmjs.org/undici/-/undici-5.25.4.tgz",
- "integrity": "sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==",
+ "version": "5.28.2",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz",
+ "integrity": "sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==",
"requires": {
"@fastify/busboy": "^2.0.0"
}
diff --git a/src/BingAIClient.js b/src/BingAIClient.js
index 5a46c8f4..569e022c 100644
--- a/src/BingAIClient.js
+++ b/src/BingAIClient.js
@@ -68,6 +68,7 @@ export default class BingAIClient {
conversationSignature,
clientId,
plugins,
+ accountType,
systemMessage,
} = opts;
systemMessage = systemMessage || this.options.systemMessage;
@@ -173,7 +174,8 @@ export default class BingAIClient {
const imageBase64 = imageURL ? await BingAIClient.getBase64FromImageUrl(imageURL) : opts?.imageBase64;
const imageUploadResult = imageBase64 ? await this.uploadImage(imageBase64) : undefined;
const noSearch = plugins?.search === false ? 'nosearchall' : undefined;
- plugins = await BingAIClient.#resolvePlugins(plugins);
+ plugins = BingAIClient.#resolvePlugins(plugins);
+ accountType = BingAIClient.#resolveAccountType(accountType);
const webSocketParameters = {
message,
invocationId,
@@ -188,6 +190,7 @@ export default class BingAIClient {
useUserSuffixMessage: opts.useUserSuffixMessage,
noSearch,
persona,
+ accountType,
};
const ws = await this.#createWebSocketConnection(conversationSignature);
@@ -379,13 +382,14 @@ export default class BingAIClient {
useUserSuffixMessage,
noSearch,
persona,
+ accountType,
} = webSocketParameters;
const imageBaseURL = 'https://www.bing.com/images/blob?bcid=';
const pluginIds = plugins.map(plugin => ({ id: plugin.id, category: 1 })).filter(Boolean);
const pluginOptionSets = plugins.map(plugin => plugin.optionSet).filter(Boolean);
const personaString = this.#resolvePersona(persona);
- const tone = this.#resolveTone(toneStyle);
+ const tone = this.#resolveTone(toneStyle, accountType);
let userMessageSuffix;
if (useUserSuffixMessage === true) {
@@ -440,9 +444,9 @@ export default class BingAIClient {
isStartOfSession: invocationId === 0,
message: {
...imageUploadResult
- && { imageUrl: `${imageBaseURL}${imageUploadResult.blobId}` },
+ && { imageUrl: `${imageBaseURL}${imageUploadResult.blobId}` },
...imageUploadResult
- && { originalImageUrl: `${imageBaseURL}${imageUploadResult.blobId}` },
+ && { originalImageUrl: `${imageBaseURL}${imageUploadResult.blobId}` },
author: 'user',
text: useUserSuffixMessage ? userMessageSuffix : message,
messageType: 'Chat',
@@ -464,6 +468,25 @@ export default class BingAIClient {
return userWebsocketRequest;
}
+ /**
+ * Resolves the accountType and returns the string to use for further usage.
+ * @param {String} accountType String description of account type.
+ * @returns {String} The resolved account type to use.
+ */
+ static #resolveAccountType(accountType) {
+ let resolvedAccountType;
+ switch (accountType) {
+ case 'pro':
+ resolvedAccountType = 'pro';
+ break;
+ case 'free':
+ default:
+ resolvedAccountType = 'free';
+ }
+
+ return resolvedAccountType;
+ }
+
/**
* This method converts persona names from simple names to technical names.
* @param {String | undefined} persona Simple name of the persona to use.
@@ -499,7 +522,7 @@ export default class BingAIClient {
* @param {Object} plugins Object containing the plugins to use as strings.
* @returns {Object[]} The resolved array of plugin objects that can be used later.
*/
- static async #resolvePlugins(plugins) {
+ static #resolvePlugins(plugins) {
const pluginLookup = {
codeInterpreter: {
optionSet: 'codeint',
@@ -552,20 +575,24 @@ export default class BingAIClient {
/**
* This method converts toneStyles from simple names to technical names.
* @param {String | undefined} toneStyle Simple name of the tone to use.
+ * @param {String} accountType Account type which influences modes.
* @returns {String} Technical name of the tone to use.
*/
- static #resolveTone(toneStyle) {
+ static #resolveTone(toneStyle, accountType) {
let tone;
- if (toneStyle === 'creative') {
- tone = 'CreativeClassic';
- } else if (toneStyle === 'turbo') {
- tone = 'Creative';
- } else if (toneStyle === 'precise') {
- tone = 'Precise';
- } else if (toneStyle === 'balanced') {
- tone = 'Balanced';
- } else {
- tone = 'CreativeClassic';
+ switch (toneStyle) {
+ case 'turbo':
+ tone = 'Creative';
+ break;
+ case 'precise':
+ tone = 'Precise';
+ break;
+ case 'balanced':
+ tone = 'Balanced';
+ break;
+ case 'creative':
+ default:
+ tone = accountType === 'pro' ? 'CreativeClassic' : 'Creative';
}
return tone;
@@ -625,7 +652,7 @@ export default class BingAIClient {
return;
}
if (messages[0]?.contentType === 'IMAGE') {
- // You will never get a message of this type without 'gencontentv3' being on.
+ // You will never get a message of this type without 'gencontentv3' being on.
bicIframe = this.bic.genImageIframeSsr(
messages[0].text,
messages[0].messageId,
@@ -718,12 +745,12 @@ export default class BingAIClient {
// The moderation filter triggered, so just return the text we have so far
if (
opts.jailbreakConversationId
- && (
- stopTokenFound
- || event.item.messages[0].topicChangerText
- || event.item.messages[0].offense === 'OffenseTrigger'
- || (event.item.messages.length > 1 && event.item.messages[1].contentOrigin === 'Apology')
- )
+ && (
+ stopTokenFound
+ || event.item.messages[0].topicChangerText
+ || event.item.messages[0].offense === 'OffenseTrigger'
+ || (event.item.messages.length > 1 && event.item.messages[1].contentOrigin === 'Apology')
+ )
) {
if (!replySoFar) {
replySoFar = 'I need some time to process your message. Please wait a moment.';
@@ -734,7 +761,7 @@ export default class BingAIClient {
delete eventMessage.suggestedResponses;
}
if (bicIframe) {
- // the last messages will be a image creation event if bicIframe is present.
+ // the last messages will be a image creation event if bicIframe is present.
let i = messages.length - 1;
while (eventMessage?.contentType === 'IMAGE' && i > 0) {
eventMessage = messages[i -= 1];
@@ -751,7 +778,7 @@ export default class BingAIClient {
}
}
if ((opts.showSuggestions === false || opts.useBase64 === true)
- && eventMessage.suggestedResponses) {
+ && eventMessage.suggestedResponses) {
delete eventMessage.suggestedResponses;
}
resolve({
@@ -762,7 +789,7 @@ export default class BingAIClient {
return;
}
case 7: {
- // [{"type":7,"error":"Connection closed with an error.","allowReconnect":true}]
+ // [{"type":7,"error":"Connection closed with an error.","allowReconnect":true}]
clearTimeout(messageTimeout);
this.constructor.cleanupWebSocketConnection(ws);
reject(new Error(event.error || 'Connection closed with an error.'));