A persistent memory and self-improvement system that transforms Home Assistant's conversation agent from a stateless chatbot into an intelligent assistant that remembers, learns, monitors, and maintains your smart home over time.
Built and battle-tested on a Raspberry Pi 4 (2GB RAM) running HAOS. No external databases, no cloud storage, no paid services beyond what you already use.
Home Assistant's conversation agents (Gemini, OpenAI, etc.) have no memory between interactions. Every conversation starts from zero. PERMEAR fixes that with a file-based memory architecture that gives your agent a persistent soul, user profiles, learned insights, and the ability to create automations and monitor system health.
The agent evolves from household assistant to system caretaker — it monitors HA health, detects errors (including its own), checks for updates, autodiscovers entities, and can create native HA automations with user approval.
MEMORY (persistent JSON files)
├── guidelines.json ← IMMUTABLE constitution (chmod 444)
├── soul.json ← Agent personality (edited weekly by agent)
├── users.json ← Household profiles (edited weekly + quick-learn)
├── insights.json ← Detected patterns (edited weekly)
├── monitored_entities.json ← Single source of truth for entities
│ monitor:true → pre-briefing reads state
│ events:[] → buffer logs state changes
└── daily/
└── monday..sunday.json ← 7-day rotating event logs
SCRIPTS (all import from permear_config.py)
├── permear_config.py ← Centralized paths and constants
├── append_daily.py ← Log events/interactions/memories
├── build_briefing.py ← Daily briefing prompt (21h)
├── build_prebriefing.py ← Proactive evaluation (30min) + SELF_ERRORS
├── build_weekly_prompt.py ← Weekly compilation prompt (Sunday)
├── update_daily_memory.py ← Save extracted memories
├── weekly_compile.py ← Apply LLM edits to perennials
├── apply_quick_learning.py ← Instant restriction from rejections
├── discover_entities.py ← Autodiscover exposed entities
├── generate_buffer_events.py ← Regenerate triggers from JSON
├── ha_log_monitor.py ← Parse logs: SELF_ERRORS vs ERRORS
├── ha_updates_check.py ← Check HA/addon updates
├── manage_agent_automations.py ← Create/remove HA automations
├── sensor_current_day.py ← HA sensor: current day memory
└── sensor_perennial.py ← HA sensor: perennial files
CYCLES
├── Every 30 min (08-20h) ── Pre-briefing: health + house evaluation
├── Daily 21h ────────────── Briefing: day summary + updates + memories
├── Daily 06:00 ──────────── Entity autodiscovery
├── Sunday 00:05 ─────────── Weekly compile: self-improvement
└── On demand ────────────── Telegram chat + voice commands
git clone https://github.com/zzzmada/permear.git
cd permear
./install.shWith HA packages support:
./install.sh /config automations scripts packagesThe installer prompts for your token and secrets interactively.
See detailed steps below.
- Home Assistant 2023.7+
- A conversation agent (Gemini 2.5 Flash recommended — free tier sufficient)
- Telegram bot in HA (polling mode)
- Python 3 + PyYAML (included in HAOS)
- Long-lived HA access token
max_tokensset to 8192+ in your LLM integration
mkdir -p /config/memory/daily /config/scripts /config/logs
touch /config/automations/agent_automations.yaml# configuration.yaml — must be directory-based:
automation: !include_dir_merge_list automations/HA sidebar → username → Long-Lived Access Tokens → Create → "PERMEAR"
echo "YOUR_TOKEN" > /config/.permear_token
chmod 600 /config/.permear_tokenAdd to your /config/secrets.yaml:
permear_chat_id: 123456789
permear_agent_id: conversation.google_ai_conversation
permear_person_entity: person.your_nameSee secrets.yaml.example for details on finding these values.
Google Generative AI: Settings → Configure → uncheck "Recommended model settings" → Maximum tokens: 8192
scripts/*.py → /config/scripts/
memory/*.json → /config/memory/
automations/*.yaml → /config/automations/
Option A (packages): Copy configuration_additions.yaml to /config/packages/permear.yaml
Option B (manual): Copy contents of configuration_additions.yaml into your configuration.yaml
chmod 444 /config/memory/guidelines.jsonpermear_config.py— Paths,DAYSfor language,SELF_COMPONENTS. See Customization Guide.soul.json— Agent personality.users.json— Household profiles.guidelines.json— Edit before locking.
SYSTEM MONITORING: You monitor HA health. Critical errors: notify immediately.
SELF_ERRORS are from your own actions — always report what you think went wrong.
Updates: mention in daily briefing only. New devices: ask user to name them.
AUTOMATIONS: Create with permear_create_automation, remove with permear_remove_automation,
list with permear_list_automations. ALWAYS ask confirmation before creating.
ENTITY MONITORING: "monitor [entity]" → add_monitored_entity.
"stop monitoring [entity]" → remove_monitored_entity.
The LLM agent cannot call shell_commands directly — it can only use exposed HA scripts. After restarting:
Settings → Voice Assistants → your agent → Exposed Entities → enable:
script.permear_list_automationsscript.permear_create_automationscript.permear_remove_automation
Without this step, the agent will return "function does not exist" when trying to manage automations.
Developer Tools → Services → shell_command.discover_entities
- Never use sentence triggers (
platform: conversation). - Verify your agent_id — often
conversation.google_ai_conversation, NOTgoogle_generative_ai. Check Developer Tools. telegram_bot.send_message:chat_id, nottarget.- HA triggers are static. Define events in JSON, run
generate_buffer_events.py. max_tokensmust be 8192+ for weekly compilation.ha_updates_check.pyonly works inside HAOS container (SUPERVISOR_TOKEN).- Use
| truncate()not[:255]in HA templates. - All response_variable stdout must use
| default('') | trim | default('fallback'). - Gemini ignores format with long conversation history. Inject instructions in message text.
discover_entities.pyfilters byshould_exposein entity registry.- SELF_ERRORS flag errors from agent components. Customize in
permear_config.py. - Shell commands are invisible to the LLM agent. The agent can only call exposed scripts. PERMEAR includes wrapper scripts (
permear_list_automations,permear_create_automation,permear_remove_automation) that must be exposed in Voice Assistants settings. - Python not available in SSH addon terminal. Run scripts via Developer Tools → Services.
- Clean phantom entities after upgrades: Settings → Entities → filter "unavailable" → delete.
- **Telegram parse_mode: All telegram_bot.send_message calls that send shell_command stdout or agent responses must include parse_mode: plain_text. Underscores in strings like NO_AUTOMATIONS break Telegram's default Markdown parser. Messages with intentional formatting should use markdownv2 with proper escaping.
- Telegram parse_mode fix: All telegram_bot.send_message calls that send shell_command stdout or LLM responses now include parse_mode: plain_text. Underscores in internal strings (like automation IDs) were breaking Telegram's default Markdown parser with "Can't parse entities" errors.
- Human-readable script outputs: manage_agent_automations.py outputs rewritten from - JSON/internal tokens to readable text. "NO_AUTOMATIONS" → "No automations created yet." Create/remove outputs are now plain sentences without underscores.
- Internal token filter: The Telegram handler default branch now filters internal protocol tokens (LIST_AUTOS, CREATE_AUTO:, REMOVE_AUTO:, NO_AUTOMATIONS) from reaching the user as raw messages.
- Script wrappers for LLM agent: Shell commands are invisible to the conversation agent. Added 3 HA scripts (
permear_list_automations,permear_create_automation,permear_remove_automation) that wrap the shell commands and can be exposed to the agent via Voice Assistants settings. Without these, the agent returns "function does not exist" when trying to manage automations.
secrets.yamlintegration: All user-specific values (chat_id,agent_id,person_entity) now use HA's native!secretmechanism. Zero placeholders to replace. Updates viagit pullnever overwrite user configuration.install.shimproved: Interactive installer with secrets.yaml setup, HA packages support,chattrprotection forpermear_config.py, soul.json preservation. Original script by @clyra.- HA packages support:
configuration_additions.yamlworks as a drop-in HA package.
- SELF_ERRORS:
ha_log_monitor.pyclassifies errors from PERMEAR components separately. Pre-briefing instructs agent to report its own failures with context.
- Centralized configuration:
permear_config.py— all scripts import from it.
monitored_entities.jsonas single source of truth:monitor+eventsdual role.generate_buffer_events.py: Regenerates YAML between markers.- Empty speech fix:
| default('') | trimwith fallback.
- Agent ID fix,
should_exposefilter,apply_usersany-field diff, truncation detection, prompt compaction.
- Agent as system caretaker. HA monitoring, entity autodiscovery, native automations. Allowed actions removed.
- Telegram context injection, quick-learn localization.
- Initial release.
MIT — Use it, fork it, improve it.
- Architecture designed in collaboration with Claude (Anthropic)
- Installation script by @clyra