import test from "node:test"; import assert from "node:assert/strict"; import os from "node:os"; import path from "node:path"; import { mkdtemp, rm } from "node:fs/promises"; let runtimeRoot = ""; let queueMasterAgentTask: (typeof import("../src/lib/boss-data"))["queueMasterAgentTask"]; let completeMasterAgentTask: (typeof import("../src/lib/boss-data"))["completeMasterAgentTask"]; let listUserMasterMemories: (typeof import("../src/lib/boss-data"))["listUserMasterMemories"]; let readState: (typeof import("../src/lib/boss-data"))["readState"]; let writeState: (typeof import("../src/lib/boss-data"))["writeState"]; async function setup() { if (runtimeRoot) return; runtimeRoot = await mkdtemp(path.join(os.tmpdir(), "boss-master-agent-memory-ingestion-")); process.env.BOSS_RUNTIME_ROOT = runtimeRoot; process.env.BOSS_STATE_FILE = path.join(runtimeRoot, "boss-state.json"); const data = await import("../src/lib/boss-data.ts"); queueMasterAgentTask = data.queueMasterAgentTask; completeMasterAgentTask = data.completeMasterAgentTask; listUserMasterMemories = data.listUserMasterMemories; readState = data.readState; writeState = data.writeState; } async function ensureBossProject() { const state = await readState(); if (state.projects.some((project) => project.id === "boss")) { return; } await writeState({ ...state, projects: [ ...state.projects, { id: "boss", name: "boss", pinned: false, systemPinned: false, deviceIds: ["mac-studio"], preview: "等待项目同步。", updatedAt: "2026-04-03T10:00:00+08:00", lastMessageAt: "2026-04-03T10:00:00+08:00", isGroup: false, unreadCount: 0, riskLevel: "low", contextBudgetPct: 80, contextBudgetLabel: "80%", threadMeta: { projectId: "boss", threadId: "boss-thread", threadDisplayName: "Boss开发主线程", folderName: "boss", activityIconCount: 0, updatedAt: "2026-04-03T10:00:00+08:00", codexFolderRef: "/Users/kris/code/boss", codexThreadRef: "boss-thread", }, groupMembers: [], messages: [], goals: [], versions: [], createdByAgent: true, collaborationMode: "development", approvalState: "not_required", lightDispatchReminderEnabled: false, }, ], }); } test.after(async () => { if (runtimeRoot) { await rm(runtimeRoot, { recursive: true, force: true }); } }); test("主 Agent 完成对话后会自动沉淀用户偏好和项目记忆", async () => { await setup(); await ensureBossProject(); const task = await queueMasterAgentTask({ projectId: "master-agent", requestMessageId: "msg-user-1", requestText: "boss 项目后续都按微信式交互来做,并且默认中文回复。", executionPrompt: "prompt", requestedBy: "krisolo", requestedByAccount: "krisolo", deviceId: "master-agent-openai", }); await completeMasterAgentTask({ taskId: task.taskId, deviceId: "master-agent-openai", status: "completed", replyBody: "boss 项目当前进度已更新:会话页会继续按微信式交互推进。", }); const memories = await listUserMasterMemories("krisolo", { includeArchived: false }); const globalMemory = memories.find((memory) => memory.scope === "global"); const projectMemory = memories.find((memory) => memory.scope === "project" && memory.projectId === "boss"); assert.ok(globalMemory, "expected a global user memory"); assert.ok(projectMemory, "expected a project-scoped memory"); assert.match(globalMemory?.content ?? "", /微信式交互|中文回复/); assert.match(projectMemory?.content ?? "", /boss 项目当前进度已更新/); }); test("主 Agent 不会把低价值短句和瞬时安排自动写入记忆", async () => { await setup(); const task = await queueMasterAgentTask({ projectId: "master-agent", requestMessageId: "msg-user-2", requestText: "好的,先这样,稍后我再看。", executionPrompt: "prompt", requestedBy: "krisolo", requestedByAccount: "krisolo", deviceId: "master-agent-openai", }); await completeMasterAgentTask({ taskId: task.taskId, deviceId: "master-agent-openai", status: "completed", replyBody: "好的,稍后继续。", }); const memories = await listUserMasterMemories("krisolo", { includeArchived: false }); const noisyMemory = memories.find( (memory) => (memory.content ?? "").includes("先这样") || (memory.content ?? "").includes("稍后继续"), ); assert.equal(noisyMemory, undefined); });