route.ts 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import { agent } from "@/lib/agent";
  2. import { minuteRateLimit, dailyRateLimit } from "@/lib/rate-limit";
  3. import {
  4. convertToModelMessages,
  5. createUIMessageStream,
  6. createUIMessageStreamResponse,
  7. type UIMessage,
  8. } from "ai";
  9. import { pipeJsonRender } from "@json-render/core";
  10. import { headers } from "next/headers";
  11. export const maxDuration = 60;
  12. export async function POST(req: Request) {
  13. const headersList = await headers();
  14. const ip = headersList.get("x-forwarded-for")?.split(",")[0] ?? "anonymous";
  15. const [minuteResult, dailyResult] = await Promise.all([
  16. minuteRateLimit.limit(ip),
  17. dailyRateLimit.limit(ip),
  18. ]);
  19. if (!minuteResult.success || !dailyResult.success) {
  20. const isMinuteLimit = !minuteResult.success;
  21. return new Response(
  22. JSON.stringify({
  23. error: "Rate limit exceeded",
  24. message: isMinuteLimit
  25. ? "Too many requests. Please wait a moment before trying again."
  26. : "Daily limit reached. Please try again tomorrow.",
  27. }),
  28. {
  29. status: 429,
  30. headers: { "Content-Type": "application/json" },
  31. },
  32. );
  33. }
  34. const body = await req.json();
  35. const uiMessages: UIMessage[] = body.messages;
  36. if (!uiMessages || !Array.isArray(uiMessages) || uiMessages.length === 0) {
  37. return new Response(
  38. JSON.stringify({ error: "messages array is required" }),
  39. {
  40. status: 400,
  41. headers: { "Content-Type": "application/json" },
  42. },
  43. );
  44. }
  45. const modelMessages = await convertToModelMessages(uiMessages);
  46. const result = await agent.stream({ messages: modelMessages });
  47. const stream = createUIMessageStream({
  48. execute: async ({ writer }) => {
  49. writer.merge(pipeJsonRender(result.toUIMessageStream()));
  50. },
  51. });
  52. return createUIMessageStreamResponse({ stream });
  53. }