mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-11-15 10:50:31 +01:00
26c220503c
* WIP edit message feature * WIP edit message * WIP editing messages feature * Fix PFPs TODO: Fix default user profile image Add User and Assistant workspace response * unset PFP changes for later PR --------- Co-authored-by: timothycarambat <rambat1010@gmail.com>
214 lines
5.8 KiB
JavaScript
214 lines
5.8 KiB
JavaScript
import { ABORT_STREAM_EVENT } from "@/utils/chat";
|
|
import { API_BASE } from "@/utils/constants";
|
|
import { baseHeaders } from "@/utils/request";
|
|
import { fetchEventSource } from "@microsoft/fetch-event-source";
|
|
import { v4 } from "uuid";
|
|
|
|
const WorkspaceThread = {
|
|
all: async function (workspaceSlug) {
|
|
const { threads } = await fetch(
|
|
`${API_BASE}/workspace/${workspaceSlug}/threads`,
|
|
{
|
|
method: "GET",
|
|
headers: baseHeaders(),
|
|
}
|
|
)
|
|
.then((res) => res.json())
|
|
.catch((e) => {
|
|
return { threads: [] };
|
|
});
|
|
|
|
return { threads };
|
|
},
|
|
new: async function (workspaceSlug) {
|
|
const { thread, error } = await fetch(
|
|
`${API_BASE}/workspace/${workspaceSlug}/thread/new`,
|
|
{
|
|
method: "POST",
|
|
headers: baseHeaders(),
|
|
}
|
|
)
|
|
.then((res) => res.json())
|
|
.catch((e) => {
|
|
return { thread: null, error: e.message };
|
|
});
|
|
|
|
return { thread, error };
|
|
},
|
|
update: async function (workspaceSlug, threadSlug, data = {}) {
|
|
const { thread, message } = await fetch(
|
|
`${API_BASE}/workspace/${workspaceSlug}/thread/${threadSlug}/update`,
|
|
{
|
|
method: "POST",
|
|
body: JSON.stringify(data),
|
|
headers: baseHeaders(),
|
|
}
|
|
)
|
|
.then((res) => res.json())
|
|
.catch((e) => {
|
|
return { thread: null, message: e.message };
|
|
});
|
|
|
|
return { thread, message };
|
|
},
|
|
delete: async function (workspaceSlug, threadSlug) {
|
|
return await fetch(
|
|
`${API_BASE}/workspace/${workspaceSlug}/thread/${threadSlug}`,
|
|
{
|
|
method: "DELETE",
|
|
headers: baseHeaders(),
|
|
}
|
|
)
|
|
.then((res) => res.ok)
|
|
.catch(() => false);
|
|
},
|
|
deleteBulk: async function (workspaceSlug, threadSlugs = []) {
|
|
return await fetch(
|
|
`${API_BASE}/workspace/${workspaceSlug}/thread-bulk-delete`,
|
|
{
|
|
method: "DELETE",
|
|
body: JSON.stringify({ slugs: threadSlugs }),
|
|
headers: baseHeaders(),
|
|
}
|
|
)
|
|
.then((res) => res.ok)
|
|
.catch(() => false);
|
|
},
|
|
chatHistory: async function (workspaceSlug, threadSlug) {
|
|
const history = await fetch(
|
|
`${API_BASE}/workspace/${workspaceSlug}/thread/${threadSlug}/chats`,
|
|
{
|
|
method: "GET",
|
|
headers: baseHeaders(),
|
|
}
|
|
)
|
|
.then((res) => res.json())
|
|
.then((res) => res.history || [])
|
|
.catch(() => []);
|
|
return history;
|
|
},
|
|
streamChat: async function (
|
|
{ workspaceSlug, threadSlug },
|
|
message,
|
|
handleChat
|
|
) {
|
|
const ctrl = new AbortController();
|
|
|
|
// Listen for the ABORT_STREAM_EVENT key to be emitted by the client
|
|
// to early abort the streaming response. On abort we send a special `stopGeneration`
|
|
// event to be handled which resets the UI for us to be able to send another message.
|
|
// The backend response abort handling is done in each LLM's handleStreamResponse.
|
|
window.addEventListener(ABORT_STREAM_EVENT, () => {
|
|
ctrl.abort();
|
|
handleChat({ id: v4(), type: "stopGeneration" });
|
|
});
|
|
|
|
await fetchEventSource(
|
|
`${API_BASE}/workspace/${workspaceSlug}/thread/${threadSlug}/stream-chat`,
|
|
{
|
|
method: "POST",
|
|
body: JSON.stringify({ message }),
|
|
headers: baseHeaders(),
|
|
signal: ctrl.signal,
|
|
openWhenHidden: true,
|
|
async onopen(response) {
|
|
if (response.ok) {
|
|
return; // everything's good
|
|
} else if (
|
|
response.status >= 400 &&
|
|
response.status < 500 &&
|
|
response.status !== 429
|
|
) {
|
|
handleChat({
|
|
id: v4(),
|
|
type: "abort",
|
|
textResponse: null,
|
|
sources: [],
|
|
close: true,
|
|
error: `An error occurred while streaming response. Code ${response.status}`,
|
|
});
|
|
ctrl.abort();
|
|
throw new Error("Invalid Status code response.");
|
|
} else {
|
|
handleChat({
|
|
id: v4(),
|
|
type: "abort",
|
|
textResponse: null,
|
|
sources: [],
|
|
close: true,
|
|
error: `An error occurred while streaming response. Unknown Error.`,
|
|
});
|
|
ctrl.abort();
|
|
throw new Error("Unknown error");
|
|
}
|
|
},
|
|
async onmessage(msg) {
|
|
try {
|
|
const chatResult = JSON.parse(msg.data);
|
|
handleChat(chatResult);
|
|
} catch {}
|
|
},
|
|
onerror(err) {
|
|
handleChat({
|
|
id: v4(),
|
|
type: "abort",
|
|
textResponse: null,
|
|
sources: [],
|
|
close: true,
|
|
error: `An error occurred while streaming response. ${err.message}`,
|
|
});
|
|
ctrl.abort();
|
|
throw new Error();
|
|
},
|
|
}
|
|
);
|
|
},
|
|
_deleteEditedChats: async function (
|
|
workspaceSlug = "",
|
|
threadSlug = "",
|
|
startingId
|
|
) {
|
|
return await fetch(
|
|
`${API_BASE}/workspace/${workspaceSlug}/thread/${threadSlug}/delete-edited-chats`,
|
|
{
|
|
method: "DELETE",
|
|
headers: baseHeaders(),
|
|
body: JSON.stringify({ startingId }),
|
|
}
|
|
)
|
|
.then((res) => {
|
|
if (res.ok) return true;
|
|
throw new Error("Failed to delete chats.");
|
|
})
|
|
.catch((e) => {
|
|
console.log(e);
|
|
return false;
|
|
});
|
|
},
|
|
_updateChatResponse: async function (
|
|
workspaceSlug = "",
|
|
threadSlug = "",
|
|
chatId,
|
|
newText
|
|
) {
|
|
return await fetch(
|
|
`${API_BASE}/workspace/${workspaceSlug}/thread/${threadSlug}/update-chat`,
|
|
{
|
|
method: "POST",
|
|
headers: baseHeaders(),
|
|
body: JSON.stringify({ chatId, newText }),
|
|
}
|
|
)
|
|
.then((res) => {
|
|
if (res.ok) return true;
|
|
throw new Error("Failed to update chat.");
|
|
})
|
|
.catch((e) => {
|
|
console.log(e);
|
|
return false;
|
|
});
|
|
},
|
|
};
|
|
|
|
export default WorkspaceThread;
|