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:
71
frontend/src/adapters/memory.ts
Normal file
71
frontend/src/adapters/memory.ts
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Tauri adapter for {@link MemoryGateway} (L14).
|
||||
*
|
||||
* Commands use snake_case (Tauri convention); payload keys are camelCase
|
||||
* (matching the backend DTO `#[serde(rename_all = "camelCase")]`), consistent
|
||||
* with the other adapters in this directory. Mutating commands that take a
|
||||
* structured request (`create_memory`, `update_memory`, `recall_memory`) wrap
|
||||
* their fields under a `request` key; the read commands pass their args flat.
|
||||
* Identity is the immutable **slug**, so `updateMemory` never sends a name.
|
||||
*/
|
||||
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
import type { Memory, MemoryIndexEntry, MemoryLink, MemoryType } from "@/domain";
|
||||
import type { CreateMemoryInput, MemoryGateway } from "@/ports";
|
||||
|
||||
export class TauriMemoryGateway implements MemoryGateway {
|
||||
listMemories(projectId: string): Promise<Memory[]> {
|
||||
return invoke<Memory[]>("list_memories", { projectId });
|
||||
}
|
||||
|
||||
getMemory(projectId: string, slug: string): Promise<Memory> {
|
||||
return invoke<Memory>("get_memory", { projectId, slug });
|
||||
}
|
||||
|
||||
createMemory(input: CreateMemoryInput): Promise<Memory> {
|
||||
return invoke<Memory>("create_memory", {
|
||||
request: {
|
||||
projectId: input.projectId,
|
||||
name: input.name,
|
||||
description: input.description,
|
||||
type: input.type,
|
||||
content: input.content,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
updateMemory(
|
||||
projectId: string,
|
||||
slug: string,
|
||||
description: string,
|
||||
type: MemoryType,
|
||||
content: string,
|
||||
): Promise<Memory> {
|
||||
return invoke<Memory>("update_memory", {
|
||||
request: { projectId, slug, description, type, content },
|
||||
});
|
||||
}
|
||||
|
||||
async deleteMemory(projectId: string, slug: string): Promise<void> {
|
||||
await invoke("delete_memory", { projectId, slug });
|
||||
}
|
||||
|
||||
readIndex(projectId: string): Promise<MemoryIndexEntry[]> {
|
||||
return invoke<MemoryIndexEntry[]>("read_memory_index", { projectId });
|
||||
}
|
||||
|
||||
resolveLinks(projectId: string, slug: string): Promise<MemoryLink[]> {
|
||||
return invoke<MemoryLink[]>("resolve_memory_links", { projectId, slug });
|
||||
}
|
||||
|
||||
recall(
|
||||
projectId: string,
|
||||
text: string,
|
||||
tokenBudget: number,
|
||||
): Promise<MemoryIndexEntry[]> {
|
||||
return invoke<MemoryIndexEntry[]>("recall_memory", {
|
||||
request: { projectId, text, tokenBudget },
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user