196 lines
6.4 KiB
JavaScript
196 lines
6.4 KiB
JavaScript
const { Workspace } = require("../../../models/workspace");
|
|
const { WorkspaceChats } = require("../../../models/workspaceChats");
|
|
const { WorkspaceThread } = require("../../../models/workspaceThread");
|
|
const { ApiChatHandler } = require("../../../utils/chats/apiChatHandler");
|
|
const { reqBody } = require("../../../utils/http");
|
|
const prisma = require("../../../utils/prisma");
|
|
const { getModelTag } = require("../../utils");
|
|
const { MobileDevice } = require("../../../models/mobileDevice");
|
|
|
|
/**
|
|
*
|
|
* @param {import("express").Request} request
|
|
* @param {import("express").Response} response
|
|
* @returns
|
|
*/
|
|
async function handleMobileCommand(request, response) {
|
|
const { command } = request.params;
|
|
const user = response.locals.user ?? null;
|
|
const body = reqBody(request);
|
|
|
|
if (command === "workspaces") {
|
|
const workspaces = user
|
|
? await Workspace.whereWithUser(user, {})
|
|
: await Workspace.where({});
|
|
for (const workspace of workspaces) {
|
|
const [threadCount, chatCount] = await Promise.all([
|
|
prisma.workspace_threads.count({
|
|
where: {
|
|
workspace_id: workspace.id,
|
|
...(user ? { user_id: user.id } : {}),
|
|
},
|
|
}),
|
|
prisma.workspace_chats.count({
|
|
where: {
|
|
workspaceId: workspace.id,
|
|
include: true,
|
|
...(user ? { user_id: user.id } : {}),
|
|
},
|
|
}),
|
|
]);
|
|
workspace.threadCount = threadCount;
|
|
workspace.chatCount = chatCount;
|
|
workspace.platform = MobileDevice.platform;
|
|
}
|
|
return response.status(200).json({ workspaces });
|
|
}
|
|
|
|
if (command === "workspace-content") {
|
|
const workspace = user
|
|
? await Workspace.getWithUser(user, { slug: String(body.workspaceSlug) })
|
|
: await Workspace.get({ slug: String(body.workspaceSlug) });
|
|
|
|
if (!workspace)
|
|
return response.status(400).json({ error: "Workspace not found" });
|
|
const threads = [
|
|
{
|
|
id: 0,
|
|
name: "Default Thread",
|
|
slug: "default-thread",
|
|
workspace_id: workspace.id,
|
|
createdAt: new Date(),
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
...(await prisma.workspace_threads.findMany({
|
|
where: {
|
|
workspace_id: workspace.id,
|
|
...(user ? { user_id: user.id } : {}),
|
|
},
|
|
})),
|
|
];
|
|
const chats = (
|
|
await prisma.workspace_chats.findMany({
|
|
where: {
|
|
workspaceId: workspace.id,
|
|
include: true,
|
|
...(user ? { user_id: user.id } : {}),
|
|
},
|
|
})
|
|
).map((chat) => ({
|
|
...chat,
|
|
// Create a dummy thread_id for the default thread so the chats can be mapped correctly.
|
|
...(chat.thread_id === null ? { thread_id: 0 } : {}),
|
|
createdAt: chat.createdAt.toISOString(),
|
|
lastUpdatedAt: chat.lastUpdatedAt.toISOString(),
|
|
}));
|
|
return response.status(200).json({ threads, chats });
|
|
}
|
|
|
|
// Get the model for this workspace (workspace -> system)
|
|
if (command === "model-tag") {
|
|
const { workspaceSlug } = body;
|
|
const workspace = user
|
|
? await Workspace.getWithUser(user, { slug: String(workspaceSlug) })
|
|
: await Workspace.get({ slug: String(workspaceSlug) });
|
|
|
|
if (!workspace)
|
|
return response.status(400).json({ error: "Workspace not found" });
|
|
if (workspace.chatModel)
|
|
return response.status(200).json({ model: workspace.chatModel });
|
|
else return response.status(200).json({ model: getModelTag() });
|
|
}
|
|
|
|
if (command === "reset-chat") {
|
|
const { workspaceSlug, threadSlug } = body;
|
|
const workspace = user
|
|
? await Workspace.getWithUser(user, { slug: String(workspaceSlug) })
|
|
: await Workspace.get({ slug: String(workspaceSlug) });
|
|
|
|
if (!workspace)
|
|
return response.status(400).json({ error: "Workspace not found" });
|
|
const threadId = threadSlug
|
|
? await prisma.workspace_threads.findFirst({
|
|
where: {
|
|
workspace_id: workspace.id,
|
|
slug: String(threadSlug),
|
|
...(user ? { user_id: user.id } : {}),
|
|
},
|
|
})?.id
|
|
: null;
|
|
|
|
await WorkspaceChats.markThreadHistoryInvalidV2({
|
|
workspaceId: workspace.id,
|
|
...(user ? { user_id: user.id } : {}),
|
|
thread_id: threadId, // if threadId is null, this will reset the default thread.
|
|
});
|
|
return response.status(200).json({ success: true });
|
|
}
|
|
|
|
if (command === "new-thread") {
|
|
const { workspaceSlug } = body;
|
|
const workspace = user
|
|
? await Workspace.getWithUser(user, { slug: String(workspaceSlug) })
|
|
: await Workspace.get({ slug: String(workspaceSlug) });
|
|
|
|
if (!workspace)
|
|
return response.status(400).json({ error: "Workspace not found" });
|
|
const { thread } = await WorkspaceThread.new(workspace, user?.id);
|
|
return response.status(200).json({ thread });
|
|
}
|
|
|
|
if (command === "stream-chat") {
|
|
const { workspaceSlug = null, threadSlug = null, message } = body;
|
|
if (!workspaceSlug)
|
|
return response.status(400).json({ error: "Workspace ID is required" });
|
|
else if (!message)
|
|
return response.status(400).json({ error: "Message is required" });
|
|
|
|
const workspace = user
|
|
? await Workspace.getWithUser(user, { slug: String(workspaceSlug) })
|
|
: await Workspace.get({ slug: String(workspaceSlug) });
|
|
|
|
if (!workspace)
|
|
return response.status(400).json({ error: "Workspace not found" });
|
|
const thread = threadSlug
|
|
? await prisma.workspace_threads.findFirst({
|
|
where: {
|
|
workspace_id: workspace.id,
|
|
slug: String(threadSlug),
|
|
...(user ? { user_id: user.id } : {}),
|
|
},
|
|
})
|
|
: null;
|
|
|
|
response.setHeader("Cache-Control", "no-cache");
|
|
response.setHeader("Content-Type", "text/event-stream");
|
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
response.setHeader("Connection", "keep-alive");
|
|
response.flushHeaders();
|
|
await ApiChatHandler.streamChat({
|
|
response,
|
|
workspace,
|
|
thread,
|
|
message,
|
|
mode: "chat",
|
|
user: user,
|
|
sessionId: null,
|
|
attachments: [],
|
|
reset: false,
|
|
});
|
|
return response.end();
|
|
}
|
|
|
|
if (command === "unregister-device") {
|
|
if (!response.locals.device)
|
|
return response.status(200).json({ success: true });
|
|
await MobileDevice.delete(response.locals.device.id);
|
|
return response.status(200).json({ success: true });
|
|
}
|
|
|
|
return response.status(400).json({ error: "Invalid command" });
|
|
}
|
|
|
|
module.exports = {
|
|
handleMobileCommand,
|
|
};
|