mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
- fix(memory): wrap JSON.parse in try/catch in retrieval.ts to prevent 500 on corrupt metadata; add stats to GET /api/memory response - fix(#949): add sanitizeToolId() to replace invalid chars in cross-provider tool IDs; clamp max_tokens to Math.max(1, value) - feat(skills): add SkillsMP marketplace integration (search + install via /api/skills/marketplace); add skill upload/install modal and DELETE endpoint; wire skillsEnabled guard in executor - feat(settings): add Maintenance section to General tab (Clear Cache + Purge Expired Logs buttons) - feat(lkgp): add lkgpEnabled toggle and Clear LKGP Cache button to Routing settings; add clearAllLKGP(); respect toggle in LKGPStrategyImpl - test: add vitest coverage for all new functionality Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { listMemories, createMemory } from "@/lib/memory/store";
|
|
import { MemoryType } from "@/lib/memory/types";
|
|
import { z } from "zod";
|
|
import { validateBody, isValidationFailure } from "@/shared/validation/helpers";
|
|
|
|
const createMemorySchema = z.object({
|
|
content: z.string().min(1),
|
|
key: z.string().min(1),
|
|
type: z.nativeEnum(MemoryType).default(MemoryType.FACTUAL),
|
|
sessionId: z.string().default(""),
|
|
apiKeyId: z.string().default(""),
|
|
metadata: z.record(z.string(), z.unknown()).default({}),
|
|
expiresAt: z.coerce.date().nullable().default(null),
|
|
});
|
|
|
|
export async function GET(request: Request) {
|
|
try {
|
|
const { searchParams } = new URL(request.url);
|
|
const apiKeyId = searchParams.get("apiKeyId") || undefined;
|
|
const type = (searchParams.get("type") as any) || undefined;
|
|
const sessionId = searchParams.get("sessionId") || undefined;
|
|
const limitParams = searchParams.get("limit");
|
|
const offsetParams = searchParams.get("offset");
|
|
|
|
const memories = await listMemories({
|
|
apiKeyId,
|
|
type,
|
|
sessionId,
|
|
limit: limitParams ? parseInt(limitParams, 10) : undefined,
|
|
offset: offsetParams ? parseInt(offsetParams, 10) : undefined,
|
|
});
|
|
const stats = {
|
|
total: memories.length,
|
|
byType: memories.reduce(
|
|
(acc, m) => {
|
|
acc[m.type] = (acc[m.type] || 0) + 1;
|
|
return acc;
|
|
},
|
|
{} as Record<string, number>
|
|
),
|
|
};
|
|
return NextResponse.json({ memories, stats });
|
|
} catch (err: unknown) {
|
|
const error = err instanceof Error ? err.message : String(err);
|
|
return NextResponse.json({ error }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
export async function POST(request: Request) {
|
|
try {
|
|
const rawBody = await request.json();
|
|
const validation = validateBody(createMemorySchema, rawBody);
|
|
if (isValidationFailure(validation)) {
|
|
return NextResponse.json(validation.error, { status: 400 });
|
|
}
|
|
const memoryId = await createMemory(validation.data);
|
|
return NextResponse.json({ success: true, id: memoryId });
|
|
} catch (err: unknown) {
|
|
const error = err instanceof Error ? err.message : String(err);
|
|
return NextResponse.json({ error }, { status: 400 });
|
|
}
|
|
}
|