Files
FusionAGI/fusionagi/memory/procedural.py
defiQUG c052b07662
Some checks failed
Tests / test (3.10) (push) Has been cancelled
Tests / test (3.11) (push) Has been cancelled
Tests / test (3.12) (push) Has been cancelled
Tests / lint (push) Has been cancelled
Tests / docker (push) Has been cancelled
Initial commit: add .gitignore and README
2026-02-09 21:51:42 -08:00

56 lines
1.9 KiB
Python

"""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)