import OpenAI from "openai"; import { z } from "zod"; import { env } from "../../../env/server.mjs"; import { messageSchema } from "../../../types/message"; import { MESSAGE_TYPE_TASK } from "../../../types/task"; import { prisma } from "../../db"; import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc"; const createAgentParser = z.object({ goal: z.string(), }); export type CreateAgentProps = z.infer; const saveAgentParser = z.object({ id: z.string(), tasks: z.array(messageSchema), }); export type SaveAgentProps = z.infer; async function generateAgentName(goal: string) { if (!env.OPENAI_API_KEY) return undefined; try { const openAI = new OpenAI({ apiKey: env.OPENAI_API_KEY as string, }); const chatCompletion = await openAI.chat.completions.create({ messages: [ { role: "user", content: goal, }, { role: "system", content: `Summarize this into one or two words followed by "GPT" and a single emoji. Examples: - 'I want to buy a house' becomes HouseGPT 🏠 - 'Analyze top stock prices and generate a report' becomes AnalyzeStockGPT 📈 `, }, ], model: "gpt-3.5-turbo", }); // @ts-ignore return chatCompletion.choices[0].message.content as string; } catch (e) { console.error(e); return undefined; } } export const agentRouter = createTRPCRouter({ create: protectedProcedure.input(createAgentParser).mutation(async ({ input, ctx }) => { const name = (await generateAgentName(input.goal)) || input.goal; return ctx.prisma.agent.create({ data: { name: name.trim(), goal: input.goal, userId: ctx.session?.user?.id, }, }); }), save: protectedProcedure.input(saveAgentParser).mutation(async ({ input, ctx }) => { const agent = await prisma.agent.findFirst({ where: { id: input.id, userId: ctx.session?.user?.id, }, }); if (!agent) throw new Error("Agent not found"); const all = input.tasks.map((e, i) => { return prisma.agentTask.create({ data: { agentId: agent.id, type: e.type, ...(e.type === MESSAGE_TYPE_TASK && { status: e.status }), info: e.info, value: e.value, sort: 0, // TODO: Remove sort }, }); }); await Promise.all(all); return agent; }), getAll: protectedProcedure.query(async ({ ctx }) => { return prisma.agent.findMany({ where: { userId: ctx.session?.user?.id, deleteDate: null, }, orderBy: { createDate: "desc" }, take: 20, }); }), findById: publicProcedure.input(z.string()).query(async ({ input, ctx }) => { return prisma.agent.findFirstOrThrow({ where: { id: input, deleteDate: null }, include: { tasks: { orderBy: { createDate: "asc", }, }, }, }); }), deleteById: protectedProcedure.input(z.string()).mutation(async ({ input, ctx }) => { await prisma.agent.updateMany({ where: { id: input, userId: ctx.session?.user?.id }, data: { deleteDate: new Date(), }, }); }), });