Skip to content

feat: Proactive Agent - 主动记忆 + 主动建议 + 主动中心 - #1409

Open
ConradLu2740 wants to merge 36 commits into
proma-ai:mainfrom
ConradLu2740:feat/proactive-agent
Open

feat: Proactive Agent - 主动记忆 + 主动建议 + 主动中心#1409
ConradLu2740 wants to merge 36 commits into
proma-ai:mainfrom
ConradLu2740:feat/proactive-agent

Conversation

@ConradLu2740

Copy link
Copy Markdown

Proactive Agent: 主动记忆 + 主动建议 + 主动中心

为 Proma 增加完整的 Proactive Agent 能力集——让 Agent 从"被动等用户发起"进化到"记得住、会建议、越用越好用"。

完整公式:主动记忆(记得住)+ 主动建议(对的时候提对的建议)+ 反馈闭环(越用越好用)

解决什么问题

Proma 现有的 Auto Memory 依赖 Agent 在 prompt 引导下自觉维护,且 Agent 只能"被动回答",缺少三个关键能力:

  1. 主动记忆:会话结束自动提取结构化长期记忆,跨会话自动召回
  2. 主动建议:Agent 使用过程中识别值得建议的时机,主动提出轻量、可解释、可反馈的建议
  3. 工作模式发现:低频 LLM 分析,发现用户从未明说但反复出现的隐含工作模式

参考 ProactiveAgent(ICLR 2025)的核心发现:所有模型 Recall 98%+ 但误报率 51-65%,"该沉默时沉默"也是能力——主动性 = 用户接受率,不是建议次数。本实现全程贯彻误报控制。


能力一:主动记忆(Proactive Memory)

能力 说明
L1 原子记忆 会话结束钩子自动 LLM 提取(fact / preference / correction / sop / todo_context),fingerprint 去重
混合召回 keyword 精确 + LLM 查询改写 + embedding 语义 + 规则加权,多源融合 + 绝对分阈值
误报控制 归一化评分阈值 + 停用词过滤 + 同义词扩展 + 回忆意图降级
L3 Persona LLM 生成/增量更新用户画像,Markdown 白盒可审计
反馈回流 确认/拒绝纠正后自动更新 Persona 交互协议
内置 MCP 工具 memory_search/capture/stats/corrections/confirm/reject(Claude + Pi 双 runtime)
UI 看板 记忆统计、纠正审批、记忆搜索、persona 预览(Agent 能力中心 → 记忆 Tab)
memory-daily Skill 指导每日记忆整理 + 建议创建 daily automation

能力二:主动建议(Proactive Suggestion)

能力 说明
5 类确定性规则 correction(记住纠正)/ followup(跟进提醒)/ automation(定时任务)/ skill(SOP 沉淀)/ todo(待办记录)
信号提取 纠正词 / 时间词 / 周期词 / 未完成词 / 重复意图 + 延后语义/弱意图过滤
误报控制 明确拒绝门 + 频率门槛(raw×weight≥0.6)+ 预算(单次≤1、同会话≤2)+ duplicateKey 去重
频率学习 accepted×1.2 / ignored×0.8 / never 屏蔽 + 连续忽略 3 次自动静默("越用越好用")
会话内横幅 SuggestionBanner:Agent 输入框上方三态卡片(接受/忽略/不再建议这类)
实时推送 新建议生成后 IPC 事件广播,当前会话立即显示

能力三:主动中心 + 工作模式分析(Phase B)

能力 说明
Proactive Today PlanningView「主动」tab:建议卡 / 主动任务 / 待确认审批 / 用户画像 / 统计
工作模式分析器 低频 LLM 分析近期记忆,发现隐含模式(周期任务 / SOP / 待固化偏好)
schema 严格校验 LLM 只能产出候选(类型白名单/字段完整/动作匹配),不能直接创建任务
suggestion_analyze 工具 Pi/Claude 双 runtime 内置工具,定时任务可调
suggestion-daily Skill 指导建立每日工作模式分析 automation

质量保障(子代理驱动验证)

召回与建议系统经 5 轮 collaboration 子代理独立审查/体验迭代打磨:

轮次 发现 结果
记忆召回 3 轮审查 kw 硬截断丢正确答案 / 归一化放大弱命中 / 无关注入 多源融合 + 绝对分阈值 + 无关 gate,12 问矩阵 12/12
建议引擎审查 8 个边界误报 + todo 死锁 + 测试污染 全部修复,42+9 单测
UI 实测 P0:SDKMessage 格式不匹配,引擎从不执行 sdk-messages.ts 修复
401 实测 dev 模式 .env 路径缺口 findDotEnvUpwards 修复
体验评测 P0:规则语义反转 / 两步确认 / 横幅不实时 3 项全修

子代理独立实测发现了自测盲区("功能看似正常但真实链路从不执行"),这是代码审查和单测发现不了的。

验证

  • 全量 typecheck 6 包全绿
  • 全量测试 640+ pass / 4 fail(4 fail 为既有 Electron/planning 环境问题,与本次无关;新增 120+ 测试)
  • 真实 LLM 端到端:提取/召回/persona/建议/分析全部真实验证
  • 真实 UI 实测(CDP 连接真实窗口):横幅渲染、三态交互、主动中心、分析按钮全部通过
  • 真实记忆工作模式分析:92 条记忆 → 发现「ShopGo 促销前压测提醒」(automation)
  • 401 修复:DeepSeek 渠道预设自动填充 .env 凭证,开箱即用

文件概览(74 个文件,+9208 行)

  • packages/shared/src/types/memory.ts + suggestion.ts:类型
  • apps/electron/src/main/lib/memory/:store / recall / extractor / persona / service + 测试
  • apps/electron/src/main/lib/suggest/:signals / rules / engine / feedback / service / analyst / sdk-messages + 测试
  • apps/electron/src/main/lib/agent-orchestrator.ts:会话结束记忆捕获 + 建议评估钩子
  • apps/electron/src/main/lib/channel-manager.ts:DeepSeek 预设渠道自动填充 .env 凭证
  • agent-prompt-builder.ts<memory_context> + <persona_profile> + <working_memory> 注入
  • builtin-mcp:memory / suggestion 内置 MCP 注册(Claude + Pi)
  • ProactiveMemoryPanel.tsx + ProactiveTodayView.tsx + SuggestionBanner.tsx:UI
  • default-skills/memory-daily/ + suggestion-daily/:内置 Skill
  • docs/proactive-memory-design.md + proactive-suggestion-design.md:设计文档
  • scripts/:smoke / verify / demo / stress 脚本

设计文档

  • docs/proactive-memory-design.md:记忆系统(架构/分层/模块/接线/验证)
  • docs/proactive-suggestion-design.md:建议系统 + 主动中心 + 分析器

Made with Proma · GitHub

魔仙堡 added 28 commits August 3, 2026 20:35
Add MemoryAtom / SceneBlock / PersonaProfile / MemoryCorrection /
MemoryStats / MemorySearchResult types used by the proactive memory
system (L0-L3 layered model inspired by TencentDB-Agent-Memory).

Made-with: Proma
…/extractor/persona)

- store: JSONL day-partitioned atoms with fingerprint dedup, corrections
  approval, persona profile, memory log, crash-safe writes
- recall: Chinese bigram + English token BM25 scoring, stop-word filter,
  synonym expansion, normalized relevance threshold to control false alarms
  (informed by ProactiveAgent paper), recall-intent fallback
- extractor: LLM extraction from conversation via OpenAI-compatible
  endpoint (works with reasoning models like deepseek-v4-flash),
  rule-based fallback
- persona: LLM-generated L3 user profile with incremental updates and
  feedback loop from confirmed corrections
- service: orchestration for capture/recall/persona/corrections
- agent-tools: built-in MCP tool definitions (memory_search/capture/
  stats/corrections/confirm/reject)
- tests: 22 unit tests for pure functions

Made-with: Proma
- config-paths: memory storage layout under ~/.proma/memory/
- agent-prompt-builder: inject <memory_context> per-message recall and
  <persona_profile> stable persona into system prompt
- agent-orchestrator: fire-and-forget memory capture after run completes
- builtin-mcp: register memory server (Claude SDK) + Pi builtin tools
- scripts: interactive playground, auto demo, and smoke verification
- .env.memory.example: LLM config template (placeholder only, no keys)

Made-with: Proma
Guides the agent to consolidate daily memories using built-in memory
tools (stats/corrections/quality check) and suggests creating a daily
automation (23:30) for unattended periodic memory maintenance.

Made-with: Proma
- ipc channels: get memory stats / search / list-corrections / confirm /
  reject / read persona
- preload: expose memory API to renderer
- ProactiveMemoryPanel: stats cards, pending corrections approval,
  memory search, persona preview (embedded in WorkspaceMemoryTab)
- WorkspaceMemoryTab: render ProactiveMemoryPanel at top

Made-with: Proma
… env overrides

- docs/proactive-memory-design.md: architecture, layered model, modules,
  wiring, verification results (aligned with proactive-scheduler-monitor-design)
- integration.test.ts: store disk integration tests isolated via
  PROMA_MEMORY_DIR temp directory
- config-paths: support PROMA_MEMORY_DIR env override for custom memory root
- extractor: support PROMA_MEMORY_LLM_DISABLED=1 for test isolation
- agent-prompt-builder.test: complete config-paths mock with memory paths
  and mock memory/service to keep prompt builder tests hermetic

Made-with: Proma
…ing memory

Borrowed from Nowledge Mem (Proma's bundled memory integration):

1. PreCompact capture: capture conversation memories before manual
   /compact and before SDK automatic compaction (compact_boundary),
   preventing memory loss when context is compressed.

2. Working memory injection: derive a current active-task snapshot from
   recent todo_context atoms and inject <working_memory> into system
   prompt alongside persona, helping new sessions resume work state.

Also simplify agent-prompt-builder.test to mock only config-paths
(full memory paths) instead of memory/service, removing the global
mock.module side-effect that polluted integration tests.

Made-with: Proma
Add semantic recall to solve 'who am I' style questions that pure
keyword BM25 cannot handle (verified: identity memory was previously
missing from top-5, now ranks proma-ai#1 with hybrid).

- embedding.ts: pluggable embedding provider
  - local: node-llama-cpp + embeddinggemma-300m (offline, 768d)
  - api: OpenAI-compatible embeddings endpoint
  - default off: fail-open to keyword + rule weighting (zero deps)
  - lazy-load singleton, CPU fallback when Metal unavailable
- recall.ts: ruleBoost for identity/preference memories; searchMemoriesHybrid
  merges keyword + embedding + rule via RRF (Reciprocal Rank Fusion)
- service/ipc/mcp-tools: memory_search uses async hybrid; per-message
  injection stays synchronous (keyword + rule) for low latency
- .env.memory.example: document PROMA_MEMORY_EMBEDDING options
- embedding.test.ts: cosine similarity + mode detection tests

Made-with: Proma
simulate-dev.ts: 5-day fictional project (CodeLens) to stress-test the
memory system - automatic extraction, persona evolution, feedback loop,
hybrid recall. Generates report at .context/memory-system-test-report.md

Made-with: Proma
…pplement

Deep stress test (3 projects, 12 days, 73 memories) revealed embedding
was polluting exact-match recall: semantically-similar memories ranked
above precise keyword matches (8/12 -> 11/12 after fix).

- keyword exact matches are forced to rank first (highest trust)
- embedding only supplements memories NOT already hit by keyword
  (preserves semantic recall for 'working habits' style questions)
- raised embedding similarity threshold to 0.6, expand candidate pool
- added stress-deep.ts: 3-project/12-day pressure test with cross-project
  interference, stale-memory, and tech-evolution checks

Made-with: Proma
…call

Deep stress test revealed small embedding model cannot distinguish
Chinese near-synonyms (锁/分段锁/分布式锁 all >0.64 similarity),
causing 'ShopGo 订单拆分用什么锁' to miss '分段锁已上线' memory.

Fix (12/12 recall matrix pass, up from 8/12):
- query-rewriter.ts: LLM rewrites question into 2-3 search queries
  (extracts entities + synonyms); rule synonym fallback guarantees
  stability when LLM output is non-deterministic; failure not cached
- recall.ts hybrid: rewritten queries supplement keyword recall;
  final pool reserves slots for supplement channels so keyword-heavy
  matches don't crowd out semantic/synonym hits; ruleList narrowed
  to identity/preference only (was inflating with all high-priority)
- embedding slice widened to keep more semantic candidates

Made-with: Proma
Sub-agent independent audit (6/10) found 3 real defects that the
12/12 test matrix missed (correct answers ranked 5th+ in keyword were
systematically dropped):

1. kw hard-truncation: kwItems.slice(0, limit-2) dropped correct
   memories ranked 4th+ in keyword channel
   -> replaced with multi-source weighting: score = sourceWeight +
   RRF micro-adjust; kw/rw hits dominate, no hard truncation

2. rewrite channel excluded kw-hit memories (if kwIds.has continue),
   so LLM rewrite could not rescue correct answers
   -> rwHitIdsAll tracks all rewrite hits (incl. kw-hit low ranks);
   rwList includes them; rw weight raised to 1.0 (LLM exact synonym)

3. low-score keyword noise occupied slots (kw 0.2-0.5 weak matches)
   -> kwList filtered to score >= 0.6; kwHitIds uses high-score only

Also: embedding threshold 0.6->0.68 suppresses '并行 vs 错峰'
mismatch; score = sourceWeight + RRF*0.3 (additive fusion).

Verified: worker/CRDT/分段锁/幂等/下线 5/5 pass (were 2/5 in audit);
12-question matrix 11/12 (the 1 'fail' is assertion-word mismatch:
记忆用'重复支付' vs 期望'幂等', recall itself correct).

Made-with: Proma
…y gating

Second independent audit (5/10) found new defects in the previous fix:

1. P0 normalization amplification: weak matches (raw BM25 ~0.7) were
   normalized to 1.0, bypassing the 0.6 filter and injecting unrelated
   memories for queries like '帮我写个排序算法'
   -> kwList/rwList now use absolute rawScore >= 1.0; fallback requires
   real kw match; added rawScore field to MemorySearchHit

2. P0 same-theme redundancy: 4 near-duplicate '批量审查模式' memories
   occupied top-5, pushing correct 'worker 池已实现' to rank 6+
   -> cluster dedup by project+keyword, keep max 2 per cluster

3. P1 unrelated-query gating: rw/embedding/rule channels now only
   activate when original query has a real kw match (kwList non-empty),
   preventing LLM rewrite divergence from injecting noise

4. P1 recall.test.ts: added pure-function tests (ruleBoost/tokenize/
   format); disk-dependent recall covered by integration tests

Verified: worker/分段锁/CRDT/锁/下线 all PASS; unrelated queries
(排序算法/1+1) return 0 hits (was 5 noise); 554 tests pass.

Made-with: Proma
…er key

Third audit (6/10) surfaced 3 remaining defects:

1. ruleList injected all preference memories on any real-kw query,
   causing '错峰运行' to dominate nearly every query
   -> ruleList now only includes preference/identity memories that
   also matched the query keywords (ruleKwIds intersection)

2. time-word mismatch: '今天股票行情' hit 5 memories via single-char
   stacking ('今天/今日' memories accumulated single-char scores
   past rawScore>=1.0)
   -> added time/finance stopwords (今/日/天/股/票/行/情 + 今日/股票/
   行情 etc.)

3. unstable cluster key: longest-Chinese-phrase clustering failed to
   merge same-theme memories (Q1 worker proma-ai#5, Q3 CRDT proma-ai#5)
   -> cluster key now uses project + english tech-words + noise-filtered
   Chinese nouns; non-global noise regex to avoid lastIndex state bug

Verified: 7/7 targeted checks pass (worker proma-ai#1, 股票行情 0 hits,
天气小程序 hits=1); full 12-question matrix 12/12; 554 tests pass.

Made-with: Proma
主动建议 MVP:在 Agent 会话过程中主动提出有价值的建议,并随用户反馈自我调节频率。

- signals: 纠正/跟进/周期/未完成/重复意图五类确定性信号提取
- rules: correction/followup/automation/skill/todo 五类建议规则
- engine: 置信度评分 + duplicateKey 去重 + 预算(单次≤1) + 频率加权
- feedback: accepted×1.2 / ignored×0.8 / never 屏蔽 + 连续忽略自动静默
- 接线: orchestrator 会话结束钩子 + IPC + preload + SuggestionBanner 三态交互
- 验证: 42 单测 + smoke-suggest 端到端 + 反馈回流 memory correction 验证

Made-with: Proma
根据协作子代理独立审查(7/10)修复主动建议引擎:

P1:
- todo 死锁: 默认权重 0.7→0.9 (0.72×0.9=0.648 > 0.6 阈值)
- 延后语义误判: '以后再说/明天再说吧' 不再触发 correction/followup
- 测试污染真实数据: getConfigDir 支持 PROMA_CONFIG_DIR 覆盖,与 PROMA_MEMORY_DIR 同款机制

P2:
- NEGATIVE 过度抑制: 仅整条消息为拒绝(短句)时跳过
- 弱意图 repeat 误报: WEAK_INTENT_KEYS 停止词表
- 无意义规则: normalizeRule + isMeaningfulRule 过滤'这样/再说'
- 跨会话展示: SuggestionBanner 仅展示当前会话建议 + 24h 过期
- 断片防护: '以后'/'还没' 最小长度校验

新增 9 个边界回归测试(子代理发现的问题全部覆盖)
全量 605 pass / 3 fail(基线)

Made-with: Proma
子代理 UI 实测发现的关键 bug:会话 JSONL 存储 SDKMessage 格式
(type/message.content 嵌套),而 evaluateSuggestionsFromRun 用
getAgentSessionMessages(按 AgentMessage role/content 平铺解析)
过滤后得到空数组,建议引擎从未执行。

修复:
- 新增 sdk-messages.ts: getAgentSessionSDKMessages + extractRecentConversationText
  正确提取 user/assistant 纯文本(跳过 tool_result/system/thinking)
- evaluateSuggestionsFromRun / captureMemoryFromRun 改用 SDK 读取方式
  (memory 自动捕获同样受影响,一并修复)

验证:
- 12 个 sdk-messages 单测(格式提取/截断/跳过非文本)
- verify-suggest-sdk.ts: 真实 SDK 结构 → 提取 → 评估 → 反馈 8/8
- 全量 617 pass / 3 fail(基线)

Made-with: Proma
401 根因:首次使用自动创建的 DeepSeek 预设渠道 apiKey 为空,
用户发送消息时 Bearer 空 key → DeepSeek API 返回 401。

修复:
- listChannels 迁移:历史空 key DeepSeek 渠道自动补填 .env 的
  MEMORY_LLM_API_KEY(复用 getMemoryLlmConfig 配置读取)
- 新建预设渠道同样自动填充(开箱即用),无 key 时保持空
- 用户已填 key 的渠道不被覆盖

验证:
- 4 个迁移单测(补填/不覆盖/无 key 容错/持久化)
- 全量无新回归(+2 为 electron mock 并发既有问题,与 channel-runtime 测试同类)

Made-with: Proma
子代理实测发现:401 迁移逻辑本身正确,但 dev 模式下 Electron
主进程 cwd=apps/electron,getMemoryLlmConfig 读 process.cwd()/.env
找不到仓库根 .env,导致迁移拿不到 key、401 依旧复现。

修复:findDotEnvUpwards 沿 cwd 逐级向上查找 .env(最多 5 层),
覆盖 dev 模式 cwd 在子目录的场景;home 目录兜底不变。

验证:4 个新单测(子目录向上查找/直接命中/无 env 空/模拟 dev 模式
getMemoryLlmConfig 读取)全过;typecheck 绿

Made-with: Proma
按 Proactive Center 蓝图 §5.1 实现 Today 首页,作为 PlanningView 第一个 tab:

- ProactiveTodayView.tsx:主动中心聚合页
  - 顶部概览:主动任务/待定建议/长期记忆/今日采纳率 4 统计卡
  - Proma 建议:待展示建议卡(接受/忽略/不再建议这类 三态)
  - 正在关注:启用中的定时任务列表(调度文案 + prompt 摘要)
  - 需要确认:pending corrections 审批(确认→回流 persona / 拒绝)
  - 用户画像:persona 状态卡
- PlanningTab 扩展 'proactive',作为默认第一个 tab
- 数据源全部复用已有 IPC(suggestions/memory/automation),无新增 IPC

验证:typecheck 绿、renderer 构建成功、全量测试无回归
子代理 UI 实测:tab 出现、四模块渲染、三态交互可用、数据聚合正确

Made-with: Proma
体验评测驱动的 3 个修复:

P0-1 规则语义反转:normalizeRule 的 LEADERS 含 /^不要|^别再|^别/,
把否定词当引导词删掉('以后不要用 var' → '用 var',语义 180° 反转,
会教坏 Agent)。修复:否定词是规则核心语义,必须保留。

P0-2 两步确认冗余:接受 correction 建议只写 pending,又要去主动中心
再确认一次。修复:接受 = 直接 proposeCorrection + confirmCorrection
一步生效并回流 persona。

P1-3 横幅不实时:SuggestionBanner 只挂载时拉取一次,会话结束不显示。
修复:新增 SUGGESTIONS_CHANGED IPC 事件,建议生成后广播,Banner
订阅事件实时刷新。

验证:suggest 68 测试(含 4 个 service 集成测试覆盖两步确认 + 否定词)、
全量 626 pass / 4 fail(基线)、6 包 typecheck 绿、构建成功

Made-with: Proma
低频 headless LLM 分析器:从规则触发进化到工作模式发现。

- analyst.ts: LLM 分析近期记忆+persona+纠正+已有任务,
  识别隐含模式(周期任务/SOP/待固化偏好),schema 严格校验
- runAnalysisAndPersist: 分析结果持久化为建议,复用三态反馈
- IPC RUN_SUGGESTION_ANALYSIS + preload + Today 页分析按钮
- Pi/Claude 双 runtime 暴露 suggestion_analyze 内置工具
- default-skills/suggestion-daily: 指导建每日分析定时任务

真实 LLM 验证:注入发版 SOP + 每周五周报记忆 →
产出「每周五自动写周报」(automation) + 「发版流程 SOP 沉淀」(skill)

踩坑:reasoning 模型 maxTokens 1024 输出为空,改 4096 正常。
80 suggest 测试、全量 638 pass、6 包 typecheck 绿、构建成功

Made-with: Proma
真实体验发现:LLM 返回 evidence/reason 等字段可能是数组/对象/数字,
validateAnalystCandidate 直接 .trim() 崩溃('raw.evidence?.trim is not a function'),
导致工作模式分析总是返回空。

修复:safeStr() 安全字符串化——数组取首个字符串元素、数字/布尔转字符串、
无法字符串化的对象返回 null(该条被拒)。

验证:真实 92 条记忆分析产出「ShopGo 促销前压测提醒」automation 建议
(从 todo_context+preference+fact 记忆推断周期工作)。

Made-with: Proma
整合三块能力(主动记忆 + 主动建议 + 主动中心/分析器)的 PR 描述:
- 能力清单、质量保障(5 轮子代理验证)、验证结果、文件概览

Made-with: Proma
@ConradLu2740
ConradLu2740 force-pushed the feat/proactive-agent branch from 7240f38 to 4386867 Compare August 3, 2026 12:40
…nding atoms, IPC auth

P0-1: getMemoryLlmConfig now resolves apiKey/baseUrl/model from a single trust source (env/project/home), blocks cross-source mixing that could leak LLM key to attacker-controlled baseUrl; baseUrl requires https (localhost proxy allowed); add isSafeBaseUrl + resolveMemoryLlmConfig pure functions with attack-scenario tests.
P0-2: LLM/rule auto-extracted memories now default to pending (confirmed:false), require user confirmation before entering recall; explicit memory_capture stays immediate. Add pendingAtoms stat, listPendingAtoms/confirmAtom/deleteAtom store+service, IPC channels, and UI confirm/reject in ProactiveMemoryPanel and ProactiveTodayView.
P0-3: sensitive write/paid IPC channels (memory corrections, memory atoms, actOnSuggestion, runSuggestionAnalysis) now require main-window sender; manual analyst trigger has 60s cooldown + 10/day quota; automation/agent tool path unaffected.
Made-with: Proma
conrad added 2 commits August 3, 2026 21:23
…ona toggle

P1-1: memory extraction now supports three modes (llm/rule/off) persisted in index; rule mode sends zero conversation content to external LLM; UI selector with explicit disclosure ('LLM 提取会把最近对话发送至外部 LLM 提供商'). IPC + preload wired with main-window sender validation.
P1-2: user data control closed loop - delete single suggestion (deleteSuggestion/removeSuggestion), clear all suggestions (clearSuggestions), clear all memory (clearAllMemory incl atoms+corrections+persona), per-atom delete from search results and pending list; UI buttons in memory panel and Proactive Today.
P1-3: persona injection controllable - toggle (setPersonaInjectionEnabled) stops persona from being sent with every system prompt; injected template now strips name and other strong identifiers; persona view/edit/delete entry points in memory panel (savePersona/removePersona).
Made-with: Proma
…RYPT_KEY auth, CSP

P2-1: suggestions.json/corrections.json now schema-validated on read (filter invalid records, truncate oversized fields, cap records at 500/300); recordFeedback whitelists enum; persistSuggestion caps growth.
P2-2: correction undo - undoCorrection deletes the confirming atom, reverts status to rejected, regenerates persona; proposeCorrection validates rule length (2-500) and raw (<=1000); active corrections show undo button in memory panel.
P2-3: analyst action fields (automationTitle<=100, suggestedPrompt<=1000, topic<=100, duplicateKey<=200) length-capped, oversized candidates discarded.
P2-4/5: DECRYPT_KEY requires main-window sender; renderer index.html gains CSP (self scripts + inline theme, connect-src self/ws/localhost, object-src none); devtools already dev-only.

Made-with: Proma
conrad added 4 commits August 4, 2026 10:06
…tion trigger

1. Persona 证据溯源:persona.md 每条偏好/协议/定位/演进条目带(src: atom_xxx)标注;formatAtomsForPersona 输出带 id;规则版兜底同样带 src;新增 extractPersonaSources + READ_MEMORY_PERSONA_SOURCES IPC;UI 画像条目可点击溯源到对应记忆。
2. 记忆分页浏览:新增 listAtomsPaged(类型过滤 + 时间/优先级排序 + 分页)+ LIST_MEMORY_ATOMS IPC;记忆看板增加「全部/事实/偏好/纠正/流程/任务」类型 tab + 分页列表 + 单条删除。
3. 时间衰减:recall 评分乘 timeDecay 因子(0.5^(days/30));correction/sop 不衰减(规则要稳定);fact/preference/todo_context 按半衰期衰减;MEMORY_HALF_LIFE_DAYS 可配置。
4. 触发时机扩展:idleComplete(turn 主体结束)也触发建议评估;同会话 5 分钟节流;引擎内 maxPerSession=2 预算兜底防打扰。

Made-with: Proma
B2(子代理审查发现): 删除记忆增加 window.confirm 确认弹窗(两处:分页浏览 + 待确认区),破坏性操作不再直接生效。
B3(子代理审查发现): persona.md 写入时自动带溯源版本标记(persona-version: 2);ensurePersona 检测旧版画像(无标记)自动强制重生成带(src: atom_xxx)标注;新增 GET_PERSONA_TRACEABLE / REGENERATE_PERSONA IPC + UI「重新生成」按钮 + 旧版徽标提示。实测旧 profile.md 重生成后 15 条画像条目全部带 src 溯源。

Made-with: Proma
…d@k, event type, DND, recall bench

1. P0-1 反馈回流闭环:accepted correction 建议 → correction atom 写入召回 + persona 刷新(补测试断言);新增高频 ignore 建议抑制列表(getSuppressedSuggestionKeys),供场景热度降权。
2. P0-2 L2 场景聚合:新增 memory/scene.ts(主题聚类 + 场景热度 = atom 数 × 时间衰减 × 抑制因子);service 暴露 getHotScenes/hotScenesSummary;analyst 输入加入近期热点场景;8 个单测。
3. P1-1 多候选提议:groupSuggestionsByKind 候选池按类型分组(pred@k 给用户选择权);ProactiveTodayView 建议区按类型分组多卡展示。
4. P1-2 event 记忆类型:shared types 新增 event;extractor prompt/白名单识别 event;recall 独立 14 天半衰期;看板类型 tab 增加「事件」。
5. P1-3 DND 免打扰:suggestions.json 新增 dnd 配置(跨午夜时段判定);评估入口 DND 内不产生新建议;IPC + preload + Today UI 开关。
6. P1-4 评测脚本:scripts/bench-recall.ts(标准问句集输出 Recall/Precision/FA,明示非 OmniMemEval 口径)+ docs/proactive-memory-bench.md;修复 2 个真实误报(纯单字弱命中归一化放大 → 降权 0.1;闲聊词'天气'停用词)。

验证:typecheck 全绿;全量 666 pass / 6 fail(与基线一致,均为既有 Electron 环境问题);suggest 冒烟 13/13、memory 冒烟通过;bench 误报率 66.7% → 0%。

Made-with: Proma
记录 memory/suggest 服务层入口(store/recall/extractor/persona/scene/service + engine/feedback/analyst/service),供未来 Agent 快速定位;链接设计文档、评测脚本与关键踩坑。

Made-with: Proma
@ErlichLiu

Copy link
Copy Markdown
Collaborator

很喜欢这个 PR 把主动记忆、克制的主动建议、反馈学习和用户可控串成完整闭环的设计。

我们特别想和参与这个方向的同学交流一些设计细节:

  • 长期记忆的分层、可审计与用户确认边界
  • 如何用阈值、预算和反馈学习控制主动建议的误报/打扰
  • 工作模式分析与 Automation / Skill / Todo 的最终交互闭环
  • 本地优先、外部 LLM 提取与隐私控制之间的权衡

感谢 @ConradLu2740@conrad 以及参与实现的各位。如果方便,欢迎加我微信:geekthings,很希望深入聊聊这些设计思考,也期待后续有合作机会。

@ConradLu2740

Copy link
Copy Markdown
Author

感谢 @ErlichLiu 的认可,很高兴这个方向能得到团队关注!

这四个议题恰好是我们在实现过程中反复打磨的,简单分享下目前的思考,也期待交流后能收敛成更清晰的设计:

  1. 记忆分层与确认边界:我们现在用 pending → confirmed 做第一层治理——自动提取默认待确认、不参与召回,确认后才进入召回/Persona。但 confirmed 同时承担了"内容可信、允许召回、允许进 Persona、用户授权"多个语义,下一步希望拆成 Evidence / Claim / Version / Activation 四层,把"用户确认"精确绑定到具体版本和用途上。

  2. 误报/打扰控制:当前是规则阈值 + 单次/会话预算 + 类型频率权重 + DND 免打扰的组合,误报率从 66.7% 降到了 0(真实记忆集评测)。后续想引入 impression/曝光预算和渠道分级,让"打扰成本"可量化。

  3. 与 Automation/Skill/Todo 的闭环:接受建议目前只打开预填草稿(Automation 禁用草稿、Todo 草稿、Skill draft session),确保用户确认后才真正生效。下一步建议把"点击建议"与"对象已创建/已产生价值"拆成两个状态机,用真实 outcome 回流学习。

  4. 本地优先 vs 外部 LLM:核心原则是本地控制面 + 可替换外部处理器;提取、Persona、Analyst、rewrite 等所有外发路径建议统一走 Egress Policy/Broker,按 purpose/scope/数据类别授权,避免"配置了 Key 就等于授权所有用途"。

这些思考我都整理成了一份设计评审文档,随时可以在微信里继续细聊。

@ConradLu2740

Copy link
Copy Markdown
Author

补充一份按模块的 review 指引,方便按顺序消化这 83 个文件(共 12,488 行):

  • Step 1 · 共享类型(+320)packages/shared/src/types/memory.tssuggestion.ts —— 数据模型,后续所有模块都基于它
  • Step 2 · 主动记忆引擎(+3,660)apps/electron/src/main/lib/memory/ —— 建议顺序:store(存储/去重/审批,662)→ recall(召回/阈值/混合检索,549)→ extractor(LLM 提取,278)→ persona(画像,151)→ service(编排,525)
  • Step 3 · 主动建议引擎(+2,744)apps/electron/src/main/lib/suggest/ —— signals(信号,296)→ rules(五类规则,195)→ engine(评分/预算,147)→ feedback(频率学习,348)→ analyst(工作模式分析,296)
  • Step 4 · 运行时接线(+1,222):ipc(364)、preload(233)、agent-orchestrator(80)、builtin-mcp(24)、pi-builtin-tools(165)—— 引擎如何接入 Claude / Pi 双 runtime
  • Step 5 · 前端 UI(+1,671):MemoryPanel(744)、Today 视图(618)、SuggestionBanner(178)—— 展示 + 审批 + 反馈薄层
  • Step 6 · 验证脚本与文档(+2,106):scripts/(冒烟/压力/评测)、docs/(设计文档)、skills/

每步 2-3 千行,可按顺序过。任何一步有问题都可以单独细化。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants