feat: confidence tracking, entity graph, and proactive memory injection#592
feat: confidence tracking, entity graph, and proactive memory injection#592helal-muneer wants to merge 4 commits intoCortexReach:masterfrom
Conversation
Implements CortexReach#577 - Dreaming functionality for memory-lancedb-pro Three-phase dreaming cycle: - Light Sleep: Decay scoring + tier re-evaluation for recent memories - Deep Sleep: Promote high-performing Working memories to Core tier - REM: Pattern detection across categories + reflection memory creation Changes: - Add dreaming config schema to openclaw.plugin.json with UI hints - Create src/dreaming-engine.ts with createDreamingEngine factory - Wire dreaming into service lifecycle (start/stop) in index.ts - Add DreamingConfig to PluginConfig interface + parsePluginConfig - Fix resolveEnvVars to return empty string instead of throwing when env var is missing (prevents plugin startup failure) Dreaming runs on a 6-hour interval after 5-minute initial delay, configurable via plugins.entries.memory-lancedb-pro.config.dreaming
rwmjhb
left a comment
There was a problem hiding this comment.
Interesting feature with a sound architecture (bridging existing tier-manager and decay-engine). Branch needs a rebase and one scope isolation issue needs fixing before merge.
Please rebase onto current main — stale_base=true and index.ts has had significant recent activity. Rebase needed to surface any conflicts before this can land.
Must fix
MR1 — Dreaming ignores scope isolation and synthesizes cross-scope memories into global
The engine fetches memories across all scopes, then stores REM reflections with a hardcoded scope: 'global'. In multi-user or multi-workspace deployments this leaks content between isolated memory spaces — a user's private memories can influence another user's global reflection entries.
Fix: filter store.list() by the active scope in each phase, and tag REM reflections with the same scope as the source memories.
Non-blocking
- F1 —
resolveEnvVarsnow returns''instead of throwing for unset env vars. This silently propagates an empty API key throughresolveFirstApiKey'sif (!key)guard (which only checks the raw config string, before resolution). Users with"${JINA_API_KEY}"configured but the env var unset will get opaque HTTP 401 failures instead of a clear startup error. - F2 — REM stores reflection with
vector: []. LanceDB uses fixed-dimension Arrow columns — a 0-dimension vector will throw an Arrow schema mismatch on every cycle. The error is caught and logged as⚠️ REM failed, so the REM phase silently never creates any reflection memories. - F3 —
config.phases.light(and.deep,.rem) accessed without null guard. A minimal config like{ "dreaming": { "enabled": true } }crashes withTypeError: Cannot read properties of undefinedon first cycle. Add aDEFAULT_DREAMING_CONFIGand deep-merge it at parse time. - F6 —
storageMode('separate'/'both') andcronfields are exposed inconfigSchemaand UI hints but never read at runtime. Users selecting these options silently getinlinebehavior and 6-hour fixed intervals. Remove from schema until implemented, or log a warning when set.
- MR1: Add scope isolation to dreaming engine — all phases now filter by active scope, REM reflections tagged with source scope instead of hardcoded 'global' - F1: resolveFirstApiKey now validates resolved env var value, throws clear error if env var is unset instead of silently propagating empty API key - F2: REM phase no longer stores vector:[] (Arrow schema mismatch). Accepts optional embedFn; if unavailable, logs patterns without creating a memory entry - F3: Add DEFAULT_DREAMING_CONFIG + mergeDreamingConfig() for safe deep-merge of partial user configs over defaults - F6: Remove unimplemented cron/timezone/storageMode/separateReports from DreamingConfig interface and openclaw.plugin.json schema
a240a8a to
705da9a
Compare
82f710c to
62e44a6
Compare
rwmjhb
left a comment
There was a problem hiding this comment.
The three-phase dreaming concept is interesting, but there are several correctness blockers that need to be resolved before this is mergeable.
Must fix before merge:
-
MR1: Scope isolation violated. The dreaming engine can synthesize cross-scope memories into
global, defeating the per-user/per-agent isolation guarantees the rest of the plugin provides. Dreaming should only consolidate within the originating scope. -
MR2: REM output re-enters the consolidation pool. REM reflections are stored as generic legacy working memories, so subsequent dreaming cycles can reprocess their own output — unbounded feedback loop.
-
F2: REM phase stores reflection with
vector: []. LanceDB enforces a fixed vector dimension. An empty vector will crash every REM cycle against the schema constraint. -
F3:
config.phasesaccessed without null guard. A minimal dreaming config (omittingphases) throws a TypeError at startup. -
F6:
storageModeandcronfields are schema-advertised but entirely unimplemented. Shipping config knobs that silently do nothing is a user-trust issue. Either implement or remove from schema before merge.
Nice to have (non-blocking):
- F1:
resolveEnvVarssilently returns''for unset env vars — a missing embedding API key becomes an empty string with no warning. - F4: Initial
setTimeouthandle is discarded — the first cycle can fire afterstop()if the plugin restarts within 5 minutes. - EF1: The 319-line dreaming engine has zero automated test coverage across all three phases.
Address the must-fix items and this is ready for a proper review.
|
The schema gap causing UI validation errors is a real problem, and bridging tier-manager + decay-engine is the right architectural approach. However there are several correctness issues that need to land before this is safe to enable. Must fix
High priority
Other
Question for author: Was Strategy B (bridge mode) explicitly endorsed by a maintainer? Issue #577 describes three strategies but shows no maintainer response before implementation started — want to make sure the approach was aligned. |
62e44a6 to
517f5f6
Compare
Rebased and RebuiltThis PR has been completely rebuilt from scratch on top of the latest
Reviewer Feedback Addressed
CI StatusCI workflows require maintainer approval to run (first-time fork push). All local tests pass:
Files Changed (9 files, +838/-5) |
- Add dreaming field to PluginConfig interface - Add DEFAULT_DREAMING_CONFIG + mergeDreamingConfig() for safe config merging - Initialize dreaming engine in register() when enabled - Simple cron-based scheduler (60s check interval, supports minute/hour fields) - Write DREAMS.md reports after each cycle - Cleanup timer on gateway_stop - Update openclaw.plugin.json schema with phases sub-config
The dreaming code was at the plugin factory level (non-async scope), causing 'ParseError: Unexpected reserved word await' at runtime. Moving it inside the async start() callback resolves the error.
…llback Resolves 'ParseError: Unexpected reserved word await' by moving dreaming initialization into the async start() context. Also moves backup scheduling and BACKUP_INTERVAL_MS into start() to avoid TDZ errors.
|
感谢提交这个 PR!dreaming engine 的方向是对的,三阶段设计(Light Sleep / Deep Sleep / REM)与 tier-manager 和 decay-engine 的集成思路也清晰。不过有几个问题需要在合并前解决。 必须修复MR1 — Scope 隔离缺失 dreaming-engine 合成记忆时未做 scope 隔离,可能将来自不同 agent scope 的记忆合并写入 MR2 — REM reflection 会被自身的下一轮重新处理 REM 阶段生成的 reflection 被存储为普通 legacy working memory,导致下一轮 dreaming 会把这些 reflection 再次作为输入处理,形成自我强化的循环。 重要问题(建议修复)F1 — resolveEnvVars 行为变更(throw → return '') 这个改动与 dreaming 无关,但影响全局 env var 解析,包括 F2 — REM reflection 用 LanceDB schema 有固定维度约束, F3 — 最小化 dreaming config 下会 TypeError crash。 F6 — 死配置项暴露给用户
开放问题
测试覆盖319 行新增的 dreaming-engine.ts 目前零测试覆盖。至少建议为三个阶段各补一个 happy path 测试,以及 scope 隔离的边界测试。 整体来说这个功能是有价值的,解决了 OpenClaw UI 的 schema 验证报错。修复上述问题后欢迎重新 review。 |
517f5f6 to
e3e1ac2
Compare
… tests Clean implementation addressing all reviewer feedback from PR CortexReach#592: MR1 — Scope isolation: Each phase filters store.list() by scope. Dreaming runs per-scope using scopeManager.getAllScopes(). MR2 — REM reflection loop prevention: Reflections tagged with metadata.source = 'dreaming-engine' and excluded from all phase inputs. F2 — REM reflections now embedded via embedder.embed() instead of vector: []. Falls back to zero-vector on embedding failure. F3 — DEFAULT_DREAMING_CONFIG + mergeDreamingConfig() provides null-safe deep merge. Minimal config { enabled: true } works. F6 — Removed unimplemented fields (storageMode, separateReports, timezone) from schema. Only runtime-active fields exposed. Also includes: - 8 unit tests covering MR1, MR2, F2, F3, all 3 phases, error resilience - Dreaming wired inside async start() callback (fixes ParseError) - Cron scheduler with per-scope execution - DREAMS.md report generation per scope
|
All reviewer feedback has been addressed in a clean rebase: #672 Key changes:
|
|
Closing in favor of #672 — clean rebase with all reviewer feedback addressed. |
Summary
Closes #577
Adds three new subsystems to LanceDB Pro with corresponding tools and config schema. Built on top of the existing singleton state pattern from PR #598.
New Components
📊 Confidence Tracker (
src/confidence-tracker.ts)Per-memory confidence scoring based on recall/useful signals with configurable decay. Enabled by default (opt-out).
memory_boost— boost a memory's confidence score🔗 Entity Graph (
src/entity-graph.ts)On-demand entity extraction and relationship mapping. Disabled by default (opt-in).
memory_entities— query entity profiles and relationships🔮 Proactive Injector (
src/proactive-injector.ts)Contextual memory injection alongside auto-recall based on staleness, entity mentions, and pattern triggers. Disabled by default (opt-in).
memory_shared— write to shared scopeChanges
src/confidence-tracker.tssrc/entity-graph.tssrc/proactive-injector.tssrc/scopes.tssharedscope,isSharedScope()helpersrc/tools.tsmemory_entities,memory_boost,memory_sharedtoolsindex.tsopenclaw.plugin.jsonDesign Decisions
_initPluginState()following PR Memory leak issues causing heap out of memory #598's established patternscopeManagerto filter queries per agent scopedecayFactor: 0.95sharedscope: New cross-agent read-only scope added to default definitionsReviewer Responses
Configuration
{ "confidenceTracking": { "enabled": true, "decayFactor": 0.95 }, "entityGraph": { "enabled": false }, "proactive": { "enabled": false, "staleMemoryDays": 7, "entityPrefetch": true, "patternTriggers": {} } }Testing
sharedscope