Module: RubyLLM::Chat::MultiSubscriberCallbacks
- Included in:
- RubyLLM::Chat
- Defined in:
- lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb
Overview
Module to prepend for multi-subscriber callbacks
Instance Method Summary collapse
-
#after_tool_calls { ... } ⇒ self
Sets a hook that fires once per tool-call round, after all tool results are committed to chat history and before the next LLM call.
-
#around_llm_request {|Array<Message>, Proc| ... } ⇒ self
Sets a hook to wrap LLM API requests with custom behavior.
-
#around_tool_execution {|ToolCall, Tool, Proc| ... } ⇒ self
Sets a hook to wrap tool execution with custom behavior.
-
#callback_count(event = nil) ⇒ Object
Returns the number of callbacks registered for the specified event.
-
#clear_callbacks(event = nil) ⇒ Object
Clears all callbacks for the specified event, or all events if none specified.
-
#complete(&block) ⇒ Object
Override complete to use emit() and support around_llm_request hook.
- #initialize(**kwargs) ⇒ Object
- #on_end_message(&block) ⇒ Object
-
#on_new_message(&block) ⇒ Object
Override callback registration methods to support multi-subscriber.
- #on_tool_call(&block) ⇒ Object
- #on_tool_result(&block) ⇒ Object
-
#once(event, tag: nil, &block) ⇒ Object
Subscribe to an event that automatically unsubscribes after firing once.
-
#subscribe(event, tag: nil, &block) ⇒ Object
Subscribe to an event with the given block Returns a Subscription that can be used to unsubscribe.
Instance Method Details
#after_tool_calls { ... } ⇒ self
Sets a hook that fires once per tool-call round, after all tool results are committed to chat history and before the next LLM call
Skipped when a tool returns Tool::Halt — pending work stays queued for the next #ask call.
142 143 144 145 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 142 def after_tool_calls(&block) @after_tool_calls_hook = block self end |
#around_llm_request {|Array<Message>, Proc| ... } ⇒ self
Sets a hook to wrap LLM API requests with custom behavior
129 130 131 132 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 129 def around_llm_request(&block) @around_llm_request_hook = block self end |
#around_tool_execution {|ToolCall, Tool, Proc| ... } ⇒ self
Sets a hook to wrap tool execution with custom behavior
120 121 122 123 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 120 def around_tool_execution(&block) @around_tool_execution_hook = block self end |
#callback_count(event = nil) ⇒ Object
Returns the number of callbacks registered for the specified event
160 161 162 163 164 165 166 167 168 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 160 def callback_count(event = nil) @callback_monitor.synchronize do if event @callbacks[event]&.size || 0 else @callbacks.transform_values(&:size) end end end |
#clear_callbacks(event = nil) ⇒ Object
Clears all callbacks for the specified event, or all events if none specified
148 149 150 151 152 153 154 155 156 157 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 148 def clear_callbacks(event = nil) @callback_monitor.synchronize do if event @callbacks[event]&.clear else @callbacks.each_value(&:clear) end end self end |
#complete(&block) ⇒ Object
Override complete to use emit() and support around_llm_request hook. Uses a trampoline loop instead of mutual recursion with handle_tool_calls to avoid stack growth during multi-round tool-call conversations.
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 173 def complete(&block) loop do response = execute_llm_request(&block) emit(:new_message) unless block_given? if @schema && response.content.is_a?(String) begin response.content = JSON.parse(response.content) rescue JSON::ParserError # If parsing fails, keep content as string end end (response) emit(:end_message, response) if response.tool_call? halt_result = handle_tool_calls(response, &block) return halt_result if halt_result @after_tool_calls_hook&.call # Loop continues: next LLM call with zero stack growth else return response end end end |
#initialize(**kwargs) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 51 def initialize(**kwargs) super(**kwargs) # Replace single callback hash with multi-subscriber arrays @callbacks = { new_message: [], end_message: [], tool_call: [], tool_result: [], } @callback_monitor = Monitor.new # Initialize around hooks @around_tool_execution_hook = nil @around_llm_request_hook = nil @after_tool_calls_hook = nil # Keep @on for backward compatibility (read-only) @on = nil end |
#on_end_message(&block) ⇒ Object
101 102 103 104 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 101 def (&block) subscribe(:end_message, &block) self end |
#on_new_message(&block) ⇒ Object
Override callback registration methods to support multi-subscriber
96 97 98 99 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 96 def (&block) subscribe(:new_message, &block) self end |
#on_tool_call(&block) ⇒ Object
106 107 108 109 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 106 def on_tool_call(&block) subscribe(:tool_call, &block) self end |
#on_tool_result(&block) ⇒ Object
111 112 113 114 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 111 def on_tool_result(&block) subscribe(:tool_result, &block) self end |
#once(event, tag: nil, &block) ⇒ Object
Subscribe to an event that automatically unsubscribes after firing once
86 87 88 89 90 91 92 93 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 86 def once(event, tag: nil, &block) subscription = nil wrapper = lambda do |*args| subscription&.unsubscribe block.call(*args) end subscription = subscribe(event, tag: tag, &wrapper) end |
#subscribe(event, tag: nil, &block) ⇒ Object
Subscribe to an event with the given block Returns a Subscription that can be used to unsubscribe
74 75 76 77 78 79 80 81 82 83 |
# File 'lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb', line 74 def subscribe(event, tag: nil, &block) @callback_monitor.synchronize do unless @callbacks.key?(event) raise ArgumentError, "Unknown event: #{event}. Valid events: #{@callbacks.keys.join(", ")}" end @callbacks[event] << block Subscription.new(@callbacks[event], block, monitor: @callback_monitor, tag: tag) end end |