Skip to main content
OpenHome Agents have a persistent memory system powered by MemorySnapshotCapabilityBackground — a background daemon that continuously updates Agent context with information from persistent files.

How It Works

  • The background reads user-level persistent files and injects every .md file into the Agent prompt.
  • .md files are the primary path for ambient context injection into Agent behavior.
  • The Profile UI exposes key memory files (user_profile.md, user_summary.md) as editable content.

Background Cycle

The background runs sequentially every ~60–90 seconds:
  1. save_user_summary() — updates user_summary.md with a rolling conversation summary.
  2. save_user_profile() — updates user_profile.md with durable user facts.
  3. update_agent_prompt() — scans persistent storage and injects all .md files into the live Agent prompt.
Latency: Changes to files typically appear in Agent behavior after the next background cycle (60–90 seconds).

What Gets Injected

Only .md files in persistent storage are injected into the Agent prompt. Other file types are stored but not injected:
File typeBehavior
.mdInjected into Agent prompt on next cycle
.json, .txt, .log, .csv, .yaml, .ymlStored only, not injected

Writing Context Files

write_file() appends by default. For context files that represent current state (not history), always delete then write to avoid stale content accumulating:
async def write_context_file(self, filename: str, content: str):
    exists = await self.capability_worker.check_if_file_exists(filename, in_ability_directory=False)
    if exists:
        await self.capability_worker.delete_file(filename, in_ability_directory=False)
    await self.capability_worker.write_file(filename, content, in_ability_directory=False)
Use this pattern for files like audio_emotion.md, upcoming_schedule.md, and home_state.md.

Reserved Files

Do not write these from custom Abilities — they are owned and managed by the memory background:
  • user_profile.md
  • user_summary.md

Naming and Size Guidance

  • Namespace filenames by feature: use audio_emotion.md, not context.md.
  • Keep files concise: target under 200 words per injected .md file.
  • Write current state, not long history logs.

Cleaning Up Stale Context

For ephemeral daemon context, clear stale .md state at daemon startup before the first processing cycle to prevent old context from being injected after reconnect:
exists = await self.capability_worker.check_if_file_exists("audio_emotion.md", in_ability_directory=False)
if exists:
    await self.capability_worker.delete_file("audio_emotion.md", in_ability_directory=False)

Dual-Path Response Model

There are two ways an Ability can affect the Agent:
  • Ambient path: Write .md files for background-based prompt injection. The Agent absorbs this context over the next 60–90 seconds and incorporates it naturally into conversation.
  • Urgent path: Call send_interrupt_signal() first, then speak() for immediate intervention when the Agent needs to act right now.
await self.capability_worker.send_interrupt_signal()
await self.capability_worker.speak("You seem stressed. Want a quick breather?")
Use the ambient path for ongoing context (mood, schedule, home state). Use the urgent path when something time-sensitive needs immediate attention.

Editing Memory Files in the Dashboard

In Dashboard → Profile, persistent memory files are visible and editable directly from the UI:
  • user_profile.md — durable user facts (name, role, location, preferences)
  • user_summary.md — rolling summary of recent conversation context
  • user_goals.md — user-defined goals the Agent should keep in mind
Changes made in the Profile UI are reflected in Agent behavior after the next background cycle (~60–90 seconds).