Module: PWN::AI::Agent::TaskSummarizer
- Defined in:
- lib/pwn/ai/agent/task_summarizer.rb
Overview
Coalesce a burst of tool calls into periodic "summary_of_current_task" UI lines without stopping the loop.
Constant Summary collapse
- DEFAULT_EVERY =
5- DEFAULT_INTERVAL_S =
8.0- MAX_BUFFER =
64
Class Method Summary collapse
-
.authors ⇒ Object
- Author(s)
0day Inc.
- .emit!(state, final: false) ⇒ Object
- .enabled? ⇒ Boolean
- .every_n ⇒ Object
- .flush!(state) ⇒ Object
-
.fresh(opts = {}) ⇒ Object
Per-run state (also safe for nested/swarm if callers keep their own hash).
-
.help ⇒ Object
Display Usage for this Module.
- .interval_s ⇒ Object
- .record!(state, name, args, result) ⇒ Object
- .verbose? ⇒ Boolean
Class Method Details
.authors ⇒ Object
- Author(s)
0day Inc. support@0dayinc.com
96 97 98 |
# File 'lib/pwn/ai/agent/task_summarizer.rb', line 96 public_class_method def self. "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n" end |
.emit!(state, final: false) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/pwn/ai/agent/task_summarizer.rb', line 74 def emit!(state, final: false) return nil if state.nil? || state[:events].empty? counts = state[:counts].sort_by { |_, c| -c }.map { |n, c| "#{n}×#{c}" } recent = state[:events].last(every_n) focus = recent.map { |e| e[:name] }.uniq.first(4).join(', ') fails = state[:events].count { |e| !e[:ok] } tail = recent.map { |e| e[:preview] }.compact.reject(&:empty?).last bit = tail && !tail.empty? ? "; e.g. #{tail}" : '' fail_bit = fails.positive? ? "; failures=#{fails}" : '' phase = final ? 'done' : 'in progress' state[:since_emit] = 0 state[:last_emit_at] = Time.now "#{phase}: #{focus} — #{state[:total]} tools (#{counts.first(6).join(', ')})#{fail_bit}#{bit}" end |
.enabled? ⇒ Boolean
15 16 17 18 19 20 |
# File 'lib/pwn/ai/agent/task_summarizer.rb', line 15 def enabled? v = PWN::Env.dig(:ai, :agent, :task_summary) v.nil? || !!v rescue StandardError true end |
.every_n ⇒ Object
28 29 30 31 32 33 34 |
# File 'lib/pwn/ai/agent/task_summarizer.rb', line 28 def every_n n = PWN::Env.dig(:ai, :agent, :task_summary_every) n = DEFAULT_EVERY if n.nil? [n.to_i, 1].max rescue StandardError DEFAULT_EVERY end |
.flush!(state) ⇒ Object
90 91 92 |
# File 'lib/pwn/ai/agent/task_summarizer.rb', line 90 def flush!(state) emit!(state, final: true) end |
.fresh(opts = {}) ⇒ Object
Per-run state (also safe for nested/swarm if callers keep their own hash)
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/pwn/ai/agent/task_summarizer.rb', line 45 def fresh(opts = {}) { request: opts[:request].to_s, events: [], since_emit: 0, last_emit_at: Time.now, total: 0, counts: Hash.new(0) } end |
.help ⇒ Object
Display Usage for this Module
102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/pwn/ai/agent/task_summarizer.rb', line 102 public_class_method def self.help puts <<~USAGE USAGE: state = PWN::AI::Agent::TaskSummarizer.fresh(request: 'do the thing') line = PWN::AI::Agent::TaskSummarizer.record!(state, 'shell', 'ls', '{success:true}') line = PWN::AI::Agent::TaskSummarizer.flush!(state) PWN::AI::Agent::TaskSummarizer.enabled? PWN::AI::Agent::TaskSummarizer.verbose? PWN::AI::Agent::TaskSummarizer.every_n PWN::AI::Agent::TaskSummarizer.interval_s #{self}.authors USAGE end |
.interval_s ⇒ Object
36 37 38 39 40 41 42 |
# File 'lib/pwn/ai/agent/task_summarizer.rb', line 36 def interval_s t = PWN::Env.dig(:ai, :agent, :task_summary_interval_s) t = DEFAULT_INTERVAL_S if t.nil? [t.to_f, 1.0].max rescue StandardError DEFAULT_INTERVAL_S end |
.record!(state, name, args, result) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/pwn/ai/agent/task_summarizer.rb', line 56 def record!(state, name, args, result) return nil unless state preview = args.is_a?(String) ? args.to_s[0, 60] : args.inspect[0, 60] rs = result.to_s ok = !rs.match?(/\A\s*\{?\s*"?(success|ok)"?\s*=>\s*false/i) && !rs.match?(/ERROR:|Traceback|NoMethodError|StandardError/i) state[:events] << { name: name.to_s, preview: preview, ok: ok, t: Time.now } state[:events].shift while state[:events].size > MAX_BUFFER state[:counts][name.to_s] += 1 state[:total] += 1 state[:since_emit] += 1 due = state[:since_emit] >= every_n || (Time.now - state[:last_emit_at]) >= interval_s due ? emit!(state) : nil end |
.verbose? ⇒ Boolean
22 23 24 25 26 |
# File 'lib/pwn/ai/agent/task_summarizer.rb', line 22 def verbose? !!PWN::Env.dig(:ai, :agent, :task_summary_verbose) rescue StandardError false end |