feat(memory): clôture du sujet mémoire — bascule adaptative live + panneau UI (§14.5.5)

Pièce 1 (backend) : state.rs câble AdaptiveMemoryRecall via build_memory_recall,
piloté par le profil embedder chargé depuis embedder.json (fallback none). Défaut
none ⇒ NaiveMemoryRecall nu (comportement inchangé, StubEmbedder jamais touché,
zéro dépendance lourde). Instance de recall partagée (RecallMemory + LaunchAgent).
Chargement du profil isolé sur un runtime dédié (évite le block_on imbriqué).

Pièce 2 (frontend) : feature mémoire complète en miroir de skills —
MemoryGateway (port) + TauriMemoryGateway + MockMemoryGateway, types domaine
Memory/MemoryIndexEntry/MemoryType, MemoryPanel/MemoryEditor/useMemory, onglet
sidebar « Memory » dans ProjectsView. CRUD par slug, liens [[slug]] résolus.

Le sujet mémoire est clos : CRUD .md + index + rappel adaptatif + injection à
l'activation des agents + UI de gestion. Embedder concret ONNX/HTTP reste un
follow-up (défaut none = pleinement fonctionnel sans dépendance).

Tests: backend 57 binaires verts, frontend 285 tests verts, typecheck OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-08 13:28:27 +02:00
parent 2435857cbf
commit f3bc3f20d8
16 changed files with 1414 additions and 10 deletions

View File

@ -23,6 +23,10 @@ import type {
LayoutList,
LayoutOperation,
LayoutTree,
Memory,
MemoryIndexEntry,
MemoryLink,
MemoryType,
Project,
ProfileAvailability,
Skill,
@ -365,6 +369,52 @@ export interface SkillGateway {
): Promise<void>;
}
/** Input for {@link MemoryGateway.createMemory}. */
export interface CreateMemoryInput {
/** Owning project (resolved to its `.ideai/` memory store). */
projectId: string;
/** Human title; also the source of the note's slug identity. */
name: string;
description: string;
type: MemoryType;
content: string;
}
/**
* Memory (L14): CRUD over project memory notes + the recall-oriented index and
* `[[wikilink]]` resolution. Identity is the **slug** (kebab-case), not a UUID;
* a note's slug is immutable, so `updateMemory` never changes it. Mirrors the
* seven backend memory commands (+ optional `recall`).
*/
export interface MemoryGateway {
/** Lists every memory note of a project (full payloads). */
listMemories(projectId: string): Promise<Memory[]>;
/** Reads a single note by slug. */
getMemory(projectId: string, slug: string): Promise<Memory>;
/** Creates a new note; returns the created note. */
createMemory(input: CreateMemoryInput): Promise<Memory>;
/** Updates a note's mutable fields (slug is immutable); returns the updated note. */
updateMemory(
projectId: string,
slug: string,
description: string,
type: MemoryType,
content: string,
): Promise<Memory>;
/** Deletes a note by slug. */
deleteMemory(projectId: string, slug: string): Promise<void>;
/** Reads the recall-oriented memory index. */
readIndex(projectId: string): Promise<MemoryIndexEntry[]>;
/** Resolves a note's `[[wikilinks]]` to the slugs of existing target notes. */
resolveLinks(projectId: string, slug: string): Promise<MemoryLink[]>;
/** Best-effort recall: the index entries most relevant to `text`, within a token budget. */
recall(
projectId: string,
text: string,
tokenBudget: number,
): Promise<MemoryIndexEntry[]>;
}
/**
* AI profiles & first-run (L5). Drives the first-run wizard and profile
* management: the pre-filled reference catalogue, detection of installed CLIs,
@ -402,4 +452,5 @@ export interface Gateways {
profile: ProfileGateway;
template: TemplateGateway;
skill: SkillGateway;
memory: MemoryGateway;
}