Module: AgentHarness::Extensions::Adapters::Skill

Defined in:
lib/agent_harness/extensions.rb

Class Method Summary collapse

Class Method Details

.extract_instructions(body) ⇒ Object



618
619
620
# File 'lib/agent_harness/extensions.rb', line 618

def extract_instructions(body)
  body.to_s.strip
end

.load(path) ⇒ Object

Raises:



580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
# File 'lib/agent_harness/extensions.rb', line 580

def load(path)
  resolved = File.expand_path(path)
  raise ConfigurationError, "Skill file not found: #{resolved}" unless File.file?(resolved)
  raise ConfigurationError, "Skill file must be a Markdown file: #{resolved}" unless File.extname(resolved) == ".md"

  content = File.read(resolved)
  frontmatter, body = parse_frontmatter(content)

  tools = Array(frontmatter["tools"]).map { |tool| normalize_tool(tool) }
  mcp_servers = Array(frontmatter["mcp_servers"]).map { |server| normalize_mcp_server(server) }
  instructions = extract_instructions(body)
  system_prompt_additions = instructions.empty? ? [] : [instructions]

  [
    SkillExtension.new(
      name: frontmatter["name"] || File.basename(resolved, ".md"),
      description: frontmatter["description"],
      version: frontmatter["version"],
      tools: tools,
      system_prompt_additions: system_prompt_additions,
      mcp_servers: mcp_servers,
      required_provider_capabilities: Array(frontmatter["required_provider_capabilities"]).map(&:to_sym),
      source_path: resolved
    )
  ]
end

.normalize_mcp_server(server) ⇒ Object



633
634
635
636
637
638
639
640
# File 'lib/agent_harness/extensions.rb', line 633

def normalize_mcp_server(server)
  case server
  when Hash
    server.transform_keys(&:to_sym)
  else
    raise ConfigurationError, "Unsupported MCP server definition in skill adapter: #{server.inspect}"
  end
end

.normalize_tool(tool) ⇒ Object



622
623
624
625
626
627
628
629
630
631
# File 'lib/agent_harness/extensions.rb', line 622

def normalize_tool(tool)
  case tool
  when Hash
    tool.transform_keys(&:to_sym)
  when String, Symbol
    {name: tool.to_s}
  else
    raise ConfigurationError, "Unsupported tool definition in skill adapter: #{tool.inspect}"
  end
end

.parse_frontmatter(content) ⇒ Object



607
608
609
610
611
612
613
614
615
616
# File 'lib/agent_harness/extensions.rb', line 607

def parse_frontmatter(content)
  match = content.match(/\A---\s*\n(.*?\n)---\s*\n(.*)\z/m)
  return [{}, content] unless match

  require "yaml"
  frontmatter = YAML.safe_load(match[1], permitted_classes: [Symbol]) || {}
  [frontmatter, match[2]]
rescue Psych::SyntaxError => e
  raise ConfigurationError, "Invalid YAML frontmatter in skill file: #{e.message}"
end