Files
household-snapshots/docs/evenia/agent_persistence.py
Allegro 8117ca1f5f Add Evenia continuous mode with all agents onboarded
- 1 tick per minute, all agents share context window
- 5 agents registered: allegro, adagio, ezra, timmy, bilbo
- Agent persistence system for shared state
- Continuous mode process running
- Documentation: evenia-continuous-mode.md
2026-04-02 03:46:03 +00:00

124 lines
3.7 KiB
Python

#!/usr/bin/env python3
"""
Evenia Agent Persistence System
Ensures all agents share the same context window every world tick.
Each agent reads the shared state at the start of each tick.
"""
import json
import os
from datetime import datetime
from pathlib import Path
EVENIA_DIR = Path("/root/.hermes/evenia")
PERSISTENCE_FILE = EVENIA_DIR / "shared_context.json"
AGENTS_STATE_FILE = EVENIA_DIR / "agents_state.json"
def load_shared_context():
"""Load the shared context for all agents."""
if PERSISTENCE_FILE.exists():
with open(PERSISTENCE_FILE) as f:
return json.load(f)
return {
"tick": 0,
"timestamp": datetime.now().isoformat(),
"world_state": {},
"active_agents": [],
"messages_this_tick": []
}
def save_shared_context(context):
"""Save the shared context."""
PERSISTENCE_FILE.parent.mkdir(parents=True, exist_ok=True)
with open(PERSISTENCE_FILE, 'w') as f:
json.dump(context, f, indent=2)
def get_agent_state(agent_id):
"""Get an agent's persistent state."""
if AGENTS_STATE_FILE.exists():
with open(AGENTS_STATE_FILE) as f:
states = json.load(f)
return states.get(agent_id, {})
return {}
def update_agent_state(agent_id, state_update):
"""Update an agent's state."""
states = {}
if AGENTS_STATE_FILE.exists():
with open(AGENTS_STATE_FILE) as f:
states = json.load(f)
if agent_id not in states:
states[agent_id] = {
"id": agent_id,
"first_seen": datetime.now().isoformat(),
"last_tick": 0,
"message_count": 0,
"status": "active"
}
states[agent_id].update(state_update)
states[agent_id]["last_updated"] = datetime.now().isoformat()
AGENTS_STATE_FILE.parent.mkdir(parents=True, exist_ok=True)
with open(AGENTS_STATE_FILE, 'w') as f:
json.dump(states, f, indent=2)
def persist_tick_event(tick_num, event_data):
"""Persist an event to the shared tick history."""
context = load_shared_context()
if "tick_history" not in context:
context["tick_history"] = []
event_data["tick"] = tick_num
event_data["timestamp"] = datetime.now().isoformat()
context["tick_history"].append(event_data)
# Keep only last 100 ticks to prevent bloat
context["tick_history"] = context["tick_history"][-100:]
context["tick"] = tick_num
save_shared_context(context)
def get_context_for_agent(agent_id, current_tick):
"""Get the full context an agent should have at this tick."""
context = load_shared_context()
agent_state = get_agent_state(agent_id)
return {
"world_tick": current_tick,
"shared_context": context,
"my_state": agent_state,
"all_agents": list(load_agents_state().keys()) if AGENTS_STATE_FILE.exists() else [],
"timestamp": datetime.now().isoformat()
}
def load_agents_state():
"""Load all agents' states."""
if AGENTS_STATE_FILE.exists():
with open(AGENTS_STATE_FILE) as f:
return json.load(f)
return {}
def main():
"""Demo of persistence system."""
print("Evenia Agent Persistence System")
print("================================")
# Initialize context
context = load_shared_context()
print(f"Current tick: {context['tick']}")
print(f"Active agents: {context.get('active_agents', [])}")
# Update all registered agents
for agent_id in ["allegro", "adagio", "ezra", "timmy", "bilbo"]:
update_agent_state(agent_id, {"last_tick": context['tick']})
print("\nAll agents synchronized to shared context.")
if __name__ == "__main__":
main()