mirror of
https://github.com/wasp-lang/open-saas.git
synced 2025-07-07 22:10:07 +02:00
Address review comments
This commit is contained in:
@ -15,11 +15,11 @@ import { SubscriptionStatus } from '../payment/plans';
|
|||||||
import { ensureArgsSchemaOrThrowHttpError } from '../server/validation';
|
import { ensureArgsSchemaOrThrowHttpError } from '../server/validation';
|
||||||
|
|
||||||
const openAi = getOpenAi();
|
const openAi = getOpenAi();
|
||||||
function getOpenAi(): OpenAI | null {
|
function getOpenAi(): OpenAI {
|
||||||
if (process.env.OPENAI_API_KEY) {
|
if (process.env.OPENAI_API_KEY) {
|
||||||
return new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
return new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
||||||
} else {
|
} else {
|
||||||
return null;
|
throw new Error('OpenAI API key is not set');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,12 +38,11 @@ export const generateGptResponse: GenerateGptResponse<GenerateGptResponseInput,
|
|||||||
throw new HttpError(401, 'Only authenticated users are allowed to perform this operation');
|
throw new HttpError(401, 'Only authenticated users are allowed to perform this operation');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { hours } = ensureArgsSchemaOrThrowHttpError(generateGptResponseInputSchema, rawArgs);
|
|
||||||
|
|
||||||
if (!isEligibleForResponse(context.user)) {
|
if (!isEligibleForResponse(context.user)) {
|
||||||
throw new HttpError(402, 'User has not paid or is out of credits');
|
throw new HttpError(402, 'User has not paid or is out of credits');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { hours } = ensureArgsSchemaOrThrowHttpError(generateGptResponseInputSchema, rawArgs);
|
||||||
const tasks = await context.entities.Task.findMany({
|
const tasks = await context.entities.Task.findMany({
|
||||||
where: {
|
where: {
|
||||||
user: {
|
user: {
|
||||||
@ -53,16 +52,19 @@ export const generateGptResponse: GenerateGptResponse<GenerateGptResponseInput,
|
|||||||
});
|
});
|
||||||
|
|
||||||
console.log('Calling open AI api');
|
console.log('Calling open AI api');
|
||||||
const dailyPlanJson = await getDailyPlanFromGpt(tasks, hours);
|
const generatedSchedule = await generateScheduleWithGpt(tasks, hours);
|
||||||
if (dailyPlanJson === null) {
|
if (generatedSchedule === null) {
|
||||||
throw new HttpError(500, 'Encountered a problem in communication with OpenAI');
|
throw new HttpError(500, 'Encountered a problem in communication with OpenAI');
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Do I need a try catch now that I'm saving a response and
|
// We decrement the credits after using up tokens to get a daily plan
|
||||||
// decrementing credits in a transaction?
|
// from Chat GPT.
|
||||||
|
//
|
||||||
// NOTE: I changed this up, first I do the request, and then I decrement
|
// This way, users don't feel cheated if something goes wrong.
|
||||||
// credits. Is that dangerous? Protecting from it could be too complicated
|
// On the flipside, users can theoretically abuse this and spend more
|
||||||
|
// credits than they have, but the damage should be pretty limited.
|
||||||
|
//
|
||||||
|
// Think about which option you prefer for you and edit the code accordingly.
|
||||||
const decrementCredit = context.entities.User.update({
|
const decrementCredit = context.entities.User.update({
|
||||||
where: { id: context.user.id },
|
where: { id: context.user.id },
|
||||||
data: {
|
data: {
|
||||||
@ -75,15 +77,14 @@ export const generateGptResponse: GenerateGptResponse<GenerateGptResponseInput,
|
|||||||
const createResponse = context.entities.GptResponse.create({
|
const createResponse = context.entities.GptResponse.create({
|
||||||
data: {
|
data: {
|
||||||
user: { connect: { id: context.user.id } },
|
user: { connect: { id: context.user.id } },
|
||||||
content: dailyPlanJson,
|
content: JSON.stringify(generatedSchedule),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Decrementing credits and saving response');
|
console.log('Decrementing credits and saving response');
|
||||||
prisma.$transaction([decrementCredit, createResponse]);
|
prisma.$transaction([decrementCredit, createResponse]);
|
||||||
|
|
||||||
// TODO: Can this ever fail?
|
return generatedSchedule;
|
||||||
return JSON.parse(dailyPlanJson);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function isEligibleForResponse(user: User) {
|
function isEligibleForResponse(user: User) {
|
||||||
@ -205,11 +206,7 @@ export const getAllTasksByUser: GetAllTasksByUser<void, Task[]> = async (_args,
|
|||||||
};
|
};
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
async function getDailyPlanFromGpt(tasks: Task[], hours: string): Promise<string | null> {
|
async function generateScheduleWithGpt(tasks: Task[], hours: string): Promise<GeneratedSchedule | null> {
|
||||||
if (openAi === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const parsedTasks = tasks.map(({ description, time }) => ({
|
const parsedTasks = tasks.map(({ description, time }) => ({
|
||||||
description,
|
description,
|
||||||
time,
|
time,
|
||||||
@ -294,5 +291,5 @@ async function getDailyPlanFromGpt(tasks: Task[], hours: string): Promise<string
|
|||||||
});
|
});
|
||||||
|
|
||||||
const gptResponse = completion?.choices[0]?.message?.tool_calls?.[0]?.function.arguments;
|
const gptResponse = completion?.choices[0]?.message?.tool_calls?.[0]?.function.arguments;
|
||||||
return gptResponse ?? null;
|
return gptResponse !== undefined ? JSON.parse(gptResponse) : null;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user