mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
feat: gen title by sperate api call
feat: fix: rename of convo should based on real request.
This commit is contained in:
parent
8773878be2
commit
9f8e9cb091
8 changed files with 65 additions and 28 deletions
|
|
@ -10,7 +10,7 @@ const {
|
||||||
customClient,
|
customClient,
|
||||||
detectCode
|
detectCode
|
||||||
} = require('../../app/');
|
} = require('../../app/');
|
||||||
const { getConvo, saveMessage, deleteMessagesSince, deleteMessages, saveConvo } = require('../../models');
|
const { getConvo, saveMessage, getConvoTitle, saveConvo } = require('../../models');
|
||||||
const { handleError, sendMessage } = require('./handlers');
|
const { handleError, sendMessage } = require('./handlers');
|
||||||
|
|
||||||
router.use('/bing', askBing);
|
router.use('/bing', askBing);
|
||||||
|
|
@ -156,6 +156,7 @@ router.post('/', async (req, res) => {
|
||||||
await saveMessage(gptResponse);
|
await saveMessage(gptResponse);
|
||||||
await saveConvo(gptResponse);
|
await saveConvo(gptResponse);
|
||||||
sendMessage(res, {
|
sendMessage(res, {
|
||||||
|
title: await getConvoTitle(conversationId),
|
||||||
final: true,
|
final: true,
|
||||||
requestMessage: userMessage,
|
requestMessage: userMessage,
|
||||||
responseMessage: gptResponse
|
responseMessage: gptResponse
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ const express = require('express');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const { titleConvo, getCitations, citeText, askBing } = require('../../app/');
|
const { titleConvo, getCitations, citeText, askBing } = require('../../app/');
|
||||||
const { saveMessage, deleteMessages, deleteMessagesSince, saveConvo } = require('../../models');
|
const { saveMessage, getConvoTitle, saveConvo } = require('../../models');
|
||||||
const { handleError, sendMessage } = require('./handlers');
|
const { handleError, sendMessage } = require('./handlers');
|
||||||
const citationRegex = /\[\^\d+?\^]/g;
|
const citationRegex = /\[\^\d+?\^]/g;
|
||||||
|
|
||||||
|
|
@ -11,7 +11,7 @@ router.post('/', async (req, res) => {
|
||||||
if (text.length === 0) {
|
if (text.length === 0) {
|
||||||
return handleError(res, 'Prompt empty or too short');
|
return handleError(res, 'Prompt empty or too short');
|
||||||
}
|
}
|
||||||
|
|
||||||
const conversationId = oldConversationId || crypto.randomUUID();
|
const conversationId = oldConversationId || crypto.randomUUID();
|
||||||
|
|
||||||
const userMessageId = messageId;
|
const userMessageId = messageId;
|
||||||
|
|
@ -98,6 +98,7 @@ router.post('/', async (req, res) => {
|
||||||
await saveMessage(response);
|
await saveMessage(response);
|
||||||
await saveConvo(response);
|
await saveConvo(response);
|
||||||
sendMessage(res, {
|
sendMessage(res, {
|
||||||
|
title: await getConvoTitle(conversationId),
|
||||||
final: true,
|
final: true,
|
||||||
requestMessage: userMessage,
|
requestMessage: userMessage,
|
||||||
responseMessage: gptResponse
|
responseMessage: gptResponse
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ const express = require('express');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const { titleConvo, getCitations, citeText, askSydney } = require('../../app/');
|
const { titleConvo, getCitations, citeText, askSydney } = require('../../app/');
|
||||||
const { saveMessage, deleteMessages, saveConvo, deleteMessagesSince, getConvoTitle } = require('../../models');
|
const { saveMessage, saveConvo, getConvoTitle } = require('../../models');
|
||||||
const { handleError, sendMessage } = require('./handlers');
|
const { handleError, sendMessage } = require('./handlers');
|
||||||
const citationRegex = /\[\^\d+?\^]/g;
|
const citationRegex = /\[\^\d+?\^]/g;
|
||||||
|
|
||||||
|
|
@ -11,7 +11,7 @@ router.post('/', async (req, res) => {
|
||||||
if (text.length === 0) {
|
if (text.length === 0) {
|
||||||
return handleError(res, 'Prompt empty or too short');
|
return handleError(res, 'Prompt empty or too short');
|
||||||
}
|
}
|
||||||
|
|
||||||
const conversationId = oldConversationId || crypto.randomUUID();
|
const conversationId = oldConversationId || crypto.randomUUID();
|
||||||
|
|
||||||
const userMessageId = messageId;
|
const userMessageId = messageId;
|
||||||
|
|
@ -108,6 +108,7 @@ router.post('/', async (req, res) => {
|
||||||
await saveMessage(response);
|
await saveMessage(response);
|
||||||
await saveConvo(response);
|
await saveConvo(response);
|
||||||
sendMessage(res, {
|
sendMessage(res, {
|
||||||
|
title: await getConvoTitle(conversationId),
|
||||||
final: true,
|
final: true,
|
||||||
requestMessage: userMessage,
|
requestMessage: userMessage,
|
||||||
responseMessage: gptResponse
|
responseMessage: gptResponse
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,38 @@
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
const { titleConvo } = require('../../app/');
|
||||||
|
const { getConvo, saveConvo, getConvoTitle } = require('../../models');
|
||||||
const { getConvos, deleteConvos, updateConvo } = require('../../models/Conversation');
|
const { getConvos, deleteConvos, updateConvo } = require('../../models/Conversation');
|
||||||
|
const { getMessages } = require('../../models/Message');
|
||||||
|
|
||||||
router.get('/', async (req, res) => {
|
router.get('/', async (req, res) => {
|
||||||
const pageNumber = req.query.pageNumber || 1;
|
const pageNumber = req.query.pageNumber || 1;
|
||||||
res.status(200).send(await getConvos(pageNumber));
|
res.status(200).send(await getConvos(pageNumber));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.post('/gen_title', async (req, res) => {
|
||||||
|
const { conversationId } = req.body.arg;
|
||||||
|
|
||||||
|
const convo = await getConvo(conversationId)
|
||||||
|
const firstMessage = (await getMessages({ conversationId }))[0]
|
||||||
|
const secondMessage = (await getMessages({ conversationId }))[1]
|
||||||
|
|
||||||
|
const title = convo.jailbreakConversationId
|
||||||
|
? await getConvoTitle(conversationId)
|
||||||
|
: await titleConvo({
|
||||||
|
model: convo?.model,
|
||||||
|
message: firstMessage?.text,
|
||||||
|
response: JSON.stringify(secondMessage?.text || '')
|
||||||
|
});
|
||||||
|
|
||||||
|
await saveConvo({
|
||||||
|
conversationId,
|
||||||
|
title
|
||||||
|
})
|
||||||
|
|
||||||
|
res.status(200).send(title);
|
||||||
|
});
|
||||||
|
|
||||||
router.post('/clear', async (req, res) => {
|
router.post('/clear', async (req, res) => {
|
||||||
let filter = {};
|
let filter = {};
|
||||||
const { conversationId } = req.body.arg;
|
const { conversationId } = req.body.arg;
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,14 @@ import { setMessages, setEmptyMessage } from '~/store/messageSlice';
|
||||||
import { setText } from '~/store/textSlice';
|
import { setText } from '~/store/textSlice';
|
||||||
import manualSWR from '~/utils/fetchers';
|
import manualSWR from '~/utils/fetchers';
|
||||||
import ConvoIcon from '../svg/ConvoIcon';
|
import ConvoIcon from '../svg/ConvoIcon';
|
||||||
|
import { refreshConversation } from '../../store/convoSlice';
|
||||||
|
|
||||||
export default function Conversation({
|
export default function Conversation({
|
||||||
id,
|
id,
|
||||||
model,
|
model,
|
||||||
parentMessageId,
|
parentMessageId,
|
||||||
conversationId,
|
conversationId,
|
||||||
title = 'New conversation',
|
title,
|
||||||
chatGptLabel = null,
|
chatGptLabel = null,
|
||||||
promptPrefix = null,
|
promptPrefix = null,
|
||||||
bingData,
|
bingData,
|
||||||
|
|
@ -95,6 +96,7 @@ export default function Conversation({
|
||||||
|
|
||||||
const renameHandler = (e) => {
|
const renameHandler = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
setTitleInput(title);
|
||||||
setRenaming(true);
|
setRenaming(true);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
inputRef.current.focus();
|
inputRef.current.focus();
|
||||||
|
|
@ -112,7 +114,10 @@ export default function Conversation({
|
||||||
if (titleInput === title) {
|
if (titleInput === title) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rename.trigger({ conversationId, title: titleInput });
|
rename.trigger({ conversationId, title: titleInput })
|
||||||
|
.then(() => {
|
||||||
|
dispatch(refreshConversation())
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleKeyDown = (e) => {
|
const handleKeyDown = (e) => {
|
||||||
|
|
@ -149,7 +154,7 @@ export default function Conversation({
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
titleInput
|
title
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{conversationId === id ? (
|
{conversationId === id ? (
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { SSE } from '~/utils/sse';
|
import { SSE } from '~/utils/sse';
|
||||||
|
import axios from 'axios';
|
||||||
import SubmitButton from './SubmitButton';
|
import SubmitButton from './SubmitButton';
|
||||||
import Regenerate from './Regenerate';
|
import Regenerate from './Regenerate';
|
||||||
import ModelMenu from '../Models/ModelMenu';
|
import ModelMenu from '../Models/ModelMenu';
|
||||||
|
|
@ -7,10 +8,11 @@ import Footer from './Footer';
|
||||||
import TextareaAutosize from 'react-textarea-autosize';
|
import TextareaAutosize from 'react-textarea-autosize';
|
||||||
import handleSubmit from '~/utils/handleSubmit';
|
import handleSubmit from '~/utils/handleSubmit';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import { setConversation, setError } from '~/store/convoSlice';
|
import { setConversation, setError, refreshConversation } from '~/store/convoSlice';
|
||||||
import { setMessages } from '~/store/messageSlice';
|
import { setMessages } from '~/store/messageSlice';
|
||||||
import { setSubmitState, setSubmission } from '~/store/submitSlice';
|
import { setSubmitState, setSubmission } from '~/store/submitSlice';
|
||||||
import { setText } from '~/store/textSlice';
|
import { setText } from '~/store/textSlice';
|
||||||
|
import manualSWR from '~/utils/fetchers';
|
||||||
|
|
||||||
export default function TextChat({ messages }) {
|
export default function TextChat({ messages }) {
|
||||||
const [errorMessage, setErrorMessage] = useState('');
|
const [errorMessage, setErrorMessage] = useState('');
|
||||||
|
|
@ -22,6 +24,7 @@ export default function TextChat({ messages }) {
|
||||||
useSelector((state) => state.submit);
|
useSelector((state) => state.submit);
|
||||||
const { text } = useSelector((state) => state.text);
|
const { text } = useSelector((state) => state.text);
|
||||||
const { error } = convo;
|
const { error } = convo;
|
||||||
|
const genTitle = manualSWR(`/api/convos/gen_title`, 'post');
|
||||||
|
|
||||||
// auto focus to input, when enter a conversation.
|
// auto focus to input, when enter a conversation.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -45,26 +48,24 @@ export default function TextChat({ messages }) {
|
||||||
|
|
||||||
const convoHandler = (data, currentState, currentMsg) => {
|
const convoHandler = (data, currentState, currentMsg) => {
|
||||||
const { requestMessage, responseMessage } = data;
|
const { requestMessage, responseMessage } = data;
|
||||||
|
const { conversationId } = currentMsg;
|
||||||
const { messages, _currentMsg, message, isCustomModel, sender } =
|
const { messages, _currentMsg, message, isCustomModel, sender } =
|
||||||
currentState;
|
currentState;
|
||||||
const { model, chatGptLabel, promptPrefix } = message;
|
const { model, chatGptLabel, promptPrefix } = message;
|
||||||
dispatch(
|
dispatch(
|
||||||
setMessages([...messages,
|
setMessages([...messages, requestMessage, responseMessage,])
|
||||||
{
|
|
||||||
...requestMessage,
|
|
||||||
// messageId: data?.parentMessageId,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
...responseMessage,
|
|
||||||
// sender,
|
|
||||||
// text: data.text || data.response,
|
|
||||||
}
|
|
||||||
])
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const isBing = model === 'bingai' || model === 'sydney';
|
const isBing = model === 'bingai' || model === 'sydney';
|
||||||
|
|
||||||
// if (!message.messageId)
|
if (requestMessage.parentMessageId == '00000000-0000-0000-0000-000000000000') {
|
||||||
|
genTitle.trigger({ conversationId }).then((ret) => {
|
||||||
|
const title = ret?.data
|
||||||
|
|
||||||
|
if (title)
|
||||||
|
dispatch(refreshConversation());
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (!isBing && convo.conversationId === null && convo.parentMessageId === null) {
|
if (!isBing && convo.conversationId === null && convo.parentMessageId === null) {
|
||||||
const { title } = data;
|
const { title } = data;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import { incrementPage, setConvos } from '~/store/convoSlice';
|
||||||
export default function Nav({ navVisible, setNavVisible }) {
|
export default function Nav({ navVisible, setNavVisible }) {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [isHovering, setIsHovering] = useState(false);
|
const [isHovering, setIsHovering] = useState(false);
|
||||||
const { conversationId, convos, pageNumber } = useSelector((state) => state.convo);
|
const { conversationId, convos, pageNumber, refreshConvoHint } = useSelector((state) => state.convo);
|
||||||
const onSuccess = (data) => {
|
const onSuccess = (data) => {
|
||||||
dispatch(setConvos(data));
|
dispatch(setConvos(data));
|
||||||
};
|
};
|
||||||
|
|
@ -20,6 +20,7 @@ export default function Nav({ navVisible, setNavVisible }) {
|
||||||
`/api/convos?pageNumber=${pageNumber}`,
|
`/api/convos?pageNumber=${pageNumber}`,
|
||||||
onSuccess
|
onSuccess
|
||||||
);
|
);
|
||||||
|
|
||||||
const containerRef = useRef(null);
|
const containerRef = useRef(null);
|
||||||
const scrollPositionRef = useRef(null);
|
const scrollPositionRef = useRef(null);
|
||||||
|
|
||||||
|
|
@ -35,7 +36,7 @@ export default function Nav({ navVisible, setNavVisible }) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useDidMountEffect(() => mutate(), [conversationId]);
|
useDidMountEffect(() => mutate(), [conversationId, refreshConvoHint]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const container = containerRef.current;
|
const container = containerRef.current;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ const initialState = {
|
||||||
promptPrefix: null,
|
promptPrefix: null,
|
||||||
convosLoading: false,
|
convosLoading: false,
|
||||||
pageNumber: 1,
|
pageNumber: 1,
|
||||||
|
refreshConvoHint: 0,
|
||||||
convos: []
|
convos: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -20,6 +21,9 @@ const currentSlice = createSlice({
|
||||||
name: 'convo',
|
name: 'convo',
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
|
refreshConversation: (state, action) => {
|
||||||
|
state.refreshConvoHint = state.refreshConvoHint + 1;
|
||||||
|
},
|
||||||
setConversation: (state, action) => {
|
setConversation: (state, action) => {
|
||||||
return { ...state, ...action.payload };
|
return { ...state, ...action.payload };
|
||||||
},
|
},
|
||||||
|
|
@ -44,10 +48,7 @@ const currentSlice = createSlice({
|
||||||
state.pageNumber = 1;
|
state.pageNumber = 1;
|
||||||
},
|
},
|
||||||
setConvos: (state, action) => {
|
setConvos: (state, action) => {
|
||||||
const newConvos = action.payload.filter((convo) => {
|
state.convos = action.payload.sort(
|
||||||
return !state.convos.some((c) => c.conversationId === convo.conversationId);
|
|
||||||
});
|
|
||||||
state.convos = [...state.convos, ...newConvos].sort(
|
|
||||||
(a, b) => new Date(b.createdAt) - new Date(a.createdAt)
|
(a, b) => new Date(b.createdAt) - new Date(a.createdAt)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -60,7 +61,7 @@ const currentSlice = createSlice({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { setConversation, setConvos, setNewConvo, setError, incrementPage, removeConvo, removeAll } =
|
export const { refreshConversation, setConversation, setConvos, setNewConvo, setError, incrementPage, removeConvo, removeAll } =
|
||||||
currentSlice.actions;
|
currentSlice.actions;
|
||||||
|
|
||||||
export default currentSlice.reducer;
|
export default currentSlice.reducer;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue