feat(memory): S3 3a minnes-yta + impact-endpoint

This commit is contained in:
Sven (AAMOS AI)
2026-08-11 02:41:39 +07:00
parent 4296a64aef
commit 335cfe0bf6
5 changed files with 873 additions and 2 deletions
+99 -2
View File
@@ -76,6 +76,18 @@ export async function deriveMemoryUpdates(
}));
}
export interface MemoryOverviewItem extends MemoryItem {
summary: string;
/** Lokaliserad etikett för ursprung (user_stated/observed/ai_inferred). */
originLabel: string;
/** Konfidens 0100 %. */
confidencePercent: number;
/** Synlig etikett om posten är pausad. */
pausedLabel?: string;
/** Tydlig gissningsmarkering för ai_inferred (R1). */
guessLabel?: string;
}
/** Gruppera minnesposter för "Vad plattformen vet om mig"-vyn. */
export interface MemoryOverview {
language: string;
@@ -84,7 +96,7 @@ export interface MemoryOverview {
/** Rubrik på begärt språk (i18n M10). titleSv behålls för bakåtkompatibilitet. */
title: string;
titleSv: string;
items: Array<MemoryItem & { summary: string }>;
items: MemoryOverviewItem[];
}>;
totalCount: number;
pausedCount: number;
@@ -177,6 +189,76 @@ const KIND_TITLES: Record<string, Record<MemoryKind, string>> = {
},
};
const UI_LABELS: Record<
string,
{
origin: Record<SignalOrigin, string>;
paused: string;
guess: string;
}
> = {
sv: {
origin: { user_stated: "Du har sagt", observed: "Vi har sett", ai_inferred: "Gissning" },
paused: "Pausad",
guess: "Detta är en gissning bekräfta eller ändra om det stämmer.",
},
en: {
origin: { user_stated: "You said", observed: "We noticed", ai_inferred: "Guess" },
paused: "Paused",
guess: "This is a guess — confirm or change it if it fits.",
},
es: {
origin: { user_stated: "Dijiste", observed: "Notamos", ai_inferred: "Suposición" },
paused: "Pausado",
guess: "Esto es una suposición: confírmala o cámbiala si encaja.",
},
it: {
origin: { user_stated: "Hai detto", observed: "Abbiamo notato", ai_inferred: "Ipotesi" },
paused: "In pausa",
guess: "Questa è un'ipotesi: confermala o modificala se è corretta.",
},
de: {
origin: { user_stated: "Du hast gesagt", observed: "Wir haben bemerkt", ai_inferred: "Vermutung" },
paused: "Pausiert",
guess: "Dies ist eine Vermutung: bestätige oder ändere sie, wenn sie stimmt.",
},
fr: {
origin: { user_stated: "Vous avez dit", observed: "Nous avons remarqué", ai_inferred: "Hypothèse" },
paused: "En pause",
guess: "Ceci est une hypothèse : confirmez ou modifiez si cela vous convient.",
},
da: {
origin: { user_stated: "Du har sagt", observed: "Vi har set", ai_inferred: "Gæt" },
paused: "Pauset",
guess: "Dette er et gæt — bekræft eller ændr det, hvis det passer.",
},
nb: {
origin: { user_stated: "Du har sagt", observed: "Vi har sett", ai_inferred: "Gjettning" },
paused: "Pauset",
guess: "Dette er en gjetning — bekreft eller endre hvis det stemmer.",
},
fi: {
origin: { user_stated: "Olet sanonut", observed: "Olemme huomanneet", ai_inferred: "Arvaus" },
paused: "Tauolla",
guess: "Tämä on arvaus: vahvista tai muuta se, jos se sopii.",
},
nl: {
origin: { user_stated: "Jij zei", observed: "We hebben gezien", ai_inferred: "Gok" },
paused: "Gepauzeerd",
guess: "Dit is een gok: bevestig of pas aan als het klopt.",
},
pl: {
origin: { user_stated: "Powiedziałeś", observed: "Zauważyliśmy", ai_inferred: "Domysł" },
paused: "Wstrzymane",
guess: "To jest przypuszczenie — potwierdź lub zmień, jeśli się zgadza.",
},
pt: {
origin: { user_stated: "Disseste", observed: "Reparámos", ai_inferred: "Suposição" },
paused: "Pausado",
guess: "Isto é uma suposição: confirma ou altera se fizer sentido.",
},
};
/**
* Deterministisk rendering av summary ur strukturerad value (i18n-spec §23, M10).
* Kända value-former renderas per språk; okända faller tillbaka på summarySv
@@ -209,6 +291,7 @@ export function renderMemorySummary(
export function buildMemoryOverview(items: MemoryItem[], languageTag = "sv"): MemoryOverview {
const lang = languageTag.split("-")[0] ?? "sv";
const titles = KIND_TITLES[lang] ?? KIND_TITLES.sv!;
const labels = UI_LABELS[lang] ?? UI_LABELS.sv!;
const byKind = new Map<MemoryKind, MemoryItem[]>();
for (const item of items) {
const list = byKind.get(item.kind) ?? [];
@@ -221,7 +304,21 @@ export function buildMemoryOverview(items: MemoryItem[], languageTag = "sv"): Me
titleSv: KIND_TITLES.sv![kind],
items: list
.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))
.map((i) => ({ ...i, summary: renderMemorySummary(i, languageTag) })),
.map((i) => {
const overviewItem: MemoryOverviewItem = {
...i,
summary: renderMemorySummary(i, languageTag),
originLabel: labels.origin[i.origin] ?? labels.origin.ai_inferred,
confidencePercent: Math.round(i.confidence * 100),
};
if (i.paused) {
overviewItem.pausedLabel = labels.paused;
}
if (i.origin === "ai_inferred") {
overviewItem.guessLabel = labels.guess;
}
return overviewItem;
}),
}));
return {
language: lang,