Class: Brute::Loop::AgentStream
- Inherits:
-
LLM::Stream
- Object
- LLM::Stream
- Brute::Loop::AgentStream
- Defined in:
- lib/brute/loop/agent_stream.rb
Overview
Bridges llm.rb’s streaming callbacks to the host application.
Text and reasoning chunks fire immediately as the LLM generates them. Tool calls are collected but NOT executed — execution is deferred to the agent loop after the stream completes. This ensures text is never concurrent with tool execution.
After the stream finishes, the agent loop reads pending_tools to dispatch all tool calls concurrently, then fires on_tool_call_start once with the full batch.
Instance Attribute Summary collapse
-
#on_question ⇒ Object
readonly
The on_question callback, needed by the agent loop to set thread/fiber-locals before tool execution.
-
#pending_tool_calls ⇒ Object
readonly
Tool call metadata recorded during streaming, used by ToolUseGuard when ctx.functions is empty (nil-choice bug in llm.rb).
-
#pending_tools ⇒ Object
readonly
Deferred tool/error pairs: [(LLM::Function, error_or_nil), …] The agent loop reads these after the stream completes.
Instance Method Summary collapse
-
#clear_pending_tool_calls! ⇒ Object
Clear only the tool call metadata (used by ToolUseGuard after it has consumed the data for synthetic message injection).
-
#clear_pending_tools! ⇒ Object
Clear the deferred execution queue after the agent loop has consumed and dispatched all tool calls.
-
#initialize(on_content: nil, on_reasoning: nil, on_question: nil) ⇒ AgentStream
constructor
A new instance of AgentStream.
- #on_content(text) ⇒ Object
- #on_reasoning_content(text) ⇒ Object
-
#on_tool_call(tool, error) ⇒ Object
Called by llm.rb per tool as it arrives during streaming.
Constructor Details
#initialize(on_content: nil, on_reasoning: nil, on_question: nil) ⇒ AgentStream
Returns a new instance of AgentStream.
28 29 30 31 32 33 34 |
# File 'lib/brute/loop/agent_stream.rb', line 28 def initialize(on_content: nil, on_reasoning: nil, on_question: nil) @on_content = on_content @on_reasoning = on_reasoning @on_question = on_question @pending_tool_calls = [] @pending_tools = [] end |
Instance Attribute Details
#on_question ⇒ Object (readonly)
The on_question callback, needed by the agent loop to set thread/fiber-locals before tool execution.
38 39 40 |
# File 'lib/brute/loop/agent_stream.rb', line 38 def on_question @on_question end |
#pending_tool_calls ⇒ Object (readonly)
Tool call metadata recorded during streaming, used by ToolUseGuard when ctx.functions is empty (nil-choice bug in llm.rb).
22 23 24 |
# File 'lib/brute/loop/agent_stream.rb', line 22 def pending_tool_calls @pending_tool_calls end |
#pending_tools ⇒ Object (readonly)
Deferred tool/error pairs: [(LLM::Function, error_or_nil), …] The agent loop reads these after the stream completes.
26 27 28 |
# File 'lib/brute/loop/agent_stream.rb', line 26 def pending_tools @pending_tools end |
Instance Method Details
#clear_pending_tool_calls! ⇒ Object
Clear only the tool call metadata (used by ToolUseGuard after it has consumed the data for synthetic message injection).
57 58 59 |
# File 'lib/brute/loop/agent_stream.rb', line 57 def clear_pending_tool_calls! @pending_tool_calls.clear end |
#clear_pending_tools! ⇒ Object
Clear the deferred execution queue after the agent loop has consumed and dispatched all tool calls.
63 64 65 |
# File 'lib/brute/loop/agent_stream.rb', line 63 def clear_pending_tools! @pending_tools.clear end |
#on_content(text) ⇒ Object
40 41 42 |
# File 'lib/brute/loop/agent_stream.rb', line 40 def on_content(text) @on_content&.call(text) end |
#on_reasoning_content(text) ⇒ Object
44 45 46 |
# File 'lib/brute/loop/agent_stream.rb', line 44 def on_reasoning_content(text) @on_reasoning&.call(text) end |
#on_tool_call(tool, error) ⇒ Object
Called by llm.rb per tool as it arrives during streaming. Records only — no execution, no threads, no queue pushes.
50 51 52 53 |
# File 'lib/brute/loop/agent_stream.rb', line 50 def on_tool_call(tool, error) @pending_tool_calls << { id: tool.id, name: tool.name, arguments: tool.arguments } @pending_tools << [tool, error] end |