Module: XAeonAgents::GenHelpers

Included in:
ErbEvaluator
Defined in:
lib/x_aeon_agents/gen_helpers.rb

Overview

Helper methods for generating skill content

Defined Under Namespace

Classes: ErbEvaluator

Public API collapse

Class Method Details

.config(skill_name) ⇒ Hash

Return the skill config hash from its .skill_config.yml file, if it exists.

Parameters:

  • skill_name (String)

    The skill name (matching a directory under skills.src/)

Returns:

  • (Hash)

    The YAML config hash, or an empty Hash if no config file exists



151
152
153
154
# File 'lib/x_aeon_agents/gen_helpers.rb', line 151

def self.config(skill_name)
  skill_config_file = "skills.src/#{skill_name}/.skill_config.yml"
  File.exist?(skill_config_file) ? YAML.load_file(skill_config_file) : {}
end

Instance Method Details

#announceObject

Return the prompt to announce that the agent is working on a skill. Prerequisite: skill_goal should be set before.



50
51
52
# File 'lib/x_aeon_agents/gen_helpers.rb', line 50

def announce
  "Always tell the user \"SKILL: I am #{goal_sentence}\" to inform the user that you are running this skill."
end

#goal(goal_desc = nil) ⇒ String

Define or get the skill goal to be used in ERB templates

Parameters:

  • goal_desc (String, nil) (defaults to: nil)

    The skill goal, or nil to retrieve the previously set skill goal

Returns:

  • (String)

    The skill goal



35
36
37
38
# File 'lib/x_aeon_agents/gen_helpers.rb', line 35

def goal(goal_desc = nil)
  @skill_goal = goal_desc unless goal_desc.nil?
  @skill_goal
end

#goal_sentenceString

Get the skill goal as a sentence Prerequisite: skill_goal should be set before.

Returns:

  • (String)

    The skill goal as useable inside a sentence



44
45
46
# File 'lib/x_aeon_agents/gen_helpers.rb', line 44

def goal_sentence
  "#{@skill_goal[0].downcase}#{@skill_goal[1..]}"
end

#nameString

Return the skill being generated

Returns:

  • (String)

    Skill name being generated



159
160
161
# File 'lib/x_aeon_agents/gen_helpers.rb', line 159

def name
  current_erb_file.match(%r{/skills\.src/([^/]+)/})[1]
end

#ordered_todo_list(&erb_block) ⇒ String

Define an ordered todo list for a skill. Captures the ERB block content, parses its ## sections, numbers them starting at 2 (section 1 "Inform the USER" is auto-generated), and wraps everything with the standard skill header, checklist initialization, and final verification sections.

Parameters:

  • erb_block (#call)

    ERB block containing the markdown sections

Returns:

  • (String)

    The formatted todo list



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/x_aeon_agents/gen_helpers.rb', line 112

def ordered_todo_list(&erb_block)
  transform_erb_block(erb_block) do |erb_content|
    # Split into sections by ## headings
    # Number sections starting from 2 and strip trailing whitespace
    step_number = 2
    numbered_sections = erb_content
      .strip
      .split(/^(?=### )/)
      .reject { |s| s.strip.empty? }
      .map do |section|
        numbered = section.sub(/^### /, "### #{step_number}. ").rstrip
        step_number += 1
        numbered
      end

    # Compose the full output and append directly to ERB buffer
    # (we use <% %> not <%= %> since standard ERB doesn't support <%= method do %>)
    <<~EO_MARKDOWN
      ## Sequential steps to be followed when using this skill

      When #{goal_sentence}, follow those steps.

      #{init_skill_checklist(name).rstrip}

      ### 1. Inform the user

      - #{announce}

      #{numbered_sections.join("\n\n")}

      #{validate_skill_checklist(name).rstrip}
    EO_MARKDOWN
  end
end

#rule(title, description: nil, type: :ruby, bad: nil, good: nil, rationale: nil) ⇒ String

Generate a rule documentation block with examples and rationale.

Parameters:

  • title (String)

    The rule title

  • description (String, nil) (defaults to: nil)

    The additional description

  • type (Symbol) (defaults to: :ruby)

    The code block language type (e.g., :bash, :ruby)

  • bad (String, nil) (defaults to: nil)

    The incorrect example

  • good (String, nil) (defaults to: nil)

    The correct example

  • rationale (String, nil) (defaults to: nil)

    The explanation for why this rule exists

Returns:

  • (String)

    The formatted markdown documentation for the rule



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/x_aeon_agents/gen_helpers.rb', line 71

def rule(title, description: nil, type: :ruby, bad: nil, good: nil, rationale: nil)
  markdown_sections = [
    <<~EO_MARKDOWN
      ### Rule: #{title}#{"\n\n#{description.strip}" unless description.nil?}
    EO_MARKDOWN
  ]
  unless bad.nil?
    markdown_sections << <<~EO_MARKDOWN
      #### Example: Incorrect

      ```#{type}
      #{bad.strip}
      ```
    EO_MARKDOWN
  end
  unless good.nil?
    markdown_sections << <<~EO_MARKDOWN
      #### Example: Correct

      ```#{type}
      #{good.strip}
      ```
    EO_MARKDOWN
  end
  unless rationale.nil?
    markdown_sections << <<~EO_MARKDOWN
      #### Rationale

      #{rationale}
    EO_MARKDOWN
  end
  markdown_sections.join("\n").strip
end

#skill(description:, dependencies: [], plan: false, metadata: {}) ⇒ String

Define a skill metadata. This should always be the first call in a skill ERB file. It also returns the corresponding YAML frontmatter. The name is automatically derived from skill_name.

Parameters:

  • description (String)

    Description of the skill

  • dependencies (Array<String>) (defaults to: [])

    List of skills dependencies

  • plan (Boolean) (defaults to: false)

    Is this skill applicable to plan mode?

  • metadata (Hash) (defaults to: {})

    Optional metadata key-value pairs

Returns:

  • (String)

    The complete YAML frontmatter block (including --- delimiters)



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/x_aeon_agents/gen_helpers.rb', line 19

def skill(description:, dependencies: [], plan: false, metadata: {})
  @plan = plan
  frontmatter = {
    'name' => name,
    'description' => "#{description}#{' Use this skill also in Plan mode.' if plan}"
  }
  ['agent'] = 'Plan' if plan
  ['dependencies'] = dependencies unless dependencies.empty?
  frontmatter['metadata'] = .transform_keys(&:to_s) unless .empty?
  "#{YAML.dump(frontmatter, line_width: -1).chomp}\n---"
end

#tmp_pathString

Return a default temporary folder that agents can use in a project. It's better to force it to the agents, as some models will try weird CLI commands to create temporary files otherwise.

Returns:

  • (String)

    Temporary folder path



58
59
60
# File 'lib/x_aeon_agents/gen_helpers.rb', line 58

def tmp_path
  "#{Config.data_dir}/tmp"
end

#when_to_use(&erb_block) ⇒ String

Generate the "When to use it" section for a skill. This helper automatically includes standard items and custom usage instructions.

Parameters:

  • erb_block (#call)

    ERB block containing custom usage instructions

Returns:

  • (String)

    The formatted "When to use it" section



168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/x_aeon_agents/gen_helpers.rb', line 168

def when_to_use(&erb_block)
  transform_erb_block(erb_block) do |erb_content|
    blocks = []
    blocks << '- This skill can be used when in Plan mode.' if @plan
    blocks << "- Always use it every time another skill specifically mentions `skill: #{name}`."
    blocks << erb_content
    <<~EO_MARKDOWN
      ## When to use it

      #{blocks.join("\n").rstrip}
    EO_MARKDOWN
  end
end