Class: PWN::Plugins::REPL::AISwarm::Controller
- Inherits:
-
Object
- Object
- PWN::Plugins::REPL::AISwarm::Controller
- Defined in:
- lib/pwn/plugins/repl/ai_swarm.rb
Overview
Session-scoped swarm jobs. Workers never draw the terminal.
Constant Summary collapse
- MAX_JOBS =
rubocop:disable Metrics/ClassLength -- one session-scoped swarm command surface
8- ACTIVE =
%w[queued running steering cancelling].freeze
Instance Method Summary collapse
- #busy? ⇒ Boolean
- #cancel_all ⇒ Object
- #close ⇒ Object
- #completion_context ⇒ Object
- #execute(opts = {}) ⇒ Object
-
#initialize(session_id:) ⇒ Controller
constructor
A new instance of Controller.
- #roster ⇒ Object
- #snapshot ⇒ Object
Constructor Details
#initialize(session_id:) ⇒ Controller
Returns a new instance of Controller.
39 40 41 42 43 44 45 |
# File 'lib/pwn/plugins/repl/ai_swarm.rb', line 39 def initialize(session_id:) @session_id = session_id.to_s @mutex = Mutex.new @jobs = {} @swarm_id = nil @closed = false end |
Instance Method Details
#busy? ⇒ Boolean
71 72 73 |
# File 'lib/pwn/plugins/repl/ai_swarm.rb', line 71 def busy? snapshot[:jobs].any? { |job| ACTIVE.include?(job[:state]) } end |
#cancel_all ⇒ Object
81 82 83 84 85 |
# File 'lib/pwn/plugins/repl/ai_swarm.rb', line 81 def cancel_all ids = snapshot[:jobs].select { |job| ACTIVE.include?(job[:state]) }.map { |job| job[:id] } ids.each { |id| cancel(id) } { ok: true, cancelled: ids.length } end |
#close ⇒ Object
87 88 89 90 91 92 |
# File 'lib/pwn/plugins/repl/ai_swarm.rb', line 87 def close @closed = true cancel_all workers.each { |worker| worker.join(30) } { ok: true } end |
#completion_context ⇒ Object
66 67 68 69 |
# File 'lib/pwn/plugins/repl/ai_swarm.rb', line 66 def completion_context snap = snapshot { swarm_id: snap[:swarm_id], jobs: snap[:jobs], agents: agents } end |
#execute(opts = {}) ⇒ Object
47 48 49 50 51 52 53 54 55 |
# File 'lib/pwn/plugins/repl/ai_swarm.rb', line 47 def execute(opts = {}) line = opts[:line].to_s.strip tokens = Shellwords.split(line) tokens.shift if tokens.first == '/swarm' command = tokens.shift || 'help' dispatch(command, tokens, opts) rescue StandardError => e { ok: false, error: "#{e.class}: #{e.}" } end |
#roster ⇒ Object
75 76 77 78 79 |
# File 'lib/pwn/plugins/repl/ai_swarm.rb', line 75 def roster PWN::AI::Agent::Swarm.personas(swarm_id: @swarm_id).map do |name, persona| { name: name.to_s, role: persona[:role].to_s, engine: (persona[:engine] || 'inherit').to_s, model: (persona[:model] || 'provider default').to_s } end end |
#snapshot ⇒ Object
57 58 59 60 61 62 63 64 |
# File 'lib/pwn/plugins/repl/ai_swarm.rb', line 57 def snapshot @mutex.synchronize do { swarm_id: @swarm_id, jobs: @jobs.values.map { |job| job.slice(:id, :agent, :state, :command, :result, :error, :last_tool).transform_values { |value| value.is_a?(String) ? value.dup : value } } } end end |