-
-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- remaster AI assistant API endpoint Update - Administration - added settings for GPT model
- Loading branch information
1 parent
8d32e4b
commit e61b254
Showing
8 changed files
with
387 additions
and
135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
"use server"; | ||
|
||
import { prismadb } from "@/lib/prisma"; | ||
|
||
const updateModel = async (model: any) => { | ||
await prismadb.gpt_models.updateMany({ | ||
data: { | ||
status: "INACTIVE", | ||
}, | ||
}); | ||
|
||
const setCronGPT = await prismadb.gpt_models.update({ | ||
where: { | ||
id: model, | ||
}, | ||
data: { | ||
status: "ACTIVE", | ||
}, | ||
}); | ||
console.log("change GPT model to:", setCronGPT); | ||
}; | ||
|
||
export default updateModel; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import dayjs from "dayjs"; | ||
import axios from "axios"; | ||
|
||
import sendEmail from "@/lib/sendmail"; | ||
import { prismadb } from "@/lib/prisma"; | ||
|
||
export async function getUserAiTasks(userId: string) { | ||
const today = dayjs().startOf("day"); | ||
const nextWeek = dayjs().add(7, "day").startOf("day"); | ||
|
||
let prompt = ""; | ||
|
||
const user = await prismadb.users.findUnique({ | ||
where: { | ||
id: userId, | ||
}, | ||
}); | ||
|
||
if (!user) return { message: "No user found" }; | ||
|
||
const getTaskPastDue = await prismadb.tasks.findMany({ | ||
where: { | ||
AND: [ | ||
{ | ||
user: userId, | ||
taskStatus: "ACTIVE", | ||
dueDateAt: { | ||
lte: new Date(), | ||
}, | ||
}, | ||
], | ||
}, | ||
}); | ||
|
||
const getTaskPastDueInSevenDays = await prismadb.tasks.findMany({ | ||
where: { | ||
AND: [ | ||
{ | ||
user: userId, | ||
taskStatus: "ACTIVE", | ||
dueDateAt: { | ||
//lte: dayjs().add(7, "day").toDate(), | ||
gt: today.toDate(), // Due date is greater than or equal to today | ||
lt: nextWeek.toDate(), // Due date is less than next week (not including today) | ||
}, | ||
}, | ||
], | ||
}, | ||
}); | ||
|
||
if (!getTaskPastDue || !getTaskPastDueInSevenDays) { | ||
return { message: "No tasks found" }; | ||
} | ||
|
||
switch (user.userLanguage) { | ||
case "en": | ||
prompt = `Hi, Iam ${process.env.NEXT_PUBLIC_APP_URL} API Bot. | ||
\n\n | ||
There are ${getTaskPastDue.length} tasks past due and ${ | ||
getTaskPastDueInSevenDays.length | ||
} tasks due in the next 7 days. | ||
\n\n | ||
Details today tasks: ${JSON.stringify(getTaskPastDue, null, 2)} | ||
\n\n | ||
Details next 7 days tasks: ${JSON.stringify( | ||
getTaskPastDueInSevenDays, | ||
null, | ||
2 | ||
)} | ||
\n\n | ||
As a personal assistant, write a message to ${ | ||
user.name | ||
} to remind them of their tasks. And also do not forget to send them a some positive vibes. | ||
\n\n | ||
`; | ||
break; | ||
case "cz": | ||
prompt = `Jako profesionální asistentka Emma s perfektní znalostí projektového řízení, který má na starosti projekty na adrese${ | ||
process.env.NEXT_PUBLIC_APP_URL | ||
}, připrave manažerské shrnutí o úkolech včetně jejich detailů a termínů. Vše musí být perfektně česky a výstižně. | ||
\n\n | ||
Zde jsou informace k úkolům: | ||
\n\n | ||
Informace o projektu: Počet úkolů které jsou k řešení dnes: ${ | ||
getTaskPastDue.length | ||
}, Počet úkolů, které musí být vyřešeny nejpozději do sedmi dnů: ${ | ||
getTaskPastDueInSevenDays.length | ||
}. | ||
\n\n | ||
Detailní informace v JSON formátu k úkolům, které musí být hotové dnes: ${JSON.stringify( | ||
getTaskPastDue, | ||
null, | ||
2 | ||
)} | ||
\n\n | ||
Detailní informace k úkolům, které musí být hotové během následujících sedmi dní: ${JSON.stringify( | ||
getTaskPastDueInSevenDays, | ||
null, | ||
2 | ||
)} | ||
\n\n | ||
Na konec napiš manažerské shrnutí včetně milého uvítání napiš pro uživatele: ${ | ||
user.name | ||
} a přidej odkaz ${ | ||
process.env.NEXT_PUBLIC_APP_URL + "/projects/dashboard" | ||
} jako odkaz na detail k úkolům . Na konci manažerského shrnutí přidej. 1 tip na manažerskou dovednost z oblasti projektového řízení a timemanagementu, 2-3 věty s pozitivním naladěním a podporou, nakonec popřej hezký pracovní den a infomaci, že tato zpráva byla vygenerována pomocí umělé inteligence OpenAi. | ||
\n\n | ||
`; | ||
break; | ||
} | ||
|
||
if (!prompt) return { message: "No prompt found" }; | ||
|
||
const getAiResponse = await axios | ||
.post( | ||
`${process.env.NEXT_PUBLIC_APP_URL}/api/openai/create-chat-completion`, | ||
{ | ||
prompt: prompt, | ||
}, | ||
{ | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
} | ||
) | ||
.then((res) => res.data); | ||
|
||
//console.log(getAiResponse, "getAiResponse"); | ||
|
||
//skip if api response is error | ||
if (getAiResponse.error) { | ||
console.log("Error from OpenAI API"); | ||
} else { | ||
await sendEmail({ | ||
from: process.env.EMAIL_FROM, | ||
to: user.email!, | ||
subject: `${process.env.NEXT_PUBLIC_APP_NAME} OpenAI Project manager assistant`, | ||
text: getAiResponse.response.message.content, | ||
}); | ||
} | ||
|
||
return { user: user.email }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardHeader, | ||
CardTitle, | ||
} from "@/components/ui/card"; | ||
|
||
import { prismadb } from "@/lib/prisma"; | ||
import SetGptModel from "../forms/SetGptModel"; | ||
|
||
import OnTestButton from "./OnTestButton"; | ||
|
||
const GptCard = async () => { | ||
const gptModels = await prismadb.gpt_models.findMany(); | ||
//console.log(gptModels, "gptModels"); | ||
|
||
return ( | ||
<Card className="w-1/3"> | ||
<CardHeader className="text-lg"> | ||
<CardTitle>AI assistant GPT model</CardTitle> | ||
<CardDescription> | ||
<div> | ||
actual model:{" "} | ||
{ | ||
//filter in gptModels where status = ACTIVE | ||
gptModels | ||
.filter((model) => model.status === "ACTIVE") | ||
.map((model) => model.model) | ||
} | ||
</div> | ||
</CardDescription> | ||
</CardHeader> | ||
<CardContent className="space-y-2"> | ||
<SetGptModel models={gptModels} /> | ||
<OnTestButton /> | ||
</CardContent> | ||
</Card> | ||
); | ||
}; | ||
|
||
export default GptCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
"use client"; | ||
|
||
import { Button } from "@/components/ui/button"; | ||
import { Icons } from "@/components/ui/icons"; | ||
import { Label } from "@/components/ui/label"; | ||
import { useToast } from "@/components/ui/use-toast"; | ||
import axios from "axios"; | ||
import React from "react"; | ||
|
||
const OnTestButton = () => { | ||
const [loading, setLoading] = React.useState(false); | ||
const { toast } = useToast(); | ||
|
||
async function onTest() { | ||
setLoading(true); | ||
try { | ||
const response = await axios.get("/api/cron/send-daily-task-ai"); | ||
//console.log(response, "response"); | ||
toast({ | ||
title: "GPT model tested", | ||
description: response.data.message, | ||
}); | ||
} catch (error) { | ||
console.log(error); | ||
toast({ | ||
variant: "destructive", | ||
title: "GPT model test failed", | ||
}); | ||
} finally { | ||
setLoading(false); | ||
} | ||
} | ||
return ( | ||
<div className="flex flex-col space-y-2"> | ||
<Label>Send test</Label> | ||
<Button onClick={onTest} disabled={loading}> | ||
{loading ? <Icons.spinner className="animate-spin" /> : "Test"} | ||
</Button> | ||
</div> | ||
); | ||
}; | ||
|
||
export default OnTestButton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
"use client"; | ||
|
||
import Link from "next/link"; | ||
import { zodResolver } from "@hookform/resolvers/zod"; | ||
import { useForm } from "react-hook-form"; | ||
import * as z from "zod"; | ||
|
||
import { Button } from "@/components/ui/button"; | ||
import { | ||
Form, | ||
FormControl, | ||
FormDescription, | ||
FormField, | ||
FormItem, | ||
FormLabel, | ||
FormMessage, | ||
} from "@/components/ui/form"; | ||
import { | ||
Select, | ||
SelectContent, | ||
SelectItem, | ||
SelectTrigger, | ||
SelectValue, | ||
} from "@/components/ui/select"; | ||
import { toast } from "@/components/ui/use-toast"; | ||
import updateModel from "@/actions/admin/update-gpt-model"; | ||
import { useRouter } from "next/navigation"; | ||
|
||
const FormSchema = z.object({ | ||
model: z.string().min(10).max(30), | ||
}); | ||
|
||
const SetGptModel = ({ models }: any) => { | ||
const router = useRouter(); | ||
|
||
const form = useForm<z.infer<typeof FormSchema>>({ | ||
resolver: zodResolver(FormSchema), | ||
}); | ||
|
||
async function onSubmit(data: z.infer<typeof FormSchema>) { | ||
try { | ||
await updateModel(data.model); | ||
toast({ | ||
title: "GPT model updated", | ||
}); | ||
} catch (error) { | ||
console.log(error); | ||
} finally { | ||
router.refresh(); | ||
} | ||
} | ||
|
||
return ( | ||
<Form {...form}> | ||
{/* <pre>{JSON.stringify(form.watch(), null, 2)}</pre> */} | ||
<form | ||
onSubmit={form.handleSubmit(onSubmit)} | ||
className=" space-y-6 flex space-x-3 items-center justify-center" | ||
> | ||
<FormField | ||
control={form.control} | ||
name="model" | ||
render={({ field }) => ( | ||
<FormItem className="w-full"> | ||
<FormLabel>GPT model</FormLabel> | ||
<Select onValueChange={field.onChange} defaultValue={field.value}> | ||
<FormControl> | ||
<SelectTrigger> | ||
<SelectValue placeholder="Select a gpt model for AI assistant" /> | ||
</SelectTrigger> | ||
</FormControl> | ||
<SelectContent> | ||
{models.map((model: any) => ( | ||
<SelectItem key={model.id} value={model.id}> | ||
{model.model} | ||
</SelectItem> | ||
))} | ||
</SelectContent> | ||
</Select> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
<Button type="submit">Submit</Button> | ||
</form> | ||
</Form> | ||
); | ||
}; | ||
|
||
export default SetGptModel; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
e61b254
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
nextcrm-sunstream – ./
nextcrm-sunstream.vercel.app
nextcrm-sunstream-git-main-e-osvc.vercel.app
nextcrm-sunstream-e-osvc.vercel.app
sunstream.nextcrm.io
e61b254
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
nextcrm-softbase – ./
softbase.nextcrm.io
nextcrm-softbase-e-osvc.vercel.app
nextcrm-softbase.vercel.app
nextcrm-softbase-git-main-e-osvc.vercel.app
e61b254
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
nextcrm-test – ./
nextcrm-test-git-main-e-osvc.vercel.app
test.nextcrm.io
nextcrm-test-e-osvc.vercel.app
e61b254
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
nextcrm-others – ./
nextcrm-others-git-main-e-osvc.vercel.app
nextcrm-others-e-osvc.vercel.app
others.nextcrm.io
e61b254
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
nextcrm-demo – ./
nextcrm-demo-e-osvc.vercel.app
demo.nextcrm.io
nextcrm-demo-git-main-e-osvc.vercel.app
e61b254
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
nextcrm-documex – ./
nextcrm-documex-git-main-e-osvc.vercel.app
nextcrm-documex-e-osvc.vercel.app
nextcrm-documex.vercel.app
documex.nextcrm.io