pwn 0.5.643 → 0.5.650
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.
- checksums.yaml +4 -4
- data/documentation/Agent-Tool-Registry.md +10 -5
- data/documentation/Cron.md +3 -2
- data/documentation/Home.md +2 -2
- data/documentation/How-PWN-Works.md +1 -1
- data/documentation/Mistakes.md +13 -0
- data/documentation/Reinforcement-Learning.md +72 -3
- data/documentation/Skills-Memory-Learning.md +5 -3
- data/documentation/What-is-PWN.md +1 -1
- data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +3 -3
- data/documentation/diagrams/dot/reinforcement-learning.dot +8 -8
- data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +318 -319
- data/documentation/diagrams/reinforcement-learning.svg +188 -187
- data/documentation/pwn-ai-Agent.md +6 -5
- data/lib/pwn/ai/agent/curriculum.rb +491 -35
- data/lib/pwn/ai/agent/extrospection.rb +18 -4
- data/lib/pwn/ai/agent/learning.rb +308 -54
- data/lib/pwn/ai/agent/loop.rb +145 -11
- data/lib/pwn/ai/agent/metrics.rb +200 -11
- data/lib/pwn/ai/agent/mistakes.rb +26 -8
- data/lib/pwn/ai/agent/registry.rb +24 -2
- data/lib/pwn/ai/agent/reward.rb +447 -7
- data/lib/pwn/ai/agent/tools/curriculum.rb +23 -0
- data/lib/pwn/ai/agent/tools/reward.rb +86 -0
- data/lib/pwn/ai/agent/tools/ruby_eval.rb +29 -6
- data/lib/pwn/cron.rb +14 -2
- data/lib/pwn/version.rb +1 -1
- data/spec/integration/reinforced_feedback_loop_spec.rb +806 -12
- data/spec/lib/pwn/ai/agent/reward_spec.rb +64 -1
- data/spec/lib/pwn/ai/agent/tools/ruby_eval_spec.rb +39 -1
- data/third_party/pwn_rdoc.jsonl +33 -4
- metadata +1 -1
|
@@ -39,19 +39,42 @@ PWN::AI::Agent::Registry.register(
|
|
|
39
39
|
# INTENTIONAL: this IS the pwn-ai → PWN bridge
|
|
40
40
|
# As YTCracker says, "It ain't a bug, it's a featcha."
|
|
41
41
|
# https://www.youtube.com/watch?v=2nALqqSqdDw
|
|
42
|
-
#
|
|
42
|
+
#
|
|
43
|
+
# File label '(pwn_eval)' (not __FILE__) so SyntaxError / NameError
|
|
44
|
+
# messages cite the *payload* line, not ruby_eval.rb:49 glued to source
|
|
45
|
+
# (e.g. "ruby_eval:49results = probes.map do |R|").
|
|
46
|
+
# Rescue ScriptError (SyntaxError, LoadError, NotImplementedError) as
|
|
47
|
+
# well as StandardError — Dispatch only catches StandardError, so an
|
|
48
|
+
# unrescued SyntaxError previously escaped the tool loop. Returning a
|
|
49
|
+
# structured error lets the model self-heal (fix code and retry).
|
|
50
|
+
# rubocop:disable Style/EvalWithLocation -- intentional file label
|
|
51
|
+
# '(pwn_eval)' so SyntaxError/NameError messages cite the payload, not
|
|
52
|
+
# this library line (specs + model self-heal depend on that string).
|
|
43
53
|
proc = eval(
|
|
44
|
-
"proc { #{code}
|
|
54
|
+
"proc { #{code}\n}",
|
|
45
55
|
TOPLEVEL_BINDING,
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
'(pwn_eval)',
|
|
57
|
+
1
|
|
48
58
|
)
|
|
59
|
+
# rubocop:enable Style/EvalWithLocation
|
|
49
60
|
val = proc.call
|
|
50
61
|
# rubocop:enable Security/Eval
|
|
51
62
|
# rubocop:enable Style/DocumentDynamicEvalDefinition
|
|
52
63
|
{ stdout: buf.string, value: val.inspect }
|
|
53
|
-
|
|
54
|
-
|
|
64
|
+
rescue ScriptError, StandardError => e
|
|
65
|
+
{
|
|
66
|
+
stdout: buf.string,
|
|
67
|
+
error: "#{e.class}: #{e.message}",
|
|
68
|
+
backtrace: Array(e.backtrace).first(5),
|
|
69
|
+
# Hint common payload footguns the model keeps emitting
|
|
70
|
+
hint: (
|
|
71
|
+
if e.is_a?(SyntaxError) && e.message.match?(/formal argument cannot be a constant/)
|
|
72
|
+
'Block parameters must be local variables (lowercase), e.g. |r| not |R|. Also close every do/end.'
|
|
73
|
+
elsif e.is_a?(SyntaxError)
|
|
74
|
+
'Payload failed to parse. Check matching do/end, braces, and that no line-number prefix was glued onto the code.'
|
|
75
|
+
end
|
|
76
|
+
)
|
|
77
|
+
}
|
|
55
78
|
ensure
|
|
56
79
|
$stdout = old_stdout
|
|
57
80
|
end
|
data/lib/pwn/cron.rb
CHANGED
|
@@ -231,8 +231,11 @@ module PWN
|
|
|
231
231
|
)
|
|
232
232
|
end
|
|
233
233
|
|
|
234
|
-
# P3 — backfill ORM/PRM labels when local :failure_only introspect is on
|
|
235
|
-
|
|
234
|
+
# P3 — backfill ORM/PRM labels when local :failure_only introspect is on.
|
|
235
|
+
# P13 — treat legacy alias offline_judge_nightly as the same job so
|
|
236
|
+
# install_defaults never double-seeds the 30 3 * * * slot.
|
|
237
|
+
offline_names = %w[curriculum_offline_judge offline_judge_nightly]
|
|
238
|
+
unless names.intersect?(offline_names)
|
|
236
239
|
seeded << create(
|
|
237
240
|
name: 'curriculum_offline_judge',
|
|
238
241
|
schedule: '30 3 * * *',
|
|
@@ -241,6 +244,15 @@ module PWN
|
|
|
241
244
|
enabled: true
|
|
242
245
|
)
|
|
243
246
|
end
|
|
247
|
+
# Disable duplicate alias if both exist (idempotent cleanup).
|
|
248
|
+
if names.include?('curriculum_offline_judge') && names.include?('offline_judge_nightly')
|
|
249
|
+
begin
|
|
250
|
+
dup = jobs.values.find { |j| j[:name].to_s == 'offline_judge_nightly' }
|
|
251
|
+
disable(id: dup[:id]) if dup && dup[:enabled]
|
|
252
|
+
rescue StandardError
|
|
253
|
+
nil
|
|
254
|
+
end
|
|
255
|
+
end
|
|
244
256
|
|
|
245
257
|
# M1/M3 — nightly memory GC so the injected MEMORY block stays high-signal
|
|
246
258
|
unless names.include?('learning_consolidate_nightly')
|
data/lib/pwn/version.rb
CHANGED