diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts index 6c2eb7d..e9951c0 100644 --- a/app/api/chat/route.ts +++ b/app/api/chat/route.ts @@ -1,9 +1,9 @@ -import { getOpenAIApiInstance } from "@/lib/OpenAiCompletaions" -import { errorHandler } from "@/lib/utils"; +import { getOpenAIApiInstance } from "@/libs/OpenAiCompletaions" +import { errorHandler } from "@/libs/utils"; // export const dynamic = 'force-dynamic' -const apikey = process.env.NEXT_OPENAI_API_KEY +const apikey = process.env.NEXT_PUBLIC_OPENAI_API_KEY export async function POST(requset: Request) { const messages = await requset.json() diff --git a/app/api/langchain/route.ts b/app/api/langchain/route.ts new file mode 100644 index 0000000..c561269 --- /dev/null +++ b/app/api/langchain/route.ts @@ -0,0 +1,69 @@ +import { NextRequest, NextResponse } from "next/server"; + +import { z } from "zod"; + +import { createStructuredOutputChainFromZod } from "langchain/chains/openai_functions"; +import { PromptTemplate } from "@langchain/core/prompts"; +import { createOpenAIModel } from "@/libs/Langchain"; +import { getIP } from "@/libs/utils"; +import { checkRateLimit } from "@/store/rateLimitStore"; + +export const runtime = "edge"; + +const TEMPLATE = `Generate a compelling social media bio for user centered around context which them provide you. +The bio should be concise (150-200 characters) and capture the essence of user in a way that resonates with context. +Include elements that showcase personality, passion, and any relevant hashtags or keywords. +Feel free to add a touch of creativity to make it engaging. + +{input}`; + + +const apikey = process.env.NEXT_PUBLIC_OPENAI_API_KEY + + +export async function POST(req: NextRequest) { + try { + + const ip = getIP(req); + if (!checkRateLimit(ip as string)) { + return NextResponse.json({ error: "شما بیش از حد مجاز از سرویس استفاده کرده اید. چند ساعت بعد امتحان کنید" }, { status: 429 }); + } + + const messages = await req.json() + + const prompt = PromptTemplate.fromTemplate<{ input: string }>(TEMPLATE); + + const model = createOpenAIModel(apikey) + + const schema = z.object({ + output: z.array( + z.object({ + id: z.string(), + content: z.string(), + }) + ), + + }); + + + const chain = createStructuredOutputChainFromZod(schema, { + llm: model, + prompt, + outputKey: "output", + }); + console.log(chain) + + const result = await chain.call({ + input: messages, + }); + console.log(result) + + return NextResponse.json(result.output, { status: 200 }); + } catch (e: any) { + console.log(e) + if (e.message.includes("API key")){ + return NextResponse.json({ error: "سرویس فعلا در دسترس نیست" }, { status: 500 }); + } + return NextResponse.json({ error: e.message }, { status: 500 }); + } +} diff --git a/app/error.tsx b/app/error.tsx new file mode 100644 index 0000000..2bc908d --- /dev/null +++ b/app/error.tsx @@ -0,0 +1,25 @@ +'use client' // Error components must be Client Components + +import { useEffect } from 'react' + +export default function Error({ + error, + reset, +}: { + error: Error & { digest?: string } + reset: () => void +}) { + useEffect(() => { + // Log the error to an error reporting service + console.error(error) + }, [error]) + + return ( +
+
+

یه مشکلی به وجود اومده ⚠️

+ {error.message} +
+
+ ) +} \ No newline at end of file diff --git a/app/global-error.tsx b/app/global-error.tsx new file mode 100644 index 0000000..12488be --- /dev/null +++ b/app/global-error.tsx @@ -0,0 +1,36 @@ +"use client"; + +import { Button } from "@/components/ui/button"; +import { useRouter } from "next/router"; + +export default function GlobalError({ + error, + reset, +}: { + error: Error & { digest?: string }; + reset: () => void; +}) { + const router = useRouter(); + console.error(error); + + return ( + + +
+

Something went wrong!

+ + +
+ + + ); +} diff --git a/app/globals.css b/app/globals.css deleted file mode 100644 index 6a75725..0000000 --- a/app/globals.css +++ /dev/null @@ -1,76 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer base { - :root { - --background: 0 0% 100%; - --foreground: 222.2 84% 4.9%; - - --card: 0 0% 100%; - --card-foreground: 222.2 84% 4.9%; - - --popover: 0 0% 100%; - --popover-foreground: 222.2 84% 4.9%; - - --primary: 222.2 47.4% 11.2%; - --primary-foreground: 210 40% 98%; - - --secondary: 210 40% 96.1%; - --secondary-foreground: 222.2 47.4% 11.2%; - - --muted: 210 40% 96.1%; - --muted-foreground: 215.4 16.3% 46.9%; - - --accent: 210 40% 96.1%; - --accent-foreground: 222.2 47.4% 11.2%; - - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 210 40% 98%; - - --border: 214.3 31.8% 91.4%; - --input: 214.3 31.8% 91.4%; - --ring: 222.2 84% 4.9%; - - --radius: 0.5rem; - } - - .dark { - --background: 222.2 84% 4.9%; - --foreground: 210 40% 98%; - - --card: 222.2 84% 4.9%; - --card-foreground: 210 40% 98%; - - --popover: 222.2 84% 4.9%; - --popover-foreground: 210 40% 98%; - - --primary: 210 40% 98%; - --primary-foreground: 222.2 47.4% 11.2%; - - --secondary: 217.2 32.6% 17.5%; - --secondary-foreground: 210 40% 98%; - - --muted: 217.2 32.6% 17.5%; - --muted-foreground: 215 20.2% 65.1%; - - --accent: 217.2 32.6% 17.5%; - --accent-foreground: 210 40% 98%; - - --destructive: 0 62.8% 30.6%; - --destructive-foreground: 210 40% 98%; - - --border: 217.2 32.6% 17.5%; - --input: 217.2 32.6% 17.5%; - --ring: 212.7 26.8% 83.9%; - } -} - -@layer base { - * { - @apply border-border; - } - body { - @apply bg-background text-foreground; - } -} \ No newline at end of file diff --git a/app/layout.tsx b/app/layout.tsx index cc8deae..2f96671 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,5 +1,5 @@ import Header from '@/components/Header'; -import './globals.css'; +import '@/styles/globals.css'; import Footer from '@/components/Footer'; import { Toaster } from '@/components/ui/sonner'; import { Metadata } from 'next'; @@ -36,14 +36,14 @@ export default function RootLayout({ }) { return ( - +
{children}
-