Class: AgentHarness::Skill
- Inherits:
-
Object
- Object
- AgentHarness::Skill
- Defined in:
- lib/agent_harness/skill.rb
Overview
Canonical provider-agnostic skill definition loaded from SKILL.md.
Constant Summary collapse
- PROVIDER_FAMILY_ALIASES =
{ anthropic: :anthropic, google: :google, openai: :openai, openai_compatible: :openai }.freeze
Instance Attribute Summary collapse
-
#description ⇒ Object
readonly
Returns the value of attribute description.
-
#instructions ⇒ Object
readonly
Returns the value of attribute instructions.
-
#mcp_servers ⇒ Object
readonly
Returns the value of attribute mcp_servers.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#provider_overrides ⇒ Object
readonly
Returns the value of attribute provider_overrides.
-
#source_path ⇒ Object
readonly
Returns the value of attribute source_path.
-
#tools ⇒ Object
readonly
Returns the value of attribute tools.
-
#trigger ⇒ Object
readonly
Returns the value of attribute trigger.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(name:, description:, instructions:, trigger: nil, tools: [], mcp_servers: [], providers: {}, source_path: nil) ⇒ Skill
constructor
A new instance of Skill.
- #provider_override_for(provider) ⇒ Object
- #to_h ⇒ Object
Constructor Details
#initialize(name:, description:, instructions:, trigger: nil, tools: [], mcp_servers: [], providers: {}, source_path: nil) ⇒ Skill
Returns a new instance of Skill.
18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/agent_harness/skill.rb', line 18 def initialize(name:, description:, instructions:, trigger: nil, tools: [], mcp_servers: [], providers: {}, source_path: nil) @name = normalize_name(name) @description = validate_string!(:description, description) @instructions = validate_string!(:instructions, instructions) @trigger = trigger.nil? ? nil : validate_string!(:trigger, trigger) @tools = normalize_array(:tools, tools) @mcp_servers = normalize_mcp_servers(mcp_servers) @provider_overrides = normalize_provider_overrides(providers) @source_path = source_path && File.(source_path) end |
Instance Attribute Details
#description ⇒ Object (readonly)
Returns the value of attribute description.
15 16 17 |
# File 'lib/agent_harness/skill.rb', line 15 def description @description end |
#instructions ⇒ Object (readonly)
Returns the value of attribute instructions.
15 16 17 |
# File 'lib/agent_harness/skill.rb', line 15 def instructions @instructions end |
#mcp_servers ⇒ Object (readonly)
Returns the value of attribute mcp_servers.
15 16 17 |
# File 'lib/agent_harness/skill.rb', line 15 def mcp_servers @mcp_servers end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
15 16 17 |
# File 'lib/agent_harness/skill.rb', line 15 def name @name end |
#provider_overrides ⇒ Object (readonly)
Returns the value of attribute provider_overrides.
16 17 18 |
# File 'lib/agent_harness/skill.rb', line 16 def provider_overrides @provider_overrides end |
#source_path ⇒ Object (readonly)
Returns the value of attribute source_path.
16 17 18 |
# File 'lib/agent_harness/skill.rb', line 16 def source_path @source_path end |
#tools ⇒ Object (readonly)
Returns the value of attribute tools.
15 16 17 |
# File 'lib/agent_harness/skill.rb', line 15 def tools @tools end |
#trigger ⇒ Object (readonly)
Returns the value of attribute trigger.
15 16 17 |
# File 'lib/agent_harness/skill.rb', line 15 def trigger @trigger end |
Class Method Details
.from_hash(hash = nil, source_path: nil, **kwargs) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/agent_harness/skill.rb', line 30 def self.from_hash(hash = nil, source_path: nil, **kwargs) hash = kwargs if hash.nil? && !kwargs.empty? unless hash.is_a?(Hash) raise ConfigurationError, "Skill definition must be a Hash, got #{hash.class}" end attrs = hash.each_with_object({}) do |(key, value), memo| memo[key.to_sym] = value end %i[name description instructions].each do |field| value = attrs[field] next if value.is_a?(String) && !value.strip.empty? next if value.is_a?(Symbol) raise ConfigurationError, "#{field} is required" end new(**attrs.merge(source_path: source_path)) end |
.load_file(path) ⇒ Object
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/agent_harness/skill.rb', line 52 def self.load_file(path) = File.(path) content = File.read() frontmatter, body = parse_markdown(content) from_hash(frontmatter.merge(instructions: body), source_path: ) rescue Errno::ENOENT raise ConfigurationError, "Skill file not found: #{path}" rescue Psych::Exception => e raise ConfigurationError, "Invalid YAML frontmatter in skill #{path}: #{e.}" end |
Instance Method Details
#provider_override_for(provider) ⇒ Object
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/agent_harness/skill.rb', line 63 def provider_override_for(provider) merged = provider_override_keys_for(provider).reduce(nil) do |runtime, key| override = @provider_overrides[key] next runtime unless override runtime ? runtime.merge(override) : ProviderRuntime.wrap(override) end merged ? merged.to_h : {} end |
#to_h ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/agent_harness/skill.rb', line 74 def to_h { name: @name, description: @description, instructions: @instructions, trigger: @trigger, tools: deep_dup(@tools), mcp_servers: deep_dup(@mcp_servers), providers: deep_dup(@provider_overrides), source_path: @source_path }.compact end |