mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 09:20:15 +01:00
Merge pull request #16 from danny-avila/updateAI
feat: add sydney (jailbroken bing) and more bing styling with citations
This commit is contained in:
commit
12cf3405e4
28 changed files with 377 additions and 88 deletions
17
README.md
17
README.md
|
|
@ -8,14 +8,23 @@ https://user-images.githubusercontent.com/110412045/223754183-8b7f45ce-6517-4bd5
|
||||||
|
|
||||||
## Updates
|
## Updates
|
||||||
<details open>
|
<details open>
|
||||||
|
<summary><strong>2023-03-09</strong></summary>
|
||||||
|
Released v.0.0.2
|
||||||
|
|
||||||
|
Adds Sydney (jailbroken Bing AI) to the model menu. Thank you [DavesDevFails](https://github.com/DavesDevFails) for bringing it to my attention in this [issue](https://github.com/danny-avila/chatgpt-clone/issues/13). Bing/Sydney now correctly cite links, more styling to come. Fix some overlooked bugs, and model menu doesn't close upon deleting a customGpt.
|
||||||
|
|
||||||
|
|
||||||
|
I've re-enabled the ChatGPT browser client (free version) since it might be working for most people, it no longer works for me. Sydney is the best free route anyway.
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<details>
|
||||||
<summary><strong>2023-03-07</strong></summary>
|
<summary><strong>2023-03-07</strong></summary>
|
||||||
Due to increased interest in the repo, I've dockerized the app as of this update for quick setup! See setup instructions below. I realize this still takes some time with installing docker dependencies, so it's on the roadmap to have a deployed demo. Besides this, I've made major improvements for a lot of the existing features across the board, mainly UI/UX.
|
Due to increased interest in the repo, I've dockerized the app as of this update for quick setup! See setup instructions below. I realize this still takes some time with installing docker dependencies, so it's on the roadmap to have a deployed demo. Besides this, I've made major improvements for a lot of the existing features across the board, mainly UI/UX.
|
||||||
|
|
||||||
|
|
||||||
Also worth noting, the method to access the Free Version is no longer working, so I've removed it from model selection until further notice.
|
Also worth noting, the method to access the Free Version is no longer working, so I've removed it from model selection until further notice.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><strong>Previous Updates</strong></summary>
|
<summary><strong>Previous Updates</strong></summary>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
@ -80,12 +89,12 @@ Here are my recently completed and planned features:
|
||||||
- [x] Customize prompt prefix/label (custom ChatGPT using official API)
|
- [x] Customize prompt prefix/label (custom ChatGPT using official API)
|
||||||
- [x] Server convo pagination (limit fetch and load more with 'show more' button)
|
- [x] Server convo pagination (limit fetch and load more with 'show more' button)
|
||||||
- [x] Config file for easy startup (docker compose)
|
- [x] Config file for easy startup (docker compose)
|
||||||
|
- [ ] Bing AI Styling (for suggested responses, convo end, etc.) - **In progress**
|
||||||
- [ ] Add warning before clearing convos
|
- [ ] Add warning before clearing convos
|
||||||
- [ ] Build test suite for CI/CD
|
- [ ] Build test suite for CI/CD
|
||||||
- [ ] Conversation Search (by title)
|
- [ ] Conversation Search (by title)
|
||||||
- [ ] Resubmit/edit sent messages
|
- [ ] Resubmit/edit sent messages
|
||||||
- [ ] Semantic Search Option (requires more tokens)
|
- [ ] Semantic Search Option (requires more tokens)
|
||||||
- [ ] Bing AI Styling (for suggested responses, convo end, etc.)
|
|
||||||
- [ ] Prompt Templates/Search
|
- [ ] Prompt Templates/Search
|
||||||
- [ ] Refactor/clean up code (tech debt)
|
- [ ] Refactor/clean up code (tech debt)
|
||||||
- [ ] Optional use of local storage for credentials
|
- [ ] Optional use of local storage for credentials
|
||||||
|
|
@ -172,7 +181,7 @@ The Bing Access Token is the "_U" cookie from bing.com. Use dev tools or an exte
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Updating
|
### Updating
|
||||||
- As the project is still a work-in-progress, you should pull the latest and run some of the steps above again
|
- As the project is still a work-in-progress, you should pull the latest and run the steps over. Reset your browser cache/clear site data.
|
||||||
|
|
||||||
## Use Cases ##
|
## Use Cases ##
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const askBing = async ({ text, progressCallback, convo }) => {
|
||||||
// If the above doesn't work, provide all your cookies as a string instead
|
// If the above doesn't work, provide all your cookies as a string instead
|
||||||
// cookies: '',
|
// cookies: '',
|
||||||
debug: false,
|
debug: false,
|
||||||
store: new KeyvFile({ filename: './data/cache.json' })
|
cache: { store: new KeyvFile({ filename: './data/cache.json' }) }
|
||||||
});
|
});
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ const clientOptions = {
|
||||||
// Warning: This will expose your access token to a third party. Consider the risks before using this.
|
// Warning: This will expose your access token to a third party. Consider the risks before using this.
|
||||||
reverseProxyUrl: 'https://chatgpt.duti.tech/api/conversation',
|
reverseProxyUrl: 'https://chatgpt.duti.tech/api/conversation',
|
||||||
// Access token from https://chat.openai.com/api/auth/session
|
// Access token from https://chat.openai.com/api/auth/session
|
||||||
accessToken: process.env.CHATGPT_TOKEN
|
accessToken: process.env.CHATGPT_TOKEN,
|
||||||
|
// debug: true
|
||||||
};
|
};
|
||||||
|
|
||||||
const browserClient = async ({ text, progressCallback, convo }) => {
|
const browserClient = async ({ text, progressCallback, convo }) => {
|
||||||
|
|
|
||||||
29
api/app/citeText.js
Normal file
29
api/app/citeText.js
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
const citationRegex = /\[\^\d+?\^]/g;
|
||||||
|
|
||||||
|
const citeText = (res, noLinks = false) => {
|
||||||
|
let result = res.text || res;
|
||||||
|
const citations = Array.from(new Set(result.match(citationRegex)));
|
||||||
|
if (citations?.length === 0) return result;
|
||||||
|
|
||||||
|
if (noLinks) {
|
||||||
|
citations.forEach((citation) => {
|
||||||
|
const digit = citation.match(/\d+?/g)[0];
|
||||||
|
result = result.replaceAll(citation, `<sup>[${digit}](#) </sup>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sources = res.details.sourceAttributions;
|
||||||
|
if (sources?.length === 0) return result;
|
||||||
|
sources = sources.map((source) => source.seeMoreUrl);
|
||||||
|
|
||||||
|
citations.forEach((citation) => {
|
||||||
|
const digit = citation.match(/\d+?/g)[0];
|
||||||
|
result = result.replaceAll(citation, `<sup>[${digit}](${sources[digit - 1]}) </sup>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = citeText;
|
||||||
13
api/app/getCitations.js
Normal file
13
api/app/getCitations.js
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
// const regex = / \[\d+\..*?\]\(.*?\)/g;
|
||||||
|
const regex = / \[.*?]\(.*?\)/g;
|
||||||
|
|
||||||
|
const getCitations = (res) => {
|
||||||
|
const textBlocks = res.details.adaptiveCards[0].body;
|
||||||
|
if (!textBlocks) return '';
|
||||||
|
let links = textBlocks[textBlocks.length - 1]?.text.match(regex);
|
||||||
|
if (links?.length === 0 || !links) return '';
|
||||||
|
links = links.map((link) => link.trim());
|
||||||
|
return links.join('\n');
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = getCitations;
|
||||||
|
|
@ -2,7 +2,10 @@ const { askClient } = require('./chatgpt-client');
|
||||||
const { browserClient } = require('./chatgpt-browser');
|
const { browserClient } = require('./chatgpt-browser');
|
||||||
const customClient = require('./chatgpt-custom');
|
const customClient = require('./chatgpt-custom');
|
||||||
const { askBing } = require('./bingai');
|
const { askBing } = require('./bingai');
|
||||||
|
const { askSydney } = require('./sydney');
|
||||||
const titleConvo = require('./titleConvo');
|
const titleConvo = require('./titleConvo');
|
||||||
|
const getCitations = require('./getCitations');
|
||||||
|
const citeText = require('./citeText');
|
||||||
const detectCode = require('./detectCode');
|
const detectCode = require('./detectCode');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
@ -10,6 +13,9 @@ module.exports = {
|
||||||
browserClient,
|
browserClient,
|
||||||
customClient,
|
customClient,
|
||||||
askBing,
|
askBing,
|
||||||
|
askSydney,
|
||||||
titleConvo,
|
titleConvo,
|
||||||
|
getCitations,
|
||||||
|
citeText,
|
||||||
detectCode
|
detectCode
|
||||||
};
|
};
|
||||||
36
api/app/sydney.js
Normal file
36
api/app/sydney.js
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
require('dotenv').config();
|
||||||
|
const { KeyvFile } = require('keyv-file');
|
||||||
|
|
||||||
|
const askSydney = async ({ text, progressCallback, convo }) => {
|
||||||
|
const { BingAIClient } = (await import('@waylaidwanderer/chatgpt-api'));
|
||||||
|
|
||||||
|
const sydneyClient = new BingAIClient({
|
||||||
|
// "_U" cookie from bing.com
|
||||||
|
userToken: process.env.BING_TOKEN,
|
||||||
|
// If the above doesn't work, provide all your cookies as a string instead
|
||||||
|
// cookies: '',
|
||||||
|
debug: false,
|
||||||
|
cache: { store: new KeyvFile({ filename: './data/cache.json' }) }
|
||||||
|
});
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
jailbreakConversationId: true,
|
||||||
|
onProgress: async (partialRes) => await progressCallback(partialRes),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (convo.parentMessageId) {
|
||||||
|
options = { ...options, jailbreakConversationId: convo.jailbreakConversationId, parentMessageId: convo.parentMessageId };
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('sydney options', options);
|
||||||
|
|
||||||
|
const res = await sydneyClient.sendMessage(text, options
|
||||||
|
);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
// for reference:
|
||||||
|
// https://github.com/waylaidwanderer/node-chatgpt-api/blob/main/demos/use-bing-client.js
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { askSydney };
|
||||||
|
|
@ -15,6 +15,9 @@ const convoSchema = mongoose.Schema({
|
||||||
type: String,
|
type: String,
|
||||||
default: 'New conversation'
|
default: 'New conversation'
|
||||||
},
|
},
|
||||||
|
jailbreakConversationId: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
conversationSignature: {
|
conversationSignature: {
|
||||||
type: String
|
type: String
|
||||||
},
|
},
|
||||||
|
|
@ -44,6 +47,15 @@ const convoSchema = mongoose.Schema({
|
||||||
const Conversation =
|
const Conversation =
|
||||||
mongoose.models.Conversation || mongoose.model('Conversation', convoSchema);
|
mongoose.models.Conversation || mongoose.model('Conversation', convoSchema);
|
||||||
|
|
||||||
|
const getConvo = async (conversationId) => {
|
||||||
|
try {
|
||||||
|
return await Conversation.findOne({ conversationId }).exec();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return { message: 'Error getting single conversation' };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
saveConvo: async ({ conversationId, title, ...convo }) => {
|
saveConvo: async ({ conversationId, title, ...convo }) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -92,12 +104,14 @@ module.exports = {
|
||||||
return { message: 'Error getting conversations' };
|
return { message: 'Error getting conversations' };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getConvo: async (conversationId) => {
|
getConvo,
|
||||||
|
getConvoTitle: async (conversationId) => {
|
||||||
try {
|
try {
|
||||||
return await Conversation.findOne({ conversationId }).exec();
|
const convo = await getConvo(conversationId);
|
||||||
|
return convo.title;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
return { message: 'Error getting single conversation' };
|
return { message: 'Error getting conversation title' };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteConvos: async (filter) => {
|
deleteConvos: async (filter) => {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
const { saveMessage, deleteMessages } = require('./Message');
|
const { saveMessage, deleteMessages } = require('./Message');
|
||||||
const { getCustomGpts, updateCustomGpt, updateByLabel, deleteCustomGpts } = require('./CustomGpt');
|
const { getCustomGpts, updateCustomGpt, updateByLabel, deleteCustomGpts } = require('./CustomGpt');
|
||||||
const { getConvo, saveConvo } = require('./Conversation');
|
const { getConvoTitle, getConvo, saveConvo } = require('./Conversation');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
saveMessage,
|
saveMessage,
|
||||||
deleteMessages,
|
deleteMessages,
|
||||||
|
getConvoTitle,
|
||||||
getConvo,
|
getConvo,
|
||||||
saveConvo,
|
saveConvo,
|
||||||
getCustomGpts,
|
getCustomGpts,
|
||||||
|
|
|
||||||
14
api/package-lock.json
generated
14
api/package-lock.json
generated
|
|
@ -11,7 +11,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@keyv/mongo": "^2.1.8",
|
"@keyv/mongo": "^2.1.8",
|
||||||
"@vscode/vscode-languagedetection": "^1.0.22",
|
"@vscode/vscode-languagedetection": "^1.0.22",
|
||||||
"@waylaidwanderer/chatgpt-api": "^1.15.1",
|
"@waylaidwanderer/chatgpt-api": "^1.28.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
|
@ -1492,9 +1492,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@waylaidwanderer/chatgpt-api": {
|
"node_modules/@waylaidwanderer/chatgpt-api": {
|
||||||
"version": "1.26.1",
|
"version": "1.28.2",
|
||||||
"resolved": "https://registry.npmjs.org/@waylaidwanderer/chatgpt-api/-/chatgpt-api-1.26.1.tgz",
|
"resolved": "https://registry.npmjs.org/@waylaidwanderer/chatgpt-api/-/chatgpt-api-1.28.2.tgz",
|
||||||
"integrity": "sha512-cv9NqC0owO2EGCkVg4VQO0lcA5pDgv2VJrBE/0P6En27/v0gIC+7MedowX3htIUi4GLDkgyyDDDimst2i8ReMw==",
|
"integrity": "sha512-efNvZr8uosiYD69zFq50OPM36s+tyRMixlHpwDzn2q9UuZrdHC++kmm23OAnDxv3/+vA4UwCsZXn+92c35NHBQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dqbd/tiktoken": "^0.4.0",
|
"@dqbd/tiktoken": "^0.4.0",
|
||||||
"@fastify/cors": "^8.2.0",
|
"@fastify/cors": "^8.2.0",
|
||||||
|
|
@ -5781,9 +5781,9 @@
|
||||||
"integrity": "sha512-rQ/BgMyLuIXSmbA0MSkIPHtcOw14QkeDbAq19sjvaS9LTRr905yij0S8lsyqN5JgOsbtIx7pAcyOxFMzPmqhZQ=="
|
"integrity": "sha512-rQ/BgMyLuIXSmbA0MSkIPHtcOw14QkeDbAq19sjvaS9LTRr905yij0S8lsyqN5JgOsbtIx7pAcyOxFMzPmqhZQ=="
|
||||||
},
|
},
|
||||||
"@waylaidwanderer/chatgpt-api": {
|
"@waylaidwanderer/chatgpt-api": {
|
||||||
"version": "1.26.1",
|
"version": "1.28.2",
|
||||||
"resolved": "https://registry.npmjs.org/@waylaidwanderer/chatgpt-api/-/chatgpt-api-1.26.1.tgz",
|
"resolved": "https://registry.npmjs.org/@waylaidwanderer/chatgpt-api/-/chatgpt-api-1.28.2.tgz",
|
||||||
"integrity": "sha512-cv9NqC0owO2EGCkVg4VQO0lcA5pDgv2VJrBE/0P6En27/v0gIC+7MedowX3htIUi4GLDkgyyDDDimst2i8ReMw==",
|
"integrity": "sha512-efNvZr8uosiYD69zFq50OPM36s+tyRMixlHpwDzn2q9UuZrdHC++kmm23OAnDxv3/+vA4UwCsZXn+92c35NHBQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@dqbd/tiktoken": "^0.4.0",
|
"@dqbd/tiktoken": "^0.4.0",
|
||||||
"@fastify/cors": "^8.2.0",
|
"@fastify/cors": "^8.2.0",
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@keyv/mongo": "^2.1.8",
|
"@keyv/mongo": "^2.1.8",
|
||||||
"@vscode/vscode-languagedetection": "^1.0.22",
|
"@vscode/vscode-languagedetection": "^1.0.22",
|
||||||
"@waylaidwanderer/chatgpt-api": "^1.15.1",
|
"@waylaidwanderer/chatgpt-api": "^1.28.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.0.3",
|
"dotenv": "^16.0.3",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const express = require('express');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const askBing = require('./askBing');
|
const askBing = require('./askBing');
|
||||||
|
const askSydney = require('./askSydney');
|
||||||
const {
|
const {
|
||||||
titleConvo,
|
titleConvo,
|
||||||
askClient,
|
askClient,
|
||||||
|
|
@ -13,6 +14,7 @@ const { getConvo, saveMessage, deleteMessages, saveConvo } = require('../../mode
|
||||||
const { handleError, sendMessage } = require('./handlers');
|
const { handleError, sendMessage } = require('./handlers');
|
||||||
|
|
||||||
router.use('/bing', askBing);
|
router.use('/bing', askBing);
|
||||||
|
router.use('/sydney', askSydney);
|
||||||
|
|
||||||
router.post('/', async (req, res) => {
|
router.post('/', async (req, res) => {
|
||||||
let { model, text, parentMessageId, conversationId, chatGptLabel, promptPrefix } = req.body;
|
let { model, text, parentMessageId, conversationId, chatGptLabel, promptPrefix } = req.body;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const { titleConvo, askBing } = require('../../app/');
|
const { titleConvo, getCitations, citeText, askBing } = require('../../app/');
|
||||||
const { saveMessage, deleteMessages, saveConvo } = require('../../models');
|
const { saveMessage, deleteMessages, saveConvo } = require('../../models');
|
||||||
const { handleError, sendMessage } = require('./handlers');
|
const { handleError, sendMessage } = require('./handlers');
|
||||||
|
const citationRegex = /\[\^\d+?\^]/g;
|
||||||
|
|
||||||
router.post('/', async (req, res) => {
|
router.post('/', async (req, res) => {
|
||||||
const { model, text, ...convo } = req.body;
|
const { model, text, ...convo } = req.body;
|
||||||
|
|
@ -29,6 +30,7 @@ router.post('/', async (req, res) => {
|
||||||
const progressCallback = async (partial) => {
|
const progressCallback = async (partial) => {
|
||||||
tokens += partial === text ? '' : partial;
|
tokens += partial === text ? '' : partial;
|
||||||
// tokens = appendCode(tokens);
|
// tokens = appendCode(tokens);
|
||||||
|
tokens = citeText(tokens, true);
|
||||||
sendMessage(res, { text: tokens, message: true });
|
sendMessage(res, { text: tokens, message: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -38,8 +40,9 @@ router.post('/', async (req, res) => {
|
||||||
convo
|
convo
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('CLIENT RESPONSE');
|
console.log('BING RESPONSE');
|
||||||
console.dir(response, { depth: null });
|
// console.dir(response, { depth: null });
|
||||||
|
const hasCitations = response.response.match(citationRegex)?.length > 0;
|
||||||
|
|
||||||
userMessage.conversationSignature =
|
userMessage.conversationSignature =
|
||||||
convo.conversationSignature || response.conversationSignature;
|
convo.conversationSignature || response.conversationSignature;
|
||||||
|
|
@ -48,16 +51,27 @@ router.post('/', async (req, res) => {
|
||||||
await saveMessage(userMessage);
|
await saveMessage(userMessage);
|
||||||
|
|
||||||
if (!convo.conversationSignature) {
|
if (!convo.conversationSignature) {
|
||||||
response.title = await titleConvo(text, response.response, model);
|
response.title = await titleConvo({
|
||||||
|
model,
|
||||||
|
message: text,
|
||||||
|
response: JSON.stringify(response.response)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
response.text = response.response;
|
response.text = response.response;
|
||||||
|
delete response.response;
|
||||||
response.id = response.details.messageId;
|
response.id = response.details.messageId;
|
||||||
response.suggestions =
|
response.suggestions =
|
||||||
response.details.suggestedResponses &&
|
response.details.suggestedResponses &&
|
||||||
response.details.suggestedResponses.map((s) => s.text);
|
response.details.suggestedResponses.map((s) => s.text);
|
||||||
response.sender = model;
|
response.sender = model;
|
||||||
response.final = true;
|
response.final = true;
|
||||||
|
|
||||||
|
const links = getCitations(response);
|
||||||
|
response.text =
|
||||||
|
citeText(response) +
|
||||||
|
(links?.length > 0 && hasCitations ? `\n<small>${links}</small>` : '');
|
||||||
|
|
||||||
await saveMessage(response);
|
await saveMessage(response);
|
||||||
await saveConvo(response);
|
await saveConvo(response);
|
||||||
sendMessage(res, response);
|
sendMessage(res, response);
|
||||||
|
|
|
||||||
96
api/server/routes/askSydney.js
Normal file
96
api/server/routes/askSydney.js
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
const express = require('express');
|
||||||
|
const crypto = require('crypto');
|
||||||
|
const router = express.Router();
|
||||||
|
const { titleConvo, getCitations, citeText, askSydney } = require('../../app/');
|
||||||
|
const { saveMessage, deleteMessages, saveConvo, getConvoTitle } = require('../../models');
|
||||||
|
const { handleError, sendMessage } = require('./handlers');
|
||||||
|
const citationRegex = /\[\^\d+?\^]/g;
|
||||||
|
|
||||||
|
router.post('/', async (req, res) => {
|
||||||
|
const { model, text, ...convo } = req.body;
|
||||||
|
if (!text.trim().includes(' ') && text.length < 5) {
|
||||||
|
return handleError(res, 'Prompt empty or too short');
|
||||||
|
}
|
||||||
|
|
||||||
|
const userMessageId = crypto.randomUUID();
|
||||||
|
let userMessage = { id: userMessageId, sender: 'User', text };
|
||||||
|
|
||||||
|
console.log('ask log', { model, ...userMessage, ...convo });
|
||||||
|
|
||||||
|
res.writeHead(200, {
|
||||||
|
Connection: 'keep-alive',
|
||||||
|
'Content-Type': 'text/event-stream',
|
||||||
|
'Cache-Control': 'no-cache, no-transform',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
'X-Accel-Buffering': 'no'
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
let tokens = '';
|
||||||
|
const progressCallback = async (partial) => {
|
||||||
|
tokens += partial === text ? '' : partial;
|
||||||
|
// tokens = appendCode(tokens);
|
||||||
|
tokens = citeText(tokens, true);
|
||||||
|
sendMessage(res, { text: tokens, message: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = await askSydney({
|
||||||
|
text,
|
||||||
|
progressCallback,
|
||||||
|
convo
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('SYDNEY RESPONSE');
|
||||||
|
console.log(response.response);
|
||||||
|
// console.dir(response, { depth: null });
|
||||||
|
const hasCitations = response.response.match(citationRegex)?.length > 0;
|
||||||
|
|
||||||
|
// Save sydney response
|
||||||
|
response.id = response.messageId;
|
||||||
|
// response.parentMessageId = convo.parentMessageId ? convo.parentMessageId : response.messageId;
|
||||||
|
response.parentMessageId = response.messageId;
|
||||||
|
response.invocationId = convo.invocationId ? convo.invocationId + 1 : 1;
|
||||||
|
response.title = convo.jailbreakConversationId
|
||||||
|
? await getConvoTitle(convo.conversationId)
|
||||||
|
: await titleConvo({
|
||||||
|
model,
|
||||||
|
message: text,
|
||||||
|
response: JSON.stringify(response.response)
|
||||||
|
});
|
||||||
|
response.conversationId = convo.conversationId
|
||||||
|
? convo.conversationId
|
||||||
|
: crypto.randomUUID();
|
||||||
|
response.conversationSignature = convo.conversationSignature
|
||||||
|
? convo.conversationSignature
|
||||||
|
: crypto.randomUUID();
|
||||||
|
response.text = response.response;
|
||||||
|
delete response.response;
|
||||||
|
response.suggestions =
|
||||||
|
response.details.suggestedResponses &&
|
||||||
|
response.details.suggestedResponses.map((s) => s.text);
|
||||||
|
response.sender = model;
|
||||||
|
response.final = true;
|
||||||
|
|
||||||
|
const links = getCitations(response);
|
||||||
|
response.text =
|
||||||
|
citeText(response) +
|
||||||
|
(links?.length > 0 && hasCitations ? `\n<small>${links}</small>` : '');
|
||||||
|
|
||||||
|
// Save user message
|
||||||
|
userMessage.conversationId = response.conversationId;
|
||||||
|
userMessage.parentMessageId = response.parentMessageId;
|
||||||
|
await saveMessage(userMessage);
|
||||||
|
|
||||||
|
// Save sydney response & convo, then send
|
||||||
|
await saveMessage(response);
|
||||||
|
await saveConvo(response);
|
||||||
|
sendMessage(res, response);
|
||||||
|
res.end();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
await deleteMessages({ id: userMessageId });
|
||||||
|
handleError(res, error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
|
|
@ -16,7 +16,7 @@ export default function Conversation({
|
||||||
title = 'New conversation',
|
title = 'New conversation',
|
||||||
bingData,
|
bingData,
|
||||||
chatGptLabel = null,
|
chatGptLabel = null,
|
||||||
promptPrefix = null,
|
promptPrefix = null
|
||||||
}) {
|
}) {
|
||||||
const [renaming, setRenaming] = useState(false);
|
const [renaming, setRenaming] = useState(false);
|
||||||
const [titleInput, setTitleInput] = useState(title);
|
const [titleInput, setTitleInput] = useState(title);
|
||||||
|
|
@ -34,11 +34,18 @@ export default function Conversation({
|
||||||
const convo = { title, error: false, conversationId: id, chatGptLabel, promptPrefix };
|
const convo = { title, error: false, conversationId: id, chatGptLabel, promptPrefix };
|
||||||
|
|
||||||
if (bingData) {
|
if (bingData) {
|
||||||
const { conversationSignature, clientId, invocationId } = bingData;
|
const {
|
||||||
|
parentMessageId,
|
||||||
|
conversationSignature,
|
||||||
|
jailbreakConversationId,
|
||||||
|
clientId,
|
||||||
|
invocationId
|
||||||
|
} = bingData;
|
||||||
dispatch(
|
dispatch(
|
||||||
setConversation({
|
setConversation({
|
||||||
...convo,
|
...convo,
|
||||||
parentMessageId: null,
|
parentMessageId,
|
||||||
|
jailbreakConversationId,
|
||||||
conversationSignature,
|
conversationSignature,
|
||||||
clientId,
|
clientId,
|
||||||
invocationId
|
invocationId
|
||||||
|
|
@ -49,6 +56,7 @@ export default function Conversation({
|
||||||
setConversation({
|
setConversation({
|
||||||
...convo,
|
...convo,
|
||||||
parentMessageId,
|
parentMessageId,
|
||||||
|
jailbreakConversationId: null,
|
||||||
conversationSignature: null,
|
conversationSignature: null,
|
||||||
clientId: null,
|
clientId: null,
|
||||||
invocationId: null
|
invocationId: null
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import TrashIcon from '../svg/TrashIcon';
|
||||||
import CrossIcon from '../svg/CrossIcon';
|
import CrossIcon from '../svg/CrossIcon';
|
||||||
import manualSWR from '~/utils/fetchers';
|
import manualSWR from '~/utils/fetchers';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { setConversation, removeConvo } from '~/store/convoSlice';
|
import { setNewConvo, removeConvo } from '~/store/convoSlice';
|
||||||
import { setMessages } from '~/store/messageSlice';
|
import { setMessages } from '~/store/messageSlice';
|
||||||
|
|
||||||
export default function DeleteButton({ conversationId, renaming, cancelHandler }) {
|
export default function DeleteButton({ conversationId, renaming, cancelHandler }) {
|
||||||
|
|
@ -14,7 +14,7 @@ export default function DeleteButton({ conversationId, renaming, cancelHandler }
|
||||||
() => {
|
() => {
|
||||||
dispatch(setMessages([]));
|
dispatch(setMessages([]));
|
||||||
dispatch(removeConvo(conversationId));
|
dispatch(removeConvo(conversationId));
|
||||||
dispatch(setConversation({ title: 'New chat', conversationId: null, parentMessageId: null }));
|
dispatch(setNewConvo());
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,9 @@ export default function Conversations({ conversations, conversationId, showMore
|
||||||
conversations.map((convo) => {
|
conversations.map((convo) => {
|
||||||
const bingData = convo.conversationSignature
|
const bingData = convo.conversationSignature
|
||||||
? {
|
? {
|
||||||
|
jailbreakConversationId: convo.jailbreakConversationId,
|
||||||
conversationSignature: convo.conversationSignature,
|
conversationSignature: convo.conversationSignature,
|
||||||
|
parentMessageId: convo.parentMessageId || null,
|
||||||
clientId: convo.clientId,
|
clientId: convo.clientId,
|
||||||
invocationId: convo.invocationId
|
invocationId: convo.invocationId
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,10 @@ export default function TextChat({ messages }) {
|
||||||
setMessages([...messages, currentMsg, { sender, text: data.text || data.response }])
|
setMessages([...messages, currentMsg, { sender, text: data.text || data.response }])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isBing = model === 'bingai' || model === 'sydney';
|
||||||
|
|
||||||
if (
|
if (
|
||||||
model !== 'bingai' &&
|
!isBing &&
|
||||||
convo.conversationId === null &&
|
convo.conversationId === null &&
|
||||||
convo.parentMessageId === null
|
convo.parentMessageId === null
|
||||||
) {
|
) {
|
||||||
|
|
@ -57,6 +59,7 @@ export default function TextChat({ messages }) {
|
||||||
title,
|
title,
|
||||||
conversationId,
|
conversationId,
|
||||||
parentMessageId: id,
|
parentMessageId: id,
|
||||||
|
jailbreakConversationId: null,
|
||||||
conversationSignature: null,
|
conversationSignature: null,
|
||||||
clientId: null,
|
clientId: null,
|
||||||
invocationId: null,
|
invocationId: null,
|
||||||
|
|
@ -69,15 +72,43 @@ export default function TextChat({ messages }) {
|
||||||
convo.conversationId === null &&
|
convo.conversationId === null &&
|
||||||
convo.invocationId === null
|
convo.invocationId === null
|
||||||
) {
|
) {
|
||||||
const { title, conversationSignature, clientId, conversationId, invocationId } = data;
|
console.log('Bing data:', data)
|
||||||
dispatch(
|
const {
|
||||||
setConversation({
|
|
||||||
title,
|
title,
|
||||||
conversationSignature,
|
conversationSignature,
|
||||||
clientId,
|
clientId,
|
||||||
conversationId,
|
conversationId,
|
||||||
|
invocationId
|
||||||
|
} = data;
|
||||||
|
dispatch(
|
||||||
|
setConversation({
|
||||||
|
title,
|
||||||
|
parentMessageId: null,
|
||||||
|
conversationSignature,
|
||||||
|
clientId,
|
||||||
|
conversationId,
|
||||||
|
invocationId,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else if (model === 'sydney') {
|
||||||
|
const {
|
||||||
|
title,
|
||||||
|
jailbreakConversationId,
|
||||||
|
parentMessageId,
|
||||||
|
conversationSignature,
|
||||||
|
clientId,
|
||||||
|
conversationId,
|
||||||
|
invocationId
|
||||||
|
} = data;
|
||||||
|
dispatch(
|
||||||
|
setConversation({
|
||||||
|
title,
|
||||||
|
jailbreakConversationId,
|
||||||
|
parentMessageId,
|
||||||
|
conversationSignature,
|
||||||
|
clientId,
|
||||||
|
conversationId,
|
||||||
invocationId,
|
invocationId,
|
||||||
parentMessageId: null
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -85,24 +116,6 @@ export default function TextChat({ messages }) {
|
||||||
dispatch(setSubmitState(false));
|
dispatch(setSubmitState(false));
|
||||||
};
|
};
|
||||||
|
|
||||||
// const convoHandler = (data) => {
|
|
||||||
// const { conversationId, id, invocationId } = data;
|
|
||||||
// const conversationData = {
|
|
||||||
// title: data.title,
|
|
||||||
// conversationId,
|
|
||||||
// parentMessageId:
|
|
||||||
// model !== 'bingai' && !convo.conversationId && !convo.parentMessageId ? id : null,
|
|
||||||
// conversationSignature:
|
|
||||||
// model === 'bingai' && !convo.conversationId ? data.conversationSignature : null,
|
|
||||||
// clientId: model === 'bingai' && !convo.conversationId ? data.clientId : null,
|
|
||||||
// // invocationId: model === 'bingai' && !convo.conversationId ? data.invocationId : null
|
|
||||||
// invocationId: invocationId ? invocationId : null
|
|
||||||
// };
|
|
||||||
// dispatch(setMessages([...messages, currentMsg, { sender: model, text: data.text || data.response }]));
|
|
||||||
// dispatch(setConversation(conversationData));
|
|
||||||
// dispatch(setSubmitState(false));
|
|
||||||
// };
|
|
||||||
|
|
||||||
const errorHandler = (event) => {
|
const errorHandler = (event) => {
|
||||||
console.log('Error:', event);
|
console.log('Error:', event);
|
||||||
const errorResponse = {
|
const errorResponse = {
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,12 @@ export default function Message({
|
||||||
const bgColors = {
|
const bgColors = {
|
||||||
chatgpt: 'rgb(16, 163, 127)',
|
chatgpt: 'rgb(16, 163, 127)',
|
||||||
chatgptBrowser: 'rgb(25, 207, 207)',
|
chatgptBrowser: 'rgb(25, 207, 207)',
|
||||||
bingai: ''
|
bingai: '',
|
||||||
|
sydney: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isBing = sender === 'bingai' || sender === 'sydney';
|
||||||
|
|
||||||
let icon = `${sender}:`;
|
let icon = `${sender}:`;
|
||||||
let backgroundColor = bgColors[sender];
|
let backgroundColor = bgColors[sender];
|
||||||
|
|
||||||
|
|
@ -59,13 +62,13 @@ export default function Message({
|
||||||
'w-full border-b border-black/10 bg-gray-50 dark:border-gray-900/50 text-gray-800 dark:text-gray-100 group bg-gray-100 dark:bg-[#444654]';
|
'w-full border-b border-black/10 bg-gray-50 dark:border-gray-900/50 text-gray-800 dark:text-gray-100 group bg-gray-100 dark:bg-[#444654]';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((notUser && backgroundColor) || sender === 'bingai') {
|
if ((notUser && backgroundColor) || isBing) {
|
||||||
icon = (
|
icon = (
|
||||||
<div
|
<div
|
||||||
style={{ backgroundColor }}
|
style={isBing ? { background: 'radial-gradient(circle at 90% 110%, #F0F0FA, #D0E0F9)' } : { backgroundColor }}
|
||||||
className="relative flex h-[30px] w-[30px] items-center justify-center rounded-sm p-1 text-white"
|
className="relative flex h-[30px] w-[30px] items-center justify-center rounded-sm p-1 text-white"
|
||||||
>
|
>
|
||||||
{sender === 'bingai' ? <BingIcon /> : <GPTIcon />}
|
{isBing ? <BingIcon /> : <GPTIcon />}
|
||||||
{error && (
|
{error && (
|
||||||
<span className="absolute right-0 top-[20px] -mr-2 flex h-4 w-4 items-center justify-center rounded-full border border-white bg-red-500 text-[10px] text-white">
|
<span className="absolute right-0 top-[20px] -mr-2 flex h-4 w-4 items-center justify-center rounded-full border border-white bg-red-500 text-[10px] text-white">
|
||||||
!
|
!
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import React, { useState, useRef } from 'react';
|
||||||
import TextareaAutosize from 'react-textarea-autosize';
|
import TextareaAutosize from 'react-textarea-autosize';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import { setModel, setCustomGpt } from '~/store/submitSlice';
|
import { setModel, setCustomGpt } from '~/store/submitSlice';
|
||||||
|
import { setNewConvo } from '~/store/convoSlice';
|
||||||
import manualSWR from '~/utils/fetchers';
|
import manualSWR from '~/utils/fetchers';
|
||||||
import { Button } from '../ui/Button.tsx';
|
import { Button } from '../ui/Button.tsx';
|
||||||
import { Input } from '../ui/Input.tsx';
|
import { Input } from '../ui/Input.tsx';
|
||||||
|
|
@ -36,7 +37,8 @@ export default function ModelDialog({ mutate, setModelSave, handleSaveState }) {
|
||||||
dispatch(setCustomGpt({ chatGptLabel, promptPrefix }));
|
dispatch(setCustomGpt({ chatGptLabel, promptPrefix }));
|
||||||
dispatch(setModel('chatgptCustom'));
|
dispatch(setModel('chatgptCustom'));
|
||||||
handleSaveState(chatGptLabel.toLowerCase());
|
handleSaveState(chatGptLabel.toLowerCase());
|
||||||
// dispatch(setDisabled(false));
|
// Set new conversation
|
||||||
|
dispatch(setNewConvo());
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveHandler = (e) => {
|
const saveHandler = (e) => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import { setModel, setDisabled, setCustomGpt, setCustomModel } from '~/store/submitSlice';
|
import { setModel, setDisabled, setCustomGpt, setCustomModel } from '~/store/submitSlice';
|
||||||
import { setConversation } from '~/store/convoSlice';
|
import { setNewConvo } from '~/store/convoSlice';
|
||||||
import ModelDialog from './ModelDialog';
|
import ModelDialog from './ModelDialog';
|
||||||
import MenuItems from './MenuItems';
|
import MenuItems from './MenuItems';
|
||||||
import manualSWR from '~/utils/fetchers';
|
import manualSWR from '~/utils/fetchers';
|
||||||
|
|
@ -68,22 +68,15 @@ export default function ModelMenu() {
|
||||||
dispatch(setCustomGpt({ chatGptLabel, promptPrefix }));
|
dispatch(setCustomGpt({ chatGptLabel, promptPrefix }));
|
||||||
dispatch(setModel('chatgptCustom'));
|
dispatch(setModel('chatgptCustom'));
|
||||||
dispatch(setCustomModel(value));
|
dispatch(setCustomModel(value));
|
||||||
if (custom) {
|
// if (custom) {
|
||||||
setMenuOpen((prevOpen) => !prevOpen);
|
// setMenuOpen((prevOpen) => !prevOpen);
|
||||||
}
|
// }
|
||||||
} else if (!modelMap[value]) {
|
} else if (!modelMap[value]) {
|
||||||
dispatch(setCustomModel(null));
|
dispatch(setCustomModel(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set new conversation
|
// Set new conversation
|
||||||
dispatch(
|
dispatch(setNewConvo());
|
||||||
setConversation({
|
|
||||||
title: 'New Chat',
|
|
||||||
error: false,
|
|
||||||
conversationId: null,
|
|
||||||
parentMessageId: null
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onOpenChange = (open) => {
|
const onOpenChange = (open) => {
|
||||||
|
|
@ -126,8 +119,9 @@ export default function ModelMenu() {
|
||||||
'dark:disabled:hover:bg-transparent'
|
'dark:disabled:hover:bg-transparent'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const isBing = model === 'bingai' || model === 'sydney';
|
||||||
const colorProps = model === 'chatgpt' ? chatgptColorProps : defaultColorProps;
|
const colorProps = model === 'chatgpt' ? chatgptColorProps : defaultColorProps;
|
||||||
const icon = model === 'bingai' ? <BingIcon button={true} /> : <GPTIcon button={true} />;
|
const icon = isBing ? <BingIcon button={true} /> : <GPTIcon button={true} />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog onOpenChange={onOpenChange}>
|
<Dialog onOpenChange={onOpenChange}>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import TrashIcon from '../svg/TrashIcon';
|
||||||
import { useSWRConfig } from 'swr';
|
import { useSWRConfig } from 'swr';
|
||||||
import manualSWR from '~/utils/fetchers';
|
import manualSWR from '~/utils/fetchers';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { setConversation, removeAll } from '~/store/convoSlice';
|
import { setNewConvo, removeAll } from '~/store/convoSlice';
|
||||||
import { setMessages } from '~/store/messageSlice';
|
import { setMessages } from '~/store/messageSlice';
|
||||||
|
|
||||||
export default function ClearConvos() {
|
export default function ClearConvos() {
|
||||||
|
|
@ -12,14 +12,7 @@ export default function ClearConvos() {
|
||||||
|
|
||||||
const { trigger } = manualSWR(`http://localhost:3080/api/convos/clear`, 'post', () => {
|
const { trigger } = manualSWR(`http://localhost:3080/api/convos/clear`, 'post', () => {
|
||||||
dispatch(setMessages([]));
|
dispatch(setMessages([]));
|
||||||
dispatch(
|
dispatch(setNewConvo());
|
||||||
setConversation({
|
|
||||||
error: false,
|
|
||||||
title: 'New chat',
|
|
||||||
conversationId: null,
|
|
||||||
parentMessageId: null
|
|
||||||
})
|
|
||||||
);
|
|
||||||
mutate(`http://localhost:3080/api/convos`);
|
mutate(`http://localhost:3080/api/convos`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { setConversation } from '~/store/convoSlice';
|
import { setNewConvo } from '~/store/convoSlice';
|
||||||
import { setMessages } from '~/store/messageSlice';
|
import { setMessages } from '~/store/messageSlice';
|
||||||
import { setText } from '~/store/textSlice';
|
import { setText } from '~/store/textSlice';
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@ export default function NewChat() {
|
||||||
const clickHandler = () => {
|
const clickHandler = () => {
|
||||||
dispatch(setText(''));
|
dispatch(setText(''));
|
||||||
dispatch(setMessages([]));
|
dispatch(setMessages([]));
|
||||||
dispatch(setConversation({ title: 'New Chat', error: false, conversationId: null, parentMessageId: null }));
|
dispatch(setNewConvo());
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ const initialState = {
|
||||||
title: 'ChatGPT Clone',
|
title: 'ChatGPT Clone',
|
||||||
conversationId: null,
|
conversationId: null,
|
||||||
parentMessageId: null,
|
parentMessageId: null,
|
||||||
|
jailbreakConversationId: null,
|
||||||
conversationSignature: null,
|
conversationSignature: null,
|
||||||
clientId: null,
|
clientId: null,
|
||||||
invocationId: null,
|
invocationId: null,
|
||||||
|
|
@ -28,6 +29,20 @@ const currentSlice = createSlice({
|
||||||
incrementPage: (state) => {
|
incrementPage: (state) => {
|
||||||
state.pageNumber = state.pageNumber + 1;
|
state.pageNumber = state.pageNumber + 1;
|
||||||
},
|
},
|
||||||
|
setNewConvo: (state) => {
|
||||||
|
state.error = false;
|
||||||
|
state.title = 'New Chat';
|
||||||
|
state.conversationId = null;
|
||||||
|
state.parentMessageId = null;
|
||||||
|
state.jailbreakConversationId = null;
|
||||||
|
state.conversationSignature = null;
|
||||||
|
state.clientId = null;
|
||||||
|
state.invocationId = null;
|
||||||
|
state.chatGptLabel = null;
|
||||||
|
state.promptPrefix = null;
|
||||||
|
state.convosLoading = false;
|
||||||
|
state.pageNumber = 1;
|
||||||
|
},
|
||||||
setConvos: (state, action) => {
|
setConvos: (state, action) => {
|
||||||
const newConvos = action.payload.filter((convo) => {
|
const newConvos = action.payload.filter((convo) => {
|
||||||
return !state.convos.some((c) => c.conversationId === convo.conversationId);
|
return !state.convos.some((c) => c.conversationId === convo.conversationId);
|
||||||
|
|
@ -45,7 +60,7 @@ const currentSlice = createSlice({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { setConversation, setConvos, setError, incrementPage, removeConvo, removeAll } =
|
export const { setConversation, setConvos, setNewConvo, setError, incrementPage, removeConvo, removeAll } =
|
||||||
currentSlice.actions;
|
currentSlice.actions;
|
||||||
|
|
||||||
export default currentSlice.reducer;
|
export default currentSlice.reducer;
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,21 @@ const initialState = {
|
||||||
_id: '2',
|
_id: '2',
|
||||||
name: 'BingAI',
|
name: 'BingAI',
|
||||||
value: 'bingai'
|
value: 'bingai'
|
||||||
}
|
},
|
||||||
// {
|
{
|
||||||
// _id: '3',
|
_id: '3',
|
||||||
// name: 'ChatGPT',
|
name: 'Sydney',
|
||||||
// value: 'chatgptBrowser'
|
value: 'sydney'
|
||||||
// }
|
},
|
||||||
|
{
|
||||||
|
_id: '4',
|
||||||
|
name: 'ChatGPT',
|
||||||
|
value: 'chatgptBrowser'
|
||||||
|
},
|
||||||
],
|
],
|
||||||
modelMap: {},
|
modelMap: {},
|
||||||
// initial: { chatgpt: true, chatgptCustom: true, bingai: true, chatgptBrowser: true }
|
initial: { chatgpt: true, chatgptCustom: true, bingai: true, sydney: true, chatgptBrowser: true }
|
||||||
initial: { chatgpt: true, chatgptCustom: true, bingai: true, }
|
// initial: { chatgpt: true, chatgptCustom: true, bingai: true, }
|
||||||
};
|
};
|
||||||
|
|
||||||
const currentSlice = createSlice({
|
const currentSlice = createSlice({
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,32 @@
|
||||||
outline: 1px solid limegreen !important;
|
outline: 1px solid limegreen !important;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
|
/* p small {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fadeIn 3s ease forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
p > small {
|
||||||
|
opacity: 0;
|
||||||
|
animation: fadein 3s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadein {
|
||||||
|
from { opacity: 0; transform: translateY(-20px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre {
|
blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,12 @@ export default function handleSubmit({
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model === 'bingai' && convo.conversationId) {
|
const isBing = model === 'bingai' || model === 'sydney';
|
||||||
|
if (isBing && convo.conversationId) {
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
...payload,
|
...payload,
|
||||||
|
jailbreakConversationId: convo.jailbreakConversationId,
|
||||||
conversationId: convo.conversationId,
|
conversationId: convo.conversationId,
|
||||||
conversationSignature: convo.conversationSignature,
|
conversationSignature: convo.conversationSignature,
|
||||||
clientId: convo.clientId,
|
clientId: convo.clientId,
|
||||||
|
|
@ -31,7 +34,10 @@ export default function handleSubmit({
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const server = model === 'bingai' ? endpoint + '/bing' : endpoint;
|
let server = endpoint;
|
||||||
|
server = model === 'bingai' ? server + '/bing' : server;
|
||||||
|
server = model === 'sydney' ? server + '/sydney' : server;
|
||||||
|
|
||||||
const events = new SSE(server, {
|
const events = new SSE(server, {
|
||||||
payload: JSON.stringify(payload),
|
payload: JSON.stringify(payload),
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' }
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ module.exports = {
|
||||||
* to use its built-in optimizations accordingly. default is production
|
* to use its built-in optimizations accordingly. default is production
|
||||||
*/
|
*/
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
|
// cache: false,
|
||||||
/** "entry"
|
/** "entry"
|
||||||
* the entry point
|
* the entry point
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue