import { NextResponse } from "next/server"; import { isAuthorized } from "@/lib/auth"; import { appendMemory, recallMemories, type MemoryRole, } from "@/lib/memory"; // Cosmos SDK requires the Node.js runtime (not Edge). export const runtime = "nodejs"; export const dynamic = "force-dynamic"; const ROLES: MemoryRole[] = ["user", "assistant", "note"]; /** * GET /api/memory?q=&sessionId=&k=5 — semantic recall. * Requires AUTHOR_API_KEY (memory is private to the agent). */ export async function GET(request: Request) { if (!isAuthorized(request)) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const url = new URL(request.url); const query = url.searchParams.get("q"); if (!query) { return NextResponse.json( { error: "Query param 'q' is required." }, { status: 400 }, ); } const sessionId = url.searchParams.get("sessionId") ?? undefined; const kRaw = Number(url.searchParams.get("k")); const k = Number.isFinite(kRaw) ? kRaw : undefined; const results = await recallMemories({ query, sessionId, k }); return NextResponse.json({ results }); } /** * POST /api/memory — store a memory. * Body: { sessionId, role, content, ttlSeconds? }. Requires AUTHOR_API_KEY. */ export async function POST(request: Request) { if (!isAuthorized(request)) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } let body: { sessionId?: string; role?: string; content?: string; ttlSeconds?: number; }; try { body = await request.json(); } catch { return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 }); } const { sessionId, content } = body; if (!sessionId || !content) { return NextResponse.json( { error: "sessionId and content are required." }, { status: 400 }, ); } const role: MemoryRole = ROLES.includes(body.role as MemoryRole) ? (body.role as MemoryRole) : "note"; const { id } = await appendMemory({ sessionId, role, content, ttlSeconds: body.ttlSeconds, }); return NextResponse.json({ ok: true, id }, { status: 201 }); }