swarm_sdk 2.7.13 → 3.0.0.alpha1
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/lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb +43 -22
- data/lib/swarm_sdk/ruby_llm_patches/init.rb +6 -0
- data/lib/swarm_sdk/ruby_llm_patches/mcp_ssl_patch.rb +144 -0
- data/lib/swarm_sdk/ruby_llm_patches/tool_concurrency_patch.rb +3 -4
- data/lib/swarm_sdk/v3/agent.rb +1165 -0
- data/lib/swarm_sdk/v3/agent_builder.rb +533 -0
- data/lib/swarm_sdk/v3/agent_definition.rb +330 -0
- data/lib/swarm_sdk/v3/configuration.rb +490 -0
- data/lib/swarm_sdk/v3/debug_log.rb +86 -0
- data/lib/swarm_sdk/v3/event_stream.rb +130 -0
- data/lib/swarm_sdk/v3/hooks/context.rb +112 -0
- data/lib/swarm_sdk/v3/hooks/result.rb +115 -0
- data/lib/swarm_sdk/v3/hooks/runner.rb +128 -0
- data/lib/swarm_sdk/v3/mcp/connector.rb +183 -0
- data/lib/swarm_sdk/v3/mcp/mcp_error.rb +15 -0
- data/lib/swarm_sdk/v3/mcp/server_definition.rb +125 -0
- data/lib/swarm_sdk/v3/mcp/ssl_http_transport.rb +103 -0
- data/lib/swarm_sdk/v3/mcp/stdio_transport.rb +135 -0
- data/lib/swarm_sdk/v3/mcp/tool_proxy.rb +53 -0
- data/lib/swarm_sdk/v3/memory/adapters/base.rb +297 -0
- data/lib/swarm_sdk/v3/memory/adapters/faiss_support.rb +194 -0
- data/lib/swarm_sdk/v3/memory/adapters/filesystem_adapter.rb +212 -0
- data/lib/swarm_sdk/v3/memory/adapters/sqlite_adapter.rb +507 -0
- data/lib/swarm_sdk/v3/memory/adapters/vector_utils.rb +88 -0
- data/lib/swarm_sdk/v3/memory/card.rb +206 -0
- data/lib/swarm_sdk/v3/memory/cluster.rb +146 -0
- data/lib/swarm_sdk/v3/memory/compressor.rb +496 -0
- data/lib/swarm_sdk/v3/memory/consolidator.rb +427 -0
- data/lib/swarm_sdk/v3/memory/context_builder.rb +339 -0
- data/lib/swarm_sdk/v3/memory/edge.rb +105 -0
- data/lib/swarm_sdk/v3/memory/embedder.rb +185 -0
- data/lib/swarm_sdk/v3/memory/exposure_tracker.rb +104 -0
- data/lib/swarm_sdk/v3/memory/ingestion_pipeline.rb +394 -0
- data/lib/swarm_sdk/v3/memory/retriever.rb +289 -0
- data/lib/swarm_sdk/v3/memory/store.rb +489 -0
- data/lib/swarm_sdk/v3/skills/loader.rb +147 -0
- data/lib/swarm_sdk/v3/skills/manifest.rb +45 -0
- data/lib/swarm_sdk/v3/sub_task_agent.rb +248 -0
- data/lib/swarm_sdk/v3/tools/base.rb +80 -0
- data/lib/swarm_sdk/v3/tools/bash.rb +174 -0
- data/lib/swarm_sdk/v3/tools/clock.rb +32 -0
- data/lib/swarm_sdk/v3/tools/edit.rb +111 -0
- data/lib/swarm_sdk/v3/tools/glob.rb +96 -0
- data/lib/swarm_sdk/v3/tools/grep.rb +200 -0
- data/lib/swarm_sdk/v3/tools/message_teammate.rb +15 -0
- data/lib/swarm_sdk/v3/tools/message_user.rb +15 -0
- data/lib/swarm_sdk/v3/tools/read.rb +181 -0
- data/lib/swarm_sdk/v3/tools/read_tracker.rb +40 -0
- data/lib/swarm_sdk/v3/tools/registry.rb +208 -0
- data/lib/swarm_sdk/v3/tools/sub_task.rb +183 -0
- data/lib/swarm_sdk/v3/tools/think.rb +88 -0
- data/lib/swarm_sdk/v3/tools/write.rb +87 -0
- data/lib/swarm_sdk/v3.rb +145 -0
- metadata +84 -148
- data/lib/swarm_sdk/agent/RETRY_LOGIC.md +0 -175
- data/lib/swarm_sdk/agent/builder.rb +0 -680
- data/lib/swarm_sdk/agent/chat.rb +0 -1432
- data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +0 -375
- data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +0 -204
- data/lib/swarm_sdk/agent/chat_helpers/hook_integration.rb +0 -480
- data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +0 -85
- data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +0 -290
- data/lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb +0 -116
- data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +0 -83
- data/lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb +0 -134
- data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +0 -79
- data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +0 -146
- data/lib/swarm_sdk/agent/context.rb +0 -115
- data/lib/swarm_sdk/agent/context_manager.rb +0 -315
- data/lib/swarm_sdk/agent/definition.rb +0 -581
- data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +0 -226
- data/lib/swarm_sdk/agent/system_prompt_builder.rb +0 -161
- data/lib/swarm_sdk/agent/tool_registry.rb +0 -189
- data/lib/swarm_sdk/agent_registry.rb +0 -146
- data/lib/swarm_sdk/builders/base_builder.rb +0 -553
- data/lib/swarm_sdk/claude_code_agent_adapter.rb +0 -205
- data/lib/swarm_sdk/concerns/cleanupable.rb +0 -39
- data/lib/swarm_sdk/concerns/snapshotable.rb +0 -67
- data/lib/swarm_sdk/concerns/validatable.rb +0 -55
- data/lib/swarm_sdk/config.rb +0 -367
- data/lib/swarm_sdk/configuration/parser.rb +0 -397
- data/lib/swarm_sdk/configuration/translator.rb +0 -283
- data/lib/swarm_sdk/configuration.rb +0 -165
- data/lib/swarm_sdk/context_compactor/metrics.rb +0 -147
- data/lib/swarm_sdk/context_compactor/token_counter.rb +0 -102
- data/lib/swarm_sdk/context_compactor.rb +0 -335
- data/lib/swarm_sdk/context_management/builder.rb +0 -128
- data/lib/swarm_sdk/context_management/context.rb +0 -328
- data/lib/swarm_sdk/custom_tool_registry.rb +0 -226
- data/lib/swarm_sdk/defaults.rb +0 -251
- data/lib/swarm_sdk/events_to_messages.rb +0 -199
- data/lib/swarm_sdk/hooks/adapter.rb +0 -359
- data/lib/swarm_sdk/hooks/context.rb +0 -197
- data/lib/swarm_sdk/hooks/definition.rb +0 -80
- data/lib/swarm_sdk/hooks/error.rb +0 -29
- data/lib/swarm_sdk/hooks/executor.rb +0 -146
- data/lib/swarm_sdk/hooks/registry.rb +0 -147
- data/lib/swarm_sdk/hooks/result.rb +0 -150
- data/lib/swarm_sdk/hooks/shell_executor.rb +0 -256
- data/lib/swarm_sdk/hooks/tool_call.rb +0 -35
- data/lib/swarm_sdk/hooks/tool_result.rb +0 -62
- data/lib/swarm_sdk/log_collector.rb +0 -227
- data/lib/swarm_sdk/log_stream.rb +0 -127
- data/lib/swarm_sdk/markdown_parser.rb +0 -75
- data/lib/swarm_sdk/model_aliases.json +0 -8
- data/lib/swarm_sdk/models.json +0 -44002
- data/lib/swarm_sdk/models.rb +0 -161
- data/lib/swarm_sdk/node_context.rb +0 -245
- data/lib/swarm_sdk/observer/builder.rb +0 -81
- data/lib/swarm_sdk/observer/config.rb +0 -45
- data/lib/swarm_sdk/observer/manager.rb +0 -236
- data/lib/swarm_sdk/patterns/agent_observer.rb +0 -160
- data/lib/swarm_sdk/permissions/config.rb +0 -239
- data/lib/swarm_sdk/permissions/error_formatter.rb +0 -121
- data/lib/swarm_sdk/permissions/path_matcher.rb +0 -35
- data/lib/swarm_sdk/permissions/validator.rb +0 -173
- data/lib/swarm_sdk/permissions_builder.rb +0 -122
- data/lib/swarm_sdk/plugin.rb +0 -309
- data/lib/swarm_sdk/plugin_registry.rb +0 -101
- data/lib/swarm_sdk/proc_helpers.rb +0 -53
- data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +0 -117
- data/lib/swarm_sdk/restore_result.rb +0 -65
- data/lib/swarm_sdk/result.rb +0 -212
- data/lib/swarm_sdk/snapshot.rb +0 -156
- data/lib/swarm_sdk/snapshot_from_events.rb +0 -397
- data/lib/swarm_sdk/state_restorer.rb +0 -476
- data/lib/swarm_sdk/state_snapshot.rb +0 -334
- data/lib/swarm_sdk/swarm/agent_initializer.rb +0 -648
- data/lib/swarm_sdk/swarm/all_agents_builder.rb +0 -195
- data/lib/swarm_sdk/swarm/builder.rb +0 -256
- data/lib/swarm_sdk/swarm/executor.rb +0 -290
- data/lib/swarm_sdk/swarm/hook_triggers.rb +0 -151
- data/lib/swarm_sdk/swarm/lazy_delegate_chat.rb +0 -372
- data/lib/swarm_sdk/swarm/logging_callbacks.rb +0 -360
- data/lib/swarm_sdk/swarm/mcp_configurator.rb +0 -270
- data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +0 -67
- data/lib/swarm_sdk/swarm/tool_configurator.rb +0 -392
- data/lib/swarm_sdk/swarm.rb +0 -843
- data/lib/swarm_sdk/swarm_loader.rb +0 -145
- data/lib/swarm_sdk/swarm_registry.rb +0 -136
- data/lib/swarm_sdk/tools/base.rb +0 -63
- data/lib/swarm_sdk/tools/bash.rb +0 -280
- data/lib/swarm_sdk/tools/clock.rb +0 -46
- data/lib/swarm_sdk/tools/delegate.rb +0 -389
- data/lib/swarm_sdk/tools/document_converters/base_converter.rb +0 -83
- data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +0 -99
- data/lib/swarm_sdk/tools/document_converters/html_converter.rb +0 -101
- data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +0 -78
- data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +0 -194
- data/lib/swarm_sdk/tools/edit.rb +0 -145
- data/lib/swarm_sdk/tools/glob.rb +0 -166
- data/lib/swarm_sdk/tools/grep.rb +0 -235
- data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +0 -43
- data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +0 -167
- data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +0 -65
- data/lib/swarm_sdk/tools/mcp_tool_stub.rb +0 -198
- data/lib/swarm_sdk/tools/multi_edit.rb +0 -236
- data/lib/swarm_sdk/tools/path_resolver.rb +0 -92
- data/lib/swarm_sdk/tools/read.rb +0 -261
- data/lib/swarm_sdk/tools/registry.rb +0 -205
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +0 -117
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +0 -97
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +0 -108
- data/lib/swarm_sdk/tools/stores/read_tracker.rb +0 -96
- data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +0 -273
- data/lib/swarm_sdk/tools/stores/storage.rb +0 -142
- data/lib/swarm_sdk/tools/stores/todo_manager.rb +0 -65
- data/lib/swarm_sdk/tools/think.rb +0 -100
- data/lib/swarm_sdk/tools/todo_write.rb +0 -237
- data/lib/swarm_sdk/tools/web_fetch.rb +0 -264
- data/lib/swarm_sdk/tools/write.rb +0 -112
- data/lib/swarm_sdk/transcript_builder.rb +0 -278
- data/lib/swarm_sdk/utils.rb +0 -68
- data/lib/swarm_sdk/validation_result.rb +0 -33
- data/lib/swarm_sdk/version.rb +0 -5
- data/lib/swarm_sdk/workflow/agent_config.rb +0 -95
- data/lib/swarm_sdk/workflow/builder.rb +0 -227
- data/lib/swarm_sdk/workflow/executor.rb +0 -497
- data/lib/swarm_sdk/workflow/node_builder.rb +0 -593
- data/lib/swarm_sdk/workflow/transformer_executor.rb +0 -250
- data/lib/swarm_sdk/workflow.rb +0 -589
- data/lib/swarm_sdk.rb +0 -718
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 373c4df61931acf2a3ed260a6686068dc918f9d3ad6f3eea746f81a38711e2b5
|
|
4
|
+
data.tar.gz: 2b5414dd35362e4e58616092717b47b2207dcf54a886c10e74f5408f07686192
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 46a0bba9e559d4acc92dbb5bf68776471bf2409a2aa0cee9b3ed458e0d9028b24b69534b6963a9a1b57de23ff305c9d69c7a927828f80de4de7750561311bb4f
|
|
7
|
+
data.tar.gz: add457e2f8a04cca43f0fd9f169207695cad562a7f7c0b98a217a002560d335e693cca5ef0a39ad0438a7d0ff818246f97d43a0155d103f9d3944e73cb9e3027
|
|
@@ -63,6 +63,7 @@ module RubyLLM
|
|
|
63
63
|
# Initialize around hooks
|
|
64
64
|
@around_tool_execution_hook = nil
|
|
65
65
|
@around_llm_request_hook = nil
|
|
66
|
+
@after_tool_calls_hook = nil
|
|
66
67
|
|
|
67
68
|
# Keep @on for backward compatibility (read-only)
|
|
68
69
|
@on = nil
|
|
@@ -130,6 +131,19 @@ module RubyLLM
|
|
|
130
131
|
self
|
|
131
132
|
end
|
|
132
133
|
|
|
134
|
+
# Sets a hook that fires once per tool-call round, after all tool
|
|
135
|
+
# results are committed to chat history and before the next LLM call
|
|
136
|
+
#
|
|
137
|
+
# Skipped when a tool returns {Tool::Halt} — pending work stays
|
|
138
|
+
# queued for the next {#ask} call.
|
|
139
|
+
#
|
|
140
|
+
# @yield Block called after tool results are added to history
|
|
141
|
+
# @return [self] for chaining
|
|
142
|
+
def after_tool_calls(&block)
|
|
143
|
+
@after_tool_calls_hook = block
|
|
144
|
+
self
|
|
145
|
+
end
|
|
146
|
+
|
|
133
147
|
# Clears all callbacks for the specified event, or all events if none specified
|
|
134
148
|
def clear_callbacks(event = nil)
|
|
135
149
|
@callback_monitor.synchronize do
|
|
@@ -153,30 +167,36 @@ module RubyLLM
|
|
|
153
167
|
end
|
|
154
168
|
end
|
|
155
169
|
|
|
156
|
-
# Override complete to use emit() and support around_llm_request hook
|
|
157
|
-
#
|
|
170
|
+
# Override complete to use emit() and support around_llm_request hook.
|
|
171
|
+
# Uses a trampoline loop instead of mutual recursion with handle_tool_calls
|
|
172
|
+
# to avoid stack growth during multi-round tool-call conversations.
|
|
158
173
|
def complete(&block)
|
|
159
|
-
|
|
160
|
-
|
|
174
|
+
loop do
|
|
175
|
+
response = execute_llm_request(&block)
|
|
161
176
|
|
|
162
|
-
|
|
177
|
+
emit(:new_message) unless block_given?
|
|
163
178
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
179
|
+
if @schema && response.content.is_a?(String)
|
|
180
|
+
begin
|
|
181
|
+
response.content = JSON.parse(response.content)
|
|
182
|
+
rescue JSON::ParserError
|
|
183
|
+
# If parsing fails, keep content as string
|
|
184
|
+
end
|
|
169
185
|
end
|
|
170
|
-
end
|
|
171
186
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
187
|
+
add_message(response)
|
|
188
|
+
emit(:end_message, response)
|
|
189
|
+
|
|
190
|
+
if response.tool_call?
|
|
191
|
+
halt_result = handle_tool_calls(response, &block)
|
|
192
|
+
return halt_result if halt_result
|
|
193
|
+
|
|
194
|
+
@after_tool_calls_hook&.call
|
|
195
|
+
|
|
196
|
+
# Loop continues: next LLM call with zero stack growth
|
|
197
|
+
else
|
|
198
|
+
return response
|
|
199
|
+
end
|
|
180
200
|
end
|
|
181
201
|
end
|
|
182
202
|
|
|
@@ -238,8 +258,9 @@ module RubyLLM
|
|
|
238
258
|
end
|
|
239
259
|
end
|
|
240
260
|
|
|
241
|
-
#
|
|
242
|
-
|
|
261
|
+
# Execute tool calls and return halt result (or nil to continue the loop).
|
|
262
|
+
# Does NOT recurse back into complete() — the trampoline loop handles that.
|
|
263
|
+
def handle_tool_calls(response, &_block)
|
|
243
264
|
halt_result = nil
|
|
244
265
|
|
|
245
266
|
response.tool_calls.each_value do |tool_call|
|
|
@@ -259,7 +280,7 @@ module RubyLLM
|
|
|
259
280
|
halt_result = result if result.is_a?(Tool::Halt)
|
|
260
281
|
end
|
|
261
282
|
|
|
262
|
-
halt_result
|
|
283
|
+
halt_result
|
|
263
284
|
end
|
|
264
285
|
|
|
265
286
|
# Execute tool with around_tool_execution hook if set
|
|
@@ -39,3 +39,9 @@ require_relative "message_management_patch"
|
|
|
39
39
|
|
|
40
40
|
# 7. Responses API patch (depends on configuration, uses error classes)
|
|
41
41
|
require_relative "responses_api_patch"
|
|
42
|
+
|
|
43
|
+
# 8. MCP SSL patch (configures SSL for HTTPX connections in ruby_llm-mcp)
|
|
44
|
+
# Only load if RubyLLM::MCP is available
|
|
45
|
+
if defined?(RubyLLM::MCP)
|
|
46
|
+
require_relative "mcp_ssl_patch"
|
|
47
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Patches ruby_llm-mcp HTTPX connections to configure SSL verification
|
|
4
|
+
#
|
|
5
|
+
# OpenSSL 3.6 enforces CRL (Certificate Revocation List) checking by default.
|
|
6
|
+
# Most certificates don't provide accessible CRL endpoints (industry moved to OCSP),
|
|
7
|
+
# which breaks HTTPS MCP connections with:
|
|
8
|
+
# "certificate verify failed (unable to get certificate CRL)"
|
|
9
|
+
#
|
|
10
|
+
# This patch injects SSL options into all 5 HTTPX connection creation paths:
|
|
11
|
+
#
|
|
12
|
+
# Via HTTPClient.build_connection (paths 1-3):
|
|
13
|
+
# 1. StreamableHTTP#create_connection
|
|
14
|
+
# 2. StreamableHTTP#create_connection_with_streaming_callbacks
|
|
15
|
+
# 3. SSE#send_request
|
|
16
|
+
#
|
|
17
|
+
# Direct HTTPX.plugin calls (paths 4-5):
|
|
18
|
+
# 4. StreamableHTTP#create_connection_with_sse_callbacks
|
|
19
|
+
# 5. SSE#create_sse_client
|
|
20
|
+
#
|
|
21
|
+
# Default: VERIFY_PEER (validates cert chain without CRL checking)
|
|
22
|
+
# Configurable: VERIFY_NONE for local development via SwarmSDK.config.mcp_ssl_verify
|
|
23
|
+
|
|
24
|
+
require "openssl"
|
|
25
|
+
|
|
26
|
+
module SwarmSDK
|
|
27
|
+
# Module-level SSL configuration for MCP HTTPX connections
|
|
28
|
+
#
|
|
29
|
+
# Set ssl_options before creating MCP clients. The patched HTTPX methods
|
|
30
|
+
# read from this accessor to configure SSL on every connection.
|
|
31
|
+
#
|
|
32
|
+
# @example Default (validates cert chain, skips CRL)
|
|
33
|
+
# McpSslPatch.ssl_options #=> { verify_mode: OpenSSL::SSL::VERIFY_PEER }
|
|
34
|
+
#
|
|
35
|
+
# @example Disable SSL verification (local dev only)
|
|
36
|
+
# McpSslPatch.ssl_options = { verify_mode: OpenSSL::SSL::VERIFY_NONE }
|
|
37
|
+
module McpSslPatch
|
|
38
|
+
@ssl_options = { verify_mode: OpenSSL::SSL::VERIFY_PEER }
|
|
39
|
+
|
|
40
|
+
class << self
|
|
41
|
+
# @return [Hash] SSL options hash passed to HTTPX .with(ssl: ...)
|
|
42
|
+
attr_accessor :ssl_options
|
|
43
|
+
|
|
44
|
+
# Clear the thread-local HTTPX connection cache
|
|
45
|
+
#
|
|
46
|
+
# Must be called after changing ssl_options so that HTTPClient.build_connection
|
|
47
|
+
# runs again with the updated options.
|
|
48
|
+
#
|
|
49
|
+
# @return [void]
|
|
50
|
+
def reset_connection!
|
|
51
|
+
Thread.current[:ruby_llm_mcp_client_connection] = nil
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Patch 1: HTTPClient.build_connection
|
|
58
|
+
#
|
|
59
|
+
# Covers paths 1-3: StreamableHTTP#create_connection,
|
|
60
|
+
# StreamableHTTP#create_connection_with_streaming_callbacks, SSE#send_request
|
|
61
|
+
#
|
|
62
|
+
# These all chain from HTTPClient.connection which calls build_connection.
|
|
63
|
+
module RubyLLM
|
|
64
|
+
module MCP
|
|
65
|
+
module Transports
|
|
66
|
+
module Support
|
|
67
|
+
class HTTPClient
|
|
68
|
+
class << self
|
|
69
|
+
def build_connection
|
|
70
|
+
HTTPX.with(
|
|
71
|
+
pool_options: {
|
|
72
|
+
max_connections: RubyLLM::MCP.config.max_connections,
|
|
73
|
+
pool_timeout: RubyLLM::MCP.config.pool_timeout,
|
|
74
|
+
},
|
|
75
|
+
ssl: SwarmSDK::McpSslPatch.ssl_options,
|
|
76
|
+
)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Patch 2: StreamableHTTP#create_connection_with_sse_callbacks
|
|
86
|
+
#
|
|
87
|
+
# This method calls HTTPX.plugin(:callbacks) directly, bypassing HTTPClient.
|
|
88
|
+
# Merges SSL options with ALPN protocol when version is :http1.
|
|
89
|
+
module SwarmSDK
|
|
90
|
+
module McpSslPatch
|
|
91
|
+
module StreamableHttpSslPatch
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
def create_connection_with_sse_callbacks(options, headers)
|
|
95
|
+
client = HTTPX.plugin(:callbacks)
|
|
96
|
+
client = add_on_response_body_chunk_callback(client, options)
|
|
97
|
+
|
|
98
|
+
ssl = SwarmSDK::McpSslPatch.ssl_options.dup
|
|
99
|
+
ssl[:alpn_protocols] = ["http/1.1"] if @version == :http1
|
|
100
|
+
|
|
101
|
+
client = client.with(
|
|
102
|
+
timeout: {
|
|
103
|
+
connect_timeout: 10,
|
|
104
|
+
read_timeout: @request_timeout / 1000,
|
|
105
|
+
write_timeout: @request_timeout / 1000,
|
|
106
|
+
operation_timeout: @request_timeout / 1000,
|
|
107
|
+
},
|
|
108
|
+
headers: headers,
|
|
109
|
+
ssl: ssl,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
register_client(client)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Patch 3: SSE#create_sse_client
|
|
119
|
+
#
|
|
120
|
+
# This method calls HTTPX.plugin(:stream) directly, bypassing HTTPClient.
|
|
121
|
+
# Merges SSL options with ALPN protocol when version is :http1.
|
|
122
|
+
module SwarmSDK
|
|
123
|
+
module McpSslPatch
|
|
124
|
+
module SseSslPatch
|
|
125
|
+
private
|
|
126
|
+
|
|
127
|
+
def create_sse_client
|
|
128
|
+
stream_headers = build_request_headers
|
|
129
|
+
|
|
130
|
+
ssl = SwarmSDK::McpSslPatch.ssl_options.dup
|
|
131
|
+
ssl[:alpn_protocols] = ["http/1.1"] if @version == :http1
|
|
132
|
+
|
|
133
|
+
HTTPX.plugin(:stream).with(
|
|
134
|
+
headers: stream_headers,
|
|
135
|
+
ssl: ssl,
|
|
136
|
+
)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Apply prepend patches for direct HTTPX.plugin calls
|
|
143
|
+
RubyLLM::MCP::Transports::StreamableHTTP.prepend(SwarmSDK::McpSslPatch::StreamableHttpSslPatch)
|
|
144
|
+
RubyLLM::MCP::Transports::SSE.prepend(SwarmSDK::McpSslPatch::SseSslPatch)
|
|
@@ -149,14 +149,13 @@ module RubyLLM
|
|
|
149
149
|
|
|
150
150
|
private
|
|
151
151
|
|
|
152
|
-
# Override handle_tool_calls to support concurrent execution
|
|
153
|
-
#
|
|
152
|
+
# Override handle_tool_calls to support concurrent execution.
|
|
153
|
+
# Returns halt result or nil — the trampoline loop in complete() handles the next iteration.
|
|
154
154
|
def handle_tool_calls(response, &block)
|
|
155
155
|
return super unless @tool_concurrency
|
|
156
156
|
|
|
157
157
|
tool_calls = response.tool_calls
|
|
158
|
-
|
|
159
|
-
halt_result || complete(&block)
|
|
158
|
+
execute_tools_concurrently(tool_calls)
|
|
160
159
|
end
|
|
161
160
|
|
|
162
161
|
def execute_tools_concurrently(tool_calls)
|