mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-08-27 20:40:13 +03:00
fix: add load_feature_skills() to properly load network planning features
The feature directory contains network planning and design functionalities (e.g., topology_planner), not device-specific features. These were not being loaded because load_device_skills() only scanned the device directory. Changes: - Added new load_feature_skills() method in SkillsLoader - Modified reload_skills() to load both device and feature directories - Device skills: device-specific configurations (e.g., VPCS) - Feature skills: network planning functionalities (e.g., topology planner) - Both are now properly loaded into SKILLS_REGISTRY This ensures that network planning features like topology_planner are available via the device_skills tool with proper category classification.
This commit is contained in:
parent
6497db6f30
commit
e76f3970ca
@ -98,7 +98,7 @@ class SkillsLoader:
|
||||
|
||||
def load_device_skills(self) -> Dict[str, Dict[str, Any]]:
|
||||
"""
|
||||
Load all device/feature skills from YAML files.
|
||||
Load all device skills from YAML files.
|
||||
|
||||
Returns:
|
||||
Dictionary mapping skill keys to skill definitions
|
||||
@ -131,7 +131,48 @@ class SkillsLoader:
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load skill from {yaml_file}: {e}")
|
||||
|
||||
logger.debug(f"Loaded {len(skills)} device skills from {device_dir}")
|
||||
logger.debug(f"Loaded {len(skills)} device skills from device directory")
|
||||
return skills
|
||||
|
||||
def load_feature_skills(self) -> Dict[str, Dict[str, Any]]:
|
||||
"""
|
||||
Load all feature skills from YAML files.
|
||||
|
||||
Feature skills are network planning and design functionalities
|
||||
(e.g., topology planner), not device-specific features.
|
||||
|
||||
Returns:
|
||||
Dictionary mapping skill keys to skill definitions
|
||||
"""
|
||||
if yaml is None:
|
||||
logger.error("PyYAML is not installed. Cannot load skills from YAML.")
|
||||
return {}
|
||||
|
||||
skills = {}
|
||||
feature_dir = self.skills_dir / "feature"
|
||||
|
||||
if not feature_dir.exists():
|
||||
logger.warning(f"Feature skills directory not found: {feature_dir}")
|
||||
return {}
|
||||
|
||||
for yaml_file in feature_dir.glob("*.yaml"):
|
||||
try:
|
||||
skill_data = self._load_yaml(yaml_file)
|
||||
if not skill_data:
|
||||
logger.warning(f"Skipping empty YAML file: {yaml_file}")
|
||||
continue
|
||||
# Use device_type from YAML content as the key
|
||||
# Fallback to filename stem if device_type not present
|
||||
skill_key = skill_data.get("device_type") if isinstance(skill_data, dict) else None
|
||||
if not skill_key:
|
||||
skill_key = yaml_file.stem
|
||||
logger.warning(f"No device_type in {yaml_file}, using filename '{skill_key}' as key")
|
||||
skills[skill_key] = skill_data
|
||||
logger.debug(f"Loaded feature skill: {skill_key} from {yaml_file}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load feature skill from {yaml_file}: {e}")
|
||||
|
||||
logger.debug(f"Loaded {len(skills)} feature skills from feature directory")
|
||||
return skills
|
||||
|
||||
def load_prompt(self, prompt_name: str) -> str:
|
||||
|
||||
@ -227,9 +227,17 @@ class SkillsManager:
|
||||
logger.error(f"Invalid skill format for {skill_key}, skipping")
|
||||
continue
|
||||
|
||||
# Load new device/feature skills from YAML files
|
||||
# Load new device skills from YAML files
|
||||
new_device_skills = self.loader.load_device_skills()
|
||||
|
||||
# Load new feature skills from YAML files
|
||||
new_feature_skills = self.loader.load_feature_skills()
|
||||
|
||||
# Merge device and feature skills into single registry
|
||||
all_skills = {}
|
||||
all_skills.update(new_device_skills)
|
||||
all_skills.update(new_feature_skills)
|
||||
|
||||
# Update registries (safe replace - never leaves dict empty)
|
||||
for k in list(INJECTION_SKILLS_REGISTRY):
|
||||
if k not in new_injection_skills:
|
||||
@ -237,11 +245,11 @@ class SkillsManager:
|
||||
INJECTION_SKILLS_REGISTRY.update(new_injection_skills)
|
||||
|
||||
for k in list(SKILLS_REGISTRY):
|
||||
if k not in new_device_skills:
|
||||
if k not in all_skills:
|
||||
del SKILLS_REGISTRY[k]
|
||||
SKILLS_REGISTRY.update(new_device_skills)
|
||||
SKILLS_REGISTRY.update(all_skills)
|
||||
|
||||
logger.info(f"Loaded {len(new_injection_skills)} injection skills and {len(new_device_skills)} device skills")
|
||||
logger.info(f"Loaded {len(new_injection_skills)} injection skills, {len(new_device_skills)} device skills, and {len(new_feature_skills)} feature skills")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to reload skills: {e}")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user