Class: OllamaAgent::TUI
- Inherits:
-
Object
- Object
- OllamaAgent::TUI
- Defined in:
- lib/ollama_agent/tui.rb
Overview
Linear scrolling TUI for interactive agent sessions (TTY toolkit). Avoids fixed multi-pane layouts; pairs with CLI::TuiRepl. rubocop:disable Metrics/ClassLength – façade over multiple tty-* components
Constant Summary collapse
- HISTORY_FILE =
File.join(Dir.home, ".config", "ollama_agent", "repl_history")
- MAX_HISTORY =
500
Instance Attribute Summary collapse
-
#prompt ⇒ Object
readonly
Returns the value of attribute prompt.
Instance Method Summary collapse
- #ask_interactive(question, options, god_mode: nil) ⇒ Object
- #ask_user_input ⇒ Object
-
#ask_user_line(completion_candidates: [], command_palette: nil, prompt_prefix: nil) ⇒ String?
Line editor with Tab completion for lines starting with
/(uses TuiSlashReader). - #goodbye ⇒ Object
-
#initialize(stdout: $stdout, stderr: $stderr, logger: nil, god_mode: false) ⇒ TUI
constructor
A new instance of TUI.
- #log(level, message) ⇒ Object
- #print_error(message) ⇒ Object
- #render_assistant_message(message) ⇒ Object
- #render_dashboard(**options) ⇒ Object
-
#render_providers_dashboard(pool_status:, routing_decisions: [], aggregate_usage: nil) ⇒ Object
Render the three-panel providers dashboard: status, usage, routing decisions.
Constructor Details
#initialize(stdout: $stdout, stderr: $stderr, logger: nil, god_mode: false) ⇒ TUI
Returns a new instance of TUI.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/ollama_agent/tui.rb', line 25 def initialize(stdout: $stdout, stderr: $stderr, logger: nil, god_mode: false) @stdout = stdout @stderr = stderr @god_mode = god_mode @prompt = TTY::Prompt.new(output: stdout, input: $stdin) @pastel = Pastel.new @logger = logger || TTY::Logger.new(output: stdout) @slash_reader = TuiSlashReader.new( completion_candidates: [], input: $stdin, output: @stdout, interrupt: :error ) load_history end |
Instance Attribute Details
#prompt ⇒ Object (readonly)
Returns the value of attribute prompt.
23 24 25 |
# File 'lib/ollama_agent/tui.rb', line 23 def prompt @prompt end |
Instance Method Details
#ask_interactive(question, options, god_mode: nil) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/ollama_agent/tui.rb', line 75 def ask_interactive(question, , god_mode: nil) return auto_pick_first() if god_mode.nil? ? @god_mode : god_mode @stdout.puts "" @prompt.select( @pastel.yellow.bold("Action required: ") + question.to_s, , cycle: true, filter: true, per_page: 10 ) end |
#ask_user_input ⇒ Object
88 89 90 91 92 |
# File 'lib/ollama_agent/tui.rb', line 88 def ask_user_input @prompt.ask(@pastel.green.bold("❯")) { |q| q.required true } rescue TTY::Reader::InputInterrupt nil end |
#ask_user_line(completion_candidates: [], command_palette: nil, prompt_prefix: nil) ⇒ String?
Line editor with Tab completion for lines starting with / (uses OllamaAgent::TuiSlashReader).
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/ollama_agent/tui.rb', line 98 def ask_user_line(completion_candidates: [], command_palette: nil, prompt_prefix: nil) prefix = prompt_prefix.to_s prompt = "#{prefix}#{@pastel.green.bold("❯ ")}" @slash_reader.completion_candidates = Array(completion_candidates).uniq.sort @slash_reader.command_palette = command_palette line = @slash_reader.read_line(prompt).to_s save_history line rescue TTY::Reader::InputInterrupt nil end |
#goodbye ⇒ Object
124 125 126 |
# File 'lib/ollama_agent/tui.rb', line 124 def goodbye @stdout.puts "\n#{@pastel.dim("Goodbye.")}" end |
#log(level, message) ⇒ Object
110 111 112 113 114 115 116 117 118 |
# File 'lib/ollama_agent/tui.rb', line 110 def log(level, ) case level when :info then @logger.info() when :warn then @logger.warn() when :error then @logger.error() else @logger.debug() end end |
#print_error(message) ⇒ Object
120 121 122 |
# File 'lib/ollama_agent/tui.rb', line 120 def print_error() @stderr.puts @pastel.red(.to_s) end |
#render_assistant_message(message) ⇒ Object
67 68 69 70 71 72 73 |
# File 'lib/ollama_agent/tui.rb', line 67 def () thinking = .respond_to?(:thinking) ? .thinking : nil content = .respond_to?(:content) ? .content : .to_s print_thinking_block(thinking) if thinking_present?(thinking) print_content_block(content) if content_present?(content) @stdout.puts @pastel.dim("-" * [TTY::Screen.width, 40].min) end |
#render_dashboard(**options) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/ollama_agent/tui.rb', line 41 def render_dashboard(**) config = .fetch(:config) skills = .fetch(:skills) scripts = .fetch(:scripts) { [] } status = .fetch(:status, "IDLE") budget = [:budget] memory_line = [:memory_line] table = build_context_table(config, skills, scripts, status, budget, memory_line) rendered_table = table.render(:unicode, padding: [0, 1]) frame = box_frame(" Ollama Agent ", rendered_table) @stdout.puts "\n#{frame}\n" end |
#render_providers_dashboard(pool_status:, routing_decisions: [], aggregate_usage: nil) ⇒ Object
Render the three-panel providers dashboard: status, usage, routing decisions.
59 60 61 62 63 64 65 |
# File 'lib/ollama_agent/tui.rb', line 59 def render_providers_dashboard(pool_status:, routing_decisions: [], aggregate_usage: nil) @stdout.puts "\n" @stdout.puts render_credential_status_box(pool_status) @stdout.puts render_usage_box(aggregate_usage || {}) if aggregate_usage @stdout.puts render_routing_decisions_box(routing_decisions) unless routing_decisions.empty? @stdout.puts "" end |