Class: AIA::PromptHandler

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

Instance Method Summary collapse

Constructor Details

#initializePromptHandler

Returns a new instance of PromptHandler.



10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/aia/prompt_handler.rb', line 10

def initialize
  @prompts_dir         = AIA.config.prompts_dir
  @roles_dir           = AIA.config.roles_dir # A sub-directory of @prompts_dir
  @directive_processor = AIA::DirectiveProcessor.new

  PromptManager::Prompt.storage_adapter =
    PromptManager::Storage::FileSystemAdapter.config do |c|
      c.prompts_dir      = @prompts_dir
      c.prompt_extension = '.txt'  # default
      c.params_extension = '.json' # default
    end.new
end

Instance Method Details

#fetch_prompt(prompt_id) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/aia/prompt_handler.rb', line 35

def fetch_prompt(prompt_id)
  # Special case for fuzzy search without an initial query
  if prompt_id == '__FUZZY_SEARCH__'
    return fuzzy_search_prompt('')
  end

  # First check if the prompt file exists to avoid ArgumentError from PromptManager
  prompt_file_path = File.join(@prompts_dir, "#{prompt_id}.txt")
  if File.exist?(prompt_file_path)
    prompt = PromptManager::Prompt.new(
      id: prompt_id,
      directives_processor: @directive_processor,
      external_binding: binding,
      erb_flag: AIA.config.erb,
      envar_flag: AIA.config.shell
    )

    # Parameters should be extracted during initialization or to_s
    return prompt if prompt
  else
    puts "Warning: Invalid prompt ID or file not found: #{prompt_id}"
  end

  handle_missing_prompt(prompt_id)
end

#fetch_role(role_id) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/aia/prompt_handler.rb', line 101

def fetch_role(role_id)
  # Handle nil role_id
  return handle_missing_role("roles/") if role_id.nil?

  # Prepend roles_prefix if not already present
  unless role_id.start_with?(AIA.config.roles_prefix)
    role_id = "#{AIA.config.roles_prefix}/#{role_id}"
  end

  # NOTE: roles_prefix is a sub-directory of the prompts directory
  role_file_path = File.join(@prompts_dir, "#{role_id}.txt")

  if File.exist?(role_file_path)
    role_prompt = PromptManager::Prompt.new(
      id: role_id,
      directives_processor: @directive_processor,
      external_binding: binding,
      erb_flag: AIA.config.erb,
      envar_flag: AIA.config.shell
    )
    return role_prompt if role_prompt
  else
    puts "Warning: Invalid role ID or file not found: #{role_id}"
  end

  handle_missing_role(role_id)
end

#fuzzy_search_prompt(prompt_id) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/aia/prompt_handler.rb', line 81

def fuzzy_search_prompt(prompt_id)
  new_prompt_id = search_prompt_id_with_fzf(prompt_id)

  if new_prompt_id.nil? || new_prompt_id.empty?
    raise "Error: Could not find prompt with ID: #{prompt_id} even with fuzzy search"
  end

  prompt = PromptManager::Prompt.new(
    id: new_prompt_id,
    directives_processor: @directive_processor,
    external_binding: binding,
    erb_flag: AIA.config.erb,
    envar_flag: AIA.config.shell
  )

  raise "Error: Could not find prompt with ID: #{prompt_id} even with fuzzy search" if prompt.nil?

  prompt
end

#fuzzy_search_role(role_id) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/aia/prompt_handler.rb', line 166

def fuzzy_search_role(role_id)
  new_role_id = search_role_id_with_fzf(role_id)
  if new_role_id.nil? || new_role_id.empty?
    raise "Error: Could not find role with ID: #{role_id} even with fuzzy search"
  end

  role_prompt = PromptManager::Prompt.new(
    id: new_role_id,
    directives_processor: @directive_processor,
    external_binding: binding,
    erb_flag: AIA.config.erb,
    envar_flag: AIA.config.shell
  )

  raise "Error: Could not find role with ID: #{role_id} even with fuzzy search" if role_prompt.nil?
  role_prompt
end

#get_prompt(prompt_id, role_id = '') ⇒ Object



24
25
26
27
28
29
30
31
32
33
# File 'lib/aia/prompt_handler.rb', line 24

def get_prompt(prompt_id, role_id = '')
  prompt = fetch_prompt(prompt_id)

  unless role_id.empty?
    role_prompt = fetch_role(role_id)
    prompt.text.prepend(role_prompt.text)
  end

  prompt
end

#handle_missing_prompt(prompt_id) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/aia/prompt_handler.rb', line 61

def handle_missing_prompt(prompt_id)
  # Handle empty/nil prompt_id
  prompt_id = prompt_id.to_s.strip
  if prompt_id.empty?
    STDERR.puts "Error: Prompt ID cannot be empty"
    exit 1
  end
  
  if AIA.config.fuzzy
    return fuzzy_search_prompt(prompt_id)
  elsif AIA.config.fuzzy
    puts "Warning: Fuzzy search is enabled but Fzf tool is not available."
    STDERR.puts "Error: Could not find prompt with ID: #{prompt_id}"
    exit 1
  else
    STDERR.puts "Error: Could not find prompt with ID: #{prompt_id}"
    exit 1
  end
end

#handle_missing_role(role_id) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/aia/prompt_handler.rb', line 150

def handle_missing_role(role_id)
  # Handle empty/nil role_id
  role_id = role_id.to_s.strip
  if role_id.empty? || role_id == "roles/"
    STDERR.puts "Error: Role ID cannot be empty"
    exit 1
  end
  
  if AIA.config.fuzzy
    return fuzzy_search_role(role_id)
  else
    STDERR.puts "Error: Could not find role with ID: #{role_id}"
    exit 1
  end
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 role text



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/aia/prompt_handler.rb', line 131

def load_role_for_model(model_spec, default_role = nil)
  # Determine which role to use
  role_id = if model_spec.is_a?(Hash)
              model_spec[:role] || default_role
            else
              # Backward compatibility: if model_spec is a string, use default role
              default_role
            end

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

  # Load the role using existing fetch_role method
  role_prompt = fetch_role(role_id)
  role_prompt.text
rescue => e
  puts "Warning: Could not load role '#{role_id}' for model: #{e.message}"
  nil
end

#search_prompt_id_with_fzf(initial_query) ⇒ Object

FIXME: original implementation used a search_proc to look into the content of the prompt

files.  The use of the select statement does not work.


187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/aia/prompt_handler.rb', line 187

def search_prompt_id_with_fzf(initial_query)
  prompt_files = Dir.glob(File.join(@prompts_dir, "*.txt"))
                   .map { |file| File.basename(file, ".txt") }
  fzf = AIA::Fzf.new(
    list: prompt_files,
    directory: @prompts_dir,
    query: initial_query,
    subject: 'Prompt IDs',
    prompt: 'Select a prompt ID:'
  )
  fzf.run || (raise "No prompt ID selected")
end

#search_role_id_with_fzf(initial_query) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/aia/prompt_handler.rb', line 200

def search_role_id_with_fzf(initial_query)
  role_files = Dir.glob(File.join(@roles_dir, "*.txt"))
                .map { |file| File.basename(file, ".txt") }
  fzf = AIA::Fzf.new(
    list: role_files,
    directory: @prompts_dir,
    query: initial_query,
    subject: 'Role IDs',
    prompt: 'Select a role ID:'
  )

  role = fzf.run

  if role.nil? || role.empty?
    raise "No role ID selected"
  end

  unless role.start_with?(AIA.config.role_prefix)
    role = AIA.config.role_prefix + '/' + role
  end

  role
end