Class: RubyCoded::Chat::State
- Inherits:
-
Object
- Object
- RubyCoded::Chat::State
- Includes:
- MessageAssistant, MessageTokenTracking, Messages, ModelSelection, PlanTracking, Scrollable, TokenCost, ToolConfirmation
- Defined in:
- lib/ruby_coded/chat/state.rb,
lib/ruby_coded/chat/state/messages.rb,
lib/ruby_coded/chat/state/scrollable.rb,
lib/ruby_coded/chat/state/token_cost.rb,
lib/ruby_coded/chat/state/plan_tracking.rb,
lib/ruby_coded/chat/state/model_selection.rb,
lib/ruby_coded/chat/state/message_assistant.rb,
lib/ruby_coded/chat/state/tool_confirmation.rb,
lib/ruby_coded/chat/state/message_token_tracking.rb
Overview
This class is used to manage the state of the chat
Defined Under Namespace
Modules: MessageAssistant, MessageTokenTracking, Messages, ModelSelection, PlanTracking, Scrollable, TokenCost, ToolConfirmation
Constant Summary collapse
- MIN_RENDER_INTERVAL =
0.05
Constants included from TokenCost
TokenCost::CACHE_CREATION_INPUT_MULTIPLIER, TokenCost::UNPRICED_DEFAULTS
Constants included from MessageTokenTracking
MessageTokenTracking::TOKEN_KEYS
Constants included from Messages
Instance Attribute Summary collapse
-
#cursor_position ⇒ Object
readonly
Returns the value of attribute cursor_position.
-
#input_buffer ⇒ Object
readonly
Returns the value of attribute input_buffer.
-
#input_scroll_offset ⇒ Object
readonly
Returns the value of attribute input_scroll_offset.
-
#messages ⇒ Object
readonly
Returns the value of attribute messages.
-
#mode ⇒ Object
readonly
Returns the value of attribute mode.
-
#model ⇒ Object
Returns the value of attribute model.
-
#model_list ⇒ Object
readonly
Returns the value of attribute model_list.
-
#model_select_filter ⇒ Object
readonly
Returns the value of attribute model_select_filter.
-
#model_select_index ⇒ Object
readonly
Returns the value of attribute model_select_index.
-
#mutex ⇒ Object
readonly
Returns the value of attribute mutex.
-
#scroll_offset ⇒ Object
readonly
Returns the value of attribute scroll_offset.
-
#should_quit ⇒ Object
Returns the value of attribute should_quit.
-
#streaming ⇒ Object
Returns the value of attribute streaming.
Attributes included from PlanTracking
#clarification_custom_input, #clarification_index, #clarification_input_mode, #clarification_options, #clarification_question
Attributes included from ToolConfirmation
Attributes included from Messages
Instance Method Summary collapse
- #agentic_mode=(value) ⇒ Object
- #agentic_mode? ⇒ Boolean
- #append_to_input(text) ⇒ Object
- #clear_input! ⇒ Object
- #consume_input! ⇒ Object
- #delete_last_char ⇒ Object
- #dirty? ⇒ Boolean
-
#initialize(model:) ⇒ State
constructor
A new instance of State.
- #mark_clean! ⇒ Object
- #mark_dirty! ⇒ Object
- #move_cursor_left ⇒ Object
- #move_cursor_right ⇒ Object
- #move_cursor_to_end ⇒ Object
- #move_cursor_to_start ⇒ Object
- #should_quit? ⇒ Boolean
- #streaming? ⇒ Boolean
-
#update_input_scroll_offset ⇒ Object
Updates the horizontal scroll offset of the input area so the cursor is always visible.
-
#update_input_visible_width(width) ⇒ Object
Called by the renderer so the state knows how many characters fit on screen (inner width minus the prompt prefix).
Methods included from TokenCost
#init_token_cost, #session_cost_breakdown, #total_session_cost
Methods included from PlanTracking
#activate_plan_mode!, #append_to_clarification_input, #clarification_down, #clarification_up, #clear_plan!, #current_plan, #deactivate_plan_mode!, #delete_last_clarification_char, #enter_plan_clarification!, #exit_plan_clarification!, #has_unsaved_plan?, #init_plan_tracking, #mark_plan_saved!, #plan_clarification?, #plan_mode_active?, #plan_saved?, #selected_clarification_option, #toggle_clarification_input_mode!, #update_current_plan!
Methods included from ToolConfirmation
#auto_approve_tools?, #awaiting_tool_confirmation?, #clear_tool_confirmation!, #disable_auto_approve!, #enable_auto_approve!, #init_tool_confirmation, #pending_tool_args, #pending_tool_name, #request_tool_confirmation!, #resolve_tool_confirmation!, #tool_confirmation_response, #tool_confirmation_response=
Methods included from Scrollable
#scroll_down, #scroll_to_bottom, #scroll_to_top, #scroll_up, #update_scroll_metrics
Methods included from MessageTokenTracking
#token_usage_by_model, #total_input_tokens, #total_output_tokens, #total_thinking_tokens, #update_last_message_tokens
Methods included from MessageAssistant
#ensure_last_is_assistant!, #fail_last_assistant, #last_assistant_empty?, #reset_last_assistant_content, #streaming_append
Methods included from Messages
#add_message, #append_to_last_message, #build_message, #clear_messages!, #init_messages, #messages_snapshot
Methods included from ModelSelection
#append_to_model_filter, #delete_last_filter_char, #enter_model_select!, #exit_model_select!, #filtered_model_list, #model_select?, #model_select_down, #model_select_show_all?, #model_select_up, #selected_model
Constructor Details
#initialize(model:) ⇒ State
Returns a new instance of State.
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 |
# File 'lib/ruby_coded/chat/state.rb', line 32 def initialize(model:) @model = model # String.new: literals like "" are frozen under frozen_string_literal @input_buffer = String.new @cursor_position = 0 @input_scroll_offset = 0 @messages = [] @streaming = false @should_quit = false @agentic_mode = false @mutex = Mutex.new @dirty = true @last_render_at = 0.0 @scroll_offset = 0 @total_lines = 0 @visible_height = 0 @mode = :chat @model_list = [] @model_select_index = 0 @model_select_filter = String.new @model_select_show_all = false init_tool_confirmation init_plan_tracking init_token_cost init_plugin_state end |
Instance Attribute Details
#cursor_position ⇒ Object (readonly)
Returns the value of attribute cursor_position.
25 26 27 |
# File 'lib/ruby_coded/chat/state.rb', line 25 def cursor_position @cursor_position end |
#input_buffer ⇒ Object (readonly)
Returns the value of attribute input_buffer.
25 26 27 |
# File 'lib/ruby_coded/chat/state.rb', line 25 def input_buffer @input_buffer end |
#input_scroll_offset ⇒ Object (readonly)
Returns the value of attribute input_scroll_offset.
25 26 27 |
# File 'lib/ruby_coded/chat/state.rb', line 25 def input_scroll_offset @input_scroll_offset end |
#messages ⇒ Object (readonly)
Returns the value of attribute messages.
25 26 27 |
# File 'lib/ruby_coded/chat/state.rb', line 25 def @messages end |
#mode ⇒ Object (readonly)
Returns the value of attribute mode.
25 26 27 |
# File 'lib/ruby_coded/chat/state.rb', line 25 def mode @mode end |
#model ⇒ Object
Returns the value of attribute model.
28 29 30 |
# File 'lib/ruby_coded/chat/state.rb', line 28 def model @model end |
#model_list ⇒ Object (readonly)
Returns the value of attribute model_list.
25 26 27 |
# File 'lib/ruby_coded/chat/state.rb', line 25 def model_list @model_list end |
#model_select_filter ⇒ Object (readonly)
Returns the value of attribute model_select_filter.
25 26 27 |
# File 'lib/ruby_coded/chat/state.rb', line 25 def model_select_filter @model_select_filter end |
#model_select_index ⇒ Object (readonly)
Returns the value of attribute model_select_index.
25 26 27 |
# File 'lib/ruby_coded/chat/state.rb', line 25 def model_select_index @model_select_index end |
#mutex ⇒ Object (readonly)
Returns the value of attribute mutex.
25 26 27 |
# File 'lib/ruby_coded/chat/state.rb', line 25 def mutex @mutex end |
#scroll_offset ⇒ Object (readonly)
Returns the value of attribute scroll_offset.
25 26 27 |
# File 'lib/ruby_coded/chat/state.rb', line 25 def scroll_offset @scroll_offset end |
#should_quit ⇒ Object
Returns the value of attribute should_quit.
28 29 30 |
# File 'lib/ruby_coded/chat/state.rb', line 28 def should_quit @should_quit end |
#streaming ⇒ Object
Returns the value of attribute streaming.
25 26 27 |
# File 'lib/ruby_coded/chat/state.rb', line 25 def streaming @streaming end |
Instance Method Details
#agentic_mode=(value) ⇒ Object
73 74 75 76 |
# File 'lib/ruby_coded/chat/state.rb', line 73 def agentic_mode=(value) @agentic_mode = value mark_dirty! end |
#agentic_mode? ⇒ Boolean
69 70 71 |
# File 'lib/ruby_coded/chat/state.rb', line 69 def agentic_mode? @agentic_mode end |
#append_to_input(text) ⇒ Object
124 125 126 127 128 129 130 |
# File 'lib/ruby_coded/chat/state.rb', line 124 def append_to_input(text) @input_buffer.insert(@cursor_position, text) @cursor_position += text.length update_input_scroll_offset mark_dirty! reset_command_completion_index if respond_to?(:reset_command_completion_index, true) end |
#clear_input! ⇒ Object
174 175 176 177 178 179 |
# File 'lib/ruby_coded/chat/state.rb', line 174 def clear_input! @input_buffer.clear @cursor_position = 0 @input_scroll_offset = 0 mark_dirty! end |
#consume_input! ⇒ Object
181 182 183 184 185 186 187 |
# File 'lib/ruby_coded/chat/state.rb', line 181 def consume_input! input = @input_buffer.dup @input_buffer.clear @cursor_position = 0 @input_scroll_offset = 0 input end |
#delete_last_char ⇒ Object
132 133 134 135 136 137 138 139 140 |
# File 'lib/ruby_coded/chat/state.rb', line 132 def delete_last_char return if @cursor_position <= 0 @input_buffer.slice!(@cursor_position - 1) @cursor_position -= 1 update_input_scroll_offset mark_dirty! reset_command_completion_index if respond_to?(:reset_command_completion_index, true) end |
#dirty? ⇒ Boolean
82 83 84 85 86 87 88 89 90 |
# File 'lib/ruby_coded/chat/state.rb', line 82 def dirty? @mutex.synchronize do return false unless @dirty return true unless @streaming now = Process.clock_gettime(Process::CLOCK_MONOTONIC) (now - @last_render_at) >= MIN_RENDER_INTERVAL end end |
#mark_clean! ⇒ Object
92 93 94 95 96 97 |
# File 'lib/ruby_coded/chat/state.rb', line 92 def mark_clean! @mutex.synchronize do @dirty = false @last_render_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) end end |
#mark_dirty! ⇒ Object
99 100 101 |
# File 'lib/ruby_coded/chat/state.rb', line 99 def mark_dirty! @mutex.synchronize { @dirty = true } end |
#move_cursor_left ⇒ Object
142 143 144 145 146 147 148 |
# File 'lib/ruby_coded/chat/state.rb', line 142 def move_cursor_left return if @cursor_position <= 0 @cursor_position -= 1 update_input_scroll_offset mark_dirty! end |
#move_cursor_right ⇒ Object
150 151 152 153 154 155 156 |
# File 'lib/ruby_coded/chat/state.rb', line 150 def move_cursor_right return if @cursor_position >= @input_buffer.length @cursor_position += 1 update_input_scroll_offset mark_dirty! end |
#move_cursor_to_end ⇒ Object
166 167 168 169 170 171 172 |
# File 'lib/ruby_coded/chat/state.rb', line 166 def move_cursor_to_end return if @cursor_position == @input_buffer.length @cursor_position = @input_buffer.length update_input_scroll_offset mark_dirty! end |
#move_cursor_to_start ⇒ Object
158 159 160 161 162 163 164 |
# File 'lib/ruby_coded/chat/state.rb', line 158 def move_cursor_to_start return if @cursor_position == 0 @cursor_position = 0 update_input_scroll_offset mark_dirty! end |
#should_quit? ⇒ Boolean
78 79 80 |
# File 'lib/ruby_coded/chat/state.rb', line 78 def should_quit? @should_quit end |
#streaming? ⇒ Boolean
65 66 67 |
# File 'lib/ruby_coded/chat/state.rb', line 65 def streaming? @streaming end |
#update_input_scroll_offset ⇒ Object
Updates the horizontal scroll offset of the input area so the cursor is always visible. Call this after every cursor / buffer change. visible_width is set by the renderer each frame via update_input_visible_width.
107 108 109 110 111 112 113 114 115 116 |
# File 'lib/ruby_coded/chat/state.rb', line 107 def update_input_scroll_offset visible = @input_visible_width || 0 return if visible <= 0 if @cursor_position < @input_scroll_offset @input_scroll_offset = @cursor_position elsif @cursor_position >= @input_scroll_offset + visible @input_scroll_offset = @cursor_position - visible + 1 end end |
#update_input_visible_width(width) ⇒ Object
Called by the renderer so the state knows how many characters fit on screen (inner width minus the prompt prefix).
120 121 122 |
# File 'lib/ruby_coded/chat/state.rb', line 120 def update_input_visible_width(width) @input_visible_width = width end |