From 9000a9f185b878e17dae34e9410202c7db7e4e69 Mon Sep 17 00:00:00 2001 From: kris Date: Wed, 1 Apr 2026 03:36:09 +0800 Subject: [PATCH] docs: add master-agent prompts and memory plan --- ...6-04-01-master-agent-prompts-and-memory.md | 998 ++++++++++++++++++ 1 file changed, 998 insertions(+) create mode 100644 docs/superpowers/plans/2026-04-01-master-agent-prompts-and-memory.md diff --git a/docs/superpowers/plans/2026-04-01-master-agent-prompts-and-memory.md b/docs/superpowers/plans/2026-04-01-master-agent-prompts-and-memory.md new file mode 100644 index 0000000..a5864eb --- /dev/null +++ b/docs/superpowers/plans/2026-04-01-master-agent-prompts-and-memory.md @@ -0,0 +1,998 @@ +# 主 Agent 提示词与记忆分层 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 为主 Agent 建立分层提示词与用户级记忆体系,并在 Web 后台和原生 Android 聊天页提供完整的查看、编辑、自动沉淀和执行接入能力。 + +**Architecture:** 文件型状态中新增管理员全局主提示词、用户私有主提示词和用户记忆实体;`master-agent` 执行链统一合成全局提示词、用户提示词、当前对话附加提示词与相关记忆。Web 后台提供管理员全局主提示词编辑页,Android `master-agent` 聊天页右上角三点菜单新增 `提示词` 与 `记忆` 两个入口,对应独立原生页面完成前台管理。 + +**Tech Stack:** Next.js App Router, TypeScript, file-backed state store, Android AppCompat/Java, node:test, Gradle unit tests + +--- + +### Task 1: 为状态模型补齐主 Agent 提示词与用户记忆结构 + +**Files:** +- Modify: `/Users/kris/code/boss/src/lib/boss-data.ts` +- Modify: `/Users/kris/code/boss/src/lib/boss-projections.ts` +- Test: `/Users/kris/code/boss/tests/master-agent-prompts-memory-state.test.ts` + +- [ ] **Step 1: 写失败测试,覆盖全局提示词、用户提示词、用户记忆的读写** + +```ts +import test from "node:test"; +import assert from "node:assert/strict"; +import { + getMasterAgentPromptPolicy, + updateMasterAgentPromptPolicy, + getUserMasterPrompt, + updateUserMasterPrompt, + listUserMasterMemories, + createUserMasterMemory, + updateUserMasterMemory, + archiveUserMasterMemory, +} from "@/lib/boss-data"; + +test("主 Agent 提示词与用户记忆可读写", async () => { + await updateMasterAgentPromptPolicy({ + globalPrompt: "全局主提示词", + updatedBy: "17600003315", + }); + await updateUserMasterPrompt("17600003315", "用户私有主提示词"); + + const created = await createUserMasterMemory({ + account: "17600003315", + scope: "project", + projectId: "master-agent", + title: "项目进度", + content: "当前主链优先打通聊天闭环。", + memoryType: "project_progress", + tags: ["聊天", "主链"], + }); + + await updateUserMasterMemory(created.memoryId, "17600003315", { + content: "当前主链优先打通主 Agent 聊天闭环。", + tags: ["聊天", "主Agent"], + }); + + const policy = await getMasterAgentPromptPolicy(); + const userPrompt = await getUserMasterPrompt("17600003315"); + const memories = await listUserMasterMemories("17600003315", { + includeArchived: false, + }); + + assert.equal(policy?.globalPrompt, "全局主提示词"); + assert.equal(userPrompt?.content, "用户私有主提示词"); + assert.equal(memories.length, 1); + assert.equal(memories[0]?.content, "当前主链优先打通主 Agent 聊天闭环。"); + assert.deepEqual(memories[0]?.tags, ["聊天", "主Agent"]); + + await archiveUserMasterMemory(created.memoryId, "17600003315"); + const visible = await listUserMasterMemories("17600003315", { includeArchived: false }); + const all = await listUserMasterMemories("17600003315", { includeArchived: true }); + assert.equal(visible.length, 0); + assert.equal(all[0]?.archived, true); +}); +``` + +- [ ] **Step 2: 跑测试确认当前失败** + +Run: + +```bash +cd /Users/kris/code/boss +npx --yes tsx --test tests/master-agent-prompts-memory-state.test.ts +``` + +Expected: + +```text +FAIL ... getMasterAgentPromptPolicy is not a function +``` + +- [ ] **Step 3: 在状态模型中新增提示词与记忆结构** + +```ts +export interface MasterAgentPromptPolicy { + globalPrompt: string; + updatedAt: string; + updatedBy?: string; +} + +export interface UserMasterPrompt { + account: string; + content: string; + updatedAt: string; +} + +export type MasterMemoryScope = "global" | "project"; +export type MasterMemoryType = + | "user_preference" + | "project_progress" + | "decision" + | "risk" + | "blocking_issue" + | "research_note" + | "workflow_rule"; + +export interface MasterAgentMemory { + memoryId: string; + account: string; + scope: MasterMemoryScope; + projectId?: string; + title: string; + content: string; + memoryType: MasterMemoryType; + tags: string[]; + sourceMessageId?: string; + createdAt: string; + updatedAt: string; + lastUsedAt?: string; + archived: boolean; +} +``` + +- [ ] **Step 4: 增加状态读写 helper** + +```ts +export async function getMasterAgentPromptPolicy() { + const state = await readState(); + return state.masterAgentPromptPolicy ?? null; +} + +export async function updateMasterAgentPromptPolicy(input: { + globalPrompt: string; + updatedBy?: string; +}) { + return withStateLock(async (state) => { + state.masterAgentPromptPolicy = { + globalPrompt: input.globalPrompt.trim(), + updatedBy: input.updatedBy, + updatedAt: new Date().toISOString(), + }; + return state.masterAgentPromptPolicy; + }); +} + +export async function getUserMasterPrompt(account: string) { + const state = await readState(); + return state.userMasterPrompts.find((item) => item.account === account) ?? null; +} + +export async function updateUserMasterPrompt(account: string, content: string) { + return withStateLock(async (state) => { + const existing = state.userMasterPrompts.find((item) => item.account === account); + const next = { + account, + content: content.trim(), + updatedAt: new Date().toISOString(), + }; + if (existing) Object.assign(existing, next); + else state.userMasterPrompts.unshift(next); + return next; + }); +} +``` + +- [ ] **Step 5: 增加用户记忆 CRUD helper** + +```ts +export async function createUserMasterMemory(input: { + account: string; + scope: MasterMemoryScope; + projectId?: string; + title: string; + content: string; + memoryType: MasterMemoryType; + tags?: string[]; + sourceMessageId?: string; +}) { + return withStateLock(async (state) => { + const now = new Date().toISOString(); + const memory: MasterAgentMemory = { + memoryId: createStableId("memory"), + account: input.account, + scope: input.scope, + projectId: input.scope === "project" ? input.projectId : undefined, + title: input.title.trim(), + content: input.content.trim(), + memoryType: input.memoryType, + tags: normalizeTags(input.tags ?? []), + sourceMessageId: input.sourceMessageId, + createdAt: now, + updatedAt: now, + lastUsedAt: now, + archived: false, + }; + state.masterAgentMemories.unshift(memory); + return memory; + }); +} +``` + +- [ ] **Step 6: 再跑测试确认通过** + +Run: + +```bash +cd /Users/kris/code/boss +npx --yes tsx --test tests/master-agent-prompts-memory-state.test.ts +``` + +Expected: + +```text +# tests 1 +# pass 1 +``` + +- [ ] **Step 7: Commit** + +```bash +cd /Users/kris/code/boss +git add tests/master-agent-prompts-memory-state.test.ts src/lib/boss-data.ts src/lib/boss-projections.ts +git commit -m "feat: add master-agent prompt and memory state" +``` + +### Task 2: 接入主 Agent 执行链,真正合成三层提示词与用户记忆 + +**Files:** +- Modify: `/Users/kris/code/boss/src/lib/boss-master-agent.ts` +- Test: `/Users/kris/code/boss/tests/master-agent-prompt-assembly.test.ts` + +- [ ] **Step 1: 写失败测试,覆盖提示词和记忆的执行合成顺序** + +```ts +import test from "node:test"; +import assert from "node:assert/strict"; +import { + updateMasterAgentPromptPolicy, + updateUserMasterPrompt, + updateProjectAgentControls, + createUserMasterMemory, +} from "@/lib/boss-data"; +import { buildMasterAgentExecutionEnvelopeForTesting } from "@/lib/boss-master-agent"; + +test("主 Agent 执行上下文按全局提示词 -> 用户提示词 -> 对话提示词 -> 相关记忆拼装", async () => { + await updateMasterAgentPromptPolicy({ + globalPrompt: "全局规则:回复务必中文。", + updatedBy: "17600003315", + }); + await updateUserMasterPrompt("17600003315", "用户规则:尽量直接给下一步。"); + await updateProjectAgentControls("master-agent", { + promptOverride: "当前对话:优先聚焦主 Agent 聊天链。", + }); + await createUserMasterMemory({ + account: "17600003315", + scope: "global", + title: "长期偏好", + content: "用户偏好微信式交互。", + memoryType: "user_preference", + tags: ["UI"], + }); + await createUserMasterMemory({ + account: "17600003315", + scope: "project", + projectId: "master-agent", + title: "当前主链", + content: "当前优先打通主 Agent 聊天体验。", + memoryType: "project_progress", + tags: ["聊天"], + }); + + const digest = await buildMasterAgentExecutionEnvelopeForTesting({ + projectId: "master-agent", + account: "17600003315", + requestText: "下一步做什么?", + }); + + assert.match(digest, /全局规则:回复务必中文/); + assert.match(digest, /用户规则:尽量直接给下一步/); + assert.match(digest, /当前对话:优先聚焦主 Agent 聊天链/); + assert.match(digest, /用户偏好微信式交互/); + assert.match(digest, /当前优先打通主 Agent 聊天体验/); +}); +``` + +- [ ] **Step 2: 跑测试确认当前失败** + +Run: + +```bash +cd /Users/kris/code/boss +npx --yes tsx --test tests/master-agent-prompt-assembly.test.ts +``` + +Expected: + +```text +FAIL ... buildMasterAgentExecutionEnvelopeForTesting is not a function +``` + +- [ ] **Step 3: 在 `boss-master-agent.ts` 中增加提示词/记忆解析函数** + +```ts +async function resolveMasterAgentPromptLayers(account: string, projectId: string) { + const [policy, userPrompt, controls, memories] = await Promise.all([ + getMasterAgentPromptPolicy(), + getUserMasterPrompt(account), + getProjectAgentControls(projectId), + listUserMasterMemories(account, { + includeArchived: false, + projectId, + }), + ]); + + return { + globalPrompt: policy?.globalPrompt?.trim() || "", + userPrompt: userPrompt?.content?.trim() || "", + conversationPrompt: controls?.promptOverride?.trim() || "", + memories, + }; +} +``` + +- [ ] **Step 4: 实现最终 prompt/记忆组合** + +```ts +function buildPromptAssembly(input: { + globalPrompt: string; + userPrompt: string; + conversationPrompt: string; + memories: MasterAgentMemory[]; +}) { + const sections = [ + input.globalPrompt && `【管理员全局主提示词】\n${input.globalPrompt}`, + input.userPrompt && `【用户私有主提示词】\n${input.userPrompt}`, + input.conversationPrompt && `【当前对话附加提示词】\n${input.conversationPrompt}`, + input.memories.length + ? `【记忆】\n${input.memories.map((item) => `- ${item.title}:${item.content}`).join("\n")}` + : "", + ].filter(Boolean); + + return sections.join("\n\n"); +} +``` + +- [ ] **Step 5: 把组合结果接到 OpenAI / Master Node 执行路径** + +```ts +const promptLayers = await resolveMasterAgentPromptLayers(params.requestedByAccount ?? "", "master-agent"); +const assembledPrompt = buildPromptAssembly(promptLayers); + +const instructions = [ + buildMasterAgentInstructions(), + assembledPrompt, +].filter(Boolean).join("\n\n"); +``` + +- [ ] **Step 6: 再跑测试确认通过** + +Run: + +```bash +cd /Users/kris/code/boss +npx --yes tsx --test tests/master-agent-prompt-assembly.test.ts +``` + +Expected: + +```text +# tests 1 +# pass 1 +``` + +- [ ] **Step 7: Commit** + +```bash +cd /Users/kris/code/boss +git add tests/master-agent-prompt-assembly.test.ts src/lib/boss-master-agent.ts +git commit -m "feat: apply layered prompts and memories to master-agent" +``` + +### Task 3: 加入自动记忆沉淀、项目/用户分流与基础去重 + +**Files:** +- Modify: `/Users/kris/code/boss/src/lib/boss-master-agent.ts` +- Modify: `/Users/kris/code/boss/src/lib/boss-data.ts` +- Test: `/Users/kris/code/boss/tests/master-agent-memory-ingestion.test.ts` + +- [ ] **Step 1: 写失败测试,覆盖项目记忆和用户记忆自动分流** + +```ts +import test from "node:test"; +import assert from "node:assert/strict"; +import { ingestMasterAgentMemoriesForTesting } from "@/lib/boss-master-agent"; +import { listUserMasterMemories } from "@/lib/boss-data"; + +test("自动记忆沉淀会按项目进度与用户偏好分流", async () => { + await ingestMasterAgentMemoriesForTesting({ + account: "17600003315", + projectId: "master-agent", + userMessage: "我更喜欢微信式交互,这个项目当前重点是主 Agent 聊天主链。", + replyText: "收到。", + }); + + const memories = await listUserMasterMemories("17600003315", { includeArchived: false }); + assert.ok(memories.some((item) => item.scope === "global" && /微信式交互/.test(item.content))); + assert.ok(memories.some((item) => item.scope === "project" && item.projectId === "master-agent" && /主 Agent 聊天主链/.test(item.content))); +}); +``` + +- [ ] **Step 2: 跑测试确认当前失败** + +Run: + +```bash +cd /Users/kris/code/boss +npx --yes tsx --test tests/master-agent-memory-ingestion.test.ts +``` + +Expected: + +```text +FAIL ... ingestMasterAgentMemoriesForTesting is not a function +``` + +- [ ] **Step 3: 实现基础自动分类规则** + +```ts +function inferMemoryCandidates(input: { userMessage: string; projectId: string }) { + const candidates = []; + if (/微信式交互|中文回复|直接给下一步/.test(input.userMessage)) { + candidates.push({ + scope: "global", + memoryType: "user_preference", + title: "用户偏好", + content: input.userMessage, + }); + } + if (/项目|主链|阻塞|进度|决策/.test(input.userMessage)) { + candidates.push({ + scope: "project", + projectId: input.projectId, + memoryType: "project_progress", + title: "项目进度", + content: input.userMessage, + }); + } + return candidates; +} +``` + +- [ ] **Step 4: 实现基础去重/合并** + +```ts +function isSimilarMemory(existing: MasterAgentMemory, incoming: { + scope: MasterMemoryScope; + projectId?: string; + title: string; + memoryType: MasterMemoryType; +}) { + return ( + existing.scope === incoming.scope && + (existing.projectId || "") === (incoming.projectId || "") && + existing.memoryType === incoming.memoryType && + existing.title === incoming.title + ); +} +``` + +- [ ] **Step 5: 在主 Agent 回复完成链路里接自动沉淀** + +```ts +if (params.requestedByAccount) { + await maybeIngestMasterAgentMemories({ + account: params.requestedByAccount, + projectId: "master-agent", + userMessage: params.requestText, + replyText: generated.content, + sourceMessageId: params.requestMessageId, + }); +} +``` + +- [ ] **Step 6: 再跑测试确认通过** + +Run: + +```bash +cd /Users/kris/code/boss +npx --yes tsx --test tests/master-agent-memory-ingestion.test.ts +``` + +Expected: + +```text +# tests 1 +# pass 1 +``` + +- [ ] **Step 7: Commit** + +```bash +cd /Users/kris/code/boss +git add tests/master-agent-memory-ingestion.test.ts src/lib/boss-master-agent.ts src/lib/boss-data.ts +git commit -m "feat: auto-ingest master-agent memories" +``` + +### Task 4: 新增管理员全局主提示词 Web 后台接口与页面 + +**Files:** +- Create: `/Users/kris/code/boss/src/app/api/v1/master-agent/prompt-policy/route.ts` +- Create: `/Users/kris/code/boss/src/app/me/ops/master-agent/page.tsx` +- Test: `/Users/kris/code/boss/tests/master-agent-prompt-policy-route.test.ts` + +- [ ] **Step 1: 写失败测试,覆盖管理员可读写全局主提示词** + +```ts +import test from "node:test"; +import assert from "node:assert/strict"; +import { NextRequest } from "next/server"; +import { GET, POST } from "@/app/api/v1/master-agent/prompt-policy/route"; + +test("管理员可读写全局主提示词", async () => { + const post = await POST(new NextRequest("http://127.0.0.1:3000/api/v1/master-agent/prompt-policy", { + method: "POST", + headers: { + "content-type": "application/json", + cookie: await createAdminCookieForTesting(), + }, + body: JSON.stringify({ globalPrompt: "全局主提示词" }), + })); + assert.equal(post.status, 200); + + const get = await GET(new NextRequest("http://127.0.0.1:3000/api/v1/master-agent/prompt-policy", { + headers: { cookie: await createAdminCookieForTesting() }, + })); + const payload = await get.json(); + assert.equal(payload.policy.globalPrompt, "全局主提示词"); +}); +``` + +- [ ] **Step 2: 跑测试确认当前失败** + +Run: + +```bash +cd /Users/kris/code/boss +npx --yes tsx --test tests/master-agent-prompt-policy-route.test.ts +``` + +Expected: + +```text +FAIL ... Cannot find module ... prompt-policy/route +``` + +- [ ] **Step 3: 实现路由** + +```ts +export async function GET(request: NextRequest) { + const session = await requireRequestSession(request); + if (!session) return NextResponse.json({ ok: false, message: "UNAUTHORIZED" }, { status: 401 }); + if (session.role !== "highest_admin") { + return NextResponse.json({ ok: false, message: "FORBIDDEN" }, { status: 403 }); + } + const policy = await getMasterAgentPromptPolicy(); + return NextResponse.json({ ok: true, policy }); +} +``` + +- [ ] **Step 4: 实现 Web 后台页面** + +```tsx +export default async function MasterAgentPromptPolicyPage() { + const policy = await getMasterAgentPromptPolicy(); + return ( +
+

主 Agent 全局主提示词

+

这层提示词对所有用户生效,且不可被覆盖。

+ +
+ ); +} +``` + +- [ ] **Step 5: 再跑测试确认通过** + +Run: + +```bash +cd /Users/kris/code/boss +npx --yes tsx --test tests/master-agent-prompt-policy-route.test.ts +``` + +Expected: + +```text +# tests 1 +# pass 1 +``` + +- [ ] **Step 6: Commit** + +```bash +cd /Users/kris/code/boss +git add src/app/api/v1/master-agent/prompt-policy/route.ts src/app/me/ops/master-agent/page.tsx tests/master-agent-prompt-policy-route.test.ts +git commit -m "feat: add master-agent global prompt policy" +``` + +### Task 5: 新增用户提示词与记忆 API + +**Files:** +- Create: `/Users/kris/code/boss/src/app/api/v1/master-agent/user-prompt/route.ts` +- Create: `/Users/kris/code/boss/src/app/api/v1/master-agent/memories/route.ts` +- Create: `/Users/kris/code/boss/src/app/api/v1/master-agent/memories/[memoryId]/route.ts` +- Test: `/Users/kris/code/boss/tests/master-agent-memory-routes.test.ts` + +- [ ] **Step 1: 写失败测试,覆盖用户私有提示词与记忆 CRUD** + +```ts +import test from "node:test"; +import assert from "node:assert/strict"; + +test("用户可更新私有提示词并维护主 Agent 记忆", async () => { + const cookie = await createAdminCookieForTesting(); + const promptResponse = await postUserPrompt(cookie, "请始终用中文直接回复"); + assert.equal(promptResponse.status, 200); + + const created = await postMemory(cookie, { + scope: "global", + title: "用户偏好", + content: "偏好微信式交互", + memoryType: "user_preference", + }); + assert.equal(created.status, 200); +}); +``` + +- [ ] **Step 2: 跑测试确认当前失败** + +Run: + +```bash +cd /Users/kris/code/boss +npx --yes tsx --test tests/master-agent-memory-routes.test.ts +``` + +Expected: + +```text +FAIL ... Cannot find module ... /user-prompt/route +``` + +- [ ] **Step 3: 实现用户私有提示词路由** + +```ts +export async function POST(request: NextRequest) { + const session = await requireRequestSession(request); + if (!session) return NextResponse.json({ ok: false, message: "UNAUTHORIZED" }, { status: 401 }); + const body = await request.json(); + const prompt = await updateUserMasterPrompt(session.account, String(body.content ?? "")); + return NextResponse.json({ ok: true, prompt }); +} +``` + +- [ ] **Step 4: 实现记忆列表与新增路由** + +```ts +export async function GET(request: NextRequest) { + const session = await requireRequestSession(request); + if (!session) return NextResponse.json({ ok: false, message: "UNAUTHORIZED" }, { status: 401 }); + const { searchParams } = new URL(request.url); + const projectId = searchParams.get("projectId") ?? undefined; + const includeArchived = searchParams.get("includeArchived") === "true"; + const memories = await listUserMasterMemories(session.account, { projectId, includeArchived }); + return NextResponse.json({ ok: true, memories }); +} +``` + +- [ ] **Step 5: 实现单条记忆编辑与删除路由** + +```ts +export async function POST(request: NextRequest, context: { params: Promise<{ memoryId: string }> }) { + const session = await requireRequestSession(request); + if (!session) return NextResponse.json({ ok: false, message: "UNAUTHORIZED" }, { status: 401 }); + const { memoryId } = await context.params; + const body = await request.json(); + const memory = await updateUserMasterMemory(memoryId, session.account, body); + return NextResponse.json({ ok: true, memory }); +} +``` + +- [ ] **Step 6: 再跑测试确认通过** + +Run: + +```bash +cd /Users/kris/code/boss +npx --yes tsx --test tests/master-agent-memory-routes.test.ts +``` + +Expected: + +```text +# tests 1 +# pass 1 +``` + +- [ ] **Step 7: Commit** + +```bash +cd /Users/kris/code/boss +git add src/app/api/v1/master-agent/user-prompt/route.ts src/app/api/v1/master-agent/memories/route.ts src/app/api/v1/master-agent/memories/[memoryId]/route.ts tests/master-agent-memory-routes.test.ts +git commit -m "feat: add master-agent prompt and memory routes" +``` + +### Task 6: Android 三点菜单新增提示词与记忆入口,并实现原生提示词页 + +**Files:** +- Modify: `/Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/ProjectDetailActivity.java` +- Modify: `/Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/BossApiClient.java` +- Create: `/Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/MasterAgentPromptActivity.java` +- Test: `/Users/kris/code/boss/android/app/src/test/java/com/hyzq/boss/ProjectDetailActivityMasterAgentMenuTest.java` +- Test: `/Users/kris/code/boss/android/app/src/test/java/com/hyzq/boss/MasterAgentPromptActivityTest.java` + +- [ ] **Step 1: 写失败测试,覆盖三点菜单新增项** + +```java +@Test +public void masterAgentMenuShowsPromptAndMemoryEntries() { + ProjectDetailActivity activity = Robolectric.buildActivity(ProjectDetailActivity.class).setup().get(); + ReflectionHelpers.setField(activity, "projectId", "master-agent"); + ReflectionHelpers.callInstanceMethod(activity, "showMasterAgentMoreMenu"); + + AlertDialog dialog = ShadowAlertDialog.getLatestAlertDialog(); + ListView listView = dialog.getListView(); + assertMenuItem(listView, 0, "提示词"); + assertMenuItem(listView, 1, "记忆"); + assertMenuItem(listView, 2, "模型"); +} +``` + +- [ ] **Step 2: 跑测试确认当前失败** + +Run: + +```bash +cd /Users/kris/code/boss/android +./gradlew testDebugUnitTest --tests com.hyzq.boss.ProjectDetailActivityMasterAgentMenuTest --no-daemon +``` + +Expected: + +```text +FAIL ... expected 提示词 +``` + +- [ ] **Step 3: 扩展 Android API 客户端** + +```java +public ApiResponse getMasterAgentPromptPolicy() throws IOException, JSONException { + return requestWithRestore("GET", "/api/v1/master-agent/prompt-policy", null); +} + +public ApiResponse getUserMasterPrompt() throws IOException, JSONException { + return requestWithRestore("GET", "/api/v1/master-agent/user-prompt", null); +} + +public ApiResponse updateUserMasterPrompt(String content) throws IOException, JSONException { + JSONObject payload = new JSONObject().put("content", content); + return requestWithRestore("POST", "/api/v1/master-agent/user-prompt", payload); +} +``` + +- [ ] **Step 4: 把聊天页三点菜单扩成提示词/记忆/模型/推理强度/会话信息/刷新** + +```java +new AlertDialog.Builder(this) + .setItems(new CharSequence[]{"提示词", "记忆", "模型", "推理强度", "会话信息", "刷新"}, (dialog, which) -> { + if (which == 0) openMasterAgentPrompt(); + else if (which == 1) openMasterAgentMemories(); + else if (which == 2) showMasterAgentModelPicker(); + else if (which == 3) showMasterAgentReasoningPicker(); + else if (which == 4) openConversationInfo(); + else reload(true); + }) + .show(); +``` + +- [ ] **Step 5: 实现原生提示词页** + +```java +public class MasterAgentPromptActivity extends BossScreenActivity { + // 显示管理员全局主提示词(只读) + // 显示我的主提示词(可编辑) + // 显示当前对话附加提示词(可编辑) + // 显示“查看组合结果” +} +``` + +- [ ] **Step 6: 再跑 Android 单测确认通过** + +Run: + +```bash +cd /Users/kris/code/boss/android +./gradlew testDebugUnitTest --tests com.hyzq.boss.ProjectDetailActivityMasterAgentMenuTest --tests com.hyzq.boss.MasterAgentPromptActivityTest --no-daemon +``` + +Expected: + +```text +BUILD SUCCESSFUL +``` + +- [ ] **Step 7: Commit** + +```bash +cd /Users/kris/code/boss +git add android/app/src/main/java/com/hyzq/boss/ProjectDetailActivity.java android/app/src/main/java/com/hyzq/boss/BossApiClient.java android/app/src/main/java/com/hyzq/boss/MasterAgentPromptActivity.java android/app/src/test/java/com/hyzq/boss/ProjectDetailActivityMasterAgentMenuTest.java android/app/src/test/java/com/hyzq/boss/MasterAgentPromptActivityTest.java +git commit -m "feat: add master-agent prompt editor on android" +``` + +### Task 7: 实现原生记忆页,支持新增/编辑/删除 + +**Files:** +- Modify: `/Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/BossApiClient.java` +- Create: `/Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/MasterAgentMemoriesActivity.java` +- Test: `/Users/kris/code/boss/android/app/src/test/java/com/hyzq/boss/MasterAgentMemoriesActivityTest.java` + +- [ ] **Step 1: 写失败测试,覆盖记忆页的新增、编辑、删除入口** + +```java +@Test +public void memoriesScreenShowsAddEditDeleteActions() { + MasterAgentMemoriesActivity activity = Robolectric.buildActivity(MasterAgentMemoriesActivity.class).setup().get(); + LinearLayout root = activity.findViewById(R.id.screen_content_container); + assertTrue(viewTreeContainsText(root, "新增记忆")); +} +``` + +- [ ] **Step 2: 跑测试确认当前失败** + +Run: + +```bash +cd /Users/kris/code/boss/android +./gradlew testDebugUnitTest --tests com.hyzq.boss.MasterAgentMemoriesActivityTest --no-daemon +``` + +Expected: + +```text +FAIL ... MasterAgentMemoriesActivity not found +``` + +- [ ] **Step 3: 扩展 Android API 客户端接记忆路由** + +```java +public ApiResponse listMasterAgentMemories(@Nullable String projectId) throws IOException, JSONException { + String path = "/api/v1/master-agent/memories"; + if (projectId != null && !projectId.isEmpty()) { + path += "?projectId=" + Uri.encode(projectId); + } + return requestWithRestore("GET", path, null); +} +``` + +- [ ] **Step 4: 实现原生记忆页** + +```java +public class MasterAgentMemoriesActivity extends BossScreenActivity { + // section 1: 项目记忆 + // section 2: 我的通用记忆 + // 每条卡片支持编辑/删除 + // 顶部提供新增记忆 +} +``` + +- [ ] **Step 5: 实现新增/编辑/删除对话框** + +```java +private void showMemoryEditor(@Nullable JSONObject memory) { + // title + content + scope + memoryType + tags +} +``` + +- [ ] **Step 6: 再跑 Android 单测确认通过** + +Run: + +```bash +cd /Users/kris/code/boss/android +./gradlew testDebugUnitTest --tests com.hyzq.boss.MasterAgentMemoriesActivityTest --no-daemon +``` + +Expected: + +```text +BUILD SUCCESSFUL +``` + +- [ ] **Step 7: Commit** + +```bash +cd /Users/kris/code/boss +git add android/app/src/main/java/com/hyzq/boss/BossApiClient.java android/app/src/main/java/com/hyzq/boss/MasterAgentMemoriesActivity.java android/app/src/test/java/com/hyzq/boss/MasterAgentMemoriesActivityTest.java +git commit -m "feat: add master-agent memories screen on android" +``` + +### Task 8: 同步 Web 前台、Android Manifest、文档并做总验证 + +**Files:** +- Modify: `/Users/kris/code/boss/android/app/src/main/AndroidManifest.xml` +- Modify: `/Users/kris/code/boss/README.md` +- Modify: `/Users/kris/code/boss/docs/architecture/current_runtime_and_deploy_status_cn.md` +- Modify: `/Users/kris/code/boss/docs/architecture/api_and_service_inventory_cn.md` + +- [ ] **Step 1: 在 Android Manifest 注册新增页面** + +```xml + + +``` + +- [ ] **Step 2: 同步 README 和架构文档** + +```md +- 主 Agent 聊天页右上角当前已新增 `提示词 / 记忆 / 模型 / 推理强度 / 会话信息 / 刷新` +- 管理员全局主提示词当前由 Web 后台配置,用户端只读 +- 用户记忆当前分为项目记忆和用户通用记忆,并支持自动沉淀与手动管理 +``` + +- [ ] **Step 3: 跑 Node 测试** + +Run: + +```bash +cd /Users/kris/code/boss +npx --yes tsx --test tests/master-agent-prompts-memory-state.test.ts tests/master-agent-prompt-assembly.test.ts tests/master-agent-memory-ingestion.test.ts tests/master-agent-prompt-policy-route.test.ts tests/master-agent-memory-routes.test.ts tests/master-agent-chat-controls.test.ts tests/master-agent-message-queue.test.ts +``` + +Expected: + +```text +all tests pass +``` + +- [ ] **Step 4: 跑 Android 单测** + +Run: + +```bash +cd /Users/kris/code/boss/android +./gradlew testDebugUnitTest --tests com.hyzq.boss.ProjectDetailActivityMasterAgentMenuTest --tests com.hyzq.boss.MasterAgentPromptActivityTest --tests com.hyzq.boss.MasterAgentMemoriesActivityTest --tests com.hyzq.boss.AiAccountsActivityTest --no-daemon +``` + +Expected: + +```text +BUILD SUCCESSFUL +``` + +- [ ] **Step 5: 跑 lint 和 build** + +Run: + +```bash +cd /Users/kris/code/boss +npm run lint +npm run build +``` + +Expected: + +```text +lint 通过 +build 通过 +``` + +- [ ] **Step 6: Commit** + +```bash +cd /Users/kris/code/boss +git add android/app/src/main/AndroidManifest.xml README.md docs/architecture/current_runtime_and_deploy_status_cn.md docs/architecture/api_and_service_inventory_cn.md +git commit -m "docs: sync master-agent prompts and memories runtime" +```