Class: AIA::PromptHandler

Inherits:
Object
  • Object
show all
Includes:
SkillUtils
Defined in:
lib/aia/prompt_handler.rb

Defined Under Namespace

Classes: RoleContent

Constant Summary collapse

SHORTHAND_KEYS =

Root-level YAML keys that are shorthands for deeper config paths

%w[model temperature top_p next pipeline shell erb].freeze
SHORTHAND_CONFLICTS =

Maps root shorthand keys to their config paths for conflict detection

{
  'model'       => [%w[config model], %w[config models]],
  'temperature' => [%w[config temperature], %w[config llm temperature]],
  'top_p'       => [%w[config top_p], %w[config llm top_p]],
  'next'        => [%w[config next], %w[config pipeline]],
  'pipeline'    => [%w[config pipeline], %w[config next]],
  'shell'       => [%w[config shell], %w[config flags shell]],
  'erb'         => [%w[config erb], %w[config flags erb]],
}.freeze

Instance Method Summary collapse

Methods included from SkillUtils

#find_skill_dir, #parse_front_matter, #path_based_id?, #safe_skill_path, #skill_body

Constructor Details

#initializePromptHandler

Returns a new instance of PromptHandler.



31
32
33
34
35
36
37
38
39
40
# File 'lib/aia/prompt_handler.rb', line 31

def initialize
  @prompts_dir = AIA.config.prompts.dir
  @roles_dir   = AIA.config.prompts.roles_dir

  PM.configure do |c|
    c.prompts_dir = @prompts_dir
  end

  register_pm_directives
end

Instance Method Details

#apply_metadata_config(parsed) ⇒ Object

Applies YAML front matter metadata to AIA.config. Processes root-level shorthand keys, detects conflicts with config: section, and deep merges the config: section into AIA.config.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/aia/prompt_handler.rb', line 115

def (parsed)
  return unless parsed&.

  meta = parsed.
  meta_hash = meta.to_h

  # Extract the config section and root-level shorthands
  config_section = meta_hash['config'] || meta_hash[:config]
  config_section = symbolize_keys_deep(config_section) if config_section

  # Detect conflicts between root shorthands and config: section
  detect_shorthand_conflicts(meta_hash, config_section)

  # Apply root-level shorthands
  apply_root_shorthands(meta_hash)

  # Deep merge config: section into AIA.config
  deep_merge_config(config_section) if config_section
end

#fetch_prompt(prompt_id) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/aia/prompt_handler.rb', line 43

def fetch_prompt(prompt_id)
  if prompt_id == '__FUZZY_SEARCH__'
    return fuzzy_search_prompt('')
  end

  if prompt_id == '__EXECUTABLE_PROMPT__'
    return fetch_executable_prompt
  end

  prompt_file_path = File.join(@prompts_dir, "#{prompt_id}#{AIA.config.prompts.extname}")

  parsed = if File.exist?(prompt_file_path)
             PM.parse(prompt_id)
           else
             warn "Warning: Invalid prompt ID or file not found: #{prompt_id}"
             logger.warn("Invalid prompt ID or file not found: #{prompt_id}")
             handle_missing_prompt(prompt_id)
           end

  (parsed) if parsed
  parsed
end

#fetch_role(role_id) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/aia/prompt_handler.rb', line 67

def fetch_role(role_id)
  return handle_missing_role("roles/") if role_id.nil?
  return fetch_role_from_path(role_id) if path_based_id?(role_id)

  unless role_id.start_with?(AIA.config.prompts.roles_prefix)
    role_id = "#{AIA.config.prompts.roles_prefix}/#{role_id}"
  end

  role_file_path = File.join(@prompts_dir, "#{role_id}#{AIA.config.prompts.extname}")

  parsed = if File.exist?(role_file_path)
             # PM.parse(role_id) cannot resolve subdirectory IDs like "roles/jersey_mike"
             # and returns the ID string as content.  Parse from raw file content instead.
             PM.parse_string(File.read(role_file_path))
           else
             warn "Warning: Invalid role ID or file not found: #{role_id}"
             logger.warn("Invalid role ID or file not found: #{role_id}")
             handle_missing_role(role_id)
           end

  (parsed) if parsed
  parsed
end

#load_role_for_model(model_spec, default_role = nil) ⇒ Object

Load role for a specific model (ADR-005) Takes a model spec hash and default role, returns rendered role text



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/aia/prompt_handler.rb', line 94

def load_role_for_model(model_spec, default_role = nil)
  role_id = if model_spec.is_a?(Hash)
              model_spec[:role] || default_role
            else
              default_role
            end

  return nil if role_id.nil? || role_id.empty?

  role_parsed = fetch_role(role_id)
  role_parsed.to_s
rescue => e
  warn "Warning: Could not load role '#{role_id}' for model: #{e.message}"
  logger.warn("Could not load role '#{role_id}' for model: #{e.message}")
  nil
end