M3b:世谱激活接入组装管线(关键词命中/常驻/预算/符文展开)与前端记忆治理页(候选箱/重忆确认/正影/删除/实录溯源)

This commit is contained in:
chenxin committed 2026-08-27 09:22:20 +08:00
1 parent eb0027757d
commit e914aec9c4
8 files changed
+569 -1

No files matched your search

+1
View File
@@ -20,6 +20,7 @@ export * as settingsApi from "./settings";
export * as importsApi from "./imports";
export * as extractionApi from "./extraction";
export * as worldApi from "./world";
export * as memoriesApi from "./memories";
export * as lorebooksApi from "./lorebooks";
export * as skillsApi from "./skills";
export * as mcpApi from "./mcp";
+34
View File
@@ -0,0 +1,34 @@
import { describe, expect, it, vi } from "vitest";
vi.mock("./client", () => ({
apiGet: vi.fn(),
apiPost: vi.fn(),
apiDelete: vi.fn(),
}));
import { apiGet, apiPost } from "./client";
import { confirmMemory, correctMemory, listMemories } from "./memories";
describe("memories api", () => {
it("listMemories GET /characters/:id/memories 带筛选", async () => {
vi.mocked(apiGet).mockResolvedValue([]);
await listMemories("character_1", { status: "pending" });
expect(apiGet).toHaveBeenCalledWith("/characters/character_1/memories", {
status: "pending",
});
});
it("confirmMemory POST /memories/:id/confirm", async () => {
vi.mocked(apiPost).mockResolvedValue({ id: "memory_1", status: "active" });
await confirmMemory("memory_1");
expect(apiPost).toHaveBeenCalledWith("/memories/memory_1/confirm");
});
it("correctMemory POST /memories/:id/correct", async () => {
vi.mocked(apiPost).mockResolvedValue({ id: "memory_2" });
await correctMemory("memory_1", "新版本");
expect(apiPost).toHaveBeenCalledWith("/memories/memory_1/correct", {
new_content: "新版本",
});
});
});
+64
View File
@@ -0,0 +1,64 @@
/** 息壤记忆 API Client(api-contracts §3.5)。 */
import { apiDelete, apiGet, apiPost } from "./client";
export interface XirangMemory {
id: string;
character_id: string;
tier: "trace" | "explicit" | "sensitive";
type: string;
status: "candidate" | "pending" | "active" | "superseded" | "tombstoned";
source: string;
content: string;
source_refs: string[];
sensitivity: string;
priority: number;
confidence: number;
vitality: number;
realm: string;
prev_version_id: string | null;
recall_count: number;
last_recalled_at: string | null;
created_at: string;
}
export interface FactualRecordView {
id: string;
canonization_id: string;
summary: string;
evidence: { path_nodes?: string[] };
occurred_at: string;
}
export function listMemories(
characterId: string,
filters?: { tier?: string; status?: string; type?: string },
) {
return apiGet<XirangMemory[]>(`/characters/${characterId}/memories`, filters);
}
export function confirmMemory(memoryId: string) {
return apiPost<XirangMemory>(`/memories/${memoryId}/confirm`);
}
export function denyMemory(memoryId: string) {
return apiPost<{ memory_id: string; exited_retrieval: boolean }>(
`/memories/${memoryId}/deny`,
);
}
export function correctMemory(memoryId: string, newContent: string) {
return apiPost<XirangMemory>(`/memories/${memoryId}/correct`, {
new_content: newContent,
});
}
export function deleteMemory(memoryId: string) {
return apiDelete<void>(`/memories/${memoryId}`);
}
export function listFactualRecords(characterId: string) {
return apiGet<FactualRecordView[]>(
`/characters/${characterId}/factual-records`,
);
}