pwn 0.5.686 → 0.5.688

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.ruby-version +1 -1
  4. data/Gemfile +3 -3
  5. data/README.md +3 -4
  6. data/documentation/Agent-Tool-Registry.md +2 -2
  7. data/documentation/Configuration.md +5 -4
  8. data/documentation/General-PWN-Usage.md +1 -1
  9. data/documentation/Home.md +1 -1
  10. data/documentation/How-PWN-Works.md +1 -1
  11. data/documentation/Mistakes.md +1 -1
  12. data/documentation/Reinforcement-Learning.md +4 -6
  13. data/documentation/Troubleshooting.md +1 -1
  14. data/documentation/pwn-REPL.md +1 -1
  15. data/documentation/pwn-ai-Agent.md +2 -3
  16. data/lib/pwn/ai/agent/curriculum.rb +2 -2
  17. data/lib/pwn/ai/agent/dispatch.rb +1 -1
  18. data/lib/pwn/ai/agent/learning.rb +150 -32
  19. data/lib/pwn/ai/agent/loop.rb +291 -129
  20. data/lib/pwn/ai/agent/prompt_builder.rb +47 -29
  21. data/lib/pwn/ai/agent/registry.rb +2 -1
  22. data/lib/pwn/ai/agent/reward.rb +9 -0
  23. data/lib/pwn/ai/agent/swarm.rb +3 -1
  24. data/lib/pwn/ai/agent/task_summarizer.rb +23 -6
  25. data/lib/pwn/ai/agent/tool_guard.rb +109 -0
  26. data/lib/pwn/ai/agent/tools/ruby_eval.rb +44 -20
  27. data/lib/pwn/ai/agent/tools/shell.rb +17 -4
  28. data/lib/pwn/ai/agent/tools/skills.rb +63 -2
  29. data/lib/pwn/ai/anthropic.rb +25 -5
  30. data/lib/pwn/ai/gemini.rb +25 -5
  31. data/lib/pwn/ai/grok.rb +30 -13
  32. data/lib/pwn/ai/http_retry.rb +78 -0
  33. data/lib/pwn/ai/ollama.rb +25 -5
  34. data/lib/pwn/ai/open_ai.rb +26 -13
  35. data/lib/pwn/ai/open_web_ui.rb +25 -5
  36. data/lib/pwn/ai.rb +1 -0
  37. data/lib/pwn/config.rb +1 -1
  38. data/lib/pwn/plugins/log.rb +183 -41
  39. data/lib/pwn/plugins/repl.rb +50 -15
  40. data/lib/pwn/plugins/transparent_browser.rb +16 -2
  41. data/lib/pwn/sessions.rb +50 -1
  42. data/lib/pwn/version.rb +1 -1
  43. data/spec/integration/reinforced_feedback_loop_spec.rb +9 -11
  44. data/spec/lib/pwn/ai/agent/loop_spec.rb +180 -20
  45. data/spec/lib/pwn/ai/agent/prompt_builder_spec.rb +3 -0
  46. data/spec/lib/pwn/ai/agent/registry_spec.rb +1 -1
  47. data/spec/lib/pwn/ai/agent/reward_spec.rb +13 -0
  48. data/spec/lib/pwn/ai/agent/swarm_spec.rb +6 -0
  49. data/spec/lib/pwn/ai/agent/task_summarizer_spec.rb +36 -0
  50. data/spec/lib/pwn/ai/agent/tool_guard_spec.rb +46 -0
  51. data/spec/lib/pwn/ai/agent/tools/ruby_eval_spec.rb +24 -0
  52. data/spec/lib/pwn/ai/agent/tools/shell_spec.rb +10 -0
  53. data/spec/lib/pwn/ai/agent/tools/skills_spec.rb +29 -0
  54. data/spec/lib/pwn/ai/grok_spec.rb +22 -0
  55. data/spec/lib/pwn/ai/http_retry_spec.rb +55 -0
  56. data/spec/lib/pwn/plugins/log_spec.rb +170 -19
  57. data/spec/lib/pwn/plugins/repl_pwn_vault_spec.rb +14 -4
  58. data/spec/lib/pwn/plugins/transparent_browser_spec.rb +8 -0
  59. data/spec/lib/pwn/sessions_spec.rb +24 -0
  60. data/third_party/pwn_rdoc.jsonl +41 -5
  61. data/tmp_pwn_critic_skills_flaw.txt +9 -0
  62. metadata +11 -8
@@ -25,12 +25,15 @@ describe PWN::Plugins::Log do
25
25
  expect(PWN::Plugins::Log).to respond_to(:progress)
26
26
  expect(PWN::Plugins::Log).to respond_to(:debug_enabled?)
27
27
  expect(PWN::Plugins::Log).to respond_to(:debug_log_path)
28
+ expect(PWN::Plugins::Log).to respond_to(:next_request_log!)
29
+ expect(PWN::Plugins::Log).to respond_to(:finish_request_log!)
28
30
 
29
31
  tee = StringIO.new
30
- path = PWN::Plugins::Log.start_debug(tee: tee, path: nil)
31
- expect(path).to match(%r{\A/tmp/pwn-ai-DEBUG-.+\.log\z})
32
- expect(File.file?(path)).to eq(true)
32
+ PWN::Plugins::Log.start_debug(tee: tee, path: nil)
33
33
  expect(PWN::Plugins::Log.debug_enabled?).to eq(true)
34
+ path = PWN::Plugins::Log.next_request_log!(session_id: "sess#{Process.pid}")
35
+ expect(path).to eq("/tmp/pwn-ai-DEBUG-sess#{Process.pid}-R1.log")
36
+ expect(File.file?(path)).to eq(true)
34
37
  expect(PWN::Plugins::Log.debug_log_path).to eq(path)
35
38
 
36
39
  ok = PWN::Plugins::Log.progress(msg: 'Loop.run start request=hi', which_self: PWN::AI::Agent::Loop)
@@ -61,21 +64,166 @@ describe PWN::Plugins::Log do
61
64
  expect(tee.string).to include('after-loud')
62
65
  end
63
66
 
64
- it 'rolls the debug log to .N+1 when the file exceeds 1MB' do
65
- stem = "/tmp/pwn-ai-DEBUG-#{Process.pid}-roll"
66
- first = "#{stem}.1.log"
67
- File.write(first, 'x' * (1_024_000 + 10))
68
- path = PWN::Plugins::Log.start_debug(tee: StringIO.new, path: first)
69
- expect(path).to eq(first)
70
- PWN::Plugins::Log.progress(msg: 'overflow-line', which_self: PWN::AI::Agent::Loop)
71
- second = "#{stem}.2.log"
72
- expect(PWN::Plugins::Log.debug_log_path).to eq(second)
73
- expect(File.file?(second)).to eq(true)
74
- expect(File.read(second)).to include('overflow-line')
67
+ it 'tees debug lines with raw ANSI, not PS1 SOH/STX markers' do
68
+ tee = StringIO.new
69
+ PWN::Plugins::Log.start_debug(
70
+ tee: tee,
71
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-ansi.log"
72
+ )
73
+ PWN::Plugins::Log.progress(msg: 'stage-line', which_self: PWN::AI::Agent::Loop)
74
+ shown = tee.string
75
+ expect(shown).to include('stage-line')
76
+ expect(shown).to include("\e[35m")
77
+ expect(shown).not_to include("\001")
78
+ expect(shown).not_to include("\002")
79
+ end
80
+
81
+ it 'writes a multiline final body when keep_newlines is set' do
82
+ path = PWN::Plugins::Log.start_debug(
83
+ tee: StringIO.new,
84
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-finalbody.log"
85
+ )
86
+ PWN::Plugins::Log.progress(
87
+ msg: "final text:\nline-one\nline-two",
88
+ which_self: PWN::AI::Agent::Loop,
89
+ keep_newlines: true,
90
+ cap: 65_536
91
+ )
92
+ body = File.read(path)
93
+ expect(body).to include("final text:\nline-one\nline-two")
94
+ end
95
+
96
+ it 'writes a full tool request/result with no char cap when cap is 0' do
97
+ path = PWN::Plugins::Log.start_debug(
98
+ tee: StringIO.new,
99
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-toolio.log"
100
+ )
101
+ blob = 'x' * 8_000
102
+ PWN::Plugins::Log.progress(
103
+ msg: "tool pwn_eval request:\n#{blob}\nresult:\n#{blob}",
104
+ which_self: PWN::AI::Agent::Loop,
105
+ keep_newlines: true,
106
+ cap: 0,
107
+ tee: nil
108
+ )
109
+ body = File.read(path)
110
+ expect(body).to include('tool pwn_eval request:')
111
+ expect(body).to include(blob)
112
+ expect(body).to include("result:\n#{blob}")
113
+ end
114
+
115
+ it 'timestamps an Interrupt line into the open request log' do
116
+ expect(PWN::Plugins::Log).to respond_to(:note_interrupt!)
117
+ path = PWN::Plugins::Log.start_debug(
118
+ tee: StringIO.new,
119
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-int.log"
120
+ )
121
+ ok = PWN::Plugins::Log.note_interrupt!(where: 'CTRL+C')
122
+ expect(ok).to eq true
123
+ body = File.read(path)
124
+ expect(body).to match(/\[DEBUG \d{4}-\d{2}-\d{2} /)
125
+ expect(body).to include('Interrupt')
126
+ expect(body).to include('CTRL+C')
127
+ end
128
+
129
+ it 'still timestamps Interrupt when progress reentrancy is stuck mid-write' do
130
+ path = PWN::Plugins::Log.start_debug(
131
+ tee: StringIO.new,
132
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-int-stuck.log"
133
+ )
134
+ Thread.current[:pwn_log_progress] = true
135
+ ok = PWN::Plugins::Log.note_interrupt!(where: 'CTRL+C')
136
+ expect(ok).to eq true
137
+ body = File.read(path)
138
+ expect(body).to include('Interrupt')
139
+ expect(body).to include('CTRL+C')
140
+ expect(body).to match(/at=|→ pwn-ai → Interrupt/)
141
+ ensure
142
+ Thread.current[:pwn_log_progress] = false
143
+ end
144
+
145
+ it 'timestamps an exception and backtrace into the open request log' do
146
+ expect(PWN::Plugins::Log).to respond_to(:note_exception!)
147
+ path = PWN::Plugins::Log.start_debug(
148
+ tee: StringIO.new,
149
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-exc.log"
150
+ )
151
+ err = NoMethodError.new("undefined method '+' for nil")
152
+ err.set_backtrace(['/opt/pwn/lib/pwn/ai/grok.rb:470:in grok_rest_call', 'loop.rb:1'])
153
+ ok = PWN::Plugins::Log.note_exception!(error: err, where: 'Loop.run')
154
+ expect(ok).to eq true
155
+ body = File.read(path)
156
+ expect(body).to include('NoMethodError')
157
+ expect(body).to include("undefined method '+' for nil")
158
+ expect(body).to include('grok.rb:470')
159
+ expect(body).to include('Loop.run')
160
+ end
161
+
162
+ it 'mirrors TUI tool/task/result rows into the request log without ANSI' do
163
+ expect(PWN::Plugins::Log).to respond_to(:mirror_tui!)
164
+ path = PWN::Plugins::Log.start_debug(
165
+ tee: StringIO.new,
166
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-tui.log"
167
+ )
168
+ ok = PWN::Plugins::Log.mirror_tui!(
169
+ msg: "\e[33m[ 2026-08-20 11:00:00-0600 → pwn-ai → pwn_eval ]\e[0m\n {\"code\":\"1+1\"}\n"
170
+ )
171
+ expect(ok).not_to be_nil
172
+ PWN::Plugins::Log.mirror_tui!(msg: "2026-08-20 11:00:01-0600 → result\n {\"value\":\"2\"}\n")
173
+ PWN::Plugins::Log.mirror_tui!(msg: '[ 2026-08-20 11:00:00-0600 → pwn-ai → task ] navigate')
174
+ body = File.read(path)
175
+ expect(body).to include('[ 2026-08-20 11:00:00-0600 → pwn-ai → pwn_eval ]')
176
+ expect(body).to include('{"code":"1+1"}')
177
+ expect(body).to include('→ result')
178
+ expect(body).to include('→ pwn-ai → task')
179
+ expect(body).not_to include("\e[33m")
180
+ expect(body).not_to include("\e[0m")
75
181
  end
76
182
 
77
- it 'traces PWN module calls into the same debug log while the session is on' do
78
- path = PWN::Plugins::Log.start_debug(tee: StringIO.new, path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-#{Time.now.to_i}.log")
183
+ it 'opens one debug log per request: SESSION_ID-R1 then SESSION_ID-R2' do
184
+ tee = StringIO.new
185
+ sid = "abc#{Process.pid}"
186
+ PWN::Plugins::Log.start_debug(tee: tee)
187
+ first = PWN::Plugins::Log.next_request_log!(session_id: sid)
188
+ PWN::Plugins::Log.progress(msg: 'req-one', which_self: PWN::AI::Agent::Loop)
189
+ PWN::Plugins::Log.finish_request_log!(iter: 1, tools_called: 0, engine_s: 0.1, final_chars: 4)
190
+ second = PWN::Plugins::Log.next_request_log!(session_id: sid)
191
+ PWN::Plugins::Log.progress(msg: 'req-two', which_self: PWN::AI::Agent::Loop)
192
+ expect(first).to eq("/tmp/pwn-ai-DEBUG-#{sid}-R1.log")
193
+ expect(second).to eq("/tmp/pwn-ai-DEBUG-#{sid}-R2.log")
194
+ expect(File.read(first)).to include('req-one')
195
+ expect(File.read(first)).to include('footer iter=1')
196
+ expect(File.read(first)).not_to include('req-two')
197
+ expect(File.read(second)).to include('req-two')
198
+ expect(File.read(second)).not_to include('req-one')
199
+ end
200
+
201
+ it 'does not roll RN when a request log is already open' do
202
+ tee = StringIO.new
203
+ sid = "nest#{Process.pid}"
204
+ PWN::Plugins::Log.start_debug(tee: tee)
205
+ first = PWN::Plugins::Log.next_request_log!(session_id: sid)
206
+ second = PWN::Plugins::Log.next_request_log!(session_id: sid)
207
+ expect(second).to eq(first)
208
+ expect(second).to eq("/tmp/pwn-ai-DEBUG-#{sid}-R1.log")
209
+ end
210
+
211
+ it 'does not TracePoint PWN calls unless trace: true' do
212
+ path = PWN::Plugins::Log.start_debug(
213
+ tee: StringIO.new,
214
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-notrace.log"
215
+ )
216
+ PWN::AI::Agent::OpenGoal.current if defined?(PWN::AI::Agent::OpenGoal)
217
+ body = File.read(path)
218
+ expect(body).not_to match(/PWN::AI::Agent::OpenGoal\.current/)
219
+ end
220
+
221
+ it 'traces PWN module calls into the same debug log when trace: true' do
222
+ path = PWN::Plugins::Log.start_debug(
223
+ tee: StringIO.new,
224
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-#{Time.now.to_i}.log",
225
+ trace: true
226
+ )
79
227
  PWN::AI::Agent::OpenGoal.current if defined?(PWN::AI::Agent::OpenGoal)
80
228
  body = File.read(path)
81
229
  expect(body).to match(/PWN::AI::Agent::OpenGoal/)
@@ -94,7 +242,8 @@ describe PWN::Plugins::Log do
94
242
  stub_const('PWN::AI::Agent::SymNameProbe', probe)
95
243
  PWN::Plugins::Log.start_debug(
96
244
  tee: StringIO.new,
97
- path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-sym.log"
245
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-sym.log",
246
+ trace: true
98
247
  )
99
248
  expect { PWN::AI::Agent::SymNameProbe.ping }.not_to raise_error
100
249
  end
@@ -108,7 +257,8 @@ describe PWN::Plugins::Log do
108
257
  stub_const('PWN::AI::Agent::ArgProbe', probe)
109
258
  path = PWN::Plugins::Log.start_debug(
110
259
  tee: StringIO.new,
111
- path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-args.log"
260
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-args.log",
261
+ trace: true
112
262
  )
113
263
  PWN::AI::Agent::ArgProbe.echo(
114
264
  msg: 'hello-browser',
@@ -132,7 +282,8 @@ describe PWN::Plugins::Log do
132
282
  stub_const('PWN::AI::Agent::ArgProbe', probe)
133
283
  path = PWN::Plugins::Log.start_debug(
134
284
  tee: StringIO.new,
135
- path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-redact.log"
285
+ path: "/tmp/pwn-ai-DEBUG-#{Process.pid}-redact.log",
286
+ trace: true
136
287
  )
137
288
  PWN::AI::Agent::ArgProbe.echo(
138
289
  header: 'Bearer eyJhbGciOiJIUzI1NiJ9.aaa.bbb',
@@ -12,7 +12,7 @@ describe 'pwn-vault Config RuntimeError retry' do
12
12
  let(:vault_src) { File.read(PWN::Plugins::Vault.method(:edit).source_location.first) }
13
13
  let(:block) do
14
14
  start = repl_src.index("Pry::Commands.create_command 'pwn-vault'")
15
- stop = repl_src.index("Pry::Commands.create_command 'toggle-pwn-ai-debug'")
15
+ stop = repl_src.index("Pry::Commands.create_command 'toggle-debug'")
16
16
  repl_src[start...stop]
17
17
  end
18
18
 
@@ -133,10 +133,10 @@ describe 'pwn-vault Config RuntimeError retry' do
133
133
  end
134
134
  end
135
135
 
136
- describe 'toggle-pwn-ai-debug' do
136
+ describe 'toggle-debug' do
137
137
  let(:repl_src) { File.read(PWN::Plugins::REPL.method(:add_commands).source_location.first) }
138
138
  let(:block) do
139
- start = repl_src.index("Pry::Commands.create_command 'toggle-pwn-ai-debug'")
139
+ start = repl_src.index("Pry::Commands.create_command 'toggle-debug'")
140
140
  stop = repl_src.index("Pry::Commands.create_command 'toggle-pwn-ai-speaks'")
141
141
  repl_src[start...stop]
142
142
  end
@@ -145,6 +145,7 @@ describe 'toggle-pwn-ai-debug' do
145
145
  expect(block).to include('PWN::Plugins::Log.start_debug')
146
146
  expect(block).to include('PWN::Plugins::Log.stop_debug')
147
147
  expect(block).to include('pwn-ai-DEBUG')
148
+ expect(block).to include('-R')
148
149
  end
149
150
  end
150
151
 
@@ -157,9 +158,18 @@ describe 'pwn-ai debug final answer placement' do
157
158
 
158
159
  it 'prints the green final after Loop.run and does not pp the session after it' do
159
160
  expect(hook).to match(/Loop\.run\(/)
160
- expect(hook).to match(/\\e\[32m\\002#\{final\}/)
161
+ expect(hook).to match(/\\e\[32m#\{final\}/)
162
+ expect(hook).not_to include('[0, 280]')
163
+ expect(hook).not_to include('[0, 700]')
161
164
  native = hook[hook.index('final = PWN::AI::Agent::Loop.run')..hook.index("request.replace('nil')")]
165
+ expect(native).not_to include('\001')
162
166
  expect(native).not_to match(/pp PWN::Sessions\.load/)
163
167
  expect(native).to match(/\$stdout\.flush/)
164
168
  end
169
+
170
+ it 'mirrors TUI task/tool/result rows into the debug RN log' do
171
+ expect(hook).to include('mirror_tui!')
172
+ expect(hook).to include('→ pwn-ai →')
173
+ expect(hook).to include('→ result')
174
+ end
165
175
  end
@@ -12,4 +12,12 @@ describe PWN::Plugins::TransparentBrowser do
12
12
  help_response = PWN::Plugins::TransparentBrowser
13
13
  expect(help_response).to respond_to :help
14
14
  end
15
+
16
+ it 'caps Watir element waits and Selenium page_load / script timeouts' do
17
+ src = File.read(described_class.method(:open).source_location.first)
18
+ expect(src).to match(/Watir\.default_timeout\s*=\s*15/)
19
+ expect(src).not_to match(/Watir\.default_timeout\s*=\s*900/)
20
+ expect(src).to match(/page_load\s*=\s*45/)
21
+ expect(src).to match(/script\s*=\s*30/)
22
+ end
15
23
  end
@@ -90,4 +90,28 @@ describe PWN::Sessions do
90
90
  ensure
91
91
  FileUtils.rm_rf(tmp) if tmp
92
92
  end
93
+
94
+ it 'to_llm_messages returns this session user/assistant turns for the next LLM call' do
95
+ tmp = Dir.mktmpdir
96
+ stub_const('PWN::Sessions::SESSIONS_DIR', tmp)
97
+ sid = 'llm_hist_sess'
98
+ PWN::Sessions.create(id: sid, title: 'hist')
99
+ PWN::Sessions.append(session_id: sid, role: 'user', content: 'where is OpenGoal?')
100
+ PWN::Sessions.append(session_id: sid, role: 'assistant', content: 'in open_goal.rb')
101
+ PWN::Sessions.append(session_id: sid, role: 'tool', content: 'ignore me')
102
+ PWN::Sessions.append(session_id: sid, role: 'user', content: 'and Loop.run?')
103
+ PWN::Sessions.append(session_id: sid, role: 'assistant', content: 'in loop.rb around resume?')
104
+ msgs = PWN::Sessions.to_llm_messages(session_id: sid)
105
+ expect(msgs.map { |m| m[:role] }).to eq(%w[user assistant user assistant])
106
+ expect(msgs.map { |m| m[:content] }).to include('where is OpenGoal?', 'in open_goal.rb', 'and Loop.run?', 'in loop.rb around resume?')
107
+ expect(msgs.none? { |m| m[:content].to_s.include?('ignore me') }).to eq true
108
+ skip_last = PWN::Sessions.to_llm_messages(session_id: sid, skip_request: 'and Loop.run?')
109
+ expect(skip_last.last[:content]).to eq('in loop.rb around resume?')
110
+ expect(skip_last.none? { |m| m[:content] == 'and Loop.run?' && m[:role] == 'user' }).to eq true
111
+ tiny = PWN::Sessions.to_llm_messages(session_id: sid, max_chars: 40)
112
+ expect(tiny.last[:content]).to include('loop.rb')
113
+ expect(tiny.map { |m| m[:content].to_s.length }.sum).to be <= 80
114
+ ensure
115
+ FileUtils.rm_rf(tmp) if tmp
116
+ end
93
117
  end
@@ -283,6 +283,7 @@
283
283
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.infer_success Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.infer_success`: "}]}
284
284
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.introspective_lessons Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.introspective_lessons`: "}]}
285
285
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.lean! Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.lean!`: "}]}
286
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.locate_skill_for_update Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.locate_skill_for_update`: "}]}
286
287
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.maybe_prune_outcomes! Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.maybe_prune_outcomes!`: "}]}
287
288
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.merge_cluster Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.merge_cluster`: "}]}
288
289
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.note_outcome Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.note_outcome`: Supported Method Parameters\n\nentry = PWN::AI::Agent::Learning.note_outcome(\n\ntask: 'required - short description of what was attempted',\nsuccess: 'required - Boolean, did the attempt achieve its goal',\ndetails: 'optional - free-form notes / error / evidence',\nsession_id: 'optional - PWN::Sessions id this outcome belongs to',\ntags: 'optional - Array of String labels for later retrieval'\n\n)\n"}]}
@@ -296,13 +297,16 @@
296
297
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.recover_predicted_from_session Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.recover_predicted_from_session`: "}]}
297
298
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.reflect Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.reflect`: Supported Method Parameters\n\nreport = PWN::AI::Agent::Learning.reflect(\n\nsession_id: 'required - PWN::Sessions id to analyse',\ndry_run: 'optional - when true, do not write to Memory/Skills (default false)'\n\n)\n\nUses PWN::AI::Agent::Reflect (when available) to LLM-summarise the session into structured lessons. Falls back to a heuristic extractor when module_reflection is disabled so learning never stops.\n"}]}
298
299
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.reset Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.reset`: Supported Method Parameters\n\nPWN::AI::Agent::Learning.reset\n"}]}
300
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.rl_skill_notes Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.rl_skill_notes`: "}]}
299
301
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.semantic_merge Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.semantic_merge`: "}]}
300
302
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.sharegpt_role Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.sharegpt_role`: "}]}
301
303
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.should_gc_stores? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.should_gc_stores?`: "}]}
304
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.skill_body_without_frontmatter Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.skill_body_without_frontmatter`: "}]}
302
305
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.skills_dir Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.skills_dir`: "}]}
303
306
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.stats Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.stats`: Supported Method Parameters\n\nstats = PWN::AI::Agent::Learning.stats\n"}]}
304
307
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.to_context Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.to_context`: Supported Method Parameters\n\nctx = PWN::AI::Agent::Learning.to_context(\n\nlimit: 'optional - number of recent outcomes to surface (default 5)'\n\n)\n"}]}
305
308
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.transcript_text Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.transcript_text`: "}]}
309
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.update_skill Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.update_skill`: "}]}
306
310
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.verdict_for_score Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.verdict_for_score`: "}]}
307
311
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Learning.weighted_judge_mean Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Learning.weighted_judge_mean`: "}]}
308
312
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.active_engine Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.active_engine`: "}]}
@@ -319,9 +323,16 @@
319
323
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.budget_hit? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.budget_hit?`: "}]}
320
324
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.calibration_state Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.calibration_state`: "}]}
321
325
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.call_engine Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.call_engine`: Supported Method Parameters\n\nmsg = PWN::AI::Agent::Loop.call_engine(\n\nmessages: 'required - OpenAI-format messages array',\ntools: 'optional - OpenAI tools array'\n\n)\n\nReturns a normalised assistant message hash:\n\n{ role: 'assistant', content: String|nil,\n tool_calls: [ {id:, type:'function', function:{name:, arguments:}} ],\n _native_content: <provider raw> (when adapter needs round-trip) }\n"}]}
326
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.catalog_lookup? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.catalog_lookup?`: "}]}
327
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.chat_response_history Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.chat_response_history`: "}]}
322
328
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.compact_history! Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.compact_history!`: "}]}
329
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.debug_final_text! Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.debug_final_text!`: "}]}
330
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.debug_msgs_line Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.debug_msgs_line`: "}]}
323
331
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.debug_on? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.debug_on?`: "}]}
324
332
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.debug_progress Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.debug_progress`: "}]}
333
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.debug_snippet Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.debug_snippet`: "}]}
334
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.debug_tool_io! Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.debug_tool_io!`: "}]}
335
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.debug_tools_line Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.debug_tools_line`: "}]}
325
336
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.default_interactive_toolsets Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.default_interactive_toolsets`: "}]}
326
337
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.degrade_text_only Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.degrade_text_only`: "}]}
327
338
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.dispatch_fail_n Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.dispatch_fail_n`: "}]}
@@ -330,6 +341,7 @@
330
341
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.evidence_enough_to_finalize? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.evidence_enough_to_finalize?`: "}]}
331
342
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.expose_current_session Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.expose_current_session`: "}]}
332
343
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.extract_recall_match Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.extract_recall_match`: "}]}
344
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.finish_debug_request! Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.finish_debug_request!`: "}]}
333
345
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.guard_repeated_failure Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.guard_repeated_failure`: "}]}
334
346
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.help Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.help`: "}]}
335
347
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.incomplete_final? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.incomplete_final?`: "}]}
@@ -359,6 +371,7 @@
359
371
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.request_need Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.request_need`: "}]}
360
372
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.request_unsatisfied? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.request_unsatisfied?`: "}]}
361
373
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.run Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.run`: Supported Method Parameters\n\nfinal = PWN::AI::Agent::Loop.run(\n\nrequest: 'required - what the human typed',\nsession_id: 'optional - PWN::Sessions id (transcript is appended to it)',\nenabled_toolsets: 'optional - subset of Registry.toolsets, or nil for all',\non_tool: 'optional - ->(name, args, result) callback for live UI',\nsystem_role_content: 'optional - override default system prompt (built from session_id if not provided)'\n\n)\n"}]}
374
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.session_chat_history Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.session_chat_history`: "}]}
362
375
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.should_auto_introspect? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.should_auto_introspect?`: "}]}
363
376
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.stamped_effect Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.stamped_effect`: "}]}
364
377
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Loop.start_debug_session Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Loop.start_debug_session`: "}]}
@@ -495,6 +508,7 @@
495
508
  {"messages":[{"role":"user","content":"PWN::AI::Agent::PromptBuilder.extrospection_block Usage"},{"role":"assistant","content":"`PWN::AI::Agent::PromptBuilder.extrospection_block`: "}]}
496
509
  {"messages":[{"role":"user","content":"PWN::AI::Agent::PromptBuilder.help Usage"},{"role":"assistant","content":"`PWN::AI::Agent::PromptBuilder.help`: "}]}
497
510
  {"messages":[{"role":"user","content":"PWN::AI::Agent::PromptBuilder.host_line Usage"},{"role":"assistant","content":"`PWN::AI::Agent::PromptBuilder.host_line`: "}]}
511
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::PromptBuilder.host_load_block Usage"},{"role":"assistant","content":"`PWN::AI::Agent::PromptBuilder.host_load_block`: "}]}
498
512
  {"messages":[{"role":"user","content":"PWN::AI::Agent::PromptBuilder.learning_block Usage"},{"role":"assistant","content":"`PWN::AI::Agent::PromptBuilder.learning_block`: "}]}
499
513
  {"messages":[{"role":"user","content":"PWN::AI::Agent::PromptBuilder.memory_block Usage"},{"role":"assistant","content":"`PWN::AI::Agent::PromptBuilder.memory_block`: "}]}
500
514
  {"messages":[{"role":"user","content":"PWN::AI::Agent::PromptBuilder.metrics_block Usage"},{"role":"assistant","content":"`PWN::AI::Agent::PromptBuilder.metrics_block`: "}]}
@@ -590,6 +604,7 @@
590
604
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Reward.sentinel Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Reward.sentinel`: Supported Method Parameters\n\nr = PWN::AI::Agent::Reward.sentinel\n"}]}
591
605
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Reward.set_proxy_distrust Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Reward.set_proxy_distrust`: "}]}
592
606
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Reward.timeout_error? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Reward.timeout_error?`: "}]}
607
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::Reward.timeout_result? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Reward.timeout_result?`: "}]}
593
608
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Reward.usable_preference? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Reward.usable_preference?`: "}]}
594
609
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Reward.user_correction_rate Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Reward.user_correction_rate`: "}]}
595
610
  {"messages":[{"role":"user","content":"PWN::AI::Agent::Reward.verify_as_reward Usage"},{"role":"assistant","content":"`PWN::AI::Agent::Reward.verify_as_reward`: Supported Method Parameters\n\ng = PWN::AI::Agent::Reward.verify_as_reward(final: text)\n"}]}
@@ -630,6 +645,7 @@
630
645
  {"messages":[{"role":"user","content":"PWN::AI::Agent::TaskSummarizer.arg_snippet Usage"},{"role":"assistant","content":"`PWN::AI::Agent::TaskSummarizer.arg_snippet`: "}]}
631
646
  {"messages":[{"role":"user","content":"PWN::AI::Agent::TaskSummarizer.authors Usage"},{"role":"assistant","content":"`PWN::AI::Agent::TaskSummarizer.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
632
647
  {"messages":[{"role":"user","content":"PWN::AI::Agent::TaskSummarizer.brief_fingerprint Usage"},{"role":"assistant","content":"`PWN::AI::Agent::TaskSummarizer.brief_fingerprint`: "}]}
648
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::TaskSummarizer.browse_shaped? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::TaskSummarizer.browse_shaped?`: "}]}
633
649
  {"messages":[{"role":"user","content":"PWN::AI::Agent::TaskSummarizer.bump_plan! Usage"},{"role":"assistant","content":"`PWN::AI::Agent::TaskSummarizer.bump_plan!`: "}]}
634
650
  {"messages":[{"role":"user","content":"PWN::AI::Agent::TaskSummarizer.canonical_request Usage"},{"role":"assistant","content":"`PWN::AI::Agent::TaskSummarizer.canonical_request`: Supported Method Parameters\n\ntext = PWN::AI::Agent::TaskSummarizer.canonical_request(\n\nrequest: 'required - raw user or wrapper string'\n\n)\n"}]}
635
651
  {"messages":[{"role":"user","content":"PWN::AI::Agent::TaskSummarizer.capabilities_for Usage"},{"role":"assistant","content":"`PWN::AI::Agent::TaskSummarizer.capabilities_for`: "}]}
@@ -689,12 +705,17 @@
689
705
  {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.authors Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.authors`: "}]}
690
706
  {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.bashism? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.bashism?`: "}]}
691
707
  {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.coerce_args Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.coerce_args`: "}]}
708
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.deadline_s Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.deadline_s`: "}]}
692
709
  {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.help Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.help`: "}]}
710
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.host_load Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.host_load`: "}]}
693
711
  {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.invalid_payload Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.invalid_payload`: "}]}
694
712
  {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.placeholder? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.placeholder?`: "}]}
695
713
  {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.present? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.present?`: "}]}
696
714
  {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.shell_bash? Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.shell_bash?`: "}]}
697
715
  {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.shell_name Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.shell_name`: "}]}
716
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.timeout_lesson Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.timeout_lesson`: "}]}
717
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.timeout_prior_count Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.timeout_prior_count`: "}]}
718
+ {"messages":[{"role":"user","content":"PWN::AI::Agent::ToolGuard.timeout_result Usage"},{"role":"assistant","content":"`PWN::AI::Agent::ToolGuard.timeout_result`: "}]}
698
719
  {"messages":[{"role":"user","content":"PWN::AI::Agent::TransparentBrowser.analyze Usage"},{"role":"assistant","content":"`PWN::AI::Agent::TransparentBrowser.analyze`: Supported Method Parameters\n\nai_analysis = PWN::AI::Agent::TransparentBrowser.analyze(\n\nrequest: 'required - current step in the JavaScript debugging session to analyze',\nsource_to_review: 'required - the block of JavaScript code in which the current step resides'\n\n)\n"}]}
699
720
  {"messages":[{"role":"user","content":"PWN::AI::Agent::TransparentBrowser.authors Usage"},{"role":"assistant","content":"`PWN::AI::Agent::TransparentBrowser.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
700
721
  {"messages":[{"role":"user","content":"PWN::AI::Agent::TransparentBrowser.help Usage"},{"role":"assistant","content":"`PWN::AI::Agent::TransparentBrowser.help`: "}]}
@@ -741,9 +762,9 @@
741
762
  {"messages":[{"role":"user","content":"PWN::AI::Gemini.oa_messages_to_gemini Usage"},{"role":"assistant","content":"`PWN::AI::Gemini.oa_messages_to_gemini`: "}]}
742
763
  {"messages":[{"role":"user","content":"PWN::AI::Grok.authors Usage"},{"role":"assistant","content":"`PWN::AI::Grok.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
743
764
  {"messages":[{"role":"user","content":"PWN::AI::Grok.chat Usage"},{"role":"assistant","content":"`PWN::AI::Grok.chat`: Supported Method Parameters\n\nresponse = PWN::AI::Grok.chat(\n\nrequest: 'required - message to Grok'\nmodel: 'optional - model to use for text generation (defaults to PWN::Env[:ai][:grok][:model])',\ntemp: 'optional - creative response float (deafults to PWN::Env[:ai][:grok][:temp])',\nsystem_role_content: 'optional - context to set up the model behavior for conversation (Default: PWN::Env[:ai][:grok][:system_role_content])',\nresponse_history: 'optional - pass response back in to have a conversation',\nspeak_answer: 'optional speak answer using PWN::Plugins::Voice.text_to_speech (Default: nil)',\ntimeout: 'optional timeout in seconds (defaults to 900)',\nspinner: 'optional - display spinner (defaults to false)'\n\n)\n"}]}
744
- {"messages":[{"role":"user","content":"PWN::AI::Grok.chat_with_tools Usage"},{"role":"assistant","content":"`PWN::AI::Grok.chat_with_tools`: Supported Method Parameters\n\nresponse = PWN::AI::Grok.chat_with_tools(\n\nmessages: 'required - full OpenAI-format messages array (system/user/assistant/tool)',\ntools: 'optional - OpenAI tools array [{type:\"function\", function:{...}}]',\ntool_choice: 'optional - \"auto\" | \"none\" | \"required\" | {type:\"function\", function:{name:..}}',\nmodel: 'optional - overrides PWN::Env[:ai][:grok][:model]',\ntemp: 'optional - temperature (defaults to PWN::Env[:ai][:grok][:temp] || 1)',\ntimeout: 'optional - seconds (default 900)',\nspinner: 'optional - display spinner (default false)'\n\n)\n\nReturns the raw chat/completions response Hash with :choices intact (including :message) — used by PWN::AI::Agent::Loop. xAI’s API is OpenAI-compatible for tool calling, so the request and response shapes are identical to PWN::AI::OpenAI.chat_with_tools.\n"}]}
765
+ {"messages":[{"role":"user","content":"PWN::AI::Grok.chat_with_tools Usage"},{"role":"assistant","content":"`PWN::AI::Grok.chat_with_tools`: Supported Method Parameters\n\nresponse = PWN::AI::Grok.chat_with_tools(\n\nmessages: 'required - full OpenAI-format messages array (system/user/assistant/tool)',\ntools: 'optional - OpenAI tools array [{type:\"function\", function:{...}}]',\ntool_choice: 'optional - \"auto\" | \"none\" | \"required\" | {type:\"function\", function:{name:..}}',\nmodel: 'optional - overrides PWN::Env[:ai][:grok][:model]',\ntemp: 'optional - temperature (defaults to PWN::Env[:ai][:grok][:temp] || 1)',\ntimeout: 'optional - seconds (default 180)',\nspinner: 'optional - display spinner (default false)'\n\n)\n\nReturns the raw chat/completions response Hash with :choices intact (including :message) — used by PWN::AI::Agent::Loop. xAI’s API is OpenAI-compatible for tool calling, so the request and response shapes are identical to PWN::AI::OpenAI.chat_with_tools.\n"}]}
745
766
  {"messages":[{"role":"user","content":"PWN::AI::Grok.get_models Usage"},{"role":"assistant","content":"`PWN::AI::Grok.get_models`: Supported Method Parameters\n\nmodels = PWN::AI::Grok.get_models\n"}]}
746
- {"messages":[{"role":"user","content":"PWN::AI::Grok.grok_rest_call Usage"},{"role":"assistant","content":"`PWN::AI::Grok.grok_rest_call`: Supported Method Parameters\n\ngrok_ai_rest_call(\n\ntoken: 'required - grok_ai bearer token',\nhttp_method: 'optional HTTP method (defaults to GET)\nbase_uri: 'optional base grok api URI (defaults to https://api.x.ai/v1)',\nrest_call: 'required rest call to make per the schema',\nparams: 'optional params passed in the URI or HTTP Headers',\nhttp_body: 'optional HTTP body sent in HTTP methods that support it e.g. POST',\ntimeout: 'optional timeout in seconds (defaults to 900)',\nspinner: 'optional - display spinner (defaults to false)'\n\n)\n"}]}
767
+ {"messages":[{"role":"user","content":"PWN::AI::Grok.grok_rest_call Usage"},{"role":"assistant","content":"`PWN::AI::Grok.grok_rest_call`: Supported Method Parameters\n\ngrok_ai_rest_call(\n\ntoken: 'required - grok_ai bearer token',\nhttp_method: 'optional HTTP method (defaults to GET)\nbase_uri: 'optional base grok api URI (defaults to https://api.x.ai/v1)',\nrest_call: 'required rest call to make per the schema',\nparams: 'optional params passed in the URI or HTTP Headers',\nhttp_body: 'optional HTTP body sent in HTTP methods that support it e.g. POST',\ntimeout: 'optional timeout in seconds (defaults to 180; 5 attempts)',\nspinner: 'optional - display spinner (defaults to false)'\n\n)\n"}]}
747
768
  {"messages":[{"role":"user","content":"PWN::AI::Grok.help Usage"},{"role":"assistant","content":"`PWN::AI::Grok.help`: "}]}
748
769
  {"messages":[{"role":"user","content":"PWN::AI::Grok.jwt_exp Usage"},{"role":"assistant","content":"`PWN::AI::Grok.jwt_exp`: "}]}
749
770
  {"messages":[{"role":"user","content":"PWN::AI::Grok.oauth_token_expiring? Usage"},{"role":"assistant","content":"`PWN::AI::Grok.oauth_token_expiring?`: "}]}
@@ -752,6 +773,12 @@
752
773
  {"messages":[{"role":"user","content":"PWN::AI::Grok.real_config_value? Usage"},{"role":"assistant","content":"`PWN::AI::Grok.real_config_value?`: "}]}
753
774
  {"messages":[{"role":"user","content":"PWN::AI::Grok.refresh_oauth_bearer_token Usage"},{"role":"assistant","content":"`PWN::AI::Grok.refresh_oauth_bearer_token`: Supported Method Parameters\n\naccess_token = PWN::AI::Grok.refresh_oauth_bearer_token(\n\nrefresh_token: 'required - xAI OAuth refresh_token',\nclient_id: 'optional - defaults to public Grok-CLI client',\ntoken_uri: 'optional - defaults to https://auth.x.ai/oauth2/token'\n\n)\n\nExchanges a refresh_token for a fresh access_token at auth.x.ai. On success, writes :bearer_token (and a rotated :refresh_token if returned) back into the passed opts/oauth Hash so the live PWN::Env stays warm for the rest of the process. Also mirrors those values onto PWN::Env[:grok] when that Hash is available, then attempts to re-encrypt the updated tokens into ~/.pwn/pwn.yaml when the matching decryptor (key + iv) is present.\n"}]}
754
775
  {"messages":[{"role":"user","content":"PWN::AI::Grok.sync_oauth_into_env Usage"},{"role":"assistant","content":"`PWN::AI::Grok.sync_oauth_into_env`: "}]}
776
+ {"messages":[{"role":"user","content":"PWN::AI::HttpRetry.authors Usage"},{"role":"assistant","content":"`PWN::AI::HttpRetry.authors`: "}]}
777
+ {"messages":[{"role":"user","content":"PWN::AI::HttpRetry.help Usage"},{"role":"assistant","content":"`PWN::AI::HttpRetry.help`: "}]}
778
+ {"messages":[{"role":"user","content":"PWN::AI::HttpRetry.max_attempts Usage"},{"role":"assistant","content":"`PWN::AI::HttpRetry.max_attempts`: "}]}
779
+ {"messages":[{"role":"user","content":"PWN::AI::HttpRetry.report_event Usage"},{"role":"assistant","content":"`PWN::AI::HttpRetry.report_event`: "}]}
780
+ {"messages":[{"role":"user","content":"PWN::AI::HttpRetry.retry_after_s Usage"},{"role":"assistant","content":"`PWN::AI::HttpRetry.retry_after_s`: "}]}
781
+ {"messages":[{"role":"user","content":"PWN::AI::HttpRetry.timeout_s Usage"},{"role":"assistant","content":"`PWN::AI::HttpRetry.timeout_s`: "}]}
755
782
  {"messages":[{"role":"user","content":"PWN::AI::Ollama.assemble_native_chat_stream Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.assemble_native_chat_stream`: "}]}
756
783
  {"messages":[{"role":"user","content":"PWN::AI::Ollama.assemble_ollama_stream Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.assemble_ollama_stream`: "}]}
757
784
  {"messages":[{"role":"user","content":"PWN::AI::Ollama.assemble_openai_compat_stream Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.assemble_openai_compat_stream`: "}]}
@@ -1881,19 +1908,26 @@
1881
1908
  {"messages":[{"role":"user","content":"PWN::Plugins::JiraDataCenter.update_issue Usage"},{"role":"assistant","content":"`PWN::Plugins::JiraDataCenter.update_issue`: Supported Method Parameters\n\nissue_resp = PWN::Plugins::JiraDataCenter.update_issue(\n\nfields: 'required - fields to update in the issue (e.g. summary, description, labels, components, custom fields, etc.)',\nattachments: 'optional - array of attachment paths to upload to the issue (e.g. [\"/tmp/file1.txt\", \"/tmp/file2.txt\"])',\n\n)\n"}]}
1882
1909
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.append Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.append`: Supported Method Parameters\n\nPWN::Log.create( )\n"}]}
1883
1910
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.authors Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
1911
+ {"messages":[{"role":"user","content":"PWN::Plugins::Log.close_debug_file! Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.close_debug_file!`: "}]}
1884
1912
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.color_progress Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.color_progress`: "}]}
1885
1913
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.debug_enabled? Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.debug_enabled?`: "}]}
1886
1914
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.debug_log_path Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.debug_log_path`: "}]}
1887
- {"messages":[{"role":"user","content":"PWN::Plugins::Log.debug_path_parts Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.debug_path_parts`: "}]}
1915
+ {"messages":[{"role":"user","content":"PWN::Plugins::Log.finish_request_log! Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.finish_request_log!`: "}]}
1888
1916
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.format_debug_hash Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.format_debug_hash`: "}]}
1889
1917
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.format_progress Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.format_progress`: "}]}
1890
1918
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.format_trace_call Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.format_trace_call`: "}]}
1891
1919
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.help Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.help`: "}]}
1892
1920
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.inspect_debug Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.inspect_debug`: "}]}
1893
1921
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.loud_tui! Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.loud_tui!`: "}]}
1922
+ {"messages":[{"role":"user","content":"PWN::Plugins::Log.mirror_tui! Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.mirror_tui!`: "}]}
1923
+ {"messages":[{"role":"user","content":"PWN::Plugins::Log.next_debug_request_n Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.next_debug_request_n`: "}]}
1924
+ {"messages":[{"role":"user","content":"PWN::Plugins::Log.next_request_log! Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.next_request_log!`: "}]}
1925
+ {"messages":[{"role":"user","content":"PWN::Plugins::Log.note_exception! Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.note_exception!`: "}]}
1926
+ {"messages":[{"role":"user","content":"PWN::Plugins::Log.note_interrupt! Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.note_interrupt!`: "}]}
1927
+ {"messages":[{"role":"user","content":"PWN::Plugins::Log.open_debug_file! Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.open_debug_file!`: "}]}
1894
1928
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.progress Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.progress`: "}]}
1895
1929
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.quiet_tui! Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.quiet_tui!`: "}]}
1896
- {"messages":[{"role":"user","content":"PWN::Plugins::Log.roll_debug_log! Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.roll_debug_log!`: "}]}
1930
+ {"messages":[{"role":"user","content":"PWN::Plugins::Log.sanitize_debug_session_id Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.sanitize_debug_session_id`: "}]}
1897
1931
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.sanitize_debug_text Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.sanitize_debug_text`: "}]}
1898
1932
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.secret_key? Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.secret_key?`: "}]}
1899
1933
  {"messages":[{"role":"user","content":"PWN::Plugins::Log.start_debug Usage"},{"role":"assistant","content":"`PWN::Plugins::Log.start_debug`: "}]}
@@ -2155,6 +2189,7 @@
2155
2189
  {"messages":[{"role":"user","content":"PWN::Plugins::Tor.stop Usage"},{"role":"assistant","content":"`PWN::Plugins::Tor.stop`: Supported Method Parameters\n\nPWN::Plugins::Tor.stop(\n\ntor_obj: 'required - tor_obj returned from #start method'\n\n)\n"}]}
2156
2190
  {"messages":[{"role":"user","content":"PWN::Plugins::Tor.switch_exit_node Usage"},{"role":"assistant","content":"`PWN::Plugins::Tor.switch_exit_node`: Supported Method Parameters\n\nPWN::Plugins::Tor.switch_exit_node(\n\ntor_obj: 'required - tor_obj returned from #start method',\nresponse_timeout: 'optional - float in seconds to timeout (default: 3.0)'\n\n)\n"}]}
2157
2191
  {"messages":[{"role":"user","content":"PWN::Plugins::Tor.tor_control_cmd Usage"},{"role":"assistant","content":"`PWN::Plugins::Tor.tor_control_cmd`: Supported Method Parameters\n\ntor_ctrl_cmd(\n\ntor_obj: 'required - tor_obj returned from #start method'\ncmd: 'required - Tor control command to execute',\nresponse_timeout: 'optional - float in seconds to timeout (default: 3.0)'\n\n)\n"}]}
2192
+ {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.apply_driver_timeouts! Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.apply_driver_timeouts!`: "}]}
2158
2193
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.authors Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
2159
2194
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.breakpoint_locations Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.breakpoint_locations`: Supported Method Parameters\n\npage_state_arr = PWN::Plugins::TransparentBrowser.breakpoint_locations(\n\nbrowser_obj: 'required - browser_obj returned from #open method)'\n\n)\n"}]}
2160
2195
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.close Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.close`: Supported Method Parameters\n\nbrowser_obj1 = PWN::Plugins::TransparentBrowser.close(\n\nbrowser_obj: 'required - browser_obj returned from #open method)'\n\n)\n"}]}
@@ -2722,7 +2757,7 @@
2722
2757
  {"messages":[{"role":"user","content":"PWN::Sessions.append Usage"},{"role":"assistant","content":"`PWN::Sessions.append`: Supported Method Parameters\n\nPWN::Sessions.append(\n\nsession_id: 'required',\nrole: 'user|assistant|system|observation',\ncontent: 'the message or obs'\n\n)\n"}]}
2723
2758
  {"messages":[{"role":"user","content":"PWN::Sessions.authors Usage"},{"role":"assistant","content":"`PWN::Sessions.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
2724
2759
  {"messages":[{"role":"user","content":"PWN::Sessions.compact_transcript! Usage"},{"role":"assistant","content":"`PWN::Sessions.compact_transcript!`: "}]}
2725
- {"messages":[{"role":"user","content":"PWN::Sessions.create Usage"},{"role":"assistant","content":"`PWN::Sessions.create`: Supported Method Parameters\n\nsession = PWN::Sessions.create(\n\ntitle: 'optional - human title',\nsource: 'optional - e.g. pwn-ai-repl',\nid: 'optional - fixed session id (tests / replay); default timestamp_hex'\n\n)\n"}]}
2760
+ {"messages":[{"role":"user","content":"PWN::Sessions.create Usage"},{"role":"assistant","content":"`PWN::Sessions.create`: Supported Method Parameters\n\nsession = PWN::Sessions.create(\n\ntitle: 'optional - human title',\nsource: 'optional - e.g. pwn-ai',\nid: 'optional - fixed session id (tests / replay); default timestamp_hex'\n\n)\n"}]}
2726
2761
  {"messages":[{"role":"user","content":"PWN::Sessions.delete Usage"},{"role":"assistant","content":"`PWN::Sessions.delete`: Supported Method Parameters\n\nPWN::Sessions.delete(\n\nsession_id: 'required',\nforce: 'optional - Boolean bypass pin policy (default false)'\n\n)\n"}]}
2727
2762
  {"messages":[{"role":"user","content":"PWN::Sessions.help Usage"},{"role":"assistant","content":"`PWN::Sessions.help`: "}]}
2728
2763
  {"messages":[{"role":"user","content":"PWN::Sessions.lean! Usage"},{"role":"assistant","content":"`PWN::Sessions.lean!`: Supported Method Parameters\n\nresult = PWN::Sessions.lean!(\n\ndry_run: 'optional - Boolean (default false)',\nretain_days: 'optional - drop unreferenced older than this',\nhot_days: 'optional - always keep newer than this',\nmax_files: 'optional - soft file cap after protections',\ncurrent_session_id: 'optional - never delete this id'\n\n)\n"}]}
@@ -2735,6 +2770,7 @@
2735
2770
  {"messages":[{"role":"user","content":"PWN::Sessions.sessions_dir Usage"},{"role":"assistant","content":"`PWN::Sessions.sessions_dir`: Supported Method Parameters\n\ndir = PWN::Sessions.sessions_dir\n"}]}
2736
2771
  {"messages":[{"role":"user","content":"PWN::Sessions.stats Usage"},{"role":"assistant","content":"`PWN::Sessions.stats`: Supported Method Parameters\n\nstats = PWN::Sessions.stats\n"}]}
2737
2772
  {"messages":[{"role":"user","content":"PWN::Sessions.stub_session? Usage"},{"role":"assistant","content":"`PWN::Sessions.stub_session?`: "}]}
2773
+ {"messages":[{"role":"user","content":"PWN::Sessions.to_llm_messages Usage"},{"role":"assistant","content":"`PWN::Sessions.to_llm_messages`: "}]}
2738
2774
  {"messages":[{"role":"user","content":"PWN::Sessions.to_response_history Usage"},{"role":"assistant","content":"`PWN::Sessions.to_response_history`: Supported Method Parameters\n\nhistory_for_ai = PWN::Sessions.to_response_history(session_id:) (converts transcript to the response_history format used by PWN::AI::* .chat)\n"}]}
2739
2775
  {"messages":[{"role":"user","content":"PWN::Setup.ai_active_engine Usage"},{"role":"assistant","content":"`PWN::Setup.ai_active_engine`: "}]}
2740
2776
  {"messages":[{"role":"user","content":"PWN::Setup.ai_key_configured? Usage"},{"role":"assistant","content":"`PWN::Setup.ai_key_configured?`: "}]}
@@ -0,0 +1,9 @@
1
+ pwn_critic swarm 20260819_214041_e6ff4d
2
+ REQUEST: what skills are available?
3
+ LIVE INDEX: /home/ninp0/.pwn/skills
4
+ LIVE COUNT: 103
5
+ CANDIDATE CLAIM: 103 skills, complete A-Z list
6
+ CANDIDATE LISTED: 24 names, last item truncated at "document-to-action-items -- Extract cited obligations, deadli"
7
+ MISSING COUNT: 79
8
+ VERDICT: FLAW
9
+ ONE LINE: Claims 103 skills from the live SKILLS index but the list stops at item 24 mid-word; 79 skills are omitted.