You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -421,6 +427,12 @@ The `memory` section controls the persistent memory system (see [docs/MEMORY.md]
421
427
|`predictive_intents`|`3`| — | — | Reserved for future predictive-intent recall (P5). Currently accepted but ignored. |
422
428
|`auto_extract_per_turn`|`true`| — | — | Extract atoms after every user message. |
423
429
|`infer_user_state`|`true`| — | — | Reserved for future user-state model inference (P3). Currently accepted but ignored. |
430
+
|`follow_up_suggestions_enabled`|`true`|`ODEK_MEMORY_EXTENDED_FOLLOW_UP_SUGGESTIONS_ENABLED`| — | Capture high-confidence predicted intents at recall time as follow-up suggestions (zero extra LLM cost). |
431
+
|`follow_up_suggestion_min_confidence`|`0.6`|`ODEK_MEMORY_EXTENDED_FOLLOW_UP_SUGGESTION_MIN_CONFIDENCE`| — | Minimum predicted-intent confidence for a follow-up suggestion. |
|`nudge_max_per_day`|`1`|`ODEK_MEMORY_EXTENDED_NUDGE_MAX_PER_DAY`| — | Maximum proactive nudges delivered per day. |
434
+
|`nudge_cooldown_hours`|`24`|`ODEK_MEMORY_EXTENDED_NUDGE_COOLDOWN_HOURS`| — | Per-kind cooldown before a nudge of the same kind can fire again. |
435
+
|`nudge_stale_goal_days`|`7`|`ODEK_MEMORY_EXTENDED_NUDGE_STALE_GOAL_DAYS`| — | Days without activity before a goal/intent atom counts as stale for nudges. |
424
436
|`llm`| omitted | — | — | Dedicated memory LLM. If omitted, the main agent LLM is reused. A warning is emitted if that model has thinking enabled. |
425
437
|`embedding`| omitted | — | — | Dedicated embedding backend for atoms. If omitted, inherits `memory.embedding` or the shared top-level `embedding`. |
Copy file name to clipboardExpand all lines: docs/EXTENDED_MEMORY.md
+39Lines changed: 39 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -380,6 +380,12 @@ Extended Memory is configured under the `memory.extended` section.
380
380
"style_mirroring_enabled": true,
381
381
"anaphora_resolution_enabled": true,
382
382
"follow_up_anticipation_enabled": true,
383
+
"follow_up_suggestions_enabled": true,
384
+
"follow_up_suggestion_min_confidence": 0.6,
385
+
"proactive_nudges_enabled": false,
386
+
"nudge_max_per_day": 1,
387
+
"nudge_cooldown_hours": 24,
388
+
"nudge_stale_goal_days": 7,
383
389
384
390
"llm": {
385
391
"base_url": "http://localhost:11434/v1",
@@ -428,6 +434,12 @@ Extended Memory is configured under the `memory.extended` section.
428
434
|`style_mirroring_enabled`|`true`| Inject a style-guidance directive based on the inferred user model. |
429
435
|`anaphora_resolution_enabled`|`true`| Resolve the first pronoun in a user message against recent trusted atoms when the top atom's score is high enough. |
430
436
|`follow_up_anticipation_enabled`|`true`| Generate predicted intents and recall atoms for them. |
437
+
|`follow_up_suggestions_enabled`|`true`| Capture high-confidence predicted intents at recall time and expose them as follow-up suggestions (zero extra LLM cost). |
438
+
|`follow_up_suggestion_min_confidence`|`0.6`| Minimum predicted-intent confidence for a follow-up suggestion to be captured. |
439
+
|`proactive_nudges_enabled`|`false`| Master switch for proactive nudge delivery via `TakeNudges`. Opt-in. |
440
+
|`nudge_max_per_day`|`1`| Maximum proactive nudges delivered per day. |
441
+
|`nudge_cooldown_hours`|`24`| Per-kind cooldown before a nudge of the same kind can fire again. |
442
+
|`nudge_stale_goal_days`|`7`| Days without activity before a goal/intent atom counts as stale for nudges. |
431
443
|`llm`| omitted | Dedicated memory LLM config. **If omitted, the default global model is used.** A warning is emitted if that model has thinking enabled. |
432
444
|`embedding`| omitted | Dedicated embedding backend. If omitted, uses the shared `embedding` config. |
433
445
@@ -513,6 +525,32 @@ Once Extended Memory is enabled, the following proactive behaviors are active by
513
525
514
526
These behaviors are always data-driven by trusted atoms and the user model, never by tainted content.
515
527
528
+
## P6 — Proactive Engagement
529
+
530
+
P6 turns Extended Memory from a passive recall layer into a source of proactive, user-facing suggestions. All three surfaces are read-only over trusted atoms and degrade to "nothing" on any failure — a broken LLM backend or malformed response can never break a session.
531
+
532
+
### Follow-up suggestions
533
+
534
+
Predictive recall (P5) already generates likely follow-up intents on every recall to widen the search. P6 captures those intents instead of discarding them: after the `minPredictedIntentConfidence` (0.3) noise floor, intents at or above `follow_up_suggestion_min_confidence` (default `0.6`) are kept — at most 3 per recall — and exposed via `ExtendedMemory.LastFollowUps()` / `MemoryManager.FollowUpSuggestions()` for the CLI/Web/Telegram surfaces to render as suggested next steps. The capture costs zero extra LLM calls (it reuses the prediction the recall pipeline already paid for) and is replaced on every recall. Disable with `follow_up_suggestions_enabled: false` (recall behavior is unchanged either way).
535
+
536
+
### Open loops
537
+
538
+
The extraction prompt now emits `question` atoms for user questions that went unanswered in the session and `goal` atoms for stated intentions ("I want to…", "we should…", "next week I'll…"). Commands and action requests are still rejected. Exact and semantic write-path dedup collapse repeats automatically.
539
+
540
+
`ExtendedMemory.OpenLoops(ctx, limit)` returns the trusted `question`/`goal`/`intent` atoms, newest first — the machine-readable "what is still open" view that powers the nudges engine and any presentation-layer listing. Tainted atoms are always excluded.
541
+
542
+
### Proactive nudges
543
+
544
+
`ExtendedMemory.ProactiveNudges(ctx, maxN)` (preview) and `ExtendedMemory.TakeNudges(ctx, maxN)` (delivery) synthesize up to `maxN` (default 2) concise, user-facing nudges from: open loops, stale goals (goal/intent atoms with no activity in `nudge_stale_goal_days`, default 7), and the user model's current focus (blockers, project drift). Each nudge carries a `kind` (`open_question`, `stale_goal`, `blocker`, `drift`) and the source atom IDs it was derived from. Synthesis is a single memory-LLM call with defensive JSON parsing; any failure returns an empty result with no error.
545
+
546
+
Anti-annoyance caps are enforced by `TakeNudges` only and persisted to `nudges.json` in the extended directory (atomic, 0600):
-**Daily budget**: at most `nudge_max_per_day` nudges per day (default `1`); the budget resets on day rollover, per-kind cooldowns persist.
550
+
-**Per-kind cooldown**: a kind that fired cannot fire again within `nudge_cooldown_hours` (default `24`).
551
+
552
+
`ProactiveNudges` is a pure preview: it computes nudges without checking or recording any cap, so a CLI/Telegram "what would you nudge me about?" surface never consumes the daily budget. `MemoryManager.PreviewNudges` / `MemoryManager.TakeNudges` are nil-safe passthroughs that return empty when Extended Memory is disabled.
553
+
516
554
## Security Architecture
517
555
518
556
Extended Memory inherits and extends the provenance model from [MEMORY.md](MEMORY.md).
Copy file name to clipboardExpand all lines: docs/MEMORY.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -169,7 +169,9 @@ Key properties:
169
169
-**Trust boundary**: per-turn extraction only produces `user_said` atoms. Tainted source classes (`tool_output`, `file_read`, `web`, `mcp`, `subagent`, `agent_generated`, `inferred`) can be stored but are quarantined and excluded from recall until promoted.
170
170
-**Size cap**: defaults to 100 MB with `retention_decay` eviction; pinned atoms are never evicted.
**Proactive nudges** (opt-in): when `memory.extended.proactive_nudges_enabled` is `true` (default `false`), Extended Memory can synthesize short, user-facing nudges from trusted atoms — open questions, stale goals, blockers, and drift. Delivery is capped by `nudge_max_per_day` with a per-kind cooldown (`nudge_cooldown_hours`); goals only become "stale" after `nudge_stale_goal_days`. The Telegram bot pushes at most one nudge after a completed turn (in the background, prefixed with 💡). `odek memory extended nudges` prints a preview of up to 2 nudges without consuming the daily cap.
173
175
174
176
When enabled, Extended Memory atoms are injected as a separate system message after the legacy memory block and episode summaries on each turn. For the full design, config reference, and implementation status, see [docs/EXTENDED_MEMORY.md](EXTENDED_MEMORY.md).
0 commit comments