Class: RubyRich::AgentShell
Constant Summary
Constants inherited
from AppShell
RubyRich::AppShell::DEFAULT_COMMANDS
Instance Attribute Summary collapse
Attributes inherited from AppShell
#composer, #focus_manager, #layout, #live, #progress_manager, #sidebar, #theme, #token_usage, #transcript, #viewport
Instance Method Summary
collapse
-
#add_assistant_message(text, streaming: false) ⇒ Object
-
#add_diff(title: nil, content:, language: "diff") ⇒ Object
-
#add_error_message(text) ⇒ Object
-
#add_markdown(content, streaming: false) ⇒ Object
-
#add_system_message(text) ⇒ Object
-
#add_user_message(text) ⇒ Object
-
#append_to_message(id, delta) ⇒ Object
-
#finish_tool_call(id, status: :done, output: nil) ⇒ Object
-
#initialize(**options) ⇒ AgentShell
constructor
A new instance of AgentShell.
-
#on_command(&block) ⇒ Object
-
#on_interrupt(&block) ⇒ Object
-
#on_mode_toggle(&block) ⇒ Object
-
#on_submit(&block) ⇒ Object
-
#remove_entry(id) ⇒ Object
-
#replace_message(id, text) ⇒ Object
-
#show_token_usage(input: nil, output: nil, total: nil, **extra) ⇒ Object
-
#start(refresh_rate: 24, mouse: true, alt_screen: false) ⇒ Object
-
#start_tool_call(name:, input: nil, status: :running) ⇒ Object
-
#stop ⇒ Object
-
#stopped? ⇒ Boolean
-
#update_status(text) ⇒ Object
-
#update_tasks(tasks) ⇒ Object
-
#update_tool_call(id, status: nil, output: nil, input: nil) ⇒ Object
Methods inherited from AppShell
#add_assistant, #add_separator, #add_thinking, #add_tool, #add_user, #confirm, #form, #open_pager, #set_tasks, #start_progress, #status=, #update_plan, #with_progress
Constructor Details
#initialize(**options) ⇒ AgentShell
Returns a new instance of AgentShell.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# File 'lib/ruby_rich/agent_shell.rb', line 9
def initialize(**options)
@callbacks = {}
@state_mutex = Mutex.new
@id_mutex = Mutex.new
@pending_actions = Queue.new
@entry_sequence = 0
@state = :initialized
@ui_thread = nil
@mode = :chat
super
@stop_on_ctrl_c = false
@composer.instance_variable_set(:@on_interrupt, method(:handle_interrupt))
@composer.instance_variable_set(:@on_eof, method(:handle_eof))
attach_agent_controls
end
|
Instance Attribute Details
#mode ⇒ Object
Returns the value of attribute mode.
7
8
9
|
# File 'lib/ruby_rich/agent_shell.rb', line 7
def mode
@mode
end
|
Instance Method Details
#add_assistant_message(text, streaming: false) ⇒ Object
85
86
87
|
# File 'lib/ruby_rich/agent_shell.rb', line 85
def add_assistant_message(text, streaming: false)
add_message(:assistant, text, streaming: streaming)
end
|
#add_diff(title: nil, content:, language: "diff") ⇒ Object
101
102
103
104
|
# File 'lib/ruby_rich/agent_shell.rb', line 101
def add_diff(title: nil, content:, language: "diff")
text = title ? "#{title}\n#{content}" : content
add_message(:diff, text, language: language)
end
|
#add_error_message(text) ⇒ Object
97
98
99
|
# File 'lib/ruby_rich/agent_shell.rb', line 97
def add_error_message(text)
add_message(:error, text)
end
|
#add_markdown(content, streaming: false) ⇒ Object
89
90
91
|
# File 'lib/ruby_rich/agent_shell.rb', line 89
def add_markdown(content, streaming: false)
add_message(:markdown, content, streaming: streaming)
end
|
#add_system_message(text) ⇒ Object
93
94
95
|
# File 'lib/ruby_rich/agent_shell.rb', line 93
def add_system_message(text)
add_message(:system, text)
end
|
#add_user_message(text) ⇒ Object
81
82
83
|
# File 'lib/ruby_rich/agent_shell.rb', line 81
def add_user_message(text)
add_message(:user, text)
end
|
#append_to_message(id, delta) ⇒ Object
106
107
108
|
# File 'lib/ruby_rich/agent_shell.rb', line 106
def append_to_message(id, delta)
dispatch { @transcript.append_block(id, delta).tap { @viewport.scroll_to_bottom } }
end
|
143
144
145
|
# File 'lib/ruby_rich/agent_shell.rb', line 143
def finish_tool_call(id, status: :done, output: nil)
update_tool_call(id, status: status, output: output)
end
|
#on_command(&block) ⇒ Object
40
41
42
43
|
# File 'lib/ruby_rich/agent_shell.rb', line 40
def on_command(&block)
@callbacks[:command] = block
self
end
|
#on_interrupt(&block) ⇒ Object
30
31
32
33
|
# File 'lib/ruby_rich/agent_shell.rb', line 30
def on_interrupt(&block)
@callbacks[:interrupt] = block
self
end
|
#on_mode_toggle(&block) ⇒ Object
35
36
37
38
|
# File 'lib/ruby_rich/agent_shell.rb', line 35
def on_mode_toggle(&block)
@callbacks[:mode_toggle] = block
self
end
|
#on_submit(&block) ⇒ Object
25
26
27
28
|
# File 'lib/ruby_rich/agent_shell.rb', line 25
def on_submit(&block)
@callbacks[:submit] = block
self
end
|
#remove_entry(id) ⇒ Object
114
115
116
|
# File 'lib/ruby_rich/agent_shell.rb', line 114
def remove_entry(id)
dispatch { @transcript.remove_block(id).tap { @viewport.scroll_to_bottom } }
end
|
#replace_message(id, text) ⇒ Object
110
111
112
|
# File 'lib/ruby_rich/agent_shell.rb', line 110
def replace_message(id, text)
dispatch { @transcript.replace_block(id, text).tap { @viewport.scroll_to_bottom } }
end
|
#show_token_usage(input: nil, output: nil, total: nil, **extra) ⇒ Object
155
156
157
|
# File 'lib/ruby_rich/agent_shell.rb', line 155
def show_token_usage(input: nil, output: nil, total: nil, **)
dispatch { @token_usage = { input: input, output: output, total: total }.merge().compact }
end
|
#start(refresh_rate: 24, mouse: true, alt_screen: false) ⇒ Object
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
# File 'lib/ruby_rich/agent_shell.rb', line 45
def start(refresh_rate: 24, mouse: true, alt_screen: false)
@state_mutex.synchronize { @state = :starting }
Live.start(@layout, refresh_rate: refresh_rate, mouse: mouse, alt_screen: alt_screen, autowrap: false) do |live|
@state_mutex.synchronize do
@live = live
@ui_thread = Thread.current
@state = :running
end
drain_pending_actions(live)
live.listening = true
end
ensure
@state_mutex.synchronize do
@live = nil
@ui_thread = nil
@state = :stopped
end
end
|
118
119
120
121
122
123
124
125
126
127
128
|
# File 'lib/ruby_rich/agent_shell.rb', line 118
def start_tool_call(name:, input: nil, status: :running)
id = reserve_id(:tool)
return nil unless id
ok = dispatch do
@transcript.add_tool(name, status: status, result: tool_body(input: input), collapsed: false, id: id)
@viewport.scroll_to_bottom
id
end
ok ? id : nil
end
|
#stop ⇒ Object
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
# File 'lib/ruby_rich/agent_shell.rb', line 64
def stop
dispatch_after_start_failure = false
@state_mutex.synchronize do
return false if @state == :stopped
if @live
return @live.stop if Thread.current == @ui_thread
return @live.post { |live| live.stop } || false
end
@state = :stopped
dispatch_after_start_failure = true
end
dispatch_after_start_failure
end
|
#stopped? ⇒ Boolean
159
160
161
|
# File 'lib/ruby_rich/agent_shell.rb', line 159
def stopped?
@state_mutex.synchronize { @state == :stopped }
end
|
#update_status(text) ⇒ Object
151
152
153
|
# File 'lib/ruby_rich/agent_shell.rb', line 151
def update_status(text)
dispatch { @status = text.to_s }
end
|
#update_tasks(tasks) ⇒ Object
147
148
149
|
# File 'lib/ruby_rich/agent_shell.rb', line 147
def update_tasks(tasks)
dispatch { @sidebar.set_tasks(tasks) }
end
|
130
131
132
133
134
135
136
137
138
139
140
141
|
# File 'lib/ruby_rich/agent_shell.rb', line 130
def update_tool_call(id, status: nil, output: nil, input: nil)
options = {}
options[:status] = status if status
text = output.nil? && input.nil? ? nil : tool_body(input: input, output: output)
dispatch do
block = @transcript.find_block(id)
next false unless block
text ||= block[:text]
@transcript.replace_block(id, text, **options).tap { @viewport.scroll_to_bottom }
end
end
|