S6: i18n-paritet, provenans + eval, copy-skanning, fabricerade-minnes-eval
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildMemoryOverview } from "../src/index.js";
|
||||
import { buildMemoryOverview, deriveMemoryUpdates, renderMemorySummary } from "../src/index.js";
|
||||
import type { AamosClient, AamosResult } from "@app/ai-contracts";
|
||||
import type { AamosTaskType } from "@app/ai-contracts";
|
||||
import type { MemoryItem } from "@app/shared-types";
|
||||
|
||||
function makeItem(overrides: Partial<MemoryItem> = {}): MemoryItem {
|
||||
@@ -79,4 +81,86 @@ describe("buildMemoryOverview", () => {
|
||||
expect(item.pausedLabel).toBe("Paused");
|
||||
expect(item.summary).toBe("Favorite cuisine: swedish");
|
||||
});
|
||||
|
||||
it("renderMemorySummary stödjer S5-value-former", () => {
|
||||
expect(renderMemorySummary({ summarySv: "", value: { favoriteCuisine: "thai" } }, "en-US")).toBe("Favorite cuisine: thai");
|
||||
expect(renderMemorySummary({ summarySv: "", value: { avoidIngredientId: "broccoli" } }, "en-US")).toBe("Avoids ingredient: broccoli");
|
||||
expect(renderMemorySummary({ summarySv: "", value: { goal: "less_waste" } }, "en-US")).toBe("Goal: less_waste");
|
||||
expect(renderMemorySummary({ summarySv: "", value: { primaryGoal: "less_waste" } }, "en-US")).toBe("Primary goal: less_waste");
|
||||
expect(renderMemorySummary({ summarySv: "", value: { allergen: "gluten" } }, "en-US")).toBe("Allergy: gluten");
|
||||
expect(renderMemorySummary({ summarySv: "", value: { spiceLevelMax: 2 } }, "en-US")).toBe("Max spice level: 2");
|
||||
});
|
||||
});
|
||||
|
||||
describe("deriveMemoryUpdates", () => {
|
||||
function fakeAamos(output: unknown): AamosClient {
|
||||
return {
|
||||
async runTask<T extends AamosTaskType>(): Promise<AamosResult<T>> {
|
||||
return {
|
||||
status: "ok",
|
||||
output: output as AamosResult<T>["output"],
|
||||
modelVersion: "fake",
|
||||
promptVersion: "fake",
|
||||
latencyMs: 10,
|
||||
costUsd: 0,
|
||||
inputTokens: 0,
|
||||
outputTokens: 0,
|
||||
};
|
||||
},
|
||||
async healthCheck() {
|
||||
return { ok: true };
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
it("avvisar fabricerade minnen utan event-stöd", async () => {
|
||||
const aamos = fakeAamos({
|
||||
memoryUpdates: [
|
||||
{
|
||||
key: "fabricated",
|
||||
kind: "structured_fact",
|
||||
summarySv: "Påhittad favoriträtt",
|
||||
value: { recipeId: "ghost" },
|
||||
origin: "ai_inferred",
|
||||
confidence: 0.6,
|
||||
expiresAt: null,
|
||||
sourceEventIds: ["event-does-not-exist"],
|
||||
},
|
||||
],
|
||||
});
|
||||
const result = await deriveMemoryUpdates(aamos, {
|
||||
scope: "user",
|
||||
scopeId: "u1",
|
||||
events: [{ id: "evt-real", type: "recipe_cooked", occurredAt: "2026-08-01T12:00:00Z", payload: {} }],
|
||||
existingMemoryKeys: [],
|
||||
consentFlags: { personalization: true, anonymizedImprovement: false, imageTraining: false },
|
||||
});
|
||||
expect(result.proposals).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("behåller grundade minnen med kända event-id", async () => {
|
||||
const aamos = fakeAamos({
|
||||
memoryUpdates: [
|
||||
{
|
||||
key: "grounded",
|
||||
kind: "structured_fact",
|
||||
summarySv: "Ggrundat minne",
|
||||
value: { recipeId: "r1" },
|
||||
origin: "observed",
|
||||
confidence: 0.8,
|
||||
expiresAt: null,
|
||||
sourceEventIds: ["evt-real"],
|
||||
},
|
||||
],
|
||||
});
|
||||
const result = await deriveMemoryUpdates(aamos, {
|
||||
scope: "user",
|
||||
scopeId: "u1",
|
||||
events: [{ id: "evt-real", type: "recipe_cooked", occurredAt: "2026-08-01T12:00:00Z", payload: {} }],
|
||||
existingMemoryKeys: [],
|
||||
consentFlags: { personalization: true, anonymizedImprovement: false, imageTraining: false },
|
||||
});
|
||||
expect(result.proposals).toHaveLength(1);
|
||||
expect(result.proposals[0]!.key).toBe("grounded");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user