mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-10-04 01:40:12 +02:00
-added switch between streaming response and not, to stop streaming while using dynamic input, as it require the full response to allow json schema extraction
- fixed auto page refresh after chat reset (quick line) - added temporary isDynamicInput as static variable for development, later to be added as dynamic setting to workspace settings menue
This commit is contained in:
parent
4817424c1a
commit
5088d8471a
@ -56,6 +56,7 @@ export function SlashCommands({ showing, setShowing, sendCommand }) {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setShowing(false);
|
setShowing(false);
|
||||||
sendCommand("/reset", true);
|
sendCommand("/reset", true);
|
||||||
|
window.location.reload();
|
||||||
}}
|
}}
|
||||||
className="w-full hover:cursor-pointer hover:bg-zinc-700 px-2 py-2 rounded-xl flex flex-col justify-start"
|
className="w-full hover:cursor-pointer hover:bg-zinc-700 px-2 py-2 rounded-xl flex flex-col justify-start"
|
||||||
>
|
>
|
||||||
|
@ -6,12 +6,18 @@ import handleChat from "@/utils/chat";
|
|||||||
import { isMobile } from "react-device-detect";
|
import { isMobile } from "react-device-detect";
|
||||||
import { SidebarMobileHeader } from "../../Sidebar";
|
import { SidebarMobileHeader } from "../../Sidebar";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
import { extractMetaData } from "@/utils/chat/extractMetaData";
|
||||||
|
|
||||||
export default function ChatContainer({ workspace, knownHistory = [] }) {
|
|
||||||
|
|
||||||
|
export default function ChatContainer({ workspace, knownHistory = [], isDynamicInput}) {
|
||||||
const { threadSlug = null } = useParams();
|
const { threadSlug = null } = useParams();
|
||||||
const [message, setMessage] = useState("");
|
const [message, setMessage] = useState("");
|
||||||
const [loadingResponse, setLoadingResponse] = useState(false);
|
const [loadingResponse, setLoadingResponse] = useState(false);
|
||||||
const [chatHistory, setChatHistory] = useState(knownHistory);
|
const [chatHistory, setChatHistory] = useState(knownHistory);
|
||||||
|
const [finalizedChatHistory, setFinalizedChatHistory] =
|
||||||
|
useState(knownHistory);
|
||||||
|
const [currentInputMeta, setCurrentInputMeta] = useState(null);
|
||||||
const handleMessageChange = (event) => {
|
const handleMessageChange = (event) => {
|
||||||
setMessage(event.target.value);
|
setMessage(event.target.value);
|
||||||
};
|
};
|
||||||
@ -33,6 +39,7 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
setChatHistory(prevChatHistory);
|
setChatHistory(prevChatHistory);
|
||||||
|
setFinalizedChatHistory(prevChatHistory);
|
||||||
setMessage("");
|
setMessage("");
|
||||||
setLoadingResponse(true);
|
setLoadingResponse(true);
|
||||||
};
|
};
|
||||||
@ -100,6 +107,17 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isDynamicInput) {
|
||||||
|
const { remainingText, metaData } = extractMetaData(
|
||||||
|
_chatHistory[_chatHistory.length - 1].content
|
||||||
|
);
|
||||||
|
_chatHistory[_chatHistory.length - 1].content = remainingText;
|
||||||
|
setFinalizedChatHistory(_chatHistory);
|
||||||
|
setCurrentInputMeta(metaData);
|
||||||
|
console.log("metaData", metaData);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
loadingResponse === true && fetchReply();
|
loadingResponse === true && fetchReply();
|
||||||
@ -113,7 +131,7 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
|
|||||||
{isMobile && <SidebarMobileHeader />}
|
{isMobile && <SidebarMobileHeader />}
|
||||||
<div className="flex flex-col h-full w-full md:mt-0 mt-[40px]">
|
<div className="flex flex-col h-full w-full md:mt-0 mt-[40px]">
|
||||||
<ChatHistory
|
<ChatHistory
|
||||||
history={chatHistory}
|
history={isDynamicInput ? finalizedChatHistory : chatHistory}
|
||||||
workspace={workspace}
|
workspace={workspace}
|
||||||
sendCommand={sendCommand}
|
sendCommand={sendCommand}
|
||||||
/>
|
/>
|
||||||
|
@ -12,6 +12,8 @@ export default function WorkspaceChat({ loading, workspace }) {
|
|||||||
const [history, setHistory] = useState([]);
|
const [history, setHistory] = useState([]);
|
||||||
const [loadingHistory, setLoadingHistory] = useState(true);
|
const [loadingHistory, setLoadingHistory] = useState(true);
|
||||||
|
|
||||||
|
const isDynamicInput = false;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getHistory() {
|
async function getHistory() {
|
||||||
if (loading) return;
|
if (loading) return;
|
||||||
@ -26,13 +28,17 @@ export default function WorkspaceChat({ loading, workspace }) {
|
|||||||
|
|
||||||
// TODO: add conditional if dynamic input is enabled in the workspace by default is false
|
// TODO: add conditional if dynamic input is enabled in the workspace by default is false
|
||||||
// Append metadata to the chat history
|
// Append metadata to the chat history
|
||||||
chatHistory = chatHistory.map((message) => {
|
if (isDynamicInput) {
|
||||||
if (message.role === "assistant") {
|
chatHistory = chatHistory.map((message) => {
|
||||||
const { remainingText, metaData } = extractMetaData(message.content);
|
if (message.role === "assistant") {
|
||||||
return { ...message, content: remainingText, metaData };
|
const { remainingText, metaData } = extractMetaData(
|
||||||
}
|
message.content
|
||||||
return message;
|
);
|
||||||
});
|
return { ...message, content: remainingText, metaData };
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setHistory(chatHistory);
|
setHistory(chatHistory);
|
||||||
setLoadingHistory(false);
|
setLoadingHistory(false);
|
||||||
@ -73,7 +79,7 @@ export default function WorkspaceChat({ loading, workspace }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setEventDelegatorForCodeSnippets();
|
setEventDelegatorForCodeSnippets();
|
||||||
return <ChatContainer workspace={workspace} knownHistory={history} />;
|
return <ChatContainer workspace={workspace} knownHistory={history} isDynamicInput={isDynamicInput} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enables us to safely markdown and sanitize all responses without risk of injection
|
// Enables us to safely markdown and sanitize all responses without risk of injection
|
||||||
|
@ -5,49 +5,52 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const extractMetaData = (textResponse) => {
|
export const extractMetaData = (textResponse) => {
|
||||||
let remainingText = textResponse;
|
console.log("textResponse", textResponse);
|
||||||
let inString = false;
|
let remainingText = textResponse;
|
||||||
let char, prevChar;
|
let inString = false;
|
||||||
let braceCount = 0;
|
let char, prevChar;
|
||||||
let bracketCount = 0;
|
let braceCount = 0;
|
||||||
let startIndex = null;
|
let bracketCount = 0;
|
||||||
let extractedObjects = {}; // Keep as an object as requested
|
let startIndex = null;
|
||||||
|
let extractedObjects = {}; // Keep as an object as requested
|
||||||
|
|
||||||
for (let i = 0; i < textResponse.length; i++) {
|
for (let i = 0; i < textResponse.length; i++) {
|
||||||
char = textResponse[i];
|
char = textResponse[i];
|
||||||
if (char === '"' && prevChar !== '\\') inString = !inString;
|
if (char === '"' && prevChar !== "\\") inString = !inString;
|
||||||
if (inString) continue;
|
if (inString) continue;
|
||||||
|
|
||||||
if (char === '{' || char === '[') {
|
if (char === "{" || char === "[") {
|
||||||
if (braceCount === 0 && bracketCount === 0) startIndex = i;
|
if (braceCount === 0 && bracketCount === 0) startIndex = i;
|
||||||
if (char === '{') braceCount++;
|
if (char === "{") braceCount++;
|
||||||
if (char === '[') bracketCount++;
|
if (char === "[") bracketCount++;
|
||||||
} else if (char === '}' || char === ']') {
|
} else if (char === "}" || char === "]") {
|
||||||
if (char === '}') braceCount--;
|
if (char === "}") braceCount--;
|
||||||
if (char === ']') bracketCount--;
|
if (char === "]") bracketCount--;
|
||||||
|
|
||||||
if (braceCount === 0 && bracketCount === 0 && startIndex !== null) {
|
if (braceCount === 0 && bracketCount === 0 && startIndex !== null) {
|
||||||
let json = textResponse.substring(startIndex, i + 1);
|
let json = textResponse.substring(startIndex, i + 1);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let parsedJson = JSON.parse(json);
|
let parsedJson = JSON.parse(json);
|
||||||
for (let key in parsedJson) {
|
console.log("Parsed JSON:", parsedJson);
|
||||||
if (parsedJson.hasOwnProperty(key)) {
|
for (let key in parsedJson) {
|
||||||
extractedObjects[key] = parsedJson[key];
|
if (parsedJson.hasOwnProperty(key)) {
|
||||||
}
|
extractedObjects[key] = parsedJson[key];
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error parsing JSON:", error, 'in JSON:', json);
|
|
||||||
}
|
|
||||||
startIndex = null;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error parsing JSON:", error, "in JSON:", json);
|
||||||
}
|
}
|
||||||
prevChar = char;
|
startIndex = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
prevChar = char;
|
||||||
|
}
|
||||||
|
|
||||||
// Remove any json objects from the text tat starts with ```json nad ends with ```
|
// Remove any json objects from the text tat starts with ```json nad ends with ```
|
||||||
const jsonRegex = /```json[\s\S]*?```/g;
|
const jsonRegex = /```json[\s\S]*?```/g;
|
||||||
remainingText = remainingText.replace(jsonRegex, '');
|
remainingText = remainingText.replace(jsonRegex, "");
|
||||||
|
console.log("remainingText", remainingText);
|
||||||
return { remainingText, metaData: extractedObjects };
|
console.log("extractedObjects", extractedObjects);
|
||||||
|
return { remainingText, metaData: extractedObjects };
|
||||||
}
|
}
|
@ -97,6 +97,7 @@ export default function handleChat(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
setChatHistory([..._chatHistory]);
|
setChatHistory([..._chatHistory]);
|
||||||
|
console.log("chunk: ", [..._chatHistory]);
|
||||||
} else if (type === "finalizeResponseStream") {
|
} else if (type === "finalizeResponseStream") {
|
||||||
const chatIdx = _chatHistory.findIndex((chat) => chat.uuid === uuid);
|
const chatIdx = _chatHistory.findIndex((chat) => chat.uuid === uuid);
|
||||||
if (chatIdx !== -1) {
|
if (chatIdx !== -1) {
|
||||||
@ -108,6 +109,7 @@ export default function handleChat(
|
|||||||
_chatHistory[chatIdx] = updatedHistory;
|
_chatHistory[chatIdx] = updatedHistory;
|
||||||
}
|
}
|
||||||
setChatHistory([..._chatHistory]);
|
setChatHistory([..._chatHistory]);
|
||||||
|
console.log("final: ", [..._chatHistory]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user