Initial commit: add .gitignore and README
This commit is contained in:
55
fusionagi/memory/procedural.py
Normal file
55
fusionagi/memory/procedural.py
Normal file
@@ -0,0 +1,55 @@
|
||||
"""Procedural memory: reusable skills/workflows for AGI."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from fusionagi.schemas.skill import Skill
|
||||
from fusionagi._logger import logger
|
||||
|
||||
|
||||
class ProceduralMemory:
|
||||
"""
|
||||
Skill store: reusable workflows and procedures. Invokable by name;
|
||||
write/update rules enforced by caller.
|
||||
"""
|
||||
|
||||
def __init__(self, max_skills: int = 5000) -> None:
|
||||
self._skills: dict[str, Skill] = {}
|
||||
self._by_name: dict[str, str] = {} # name -> skill_id (latest)
|
||||
self._max_skills = max_skills
|
||||
|
||||
def add_skill(self, skill: Skill) -> None:
|
||||
"""Register a skill (overwrites same skill_id)."""
|
||||
if len(self._skills) >= self._max_skills and skill.skill_id not in self._skills:
|
||||
self._evict_one()
|
||||
self._skills[skill.skill_id] = skill
|
||||
self._by_name[skill.name] = skill.skill_id
|
||||
logger.debug("Procedural memory: skill added", extra={"skill_id": skill.skill_id, "name": skill.name})
|
||||
|
||||
def get_skill(self, skill_id: str) -> Skill | None:
|
||||
"""Return skill by id or None."""
|
||||
return self._skills.get(skill_id)
|
||||
|
||||
def get_skill_by_name(self, name: str) -> Skill | None:
|
||||
"""Return latest skill with this name or None."""
|
||||
sid = self._by_name.get(name)
|
||||
return self._skills.get(sid) if sid else None
|
||||
|
||||
def list_skills(self, limit: int = 200) -> list[Skill]:
|
||||
"""Return skills (e.g. for planner)."""
|
||||
return list(self._skills.values())[-limit:]
|
||||
|
||||
def remove_skill(self, skill_id: str) -> bool:
|
||||
"""Remove skill. Returns True if existed."""
|
||||
if skill_id not in self._skills:
|
||||
return False
|
||||
name = self._skills[skill_id].name
|
||||
del self._skills[skill_id]
|
||||
if self._by_name.get(name) == skill_id:
|
||||
del self._by_name[name]
|
||||
return True
|
||||
|
||||
def _evict_one(self) -> None:
|
||||
if not self._skills:
|
||||
return
|
||||
rid = next(iter(self._skills))
|
||||
self.remove_skill(rid)
|
||||
Reference in New Issue
Block a user