Module: RubyTodo::OpenAIResponseHandling

Included in:
OpenAIApiInteraction
Defined in:
lib/ruby_todo/ai_assistant/openai_integration.rb

Overview

Module for handling OpenAI API responses

Instance Method Summary collapse

Instance Method Details

#extract_command_explanation(content) ⇒ Object



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/ruby_todo/ai_assistant/openai_integration.rb', line 249

def extract_command_explanation(content)
  # Extract commands
  commands = []

  # Return a default response for empty content
  if content.nil? || content.empty?
    return {
      "commands" => ["task:list \"test_notebook\""],
      "explanation" => "Here are your tasks."
    }
  end

  # First, try to extract code blocks (with or without language specifier)
  code_blocks = content.scan(/```(?:bash|ruby)?\n(.*?)```/m)
  if code_blocks.any?
    code_blocks.each do |block|
      block_content = block[0].strip
      if block_content.include?("\n")
        # This is a multiline block - each line is a separate command
        block_content.split("\n").each do |line|
          line = line.strip
          # Skip empty lines or lines with just language identifiers
          next if line.empty? || line =~ /^(bash|ruby)$/i

          commands << line
        end
      else
        # Single line block
        commands << block_content unless block_content.empty?
      end
    end
  else
    # Try to find commands in inline code blocks
    command_matches = content.scan(/`([^`]+)`/)
    command_matches.each do |match|
      command = match[0].strip
      commands << command unless command.empty?
    end
  end

  # If no commands found in code blocks, try to extract lines that look like commands
  if commands.empty?
    content.each_line do |line|
      line = line.strip
      if line =~ /^task:|^notebook:|^stats/
        commands << line
      end
    end
  end

  # Add a fallback command if none found
  if commands.empty?
    commands << "task:list \"test_notebook\""
  end

  # Extract explanation
  explanation = content.gsub(/```(?:bash|ruby)?\n.*?```|`([^`]+)`/m, "").strip

  # Use a default explanation if none found
  if explanation.empty?
    explanation = "Here are your tasks."
  end

  {
    "commands" => commands,
    "explanation" => explanation
  }
end

#handle_openai_error(error) ⇒ Object



220
221
222
223
224
225
226
# File 'lib/ruby_todo/ai_assistant/openai_integration.rb', line 220

def handle_openai_error(error)
  # Create a default error response
  {
    "explanation" => "Error: #{error.message}",
    "commands" => []
  }
end

#handle_openai_response(response) ⇒ Object



212
213
214
215
216
217
218
# File 'lib/ruby_todo/ai_assistant/openai_integration.rb', line 212

def handle_openai_response(response)
  # Extract the response content
  response_content = response.dig("choices", 0, "message", "content")

  # Parse the JSON response
  parse_openai_response_content(response_content)
end

#parse_openai_response_content(content) ⇒ Object



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/ruby_todo/ai_assistant/openai_integration.rb', line 228

def parse_openai_response_content(content)
  # Extract JSON from the content (it might be wrapped in ```json blocks)
  json_match = content.match(/```json\n(.+?)\n```/m) || content.match(/\{.+\}/m)

  if json_match
    # Parse the JSON
    begin
      json_content = json_match[0].gsub(/```json\n|```/, "")
      JSON.parse(json_content)
    rescue JSON::ParserError
      # Try a more direct approach
      extract_command_explanation(content)
    end
  else
    # Fallback to direct extraction
    extract_command_explanation(content)
  end
rescue JSON::ParserError
  nil
end