diff --git a/components/DropDown.tsx b/components/DropDown.tsx index 44e436c8..e9021de3 100644 --- a/components/DropDown.tsx +++ b/components/DropDown.tsx @@ -5,20 +5,17 @@ import { ChevronUpIcon, } from "@heroicons/react/20/solid"; import { Fragment } from "react"; +import { vibes, type VibeType } from "../utils/prompt"; function classNames(...classes: string[]) { return classes.filter(Boolean).join(" "); } -export type VibeType = "Professional" | "Casual" | "Funny"; - interface DropDownProps { vibe: VibeType; setVibe: (vibe: VibeType) => void; } -let vibes: VibeType[] = ["Professional", "Casual", "Funny"]; - export default function DropDown({ vibe, setVibe }: DropDownProps) { return ( diff --git a/pages/api/generate.ts b/pages/api/generate.ts index c31bffdb..076be5d6 100644 --- a/pages/api/generate.ts +++ b/pages/api/generate.ts @@ -1,5 +1,6 @@ import type { NextRequest } from "next/server"; import { OpenAIStream, OpenAIStreamPayload } from "../../utils/OpenAIStream"; +import { generatePrompt, vibes, VibeType } from "../../utils/prompt"; if (!process.env.OPENAI_API_KEY) { throw new Error("Missing env var from OpenAI"); @@ -9,15 +10,28 @@ export const config = { runtime: "edge", }; +type GenerateRequestBody = { + bio?: string; + vibe?: VibeType; +}; + const handler = async (req: NextRequest): Promise => { - const { prompt } = (await req.json()) as { - prompt?: string; - }; + if (req.method !== "POST") { + return new Response("Method not allowed", { status: 405 }); + } - if (!prompt) { - return new Response("No prompt in the request", { status: 400 }); + const { bio, vibe } = (await req.json()) as GenerateRequestBody; + + if (!bio) { + return new Response("No bio in the request", { status: 400 }); + } + + if (!vibe || !vibes.includes(vibe)) { + return new Response("Invalid vibe", { status: 400 }); } + const prompt = generatePrompt(bio, vibe); + const payload: OpenAIStreamPayload = { model: "text-davinci-003", prompt, diff --git a/pages/index.tsx b/pages/index.tsx index 48811ba6..c4d9f0cb 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -3,13 +3,14 @@ import type { NextPage } from "next"; import Head from "next/head"; import Image from "next/image"; import { useState } from "react"; -import { Toaster, toast } from "react-hot-toast"; -import DropDown, { VibeType } from "../components/DropDown"; +import { toast, Toaster } from "react-hot-toast"; +import DropDown from "../components/DropDown"; import Footer from "../components/Footer"; import Github from "../components/GitHub"; import Header from "../components/Header"; import LoadingDots from "../components/LoadingDots"; import ResizablePanel from "../components/ResizablePanel"; +import { type VibeType } from "../utils/prompt"; const Home: NextPage = () => { const [loading, setLoading] = useState(false); @@ -19,15 +20,6 @@ const Home: NextPage = () => { console.log("Streamed response: ", generatedBios); - const prompt = - vibe === "Funny" - ? `Generate 2 funny twitter bios with no hashtags and clearly labeled "1." and "2.". Make sure there is a joke in there and it's a little ridiculous. Make sure each generated bio is at max 20 words and base it on this context: ${bio}${ - bio.slice(-1) === "." ? "" : "." - }` - : `Generate 2 ${vibe} twitter bios with no hashtags and clearly labeled "1." and "2.". Make sure each generated bio is at least 14 words and at max 20 words and base them on this context: ${bio}${ - bio.slice(-1) === "." ? "" : "." - }`; - const generateBio = async (e: any) => { e.preventDefault(); setGeneratedBios(""); @@ -38,7 +30,8 @@ const Home: NextPage = () => { "Content-Type": "application/json", }, body: JSON.stringify({ - prompt, + bio, + vibe, }), }); console.log("Edge function returned."); diff --git a/utils/prompt.ts b/utils/prompt.ts new file mode 100644 index 00000000..e0a98842 --- /dev/null +++ b/utils/prompt.ts @@ -0,0 +1,15 @@ +export const vibes = ["Professional", "Casual", "Funny"] as const; + +export type VibeType = typeof vibes[number]; + +export function generatePrompt(bio: string, vibe: VibeType) { + if (vibe === "Funny") { + return `Generate 2 funny twitter bios with no hashtags and clearly labeled "1." and "2.". Make sure there is a joke in there and it's a little ridiculous. Make sure each generated bio is at max 20 words and base it on this context: ${bio}${ + bio.slice(-1) === "." ? "" : "." + }`; + } + + return `Generate 2 ${vibe} twitter bios with no hashtags and clearly labeled "1." and "2.". Make sure each generated bio is at least 14 words and at max 20 words and base them on this context: ${bio}${ + bio.slice(-1) === "." ? "" : "." + }`; +}