route.ts 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import {
  2. convertToModelMessages,
  3. createUIMessageStream,
  4. createUIMessageStreamResponse,
  5. type UIMessage,
  6. } from "ai";
  7. import { pipeJsonRender } from "@json-render/core";
  8. import { createAgent } from "@/lib/agent";
  9. export const maxDuration = 60;
  10. export async function POST(req: Request) {
  11. if (!process.env.AI_GATEWAY_API_KEY) {
  12. return new Response(
  13. JSON.stringify({
  14. error: "Missing AI_GATEWAY_API_KEY",
  15. message:
  16. "Set AI_GATEWAY_API_KEY in .env.local to enable AI. See https://vercel.com/ai-gateway.",
  17. }),
  18. { status: 500, headers: { "Content-Type": "application/json" } },
  19. );
  20. }
  21. const body = (await req.json()) as {
  22. messages: UIMessage[];
  23. messageId?: string;
  24. };
  25. if (!body.messages?.length) {
  26. return new Response(
  27. JSON.stringify({ error: "messages array is required" }),
  28. { status: 400, headers: { "Content-Type": "application/json" } },
  29. );
  30. }
  31. // The client generates a stable messageId per turn so the agent can
  32. // namespace state paths and element keys. Fall back to a random id.
  33. const messageId =
  34. body.messageId ?? `m${Math.random().toString(36).slice(2, 8)}`;
  35. const agent = createAgent(messageId);
  36. const modelMessages = await convertToModelMessages(body.messages);
  37. const result = await agent.stream({ messages: modelMessages });
  38. const stream = createUIMessageStream({
  39. execute: async ({ writer }) => {
  40. writer.merge(pipeJsonRender(result.toUIMessageStream()));
  41. },
  42. });
  43. return createUIMessageStreamResponse({ stream });
  44. }