import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { auth } from "@/app/(auth)/auth"; import { ChatSDKError } from "@/lib/errors"; import { createAgentPreset, getVisibleAgentCategories, getVisibleAgentPresets, } from "@/lib/db/queries"; const listQuerySchema = z.object({ scope: z.enum(["all", "public", "private"]).default("all"), type: z.enum(["image", "video"]).optional(), categoryId: z.string().uuid().optional(), keyword: z.string().trim().max(128).optional(), sort: z.enum(["latest", "hottest", "most_used"]).default("latest"), }); const slotSchema = z.object({ title: z.string().trim().max(128).optional(), promptTemplate: z.string().trim().min(1).max(8000), defaultParams: z.record(z.string(), z.any()).optional(), requireUpload: z.boolean().optional(), uploadLabel: z.string().trim().max(128).optional(), referenceAssetIds: z.array(z.string().uuid()).max(12).optional(), }); const createAgentSchema = z .object({ name: z.string().trim().min(1).max(128), type: z.enum(["image", "video"]), visibility: z.enum(["public", "private"]).default("private"), categoryId: z.string().uuid().optional(), newCategoryName: z.string().trim().min(1).max(64).optional(), description: z.string().trim().max(2000).optional(), defaultModelId: z.string().uuid(), defaultParams: z.record(z.string(), z.any()).optional(), avatarAssetId: z.string().uuid().optional(), slots: z.array(slotSchema).min(1).max(20), }) .superRefine((value, ctx) => { if (value.categoryId && value.newCategoryName) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "categoryId 和 newCategoryName 不能同时传入", path: ["newCategoryName"], }); } if (value.visibility === "public" && !value.categoryId && !value.newCategoryName) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "公开智能体必须选择分类或新建分类", path: ["categoryId"], }); } }); export async function GET(request: NextRequest) { try { const session = await auth(); if (!session?.user?.id) { return NextResponse.json({ success: false, error: "未登录" }, { status: 401 }); } const { searchParams } = new URL(request.url); const query = listQuerySchema.parse({ scope: searchParams.get("scope") || "all", type: searchParams.get("type") || undefined, categoryId: searchParams.get("categoryId") || undefined, keyword: searchParams.get("keyword") || undefined, sort: searchParams.get("sort") || "latest", }); const [presets, categories] = await Promise.all([ getVisibleAgentPresets({ userId: session.user.id, scope: query.scope, type: query.type, categoryId: query.categoryId, keyword: query.keyword, sort: query.sort, }), getVisibleAgentCategories({ userId: session.user.id, scope: query.scope === "private" ? "private" : "all", }), ]); return NextResponse.json({ success: true, data: { categories, public: presets.filter((item) => item.visibility === "public"), private: presets.filter((item) => item.visibility === "private"), }, }); } catch (error) { if (error instanceof ChatSDKError) { return error.toResponse(); } if (error instanceof z.ZodError) { return NextResponse.json( { success: false, error: error.message }, { status: 400 } ); } return NextResponse.json( { success: false, error: "获取智能体列表失败" }, { status: 500 } ); } } export async function POST(request: NextRequest) { try { const session = await auth(); if (!session?.user?.id) { return NextResponse.json({ success: false, error: "未登录" }, { status: 401 }); } const body = await request.json(); const data = createAgentSchema.parse(body); const preset = await createAgentPreset({ userId: session.user.id, name: data.name, type: data.type, visibility: data.visibility, categoryId: data.categoryId, newCategoryName: data.newCategoryName, description: data.description, defaultModelId: data.defaultModelId, defaultParams: data.defaultParams, avatarAssetId: data.avatarAssetId, slots: data.slots, }); return NextResponse.json({ success: true, data: preset }); } catch (error) { if (error instanceof ChatSDKError) { return error.toResponse(); } if (error instanceof z.ZodError) { return NextResponse.json( { success: false, error: error.message }, { status: 400 } ); } return NextResponse.json( { success: false, error: "创建智能体失败" }, { status: 500 } ); } }