Class: Genie::Session

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/genie/session.rb

Constant Summary collapse

QUIT_COMMANDS =

Supported commands to exit the session

["q", "quit", "done", "exit", "bye"].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config:) ⇒ Session

Initializes the session with a pre-loaded configuration config: instance of Genie::SessionConfig



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/genie/session.rb', line 15

def initialize(config:)
  @config = config

  Genie.output genie_lamp, color: :yellow, include_genie_icon: false

  Genie.output "Your wish is my command!", color: :magenta
  Genie.output "   base_path: #{base_path}", color: :cyan, include_genie_icon: false
  Genie.output "   model: #{model}", color: :cyan, include_genie_icon: false
  Genie.output "   run_tests_cmd: #{run_tests_cmd}", color: :cyan, include_genie_icon: false
  Genie.output "   ignore_paths: #{ignore_paths}", color: :cyan, include_genie_icon: false

  # Initialize the LLM chat with the specified model
  @chat = RubyLLM.chat(model: model)

  # Use Genie-specific instructions from config
  @chat.with_instructions instructions

  # Provide file tools for the assistant, scoped to base_path
  @chat.with_tools(
    Genie::AppendToFile.new(base_path: base_path),
    Genie::AskForHelp.new,
    # Genie::InsertIntoFile.new(base_path: base_path),
    Genie::ListFiles.new(base_path: base_path, ignore_paths: ignore_paths),
    Genie::ReadFile.new(base_path: base_path),
    Genie::RenameFile.new(base_path: base_path),
    # Genie::ReplaceLinesInFile.new(base_path: base_path),
    Genie::RunTests.new(base_path: base_path, cmd: run_tests_cmd),
    Genie::TakeANote.new,
    Genie::WriteFile.new(base_path: base_path),
  )
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



5
6
7
# File 'lib/genie/session.rb', line 5

def config
  @config
end

Instance Method Details

#ask(question) ⇒ Object

Send a question to the LLM and output both prompt and response



64
65
66
67
68
69
70
71
72
# File 'lib/genie/session.rb', line 64

def ask(question)
  Genie.output "#{question}\n", color: :white

  response = @chat.ask(question)

  Genie.output "\n#{response.content}", color: :white

  response
end

#begin(q) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/genie/session.rb', line 47

def begin(q)
  q = q.to_s

  loop do
    complete if QUIT_COMMANDS.include? q.downcase

    begin
      ask q unless q.strip == ""
    rescue RubyLLM::RateLimitError => e
      Genie.output "Rate limit exceeded: #{e.message}", color: :red
    end

    q = prompt
  end
end

#completeObject



79
80
81
82
83
84
85
86
# File 'lib/genie/session.rb', line 79

def complete
  Genie.output "\nExiting...", color: :white

  total_conversation_tokens = @chat.messages.sum { |msg| (msg.input_tokens || 0) + (msg.output_tokens || 0) }
  Genie.output "Total Conversation Tokens: #{total_conversation_tokens}", color: :white

  exit
end

#promptObject



74
75
76
77
# File 'lib/genie/session.rb', line 74

def prompt
  print "\n > "
  STDIN.gets.chomp
end