Class: LLM::Skill
- Inherits:
-
Object
- Object
- LLM::Skill
- Defined in:
- lib/llm/skill.rb
Overview
LLM::Skill represents a directory-backed packaged capability.
A skill directory must contain a SKILL.md file with YAML frontmatter.
Skills can expose themselves as normal LLM::Tool classes through
#to_tool. This keeps skills on the same execution path as local tools.
Instance Attribute Summary collapse
-
#description ⇒ String
readonly
Returns the skill description.
-
#frontmatter ⇒ LLM::Object
readonly
Returns the skill frontmatter.
-
#instructions ⇒ String
readonly
Returns the skill instructions.
-
#name ⇒ String
readonly
Returns the skill name.
-
#path ⇒ String
readonly
Returns the skill directory.
-
#tools ⇒ Array<Class<LLM::Tool>>
readonly
Returns the skill tools.
Class Method Summary collapse
-
.load(path) ⇒ LLM::Skill
Load a skill from a directory.
Instance Method Summary collapse
-
#call(ctx) ⇒ Hash
Execute the skill by wrapping it in a small agent with the skill instructions.
-
#inherit_tools? ⇒ Boolean
Returns true when a skill should inherit tools from its parent.
- #initialize(path) ⇒ LLM::Skill constructor
-
#load! ⇒ LLM::Skill
Load and parse the skill.
-
#to_tool(ctx) ⇒ Class<LLM::Tool>
Expose the skill as a normal LLM::Tool.
Constructor Details
#initialize(path) ⇒ LLM::Skill
57 58 59 60 61 62 63 64 65 |
# File 'lib/llm/skill.rb', line 57 def initialize(path) @path = path.to_s @name = ::File.basename(@path) @description = "Skill: #{@name}" @instructions = "" @frontmatter = LLM::Object.from({}) @tools = [] @inherit_tools = false end |
Instance Attribute Details
#description ⇒ String (readonly)
Returns the skill description.
36 37 38 |
# File 'lib/llm/skill.rb', line 36 def description @description end |
#frontmatter ⇒ LLM::Object (readonly)
Returns the skill frontmatter.
46 47 48 |
# File 'lib/llm/skill.rb', line 46 def frontmatter @frontmatter end |
#instructions ⇒ String (readonly)
Returns the skill instructions.
41 42 43 |
# File 'lib/llm/skill.rb', line 41 def instructions @instructions end |
#name ⇒ String (readonly)
Returns the skill name.
31 32 33 |
# File 'lib/llm/skill.rb', line 31 def name @name end |
#path ⇒ String (readonly)
Returns the skill directory.
26 27 28 |
# File 'lib/llm/skill.rb', line 26 def path @path end |
#tools ⇒ Array<Class<LLM::Tool>> (readonly)
Returns the skill tools.
51 52 53 |
# File 'lib/llm/skill.rb', line 51 def tools @tools end |
Class Method Details
.load(path) ⇒ LLM::Skill
Load a skill from a directory.
19 20 21 |
# File 'lib/llm/skill.rb', line 19 def self.load(path) new(path).tap(&:load!) end |
Instance Method Details
#call(ctx) ⇒ Hash
Execute the skill by wrapping it in a small agent with the skill instructions. The context is bound explicitly by the caller so the nested agent can inherit context-level behavior such as streaming.
88 89 90 91 |
# File 'lib/llm/skill.rb', line 88 def call(ctx) content = agent(ctx).talk("Solve the user's query.").content {content:} end |
#inherit_tools? ⇒ Boolean
Returns true when a skill should inherit tools from its parent
120 121 122 |
# File 'lib/llm/skill.rb', line 120 def inherit_tools? @inherit_tools end |
#load! ⇒ LLM::Skill
Load and parse the skill.
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/llm/skill.rb', line 70 def load! if File.file?(@path) parse(File.read(@path)) elsif File.directory?(@path) path = File.join(@path, "SKILL.md") parse(File.read(path)) else raise LLM::Error, "'#{@path}' is neither a file or directory" end self end |
#to_tool(ctx) ⇒ Class<LLM::Tool>
Expose the skill as a normal LLM::Tool. The context is bound explicitly when the tool class is built.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/llm/skill.rb', line 98 def to_tool(ctx) skill = self Class.new(LLM::Tool) do attr_accessor :tracer name skill.name description skill.description define_singleton_method(:skill?) do true end define_method(:call) do skill.call(ctx) end end end |