Class: Binocs::Agent
- Inherits:
-
Object
- Object
- Binocs::Agent
- Defined in:
- lib/binocs/agent.rb
Constant Summary collapse
- STATUSES =
%i[pending running completed failed stopped].freeze
- TOOLS =
%i[claude_code opencode].freeze
- @@agents =
[]
- @@mutex =
Mutex.new
Instance Attribute Summary collapse
-
#branch_name ⇒ Object
Returns the value of attribute branch_name.
-
#created_at ⇒ Object
Returns the value of attribute created_at.
-
#exit_code ⇒ Object
Returns the value of attribute exit_code.
-
#id ⇒ Object
Returns the value of attribute id.
-
#output_file ⇒ Object
Returns the value of attribute output_file.
-
#pid ⇒ Object
Returns the value of attribute pid.
-
#prompt ⇒ Object
Returns the value of attribute prompt.
-
#request_context ⇒ Object
Returns the value of attribute request_context.
-
#request_id ⇒ Object
Returns the value of attribute request_id.
-
#status ⇒ Object
Returns the value of attribute status.
-
#tool ⇒ Object
Returns the value of attribute tool.
-
#worktree_path ⇒ Object
Returns the value of attribute worktree_path.
Class Method Summary collapse
- .add(agent) ⇒ Object
- .all ⇒ Object
- .clear_completed ⇒ Object
- .count ⇒ Object
- .find(id) ⇒ Object
- .for_request(request_id) ⇒ Object
- .remove(agent) ⇒ Object
- .running ⇒ Object
- .running_count ⇒ Object
Instance Method Summary collapse
- #completed? ⇒ Boolean
- #duration ⇒ Object
- #failed? ⇒ Boolean
-
#initialize(attrs = {}) ⇒ Agent
constructor
A new instance of Agent.
- #output ⇒ Object
- #output_tail(lines = 50) ⇒ Object
- #process_alive? ⇒ Boolean
- #running? ⇒ Boolean
- #short_prompt(max_length = 50) ⇒ Object
- #stop! ⇒ Object
- #stopped? ⇒ Boolean
- #tool_command ⇒ Object
Constructor Details
#initialize(attrs = {}) ⇒ Agent
Returns a new instance of Agent.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/binocs/agent.rb', line 18 def initialize(attrs = {}) @id = attrs[:id] || SecureRandom.uuid[0, 8] @status = attrs[:status] || :pending @tool = attrs[:tool] || Binocs.configuration.agent_tool @worktree_path = attrs[:worktree_path] @pid = attrs[:pid] @request_id = attrs[:request_id] @prompt = attrs[:prompt] @created_at = attrs[:created_at] || Time.now @output_file = attrs[:output_file] @branch_name = attrs[:branch_name] @request_context = attrs[:request_context] @exit_code = nil end |
Instance Attribute Details
#branch_name ⇒ Object
Returns the value of attribute branch_name.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def branch_name @branch_name end |
#created_at ⇒ Object
Returns the value of attribute created_at.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def created_at @created_at end |
#exit_code ⇒ Object
Returns the value of attribute exit_code.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def exit_code @exit_code end |
#id ⇒ Object
Returns the value of attribute id.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def id @id end |
#output_file ⇒ Object
Returns the value of attribute output_file.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def output_file @output_file end |
#pid ⇒ Object
Returns the value of attribute pid.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def pid @pid end |
#prompt ⇒ Object
Returns the value of attribute prompt.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def prompt @prompt end |
#request_context ⇒ Object
Returns the value of attribute request_context.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def request_context @request_context end |
#request_id ⇒ Object
Returns the value of attribute request_id.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def request_id @request_id end |
#status ⇒ Object
Returns the value of attribute status.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def status @status end |
#tool ⇒ Object
Returns the value of attribute tool.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def tool @tool end |
#worktree_path ⇒ Object
Returns the value of attribute worktree_path.
11 12 13 |
# File 'lib/binocs/agent.rb', line 11 def worktree_path @worktree_path end |
Class Method Details
.add(agent) ⇒ Object
125 126 127 128 |
# File 'lib/binocs/agent.rb', line 125 def add(agent) @@mutex.synchronize { @@agents << agent } agent end |
.all ⇒ Object
113 114 115 |
# File 'lib/binocs/agent.rb', line 113 def all @@mutex.synchronize { @@agents.dup } end |
.clear_completed ⇒ Object
146 147 148 149 150 |
# File 'lib/binocs/agent.rb', line 146 def clear_completed @@mutex.synchronize do @@agents.reject! { |a| a.completed? || a.failed? || a.stopped? } end end |
.count ⇒ Object
138 139 140 |
# File 'lib/binocs/agent.rb', line 138 def count @@mutex.synchronize { @@agents.length } end |
.find(id) ⇒ Object
121 122 123 |
# File 'lib/binocs/agent.rb', line 121 def find(id) @@mutex.synchronize { @@agents.find { |a| a.id == id } } end |
.for_request(request_id) ⇒ Object
134 135 136 |
# File 'lib/binocs/agent.rb', line 134 def for_request(request_id) all.select { |a| a.request_id == request_id } end |
.remove(agent) ⇒ Object
130 131 132 |
# File 'lib/binocs/agent.rb', line 130 def remove(agent) @@mutex.synchronize { @@agents.delete(agent) } end |
.running ⇒ Object
117 118 119 |
# File 'lib/binocs/agent.rb', line 117 def running all.select(&:running?) end |
.running_count ⇒ Object
142 143 144 |
# File 'lib/binocs/agent.rb', line 142 def running_count running.length end |
Instance Method Details
#completed? ⇒ Boolean
37 38 39 |
# File 'lib/binocs/agent.rb', line 37 def completed? @status == :completed end |
#duration ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/binocs/agent.rb', line 84 def duration return nil unless @created_at elapsed = Time.now - @created_at if elapsed < 60 "#{elapsed.to_i}s" elsif elapsed < 3600 "#{(elapsed / 60).to_i}m" else "#{(elapsed / 3600).to_i}h #{((elapsed % 3600) / 60).to_i}m" end end |
#failed? ⇒ Boolean
41 42 43 |
# File 'lib/binocs/agent.rb', line 41 def failed? @status == :failed end |
#output ⇒ Object
72 73 74 75 76 |
# File 'lib/binocs/agent.rb', line 72 def output return '' unless @output_file && File.exist?(@output_file) File.read(@output_file) end |
#output_tail(lines = 50) ⇒ Object
78 79 80 81 82 |
# File 'lib/binocs/agent.rb', line 78 def output_tail(lines = 50) return '' unless @output_file && File.exist?(@output_file) `tail -n #{lines} #{@output_file.shellescape}`.strip end |
#process_alive? ⇒ Boolean
49 50 51 52 53 54 55 56 |
# File 'lib/binocs/agent.rb', line 49 def process_alive? return false unless @pid Process.kill(0, @pid) true rescue Errno::ESRCH, Errno::EPERM false end |
#running? ⇒ Boolean
33 34 35 |
# File 'lib/binocs/agent.rb', line 33 def running? @status == :running && @pid && process_alive? end |
#short_prompt(max_length = 50) ⇒ Object
105 106 107 108 109 |
# File 'lib/binocs/agent.rb', line 105 def short_prompt(max_length = 50) return '' unless @prompt @prompt.length > max_length ? "#{@prompt[0, max_length - 3]}..." : @prompt end |
#stop! ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/binocs/agent.rb', line 58 def stop! return unless running? begin Process.kill('TERM', @pid) sleep 0.5 Process.kill('KILL', @pid) if process_alive? rescue Errno::ESRCH, Errno::EPERM # Process already dead end @status = :stopped end |
#stopped? ⇒ Boolean
45 46 47 |
# File 'lib/binocs/agent.rb', line 45 def stopped? @status == :stopped end |
#tool_command ⇒ Object
97 98 99 100 101 102 103 |
# File 'lib/binocs/agent.rb', line 97 def tool_command case @tool when :claude_code then 'claude' when :opencode then 'opencode' else 'claude' end end |