# app/core/skills/bootstrap.py
import logging
from sqlalchemy.orm import Session
from app.db import models
from .definitions import SYSTEM_SKILLS
logger = logging.getLogger(__name__)
def bootstrap_system_skills(db: Session):
"""
Ensure all hardcoded system skills from definitions.py exist in the database.
This runs on application startup (lifespan).
"""
logger.info("Checking for system skills bootstrapping...")
# We need a system owner ID. For now, we'll try to find an admin user or use a 'system' id.
# In this DB, the root admin usually has a known ID or we can find it.
admin = db.query(models.User).filter(models.User.role == 'admin').first()
if not admin:
logger.warning("No admin user found to own system skills. Skipping bootstrap.")
return
for skill_def in SYSTEM_SKILLS:
existing = db.query(models.Skill).filter(models.Skill.name == skill_def["name"]).first()
if existing:
# We update it to ensure it matches the hardcoded version (RESTORE FACTORY)
# but preserve the skill's identity.
logger.info(f"Syncing system skill: {skill_def['name']}")
existing.description = skill_def.get("description")
existing.skill_type = skill_def.get("skill_type")
existing.is_enabled = skill_def.get("is_enabled", True)
existing.features = skill_def.get("features", ["swarm_control"])
existing.extra_metadata = skill_def.get("extra_metadata", {})
existing.is_system = True
existing.owner_id = admin.id
db.commit() # Commit to get ID for VFS files
target_skill = existing
else:
logger.info(f"Creating new system skill: {skill_def['name']}")
target_skill = models.Skill(
name=skill_def["name"],
description=skill_def.get("description"),
skill_type=skill_def.get("skill_type"),
is_enabled=skill_def.get("is_enabled", True),
features=skill_def.get("features", ["swarm_control"]),
extra_metadata=skill_def.get("extra_metadata", {}),
is_system=True,
owner_id=admin.id
)
db.add(target_skill)
db.commit() # Commit to get ID
# --- Update VFS ---
vfs_files = skill_def.get("_vfs_files", [])
existing_files = db.query(models.SkillFile).filter(models.SkillFile.skill_id == target_skill.id).all()
existing_file_map = {f.file_path: f for f in existing_files}
for vf in vfs_files:
if vf["path"] in existing_file_map:
existing_file_map[vf["path"]].content = vf["content"]
del existing_file_map[vf["path"]]
else:
db.add(models.SkillFile(skill_id=target_skill.id, file_path=vf["path"], content=vf["content"]))
# Delete any files that were removed from the filesystem
for removed_file in existing_file_map.values():
db.delete(removed_file)
try:
db.commit()
logger.info("System skills bootstrap completed.")
except Exception as e:
db.rollback()
logger.error(f"Failed to bootstrap system skills: {e}")