Module: PWN::AI::Agent::Reflect
- Defined in:
- lib/pwn/ai/agent/reflect.rb
Overview
PWN::AI::Agent::Reflect is the inward-facing counterpart to PWN::AI::Agent::Extrospection. Where Extrospection looks OUTWARD at the world the agent operates in (host state, toolchain, network, threat-intel), Reflect looks INWARD - it lets pwn hand a request to the active AI engine and reflect on its own artifacts, transcripts, findings, code, or decisions.
This module is gated by PWN::Env[:ai][:module_reflection] so that
potentially-sensitive local data is never shipped to a remote LLM
unless the operator has explicitly opted in via pwn-vault / config.
It is the single choke-point every PWN::AI::Agent::* domain agent (Assembly, BurpSuite, GQRX, HackerOne, SAST, VulnGen, ...) routes through when it wants an LLM opinion on locally-produced data, and it is also what PWN::AI::Agent::Learning.reflect uses to distill session transcripts into durable PWN::Memory lessons.
TEACHER-STUDENT REFLECTION
When PWN::Env[:reflect_engine] (or opts) names a different provider than :active, Reflect.on temporarily flips :active for the duration of the introspection call. This lets a local Ollama model EXECUTE the task while a frontier model WRITES the durable lessons about it — the local model then reads back distilled reasoning it could never have produced itself.
IMPLEMENTATION NOTE
Reflect.on MUST call the engine's text .chat API directly — never Loop.run. Nesting Loop.run re-enters TaskSummarizer/PromptBuilder/ auto_introspect and produces SystemStackError at the Pry after_read boundary whenever module_reflection is enabled. A thread-local depth counter still gates re-entrant Reflect.on (e.g. chat_for_plan inside an outer agent turn that also judges/reflects).
Constant Summary collapse
- ENGINE_MODS =
{ openai: 'PWN::AI::OpenAI', grok: 'PWN::AI::Grok', ollama: 'PWN::AI::Ollama', anthropic: 'PWN::AI::Anthropic', gemini: 'PWN::AI::Gemini' }.freeze
Class Method Summary collapse
-
.authors ⇒ Object
- Author(s)
0day Inc.
-
.help ⇒ Object
Display Usage for this Module.
-
.on(opts = {}) ⇒ Object
- Supported Method Parameters
response = PWN::AI::Agent::Reflect.on( request: 'required - String - What you want the AI to reflect on', system_role_content: 'optional - context to set up the model behavior for reflection', engine: 'optional - override engine for THIS reflection only (Symbol/String); defaults to PWN::Env[:reflect_engine] || :active', model: 'optional - override model on the reflection engine for THIS call only; defaults to PWN::Env[:reflect_model]', spinner: 'optional - Boolean - Display spinner during operation (default: false)', suppress_pii_warning: 'optional - Boolean - Suppress PII Warnings (default: false)' ).
Class Method Details
.authors ⇒ Object
- Author(s)
0day Inc. support@0dayinc.com
157 158 159 160 161 |
# File 'lib/pwn/ai/agent/reflect.rb', line 157 public_class_method def self. "AUTHOR(S): 0day Inc. <support@0dayinc.com> " end |
.help ⇒ Object
Display Usage for this Module
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/pwn/ai/agent/reflect.rb', line 165 public_class_method def self.help puts "USAGE: #{self}.on( request: 'required - String - What you want the AI to reflect on', system_role_content: 'optional - context to set up the model behavior for reflection', engine: 'optional - override engine (Symbol) for teacher-student reflection; defaults to PWN::Env[:ai][:reflect_engine]', spinner: 'optional - Boolean - Display spinner during operation (default: false)', suppress_pii_warning: 'optional - Boolean - Suppress PII Warnings (default: false)' ) Teacher-student config: PWN::Env[:ai][:reflect_engine] = :anthropic # execute on :active, critique on :anthropic #{self}.authors " end |
.on(opts = {}) ⇒ Object
- Supported Method Parameters
response = PWN::AI::Agent::Reflect.on( request: 'required - String - What you want the AI to reflect on', system_role_content: 'optional - context to set up the model behavior for reflection', engine: 'optional - override engine for THIS reflection only (Symbol/String); defaults to PWN::Env[:reflect_engine] || :active', model: 'optional - override model on the reflection engine for THIS call only; defaults to PWN::Env[:reflect_model]', spinner: 'optional - Boolean - Display spinner during operation (default: false)', suppress_pii_warning: 'optional - Boolean - Suppress PII Warnings (default: false)' )
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/pwn/ai/agent/reflect.rb', line 61 public_class_method def self.on(opts = {}) request = opts[:request] raise 'ERROR: request must be provided' if request.nil? system_role_content = opts[:system_role_content] spinner = opts[:spinner] || false suppress_pii_warning = opts[:suppress_pii_warning] || false response = nil ai_module_reflection = PWN::Env[:ai][:module_reflection] # Re-entrancy guard: nested Reflect.on (TaskSummarizer inside a # Reflect call, Reward.judge during auto_introspect, etc.) returns # nil so the outer caller can fall back. Never Loop.run from here. return nil if Thread.current[:pwn_reflect_depth].to_i.positive? if ai_module_reflection && request.length.positive? override = opts[:engine] || PWN::Env.dig(:ai, :reflect_engine) model = opts[:model] || PWN::Env.dig(:ai, :reflect_model) engine = (override || PWN::Env[:ai][:active]).to_s.downcase.to_sym valid_ai_engines = ENGINE_MODS.keys raise "ERROR: Unsupported AI engine. Supported engines are: #{valid_ai_engines}" unless valid_ai_engines.include?(engine) warn "AI Reflection is enabled. Ensure #{engine} has been authorized for use and/or requests are sanitized properly." unless suppress_pii_warning Thread.current[:pwn_reflect_depth] = Thread.current[:pwn_reflect_depth].to_i + 1 begin response = with_engine(engine: override, model: model) do engine_chat( engine: engine, request: request.chomp, system_role_content: system_role_content, spinner: spinner ) end ensure d = Thread.current[:pwn_reflect_depth].to_i - 1 if d.positive? Thread.current[:pwn_reflect_depth] = d else Thread.current[:pwn_reflect_depth] = nil end end end response rescue StandardError => e raise e end |