Class: AIA::Main

Inherits:
Object
  • Object
show all
Includes:
DynamicContent, UserQuery
Defined in:
lib/aia/main.rb

Overview

Everything is being handled within the context of a single class.

Constant Summary collapse

SPINNER_FORMAT =
:bouncing_ball

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from UserQuery

#ask_question_with_reline

Methods included from DynamicContent

#render_env, #render_erb

Constructor Details

#initialize(args = ARGV) ⇒ Main

Returns a new instance of Main.



27
28
29
30
31
32
33
34
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
60
61
62
# File 'lib/aia/main.rb', line 27

def initialize(args= ARGV)
  unless $stdin.tty?
    @piped_content = $stdin.readlines.join.chomp
    $stdin.reopen("/dev/tty")
  end

  @directive_output = ""
  AIA::Tools.load_tools

  AIA.client = AIA::Client.new

  AIA::Cli.new(args)

  if AIA.config.debug?
    debug_me('== CONFIG AFTER CLI =='){[
      "AIA.config"
    ]}
  end

  @spinner  = TTY::Spinner.new(":spinner :title", format: SPINNER_FORMAT)
  spinner.update(title: "composing response ... ")

  @logger = AIA::Logging.new(AIA.config.log_file)

  @logger.info(AIA.config) if AIA.config.debug? || AIA.config.verbose?


  @directives_processor = AIA::Directives.new 

  @prompt = AIA::Prompt.new.prompt

  @prompt.text += piped_content unless piped_content.nil?

  # TODO: still should verify that the tools are ion the $PATH
  # tools.class.verify_tools
end

Instance Attribute Details

#backendObject

Returns the value of attribute backend.



23
24
25
# File 'lib/aia/main.rb', line 23

def backend
  @backend
end

#directive_outputObject

Returns the value of attribute directive_output.



23
24
25
# File 'lib/aia/main.rb', line 23

def directive_output
  @directive_output
end

#loggerObject

Returns the value of attribute logger.



23
24
25
# File 'lib/aia/main.rb', line 23

def logger
  @logger
end

#piped_contentObject

Returns the value of attribute piped_content.



23
24
25
# File 'lib/aia/main.rb', line 23

def piped_content
  @piped_content
end

#spinnerObject (readonly)

Returns the value of attribute spinner.



25
26
27
# File 'lib/aia/main.rb', line 25

def spinner
  @spinner
end

#toolsObject

Returns the value of attribute tools.



23
24
25
# File 'lib/aia/main.rb', line 23

def tools
  @tools
end

Instance Method Details

#add_continue_optionObject



199
200
201
202
203
204
# File 'lib/aia/main.rb', line 199

def add_continue_option
  if 'mods' == AIA.config.backend
    continue_option   = " -C"
    AIA.config.extra += continue_option unless AIA.config.extra.include?(continue_option)
  end
end

#callObject

This will be recursive with the new options –next and –pipeline



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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/aia/main.rb', line 74

def call
  @directive_output = @directives_processor.execute_my_directives

  if AIA.config.chat?
    AIA.config.out_file = STDOUT 
    AIA.config.extra = "--quiet" if 'mods' == AIA.config.backend
  end

  # TODO: the context_files left in the @arguments array
  #       should be verified BEFORE asking the user for a
  #       prompt keyword or process the prompt.  Do not
  #       want invalid files to make it this far.

  found = AIA::Tools
            .search_for(
              name: AIA.config.backend, 
              role: :backend
            )

  if found.empty?
    abort "There are no :backend tools named #{AIA.config.backend}"
  end

  if found.size > 1
    abort "There are #{found.size} :backend tools with the name #{AIAA.config.backend}"
  end

  backend_klass = found.first.klass

  abort "backend not found: #{AIA.config.backend}" if backend_klass.nil?

  the_prompt = @prompt.to_s

  the_prompt.prepend(@directive_output + "\n") unless @directive_output.nil? || @directive_output.empty?

  if AIA.config.terse?
    the_prompt.prepend "Be terse in your response. "
  end

  @backend  = backend_klass.new(
                text:           the_prompt,
                files:          AIA.config.arguments    # FIXME: want validated context files
              )

  result = get_and_display_result(the_prompt)

  AIA.speak(result) if AIA.config.speak?

  logger.prompt_result(@prompt, result)

  if AIA.config.chat?
    setup_reline_history
    AIA.speak result
    lets_chat 
  end

  return if AIA.config.next.empty? && AIA.config.pipeline.empty?

  keep_going(result) unless AIA.config.pipeline.empty?
end

#get_and_display_result(the_prompt_text) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/aia/main.rb', line 163

def get_and_display_result(the_prompt_text)
  spinner.auto_spin if AIA.config.verbose?

  backend.text  = the_prompt_text
  result        = backend.run

  if AIA.config.verbose?
    spinner.success "Done." 
  end

  AIA.config.out_file.write "\nResponse:\n"

  if STDOUT == AIA.config.out_file
    if AIA.config.render?
      AIA::Glow.new(content: result).run
    else
      result  = result.wrap(indent: 2)
      AIA.config.out_file.write result
    end
  else
    AIA.config.out_file.write result
    if AIA.config.render?
      AIA::Glow.new(file_path: AIA.config.out_file).run
    end
  end

  result
end

#handle_directives(the_prompt_text) ⇒ Object



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/aia/main.rb', line 216

def handle_directives(the_prompt_text)
  signal = PromptManager::Prompt::DIRECTIVE_SIGNAL
  result = the_prompt_text.start_with?(signal)

  if result
    parts       = the_prompt_text[signal.size..].split(' ')
    directive   = parts.shift
    parameters  = parts.join(' ')
    AIA.config.directives << [directive, parameters]

    @directive_output = @directives_processor.execute_my_directives
  else
    @directive_output = ""
  end

  result
end

#insert_terse_phrase(a_string) ⇒ Object



207
208
209
210
211
212
213
# File 'lib/aia/main.rb', line 207

def insert_terse_phrase(a_string)
  if AIA.config.terse?
    a_string.prepend "Be terse in your response. "
  end

  a_string
end

#keep_going(result) ⇒ Object

The AIA.config.pipeline is NOT empty, so feed this result into the next prompt within the pipeline.



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/aia/main.rb', line 139

def keep_going(result)
  temp_file = Tempfile.new('aia_pipeline')
  temp_file.write(result)
  temp_file.close

  AIA.config.directives = []
  AIA.config.model      = ""
  AIA.config.arguments  = [
                            AIA.config.pipeline.shift, 
                            temp_file.path,
                            # TODO: additional arguments from the pipeline
                          ] 
  AIA.config.next       = ""

  AIA.config.files = [temp_file.path]

  @prompt = AIA::Prompt.new.prompt
  call # Recurse! until the AIA.config.pipeline is emplty
  puts
ensure
  temp_file.unlink
end

#lets_chatObject



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/aia/main.rb', line 235

def lets_chat
  add_continue_option    

  the_prompt_text = ask_question_with_reline("\nFollow Up: ")

  until the_prompt_text.empty?
    the_prompt_text   = render_erb(the_prompt_text) if AIA.config.erb?
    the_prompt_text   = render_env(the_prompt_text) if AIA.config.shell?

    if handle_directives(the_prompt_text)
      if @directive_output.nil? || @directive_output.empty?
        # Do nothing
      else
        the_prompt_text = @directive_output 
        the_prompt_text = render_erb(the_prompt_text) if AIA.config.erb?
        the_prompt_text = render_env(the_prompt_text) if AIA.config.shell?
        result          = get_and_display_result(the_prompt_text)
        log_the_follow_up(the_prompt_text, result)
        AIA.speak result
      end
    else
      the_prompt_text = insert_terse_phrase(the_prompt_text)
      result          = get_and_display_result(the_prompt_text)
      log_the_follow_up(the_prompt_text, result)
      AIA.speak result
    end

    the_prompt_text = ask_question_with_reline("\nFollow Up: ")
  end
end

#log_the_follow_up(the_prompt_text, result) ⇒ Object



193
194
195
196
# File 'lib/aia/main.rb', line 193

def log_the_follow_up(the_prompt_text, result)
  logger.info "Follow Up:\n#{the_prompt_text}"
  logger.info "Response:\n#{result}"
end

#setup_reline_history(max_history_size = 5) ⇒ Object

Function to setup the Reline history with a maximum depth



66
67
68
69
# File 'lib/aia/main.rb', line 66

def setup_reline_history(max_history_size=5)
  Reline::HISTORY.clear
  # Reline::HISTORY.max_size = max_history_size
end