mirror of
https://github.com/Litlyx/litlyx
synced 2025-12-10 07:48:37 +01:00
new selfhosted version
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
|
||||
import { AiChatModel } from "@schema/ai/AiChatSchema";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
|
||||
const data = await getRequestData(event, [], ['AI']);
|
||||
if (!data) return;
|
||||
|
||||
const { project_id } = data;
|
||||
|
||||
if (!event.context.params) return;
|
||||
const chat_id = event.context.params['chat_id'];
|
||||
|
||||
const result = await AiChatModel.updateOne({ _id: chat_id, project_id }, { deleted: true });
|
||||
return result.modifiedCount > 0;
|
||||
});
|
||||
@@ -1,30 +0,0 @@
|
||||
import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA";
|
||||
import { AiChatModel } from "@schema/ai/AiChatSchema";
|
||||
import type OpenAI from "openai";
|
||||
import { getChartsInMessage } from "~/server/services/AiService";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
const data = await getRequestData(event, [], ['AI']);
|
||||
if (!data) return;
|
||||
|
||||
const isAdmin = data.user.user.roles.includes('ADMIN');
|
||||
|
||||
const { project_id } = data;
|
||||
|
||||
if (!event.context.params) return;
|
||||
const chat_id = event.context.params['chat_id'];
|
||||
|
||||
const chat = await AiChatModel.findOne({ _id: chat_id, project_id });
|
||||
if (!chat) return;
|
||||
|
||||
return (chat.messages as OpenAI.Chat.Completions.ChatCompletionMessageParam[])
|
||||
.filter(e => isAdmin ? true : (e.role === 'assistant' || e.role === 'user'))
|
||||
.map(e => {
|
||||
const charts = getChartsInMessage(e);
|
||||
const content = e.content;
|
||||
return { ...e, charts }
|
||||
})
|
||||
.filter(e => {
|
||||
return isAdmin ? true : (e.charts.length > 0 || e.content);
|
||||
})
|
||||
});
|
||||
@@ -1,17 +0,0 @@
|
||||
|
||||
import { AiChatModel } from "@schema/ai/AiChatSchema";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
const data = await getRequestData(event, [], ['AI']);
|
||||
if (!data) return;
|
||||
|
||||
const { project_id } = data;
|
||||
|
||||
if (!event.context.params) return;
|
||||
const chat_id = event.context.params['chat_id'];
|
||||
|
||||
const chat = await AiChatModel.findOne({ _id: chat_id, project_id }, { status: 1, completed: 1 });
|
||||
if (!chat) return;
|
||||
|
||||
return { status: chat.status, completed: chat.completed || false }
|
||||
});
|
||||
22
dashboard/server/api/ai/ask.post.ts
Normal file
22
dashboard/server/api/ai/ask.post.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { AiService } from "~/server/services/ai/AiService";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
|
||||
const ctx = await getRequestContext(event, 'pid');
|
||||
const { user_email, pid } = ctx;
|
||||
|
||||
const query = getQuery(event);
|
||||
|
||||
const { message } = await readBody(event);
|
||||
if (!message) throw createError({ status: 400, message: 'message is required' });
|
||||
|
||||
const chat_id = await AiService.handleUserMessage({
|
||||
name: user_email.split('@')[0],
|
||||
pid,
|
||||
text: message,
|
||||
chat_id: query.chat_id?.toString()
|
||||
});
|
||||
|
||||
return { chat_id }
|
||||
|
||||
});
|
||||
16
dashboard/server/api/ai/chat.ts
Normal file
16
dashboard/server/api/ai/chat.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
import { AiNewChatModel } from "~/shared/schema/ai/AiNewChatSchema";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
|
||||
const ctx = await getRequestContext(event, 'pid');
|
||||
const { project_id } = ctx;
|
||||
|
||||
const { id } = getQuery(event);
|
||||
|
||||
const chat = await AiNewChatModel.findOne({ _id: id, project_id });
|
||||
if (!chat) return;
|
||||
|
||||
return chat;
|
||||
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA";
|
||||
import { AiChatModel } from "@schema/ai/AiChatSchema";
|
||||
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
|
||||
const data = await getRequestDataOld(event);
|
||||
if (!data) return;
|
||||
|
||||
const { project_id } = data;
|
||||
|
||||
const chatList = await AiChatModel.find({ project_id, deleted: false }, { _id: 1, title: 1 }, { sort: { updated_at: 1 } });
|
||||
|
||||
return chatList.map(e => e.toJSON());
|
||||
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
import { ProjectLimitModel } from "@schema/project/ProjectsLimits";
|
||||
|
||||
export async function getAiChatRemainings(project_id: string) {
|
||||
const limits = await ProjectLimitModel.findOne({ project_id })
|
||||
if (!limits) return 0;
|
||||
const chatsRemaining = limits.ai_limit - limits.ai_messages;
|
||||
|
||||
if (isNaN(chatsRemaining)) return 0;
|
||||
return chatsRemaining;
|
||||
}
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
const data = await getRequestData(event, [], ['AI']);
|
||||
if (!data) return;
|
||||
|
||||
const { pid } = data;
|
||||
|
||||
const chatsRemaining = await getAiChatRemainings(pid);
|
||||
return chatsRemaining;
|
||||
});
|
||||
@@ -1,13 +1,14 @@
|
||||
|
||||
import { AiChatModel } from "@schema/ai/AiChatSchema";
|
||||
import { AiNewChatModel } from "~/shared/schema/ai/AiNewChatSchema";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
|
||||
const data = await getRequestData(event, [], ['AI']);
|
||||
if (!data) return;
|
||||
const ctx = await getRequestContext(event, 'pid');
|
||||
const { project_id } = ctx;
|
||||
|
||||
const { project_id } = data;
|
||||
const chat = await AiNewChatModel.updateMany({ project_id }, { deleted: true });
|
||||
if (!chat) return;
|
||||
|
||||
return chat;
|
||||
|
||||
const result = await AiChatModel.updateMany({ project_id }, { deleted: true });
|
||||
return result.modifiedCount > 0;
|
||||
});
|
||||
16
dashboard/server/api/ai/delete_chat.ts
Normal file
16
dashboard/server/api/ai/delete_chat.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
import { AiNewChatModel } from "~/shared/schema/ai/AiNewChatSchema";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
|
||||
const ctx = await getRequestContext(event, 'pid');
|
||||
const { project_id } = ctx;
|
||||
|
||||
const { chat_id } = getQuery(event);
|
||||
|
||||
const chat = await AiNewChatModel.updateOne({ _id: chat_id, project_id }, { deleted: true });
|
||||
if (!chat) return;
|
||||
|
||||
return chat;
|
||||
|
||||
});
|
||||
21
dashboard/server/api/ai/downvote_message.post.ts
Normal file
21
dashboard/server/api/ai/downvote_message.post.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
import { Types } from "mongoose";
|
||||
import { AiNewChatModel } from "~/shared/schema/ai/AiNewChatSchema";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
|
||||
const ctx = await getRequestContext(event, 'pid');
|
||||
const { project_id } = ctx;
|
||||
|
||||
const { chat_id, message_index } = getQuery(event);
|
||||
|
||||
if (!chat_id) throw createError({ status: 400, message: 'chat_id is required' });
|
||||
if (!message_index) throw createError({ status: 400, message: 'message_index is required' });
|
||||
const index = parseInt(message_index as string);
|
||||
if (isNaN(index)) throw createError({ status: 400, message: 'message_index must be a number' });
|
||||
|
||||
const update = await AiNewChatModel.updateOne({ _id: new Types.ObjectId(chat_id as string), project_id }, { $set: { [`messages.${index}.downvoted`]: true } });
|
||||
|
||||
return update;
|
||||
|
||||
});
|
||||
9
dashboard/server/api/ai/insight.ts
Normal file
9
dashboard/server/api/ai/insight.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { AiService } from "~/server/services/ai/AiService";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
|
||||
const ctx = await getRequestContext(event, 'pid', 'permission:ai');
|
||||
const { project_id } = ctx;
|
||||
const res = await AiService.generateInsight(project_id.toString());
|
||||
return res;
|
||||
});
|
||||
12
dashboard/server/api/ai/list.ts
Normal file
12
dashboard/server/api/ai/list.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { AiNewChatModel } from "~/shared/schema/ai/AiNewChatSchema";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
|
||||
const ctx = await getRequestContext(event, 'pid');
|
||||
const { project_id } = ctx;
|
||||
|
||||
const chats = await AiNewChatModel.find({ project_id, deleted: false }, { _id: 1, title: 1, created_at: 1, updated_at: 1, status: 1 });
|
||||
|
||||
return chats;
|
||||
|
||||
});
|
||||
@@ -1,61 +0,0 @@
|
||||
import { sendMessageOnChat, updateChatStatus } from "~/server/services/AiService";
|
||||
import { getAiChatRemainings } from "./chats_remaining";
|
||||
import { ProjectLimitModel } from "@schema/project/ProjectsLimits";
|
||||
|
||||
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
const data = await getRequestData(event, [], ['AI']);
|
||||
if (!data) return;
|
||||
|
||||
const { pid } = data;
|
||||
|
||||
const { text, chat_id, timeOffset } = await readBody(event);
|
||||
if (!text) return setResponseStatus(event, 400, 'text parameter missing');
|
||||
|
||||
const chatsRemaining = await getAiChatRemainings(pid);
|
||||
if (chatsRemaining <= 0) return setResponseStatus(event, 400, 'CHAT_LIMIT_REACHED');
|
||||
|
||||
|
||||
await ProjectLimitModel.updateOne({ project_id: pid }, { $inc: { ai_messages: 1 } });
|
||||
|
||||
const currentStatus: string[] = [];
|
||||
|
||||
let responseSent = false;
|
||||
|
||||
let targetChatId = '';
|
||||
|
||||
await sendMessageOnChat(text, pid, timeOffset, chat_id, {
|
||||
onChatId: async chat_id => {
|
||||
if (!responseSent) {
|
||||
event.node.res.setHeader('Content-Type', 'application/json');
|
||||
event.node.res.end(JSON.stringify({ chat_id }));
|
||||
targetChatId = chat_id;
|
||||
responseSent = true;
|
||||
}
|
||||
},
|
||||
onDelta: async text => {
|
||||
currentStatus.push(text);
|
||||
await updateChatStatus(targetChatId, currentStatus.join(''), false);
|
||||
},
|
||||
onFunctionName: async name => {
|
||||
currentStatus.push('[data:FunctionName]');
|
||||
await updateChatStatus(targetChatId, currentStatus.join(''), false);
|
||||
},
|
||||
onFunctionCall: async name => {
|
||||
currentStatus.push('[data:FunctionCall]');
|
||||
await updateChatStatus(targetChatId, currentStatus.join(''), false);
|
||||
},
|
||||
onFunctionResult: async (name, result) => {
|
||||
currentStatus.push('[data:FunctionResult]');
|
||||
await updateChatStatus(targetChatId, currentStatus.join(''), false);
|
||||
},
|
||||
onFinish: async calls => {
|
||||
// currentStatus.push('[data:FunctionFinish]');
|
||||
// await updateChatStatus(targetChatId, currentStatus.join(''), false);
|
||||
}
|
||||
});
|
||||
|
||||
await updateChatStatus(targetChatId, '', true);
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user