mirror of
https://github.com/Litlyx/litlyx
synced 2025-12-10 07:48:37 +01:00
Add advanced ai
This commit is contained in:
@@ -1,59 +1,35 @@
|
||||
|
||||
import { getVisitsCountFromDateRange } from '~/server/api/ai/functions/AI_Visits';
|
||||
|
||||
import OpenAI from "openai";
|
||||
import { AiChatModel } from '@schema/ai/AiChatSchema';
|
||||
import { AI_EventsFunctions, AI_EventsTools } from '../api/ai/functions/AI_Events';
|
||||
import { ProjectCountModel } from '@schema/ProjectsCounts';
|
||||
import { ProjectLimitModel } from '@schema/ProjectsLimits';
|
||||
|
||||
import { AiEventsInstance } from '../ai/functions/AI_Events';
|
||||
import { AiVisitsInstance } from '../ai/functions/AI_Visits';
|
||||
import { AiComposableChartInstance } from '../ai/functions/AI_ComposableChart';
|
||||
|
||||
const { AI_ORG, AI_PROJECT, AI_KEY } = useRuntimeConfig();
|
||||
|
||||
const OPENAI_MODEL: OpenAI.Chat.ChatModel = 'gpt-4o-mini';
|
||||
|
||||
const openai = new OpenAI({
|
||||
organization: AI_ORG,
|
||||
project: AI_PROJECT,
|
||||
apiKey: AI_KEY
|
||||
});
|
||||
|
||||
|
||||
// const get_current_date: OpenAI.Chat.Completions.ChatCompletionTool = {
|
||||
// type: 'function',
|
||||
// function: {
|
||||
// name: 'get_current_date',
|
||||
// description: 'Gets the current date as ISO string',
|
||||
// }
|
||||
// }
|
||||
|
||||
const get_visits_count_Schema: OpenAI.Chat.Completions.ChatCompletionTool = {
|
||||
type: 'function',
|
||||
function: {
|
||||
name: 'get_visits_count',
|
||||
description: 'Gets the number of visits received on a date range',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
from: { type: 'string', description: 'ISO string of start date including hours' },
|
||||
to: { type: 'string', description: 'ISO string of end date including hours' }
|
||||
},
|
||||
required: ['from', 'to']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const tools: OpenAI.Chat.Completions.ChatCompletionTool[] = [
|
||||
get_visits_count_Schema,
|
||||
...AI_EventsTools
|
||||
...AiVisitsInstance.getTools(),
|
||||
...AiEventsInstance.getTools(),
|
||||
...AiComposableChartInstance.getTools()
|
||||
]
|
||||
|
||||
|
||||
const functions: any = {
|
||||
get_current_date: async ({ }) => {
|
||||
return new Date().toISOString();
|
||||
},
|
||||
get_visits_count: async ({ pid, from, to }: any) => {
|
||||
return await getVisitsCountFromDateRange(pid, from, to);
|
||||
},
|
||||
...AI_EventsFunctions
|
||||
...AiVisitsInstance.getHandlers(),
|
||||
...AiEventsInstance.getHandlers(),
|
||||
...AiComposableChartInstance.getHandlers()
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +57,14 @@ async function setChatTitle(title: string, chat_id?: string) {
|
||||
await AiChatModel.updateOne({ _id: chat_id }, { title });
|
||||
}
|
||||
|
||||
|
||||
export function getChartsInMessage(message: OpenAI.Chat.Completions.ChatCompletionMessageParam) {
|
||||
if (message.role != 'assistant') return [];
|
||||
if (!message.tool_calls) return [];
|
||||
if (message.tool_calls.length == 0) return [];
|
||||
return message.tool_calls.filter(e => e.function.name === 'createComposableChart').map(e => e.function.arguments);
|
||||
}
|
||||
|
||||
export async function sendMessageOnChat(text: string, pid: string, initial_chat_id?: string) {
|
||||
|
||||
|
||||
@@ -100,43 +84,36 @@ export async function sendMessageOnChat(text: string, pid: string, initial_chat_
|
||||
await setChatTitle(text.substring(0, 110), chat_id);
|
||||
}
|
||||
|
||||
const userMessage: OpenAI.Chat.Completions.ChatCompletionMessageParam = {
|
||||
role: 'user', content: text
|
||||
}
|
||||
const userMessage: OpenAI.Chat.Completions.ChatCompletionMessageParam = { role: 'user', content: text }
|
||||
messages.push(userMessage);
|
||||
await addMessageToChat(userMessage, chat_id);
|
||||
|
||||
let response = await openai.chat.completions.create({ model: 'gpt-3.5-turbo', messages, n: 1, tools });
|
||||
let response = await openai.chat.completions.create({ model: OPENAI_MODEL, messages, n: 1, tools });
|
||||
|
||||
let responseMessage = response.choices[0].message;
|
||||
let toolCalls = responseMessage.tool_calls;
|
||||
const chartsData: string[][] = [];
|
||||
|
||||
await addMessageToChat(responseMessage, chat_id);
|
||||
messages.push(responseMessage);
|
||||
while ((response.choices[0].message.tool_calls?.length || 0) > 0) {
|
||||
await addMessageToChat(response.choices[0].message, chat_id);
|
||||
messages.push(response.choices[0].message);
|
||||
if (response.choices[0].message.tool_calls) {
|
||||
|
||||
console.log('Tools to call', response.choices[0].message.tool_calls.length);
|
||||
chartsData.push(getChartsInMessage(response.choices[0].message));
|
||||
|
||||
if (toolCalls) {
|
||||
console.log({ toolCalls: toolCalls.length });
|
||||
for (const toolCall of toolCalls) {
|
||||
const functionName = toolCall.function.name;
|
||||
const functionToCall = functions[functionName];
|
||||
const functionArgs = JSON.parse(toolCall.function.arguments);
|
||||
console.log('CALLING FUNCTION', functionName, 'WITH PARAMS', functionArgs);
|
||||
const functionResponse = await functionToCall({ pid, ...functionArgs });
|
||||
console.log('RESPONSE FUNCTION', functionName, 'WITH VALUE', functionResponse);
|
||||
messages.push({ tool_call_id: toolCall.id, role: "tool", content: JSON.stringify(functionResponse) });
|
||||
await addMessageToChat({ tool_call_id: toolCall.id, role: "tool", content: JSON.stringify(functionResponse) }, chat_id);
|
||||
for (const toolCall of response.choices[0].message.tool_calls) {
|
||||
const functionName = toolCall.function.name;
|
||||
console.log('Calling tool function', functionName);
|
||||
const functionToCall = functions[functionName];
|
||||
const functionArgs = JSON.parse(toolCall.function.arguments);
|
||||
const functionResponse = await functionToCall({ project_id: pid, ...functionArgs });
|
||||
messages.push({ tool_call_id: toolCall.id, role: "tool", content: JSON.stringify(functionResponse) });
|
||||
await addMessageToChat({ tool_call_id: toolCall.id, role: "tool", content: JSON.stringify(functionResponse) }, chat_id);
|
||||
}
|
||||
}
|
||||
response = await openai.chat.completions.create({ model: 'gpt-4o', messages, n: 1, tools });
|
||||
responseMessage = response.choices[0].message;
|
||||
toolCalls = responseMessage.tool_calls;
|
||||
|
||||
await addMessageToChat(responseMessage, chat_id);
|
||||
|
||||
response = await openai.chat.completions.create({ model: OPENAI_MODEL, messages, n: 1, tools });
|
||||
}
|
||||
|
||||
await addMessageToChat(response.choices[0].message, chat_id);
|
||||
await ProjectLimitModel.updateOne({ project_id: pid }, { $inc: { ai_messages: 1 } })
|
||||
|
||||
return responseMessage.content;
|
||||
return { content: response.choices[0].message.content, charts: chartsData.filter(e => e.length > 0).flat() };
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getPlanFromId, getPlanFromTag } from '@data/PREMIUM';
|
||||
import { getPlanFromId, getPlanFromTag, PREMIUM_TAG } from '@data/PREMIUM';
|
||||
import Stripe from 'stripe';
|
||||
|
||||
class StripeService {
|
||||
@@ -133,9 +133,23 @@ class StripeService {
|
||||
return deleted;
|
||||
}
|
||||
|
||||
async createOneTimeCoupon() {
|
||||
async createStripeCode(plan: PREMIUM_TAG) {
|
||||
if (this.disabledMode) return;
|
||||
if (!this.stripe) throw Error('Stripe not initialized');
|
||||
|
||||
const INCUBATION_COUPON = 'sDD7Weh3';
|
||||
|
||||
if (plan === 'INCUBATION') {
|
||||
await this.stripe.promotionCodes.create({
|
||||
coupon: INCUBATION_COUPON,
|
||||
active: true,
|
||||
code: 'TESTCACCA1',
|
||||
max_redemptions: 1,
|
||||
})
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async createOneTimeSubscriptionDummy(customer_id: string, planId: number) {
|
||||
|
||||
Reference in New Issue
Block a user