Class: Pikuri::Tool::Skill
- Inherits:
-
Pikuri::Tool
- Object
- Pikuri::Tool
- Pikuri::Tool::Skill
- Defined in:
- lib/pikuri/tool/skill.rb
Overview
The skill tool: instantiating Tool::Skill.new(catalog:) produces a tool whose execute closure looks the requested name up in the bound SkillCatalog and returns the skill’s body wrapped in a <skill> block with the absolute base directory, so the LLM can resolve relative sidecar paths against it via the regular read tool.
The catalog of available skills is not duplicated into this tool’s description. It lives in the system prompt — see Pikuri::Tool::SkillCatalog#format_for_prompt — because skills describe what the agent is, not just what one of its tools returns. Putting the catalog in the system prompt keeps it next to the agent’s persona and matches what PI and Claude Code do (opencode is the outlier here). The tool description below is therefore static — it explains the load mechanism, not the inventory.
This tool is not registered manually. Agent#initialize auto- registers it whenever skill_catalog is non-empty, and skips it otherwise; sub-agents inherit it through the parent’s tool snapshot. The bound catalog rides along in the execute closure, so any sub-agent invoking skill resolves names against the same catalog the parent saw.
Constant Summary collapse
- DESCRIPTION =
Description shown to the LLM. Follows the opencode-shape (summary +
Usage:bullets) prescribed by the project’s tool-description convention. The list of which skills exist is not here — see the class header. <<~DESC Load a specialized skill that provides domain-specific instructions and resources for a particular task. Usage: - The catalog of available skills is listed in your system prompt under `<available_skills>`. - Invoke this tool with a skill's `name` to inject its full instructions into the conversation. - The loaded skill may reference helper scripts and files in its base directory — use the `read` tool to load those when the skill's instructions tell you to. - On `Error: skill '...' not found`, do NOT retry with a guessed name. Pick a name that actually appears in `<available_skills>`, or report to the user that no matching skill is installed. DESC
Constants inherited from Pikuri::Tool
CALCULATOR, FETCH, WEB_SCRAPE, WEB_SEARCH
Instance Attribute Summary
Attributes inherited from Pikuri::Tool
#description, #execute, #name, #parameters
Instance Method Summary collapse
- #initialize(catalog:) ⇒ Skill constructor
Methods inherited from Pikuri::Tool
Constructor Details
#initialize(catalog:) ⇒ Skill
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/pikuri/tool/skill.rb', line 49 def initialize(catalog:) super( name: 'skill', description: DESCRIPTION, parameters: Parameters.build { |p| p.required_string :name, 'Name of the skill to load, e.g. "pdf-extraction". ' \ 'Must match a name listed under `<available_skills>` ' \ 'in the system prompt.' }, execute: lambda { |name:| loaded = catalog.get(name) if loaded.nil? available = catalog.list.map(&:name).sort list = available.empty? ? 'none' : available.join(', ') next "Error: skill '#{name}' not found. Available skills: #{list}." end base_dir = File.dirname(loaded.location) <<~OUT <skill name="#{loaded.name}" location="#{loaded.location}"> Sidecar paths in this skill (e.g. scripts/, references/) are relative to #{base_dir}. #{loaded.body} </skill> OUT } ) end |