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
Three polish issues from real bot usage:
1. Bad nudges for answered questions. Per-turn extraction creates
'question' atoms from the user message BEFORE the assistant answers,
so every freshly asked question looked 'unanswered' and could be
nudged immediately ('You asked about my purpose earlier - want me to
answer that now?' right after it was answered). Question atoms are
now age-gated: only questions older than
memory.extended.nudge_open_question_min_age_hours (default 24, env
ODEK_MEMORY_EXTENDED_NUDGE_OPEN_QUESTION_MIN_AGE_HOURS) are nudge
candidates. Goals/intents are unaffected (own staleness window).
2. Duplicate quoted user message. The per-turn stats block and the
nudge message were both sent with ReplyToMessageID while the answer
message already quotes the user - three identical quotes per turn.
Stats and nudges are now standalone messages.
3. Cryptic cache stats: 'cache: 0cr+0rd+0ct' is now
'cache: 0 write / 0 read / 0 total'.
Copy file name to clipboardExpand all lines: docs/CONFIG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -433,6 +433,7 @@ The `memory` section controls the persistent memory system (see [docs/MEMORY.md]
433
433
|`nudge_max_per_day`|`1`|`ODEK_MEMORY_EXTENDED_NUDGE_MAX_PER_DAY`| — | Maximum proactive nudges delivered per day. |
434
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
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. |
436
+
|`nudge_open_question_min_age_hours`|`24`|`ODEK_MEMORY_EXTENDED_NUDGE_OPEN_QUESTION_MIN_AGE_HOURS`| — | Minimum age before a `question` atom may become a nudge candidate (younger questions are usually about to be answered). |
436
437
|`llm`| omitted | — | — | Dedicated memory LLM. If omitted, the main agent LLM is reused. A warning is emitted if that model has thinking enabled. |
437
438
|`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
+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
@@ -386,6 +386,7 @@ Extended Memory is configured under the `memory.extended` section.
386
386
"nudge_max_per_day": 1,
387
387
"nudge_cooldown_hours": 24,
388
388
"nudge_stale_goal_days": 7,
389
+
"nudge_open_question_min_age_hours": 24,
389
390
390
391
"llm": {
391
392
"base_url": "http://localhost:11434/v1",
@@ -440,6 +441,7 @@ Extended Memory is configured under the `memory.extended` section.
440
441
|`nudge_max_per_day`|`1`| Maximum proactive nudges delivered per day. |
441
442
|`nudge_cooldown_hours`|`24`| Per-kind cooldown before a nudge of the same kind can fire again. |
442
443
|`nudge_stale_goal_days`|`7`| Days without activity before a goal/intent atom counts as stale for nudges. |
444
+
|`nudge_open_question_min_age_hours`|`24`| Minimum age before a `question` atom may become a nudge candidate. Per-turn extraction runs before the assistant answers, so younger questions are almost always about to be answered — nudging about them is noise. |
443
445
|`llm`| omitted | Dedicated memory LLM config. **If omitted, the default global model is used.** A warning is emitted if that model has thinking enabled. |
444
446
|`embedding`| omitted | Dedicated embedding backend. If omitted, uses the shared `embedding` config. |
445
447
@@ -541,7 +543,7 @@ The extraction prompt now emits `question` atoms for user questions that went un
541
543
542
544
### Proactive nudges
543
545
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.
546
+
`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.`question` atoms are additionally age-gated: only questions older than `nudge_open_question_min_age_hours` (default 24) are candidates, because per-turn extraction runs before the assistant answers and a freshly asked question is almost always about to be answered.
545
547
546
548
Anti-annoyance caps are enforced by `TakeNudges` only and persisted to `nudges.json` in the extended directory (atomic, 0600):
0 commit comments