Vitalis_Devcore / agents /base_agent.py
FerrellSyntheticIntelligence
Add understanding engine, conversation interface, meditation engine, unified launcher
7d9e142
#!/usr/bin/env python3
"""
Vitalis Base Agent
Self-directed execution loop with memory, tools, and self-correction.
"""
import time
from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional
from pathlib import Path
import json
class BaseTool:
name: str = "base_tool"
description: str = "Override this"
def run(self, **kwargs) -> Any:
raise NotImplementedError
class AgentMemory:
def __init__(self, path: Optional[Path] = None):
self.path = path or (Path.home() / ".vitalis_workspace" / "agent_memory.json")
self._store: List[Dict] = self._load()
def _load(self) -> List[Dict]:
if self.path.exists():
try:
return json.loads(self.path.read_text())
except Exception:
return []
return []
def add(self, role: str, content: str):
self._store.append({"role": role, "content": content, "ts": time.time()})
self.path.parent.mkdir(parents=True, exist_ok=True)
self.path.write_text(json.dumps(self._store[-200:], indent=2))
def recent(self, n: int = 10) -> List[Dict]:
return self._store[-n:]
def clear(self):
self._store = []
if self.path.exists():
self.path.unlink()
class BaseAgent(ABC):
MAX_STEPS = 20
STEP_DELAY = 0.5
def __init__(self, name: str = "VitalisAgent"):
self.name = name
self.memory = AgentMemory()
self.tools: Dict[str, BaseTool] = {}
self._steps = 0
self._running = False
def register_tool(self, tool: BaseTool):
self.tools[tool.name] = tool
print(f"[AGENT:{self.name}] Tool registered: {tool.name}")
def use_tool(self, tool_name: str, **kwargs) -> Any:
tool = self.tools.get(tool_name)
if not tool:
return f"ERROR: Tool '{tool_name}' not found. Available: {list(self.tools.keys())}"
try:
result = tool.run(**kwargs)
self.memory.add("tool", f"{tool_name}({kwargs}) → {str(result)[:200]}")
return result
except Exception as e:
err = f"Tool '{tool_name}' failed: {e}"
self.memory.add("error", err)
return err
@abstractmethod
def think(self, state: Dict) -> Dict:
"""Override: decide next action given current state."""
pass
@abstractmethod
def act(self, decision: Dict) -> Any:
"""Override: execute the decided action."""
pass
@abstractmethod
def is_done(self, state: Dict) -> bool:
"""Override: return True when goal is reached."""
pass
def run(self, goal: str, initial_state: Optional[Dict] = None) -> Any:
print(f"[AGENT:{self.name}] Starting. Goal: {goal}")
self.memory.add("system", f"Goal: {goal}")
state = initial_state or {"goal": goal, "step": 0, "results": []}
self._running = True
self._steps = 0
last_result = None
while self._running and self._steps < self.MAX_STEPS:
if self.is_done(state):
print(f"[AGENT:{self.name}] Goal reached in {self._steps} steps.")
break
try:
decision = self.think(state)
result = self.act(decision)
last_result = result
state["step"] = self._steps
state["results"].append({"step": self._steps, "decision": decision, "result": str(result)[:300]})
self.memory.add("assistant", f"Step {self._steps}: {decision}{str(result)[:150]}")
except Exception as e:
print(f"[AGENT:{self.name}] Step {self._steps} error: {e}")
self.memory.add("error", str(e))
state["last_error"] = str(e)
self._steps += 1
time.sleep(self.STEP_DELAY)
if self._steps >= self.MAX_STEPS:
print(f"[AGENT:{self.name}] Max steps reached ({self.MAX_STEPS}).")
self._running = False
return last_result
def stop(self):
self._running = False
print(f"[AGENT:{self.name}] Stopped.")