"""Robot Framework helper for Agent Skills Loader integration tests. Provides a CLI-style interface for Robot to invoke Agent Skills loader operations and verify the results. Exit code 0 = success, 1 = failure. Usage: python robot/helper_agent_skills_loader.py load-skill python robot/helper_agent_skills_loader.py discover python robot/helper_agent_skills_loader.py activate python robot/helper_agent_skills_loader.py tool-descriptor python robot/helper_agent_skills_loader.py invalid-skill python robot/helper_agent_skills_loader.py list-resources """ from __future__ import annotations import sys from pathlib import Path _SRC = str(Path(__file__).resolve().parents[1] / "src") if _SRC not in sys.path: sys.path.insert(0, _SRC) from cleveragents.skills.agent_skills_loader import AgentSkillLoader # noqa: E402 def _cmd_load_skill(folder: str) -> int: """Load a skill folder and verify the spec is populated.""" try: loader = AgentSkillLoader.from_folder(Path(folder)) except (ValueError, FileNotFoundError) as exc: print(f"agent-skills-fail: {exc}") return 1 if not loader.spec.name: print("agent-skills-fail: name is empty") return 1 if not loader.spec.description: print("agent-skills-fail: description is empty") return 1 print(f"agent-skills-load-ok: {loader.spec.name}") return 0 def _cmd_discover(folder: str) -> int: """Call discover() and verify metadata-only descriptor.""" try: loader = AgentSkillLoader.from_folder(Path(folder)) except (ValueError, FileNotFoundError) as exc: print(f"agent-skills-fail: {exc}") return 1 descriptor = loader.discover() if descriptor.source != "agent_skill": print( f"agent-skills-fail: expected source=agent_skill, got {descriptor.source}" ) return 1 if descriptor.body: print( f"agent-skills-fail: body should be empty at discover, " f"got: {descriptor.body!r}" ) return 1 if not descriptor.name: print("agent-skills-fail: name is empty") return 1 print(f"agent-skills-discover-ok: {descriptor.name}") return 0 def _cmd_activate(folder: str) -> int: """Call discover() then activate() and verify body is loaded.""" try: loader = AgentSkillLoader.from_folder(Path(folder)) except (ValueError, FileNotFoundError) as exc: print(f"agent-skills-fail: {exc}") return 1 loader.discover() activated = loader.activate() if not activated.body: print("agent-skills-fail: body is empty after activate") return 1 print(f"agent-skills-activate-ok: body_len={len(activated.body)}") return 0 def _cmd_tool_descriptor(folder: str) -> int: """Convert loaded skill to tool descriptor and verify fields.""" try: loader = AgentSkillLoader.from_folder(Path(folder)) except (ValueError, FileNotFoundError) as exc: print(f"agent-skills-fail: {exc}") return 1 td = loader.to_tool_descriptor() if td.source != "agent_skill": print(f"agent-skills-fail: expected source=agent_skill, got {td.source}") return 1 if not td.read_only: print("agent-skills-fail: expected read_only=True") return 1 if td.writes: print("agent-skills-fail: expected writes=False") return 1 if not td.agent_skill_path: print("agent-skills-fail: agent_skill_path is empty") return 1 if not td.name: print("agent-skills-fail: tool descriptor name is empty") return 1 print(f"agent-skills-tool-descriptor-ok: {td.name}") print(f" resource_slots={len(td.resource_slots)}") for slot in td.resource_slots: print(f" slot: name={slot.name} access={slot.access}") return 0 def _cmd_invalid_skill(folder: str) -> int: """Attempt to load an invalid skills folder and verify error.""" try: AgentSkillLoader.from_folder(Path(folder)) print("agent-skills-fail: expected error but none was raised") return 1 except (ValueError, FileNotFoundError) as exc: print(f"agent-skills-invalid-ok: {exc}") return 0 def _cmd_list_resources(folder: str) -> int: """List resources from a skill folder.""" try: loader = AgentSkillLoader.from_folder(Path(folder)) except (ValueError, FileNotFoundError) as exc: print(f"agent-skills-fail: {exc}") return 1 resources = loader.list_resources() print(f"agent-skills-list-resources-ok: count={len(resources)}") for p in resources: print(f" resource: {p.name}") return 0 def _cmd_steps(folder: str) -> int: """Load a skill folder and print structured steps from the spec.""" try: loader = AgentSkillLoader.from_folder(Path(folder)) except (ValueError, FileNotFoundError) as exc: print(f"agent-skills-fail: {exc}") return 1 steps = loader.spec.steps print(f"agent-skills-steps-ok: count={len(steps)}") for step in steps: print(f" step[{step.index}]: {step.content}") return 0 def _cmd_resource_slots(folder: str) -> int: """Load a skill folder and print resource binding slots.""" try: loader = AgentSkillLoader.from_folder(Path(folder)) except (ValueError, FileNotFoundError) as exc: print(f"agent-skills-fail: {exc}") return 1 slots = loader.resource_slots print(f"agent-skills-resource-slots-ok: count={len(slots)}") for slot in slots: print( f" slot: name={slot.name} type={slot.resource_type} access={slot.access}" ) return 0 _COMMANDS = { "load-skill": _cmd_load_skill, "discover": _cmd_discover, "activate": _cmd_activate, "tool-descriptor": _cmd_tool_descriptor, "invalid-skill": _cmd_invalid_skill, "list-resources": _cmd_list_resources, "steps": _cmd_steps, "resource-slots": _cmd_resource_slots, } def main() -> int: """Entry point called by Robot Framework ``Run Process``.""" if len(sys.argv) < 3: print( "Usage: helper_agent_skills_loader.py " " " "" ) return 1 command = sys.argv[1] folder = sys.argv[2] handler = _COMMANDS.get(command) if handler is None: print(f"Unknown command: {command}") return 1 return handler(folder) if __name__ == "__main__": sys.exit(main())