AJERISDocs

Memory model

How Ajeris remembers. Core memories, decay, nudges, and what stays between conversations.

Memory Nudge, Passive Learning Architecture

Status: DESIGN COMPLETE, ready for implementation. Author: Ajeris team Date: 2026-04-13 Research basis: Hermes Agent run_agent.py lines 1128, 2105-2238, 7800-7807, 10535-10543, verified in source code.


1. What this is

Today, the agent only saves memories when the user explicitly says "remember X." The agent passively forgets everything else, preferences revealed mid-conversation, habits mentioned in passing, corrections to the agent's behavior, facts about the user's life.

After this: every 10 user turns, the agent gets an internal prompt asking "is anything from this conversation worth remembering?" It reviews the recent conversation, identifies facts/preferences/behavioral expectations worth persisting, and saves them to core_memories via the existing memory_save tool. The user never sees this, it happens in the background after their response is delivered.

Example of what gets captured passively:

  • User says "I hate when you start every reply with 'Got it'" → agent saves [instruction] "Don't start replies with 'Got it'"
  • User mentions "my wife's birthday is March 15th" → agent saves [fact] "Wife's birthday: March 15th"
  • User always asks for Uber to "the airport" at 6am → agent saves [routine] "Frequent 6am Uber to ATL airport"

2. How it works (adapted from Hermes)

Turn 1: user asks something → agent responds → counter: 1
Turn 2: user asks something → agent responds → counter: 2
...
Turn 10: user asks something → agent responds → counter: 10
  → NUDGE FIRES
  → Agent gets internal prompt: "review conversation, save if worth it"
  → Agent calls memory_save if it finds something
  → Counter resets to 0
Turn 11: ... counter: 1 (cycle repeats)

Key design choices from Hermes (keeping):

  • Fires AFTER the user response is delivered (never blocks the user)
  • Counter is per-session (resets on agent restart)
  • Default interval: 10 turns (configurable)
  • Review prompt focuses on: persona, preferences, behavioral expectations
  • Best-effort: failures are silent
  • "Nothing to save" is the expected outcome most of the time

What we adapt for Ajeris:

  • Hermes spawns a full background AIAgent clone in a daemon thread. We can't do that easily (our agent is per-request, not persistent). Instead: the nudge fires as a LIGHTWEIGHT check within the same request pipeline, AFTER the response is sent but before the route handler returns. The agent's reply is already sent to the user , the nudge is a post-response side effect.
  • Hermes uses 8 max_iterations for the review agent. We use a SINGLE Claude API call with the review prompt (no tools needed, just the memory_save tool if it finds something worth saving).

3. Implementation

3.1 Turn counter (in agent-runner.ts or routes)

Process-scoped counter, incremented per voice/sms turn:

let turnsSinceMemoryNudge = 0;
const MEMORY_NUDGE_INTERVAL = 10;

3.2 Nudge check (in voice.ts and sms.ts, after response)

After runAgent() returns and the response is sent/logged:

turnsSinceMemoryNudge++;
if (turnsSinceMemoryNudge >= MEMORY_NUDGE_INTERVAL) {
  turnsSinceMemoryNudge = 0;
  // Fire and forget, don't await, don't block
  runMemoryNudge(deps, history, result.replyText).catch(() => {});
}

3.3 The nudge itself

async function runMemoryNudge(deps, history, lastReply) {
  // Build a compact conversation summary from recent history
  const summary = history.map(t =>
    `${t.role}: ${t.content.slice(0, 200)}`
  ).join('\n');
 
  // Ask the agent to review
  const result = await runAgent({
    user: deps.userContext,
    memories: frozenSession.memories,
    userMessage: MEMORY_REVIEW_PROMPT + '\n\n' + summary,
    // ... minimal config, no custom MCP needed
    frozenSystemPrompt: frozenSession.systemPrompt,
  });
 
  // The agent will call memory_save if it finds something.
  // If "Nothing to save" → no tool call → we just discard.
}

3.4 The review prompt (from Hermes, adapted)

Review the recent conversation and consider saving to memory.

Focus on:
1. Has the user revealed things about themselves, their name,
   preferences, habits, personal details worth remembering?
2. Has the user expressed expectations about how you should behave,
   their communication style, or ways they want you to operate?
3. Has the user mentioned facts (birthdays, addresses, routines)
   that would be useful in future conversations?

If something stands out, save it using the memory_save tool.
If nothing is worth saving, just say "Nothing to save."

4. What we're NOT building (yet)

  • Skill persistence (#4 on the steal list), the nudge only saves FACTS/PREFERENCES, not PROCEDURES. Skill persistence is a separate, larger feature.
  • Background thread, Hermes spawns a daemon thread. We run the nudge inline (fire-and-forget async). Simpler, same effect.
  • Configurable interval, hardcoded to 10 for V1. Can add a user setting later.

5. Files to change

FileChange
packages/agent/src/memory-nudge.tsNew. Nudge logic + review prompt
packages/agent/src/routes/voice.tsIncrement counter, fire nudge after response
packages/agent/src/routes/sms.tsSame
packages/agent/src/__tests__/memory-nudge.test.tsNew. Tests

Estimated scope: ~30 minutes.