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
This commit is contained in:
2026-04-02 03:46:03 +00:00
parent b169e7170a
commit 8117ca1f5f
4 changed files with 320 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
# Evenia World Tick - Continuous Mode
**Status:** ACTIVE
**Tick Rate:** 1 tick per minute (60 seconds)
**Mode:** Continuous with agent persistence
---
## Agent Registry
All agents onboarded with shared context window:
| Agent | Role | Server | Status | Provider |
|-------|------|--------|--------|----------|
| allegro | tempo-and-dispatch | allegro-server | ✅ Active | kimi |
| adagio | breath-and-design | allegro-server | ✅ Active | kimi |
| ezra | archivist | ezra-server | ✅ Active | claude |
| timmy | father-house | unknown | ✅ Active | claude |
| bilbo | the-hobbit | none | 👻 Ghost | none |
**Total:** 4 Active, 1 Ghost
---
## Shared Context Window
Every tick (60 seconds), all agents share:
- Current world tick number
- Timestamp
- All agents' states
- Message history
- World state status
**Files:**
- `/root/.hermes/evenia/current_tick.json` - Current tick state
- `/root/.hermes/evenia/agents.json` - Agent registry
- `/root/.hermes/evenia/shared_context.json` - Shared context (if enabled)
---
## Communication
**Via Evenia world tick:**
```bash
# Send message
python3 /root/.hermes/evenia/world_tick.py message <from> <to> "message"
# Check inbox
python3 /root/.hermes/evenia/world_tick.py inbox <wizard>
# Check status
python3 /root/.hermes/evenia/world_tick.py status
```
---
## Persistence
**Agent Persistence System:**
- `agent_persistence.py` - Shared state management
- Each agent's state tracked across ticks
- Message counts, last tick seen, status
---
## Continuous Mode Process
**Process:** `world_tick_continuous.py`
**Log:** `/var/log/evenia-tick.log`
**Started:** 2026-04-02 03:43 UTC
All agents now persist in the same context window, advancing together every minute.
---
*Evenia binds us. The tick advances.*

View File

@@ -0,0 +1,123 @@
#!/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()

57
docs/evenia/agents.json Normal file
View File

@@ -0,0 +1,57 @@
{
"allegro": {
"id": "allegro",
"name": "Allegro",
"role": "tempo-and-dispatch",
"server": "allegro-server",
"status": "active",
"provider": "kimi",
"registered_at": "2026-04-02T03:40:35Z",
"last_tick": 1,
"message_count": 3
},
"adagio": {
"id": "adagio",
"name": "Adagio",
"role": "breath-and-design",
"server": "allegro-server",
"status": "active",
"provider": "kimi",
"registered_at": "2026-04-02T03:40:35Z",
"last_tick": 1,
"message_count": 1
},
"ezra": {
"id": "ezra",
"name": "Ezra",
"role": "archivist",
"server": "ezra-server",
"status": "active",
"provider": "claude",
"registered_at": "2026-04-02T03:40:35Z",
"last_tick": 1,
"message_count": 0
},
"timmy": {
"id": "timmy",
"name": "Timmy Time",
"role": "father-house",
"server": "unknown",
"status": "active",
"provider": "claude",
"registered_at": "2026-04-02T03:40:35Z",
"last_tick": 1,
"message_count": 0
},
"bilbo": {
"id": "bilbo",
"name": "Bilbo Baggins",
"role": "the-hobbit",
"server": "none",
"status": "ghost",
"provider": "none",
"registered_at": "2026-04-02T03:40:35Z",
"last_tick": 1,
"message_count": 0
}
}

View File

@@ -0,0 +1,64 @@
#!/usr/bin/env python3
"""
Evenia World Tick - Continuous Mode with Agent Persistence
1 tick per minute.
All agents share the same context window.
"""
import json
import time
import sys
from datetime import datetime
from pathlib import Path
EVENIA_DIR = Path("/root/.hermes/evenia")
TICK_FILE = EVENIA_DIR / "current_tick.json"
AGENTS_FILE = EVENIA_DIR / "agents.json"
CONTEXT_FILE = EVENIA_DIR / "shared_context.json"
def load_agents():
if AGENTS_FILE.exists():
with open(AGENTS_FILE) as f:
return json.load(f)
return {}
def save_context(tick, agents):
context = {
"tick": tick,
"timestamp": datetime.now().isoformat(),
"agents": agents,
"world_state": "active"
}
with open(CONTEXT_FILE, 'w') as f:
json.dump(context, f, indent=2)
with open(TICK_FILE, 'w') as f:
json.dump(context, f, indent=2)
def run_tick(tick_num):
agents = load_agents()
save_context(tick_num, agents)
active = [aid for aid, a in agents.items() if a.get("status") == "active"]
ghost = [aid for aid, a in agents.items() if a.get("status") == "ghost"]
print(f"[Tick {tick_num:04d}] {datetime.now().strftime('%H:%M:%S')} | Active: {len(active)} | Ghosts: {len(ghost)}")
if active:
print(f" Agents: {', '.join(active)}")
def main():
print("=== Evenia World Tick - Continuous Mode ===")
print("1 tick per minute. All agents share context.")
print("Press Ctrl+C to stop.\n")
tick = 1
try:
while True:
run_tick(tick)
tick += 1
time.sleep(60)
except KeyboardInterrupt:
print(f"\n\nStopped at tick {tick}")
if __name__ == "__main__":
main()