mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-09-19 08:20:42 +03:00
Merge pull request #2769 from yueguobin/fix/load-feature-skills
fix: add load_feature_skills() to properly load network planning features
This commit is contained in:
commit
68f63597eb
@ -98,7 +98,7 @@ class SkillsLoader:
|
|||||||
|
|
||||||
def load_device_skills(self) -> Dict[str, Dict[str, Any]]:
|
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:
|
Returns:
|
||||||
Dictionary mapping skill keys to skill definitions
|
Dictionary mapping skill keys to skill definitions
|
||||||
@ -131,7 +131,48 @@ class SkillsLoader:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to load skill from {yaml_file}: {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
|
return skills
|
||||||
|
|
||||||
def load_prompt(self, prompt_name: str) -> str:
|
def load_prompt(self, prompt_name: str) -> str:
|
||||||
|
|||||||
@ -227,9 +227,17 @@ class SkillsManager:
|
|||||||
logger.error(f"Invalid skill format for {skill_key}, skipping")
|
logger.error(f"Invalid skill format for {skill_key}, skipping")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Load new device/feature skills from YAML files
|
# Load new device skills from YAML files
|
||||||
new_device_skills = self.loader.load_device_skills()
|
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)
|
# Update registries (safe replace - never leaves dict empty)
|
||||||
for k in list(INJECTION_SKILLS_REGISTRY):
|
for k in list(INJECTION_SKILLS_REGISTRY):
|
||||||
if k not in new_injection_skills:
|
if k not in new_injection_skills:
|
||||||
@ -237,11 +245,11 @@ class SkillsManager:
|
|||||||
INJECTION_SKILLS_REGISTRY.update(new_injection_skills)
|
INJECTION_SKILLS_REGISTRY.update(new_injection_skills)
|
||||||
|
|
||||||
for k in list(SKILLS_REGISTRY):
|
for k in list(SKILLS_REGISTRY):
|
||||||
if k not in new_device_skills:
|
if k not in all_skills:
|
||||||
del SKILLS_REGISTRY[k]
|
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
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to reload skills: {e}")
|
logger.error(f"Failed to reload skills: {e}")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user