Class: Phronomy::Agent::ReactAgent
- Defined in:
- lib/phronomy/agent/react_agent.rb
Overview
ReAct pattern (Reasoning + Acting) agent. Repeats the LLM <-> Tool loop until no more tool calls are made.
Instance Attribute Summary
Attributes included from Concerns::BeforeCompletion
Instance Method Summary collapse
-
#stream(input, messages: [], thread_id: nil, config: {}) {|Phronomy::Agent::StreamEvent| ... } ⇒ Hash
Streaming version of #invoke for the ReAct loop.
Methods inherited from Base
#_add_handoff_tool, #_handoff_tools, _on_compact_callback, _on_compaction_trigger_callback, _on_trim_callback, cache_instructions, context_overhead, #context_version_cache, context_window, instructions, #invoke, invoke_timeout, max_iterations, max_output_tokens, max_parallel_tools, model, on_compact, on_compaction_trigger, on_trim, provider, #run_as_child, static_knowledge, static_knowledge_chunks, static_knowledge_refresh!, static_knowledge_sources, temperature, tool_aliases, tools
Methods included from Concerns::Suspendable
#on_approval_required, #resume
Methods included from Concerns::BeforeCompletion
Methods included from Concerns::Guardrailable
#add_input_guardrail, #add_output_guardrail
Methods included from Concerns::Retryable
Methods included from Runnable
Instance Method Details
#stream(input, messages: [], thread_id: nil, config: {}) {|Phronomy::Agent::StreamEvent| ... } ⇒ Hash
Streaming version of #invoke for the ReAct loop. Yields StreamEvent events while the LLM-tool loop runs.
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 |
# File 'lib/phronomy/agent/react_agent.rb', line 65 def stream(input, messages: [], thread_id: nil, config: {}, &block) return invoke(input, messages: , thread_id: thread_id, config: config) unless block = {} [:user_id] = config[:user_id] if config[:user_id] [:session_id] = config[:session_id] if config[:session_id] trace("agent.invoke", input: input, **) do |_span| run_input_guardrails!(input) max_iter = self.class.max_iterations = Array().dup user_asked = false total_usage = Phronomy::TokenUsage.zero iterations_exhausted = true max_iter.times do response = stream_step(, input, user_asked: user_asked, thread_id: thread_id, config: config, &block) user_asked = true = response[:messages] total_usage += response[:usage] if response[:done] iterations_exhausted = false break end end # Select the last assistant-produced content as the output, skipping # raw tool result messages (role: :tool) — same as the non-streaming path. output = .reverse.find { |m| m.content && !m.content.empty? && m.role != :tool }&.content run_output_guardrails!(output) result = {output: output, messages: , usage: total_usage, iterations_exhausted: iterations_exhausted} block.call(StreamEvent.new(type: :done, payload: result)) [result, total_usage] end rescue => e block&.call(StreamEvent.new(type: :error, payload: {error: e})) raise end |