swarm_sdk 2.4.6 → 2.5.0
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/agent/system_prompt_builder.rb +1 -1
- data/lib/swarm_sdk/custom_tool_registry.rb +226 -0
- data/lib/swarm_sdk/plugin.rb +2 -2
- data/lib/swarm_sdk/swarm/agent_initializer.rb +1 -1
- data/lib/swarm_sdk/swarm/tool_configurator.rb +16 -2
- data/lib/swarm_sdk/version.rb +1 -1
- data/lib/swarm_sdk.rb +143 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5043d994b9ec60ad756b1c088571886acec8e5225ebac60f55484b0004e8ff0a
|
|
4
|
+
data.tar.gz: 37ce390a6a458cde546be634388a436459c70db1de9cf3f86b19345c2a556846
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4c7964fa7d22f1b059fcadd5f2a8f963037018bed4fe57ae9f430ffa4f593275868ab44a83692e7706faf5fb2ac2e933b46922c393b3c684227d7facb46e98d7
|
|
7
|
+
data.tar.gz: 0f8fab5ebd7c97f6de61f12a0ed30af096e1130472691e0bd4ee66bcdc6e6bb7823a583a268ff56b4e01ecb91970217900f31bca40f47d69af1bb0698652e5ca
|
|
@@ -148,7 +148,7 @@ module SwarmSDK
|
|
|
148
148
|
contributions = []
|
|
149
149
|
|
|
150
150
|
PluginRegistry.all.each do |plugin|
|
|
151
|
-
next unless plugin.
|
|
151
|
+
next unless plugin.memory_configured?(@definition)
|
|
152
152
|
|
|
153
153
|
contribution = plugin.system_prompt_contribution(agent_definition: @definition, storage: nil)
|
|
154
154
|
contributions << contribution if contribution && !contribution.strip.empty?
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "delegate"
|
|
4
|
+
|
|
5
|
+
module SwarmSDK
|
|
6
|
+
# Registry for user-defined custom tools
|
|
7
|
+
#
|
|
8
|
+
# Provides a simple way to register custom tools without creating a full plugin.
|
|
9
|
+
# Custom tools are registered globally and available to all agents that request them.
|
|
10
|
+
#
|
|
11
|
+
# ## When to Use Custom Tools vs Plugins
|
|
12
|
+
#
|
|
13
|
+
# **Use Custom Tools when:**
|
|
14
|
+
# - You have simple, stateless tools
|
|
15
|
+
# - Tools don't need persistent storage
|
|
16
|
+
# - Tools don't need lifecycle hooks
|
|
17
|
+
# - Tools don't need system prompt contributions
|
|
18
|
+
#
|
|
19
|
+
# **Use Plugins when:**
|
|
20
|
+
# - Tools need persistent storage per agent
|
|
21
|
+
# - Tools need lifecycle hooks (on_agent_initialized, on_user_message, etc.)
|
|
22
|
+
# - Tools need to contribute to system prompts
|
|
23
|
+
# - You have a suite of related tools that share configuration
|
|
24
|
+
#
|
|
25
|
+
# @example Register a simple tool
|
|
26
|
+
# class WeatherTool < RubyLLM::Tool
|
|
27
|
+
# description "Get weather for a city"
|
|
28
|
+
# param :city, type: "string", required: true
|
|
29
|
+
#
|
|
30
|
+
# def execute(city:)
|
|
31
|
+
# "Weather in #{city}: Sunny"
|
|
32
|
+
# end
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# SwarmSDK.register_tool(WeatherTool)
|
|
36
|
+
#
|
|
37
|
+
# @example Register with explicit name
|
|
38
|
+
# SwarmSDK.register_tool(:Weather, WeatherTool)
|
|
39
|
+
#
|
|
40
|
+
# @example Tool with creation requirements
|
|
41
|
+
# class AgentAwareTool < RubyLLM::Tool
|
|
42
|
+
# def self.creation_requirements
|
|
43
|
+
# [:agent_name, :directory]
|
|
44
|
+
# end
|
|
45
|
+
#
|
|
46
|
+
# def initialize(agent_name:, directory:)
|
|
47
|
+
# super()
|
|
48
|
+
# @agent_name = agent_name
|
|
49
|
+
# @directory = directory
|
|
50
|
+
# end
|
|
51
|
+
#
|
|
52
|
+
# def execute
|
|
53
|
+
# "Agent: #{@agent_name}, Dir: #{@directory}"
|
|
54
|
+
# end
|
|
55
|
+
# end
|
|
56
|
+
#
|
|
57
|
+
# SwarmSDK.register_tool(AgentAwareTool)
|
|
58
|
+
#
|
|
59
|
+
module CustomToolRegistry
|
|
60
|
+
# Wrapper that overrides the tool's name to match the registered name
|
|
61
|
+
#
|
|
62
|
+
# This ensures that when a user registers a tool with a specific name,
|
|
63
|
+
# that name is what gets used for tool lookup (has_tool?) and LLM tool calls.
|
|
64
|
+
class NamedToolWrapper < SimpleDelegator
|
|
65
|
+
def initialize(tool, registered_name)
|
|
66
|
+
super(tool)
|
|
67
|
+
@registered_name = registered_name.to_s
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Override name to return the registered name
|
|
71
|
+
def name
|
|
72
|
+
@registered_name
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
@tools = {}
|
|
77
|
+
|
|
78
|
+
class << self
|
|
79
|
+
# Register a custom tool
|
|
80
|
+
#
|
|
81
|
+
# @param name [Symbol] Tool name
|
|
82
|
+
# @param tool_class [Class] Tool class (must be a RubyLLM::Tool subclass)
|
|
83
|
+
# @raise [ArgumentError] If tool_class is not a RubyLLM::Tool subclass
|
|
84
|
+
# @raise [ArgumentError] If a tool with the same name is already registered
|
|
85
|
+
# @return [void]
|
|
86
|
+
def register(name, tool_class)
|
|
87
|
+
name = name.to_sym
|
|
88
|
+
|
|
89
|
+
unless tool_class.is_a?(Class) && tool_class < RubyLLM::Tool
|
|
90
|
+
raise ArgumentError, "Tool class must inherit from RubyLLM::Tool"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
if @tools.key?(name)
|
|
94
|
+
raise ArgumentError, "Custom tool '#{name}' is already registered"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
if PluginRegistry.plugin_tool?(name)
|
|
98
|
+
raise ArgumentError, "Tool '#{name}' is already provided by a plugin"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
if Tools::Registry.exists?(name)
|
|
102
|
+
raise ArgumentError, "Tool '#{name}' is a built-in tool and cannot be overridden"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
@tools[name] = tool_class
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Check if a custom tool is registered
|
|
109
|
+
#
|
|
110
|
+
# @param name [Symbol, String] Tool name
|
|
111
|
+
# @return [Boolean]
|
|
112
|
+
def registered?(name)
|
|
113
|
+
@tools.key?(name.to_sym)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Get a registered tool class
|
|
117
|
+
#
|
|
118
|
+
# @param name [Symbol, String] Tool name
|
|
119
|
+
# @return [Class, nil] Tool class or nil if not found
|
|
120
|
+
def get(name)
|
|
121
|
+
@tools[name.to_sym]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Get all registered custom tool names
|
|
125
|
+
#
|
|
126
|
+
# @return [Array<Symbol>]
|
|
127
|
+
def tool_names
|
|
128
|
+
@tools.keys
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Create a tool instance
|
|
132
|
+
#
|
|
133
|
+
# Uses the tool's `creation_requirements` class method (if defined) to determine
|
|
134
|
+
# what parameters to pass to the constructor. The created tool is wrapped with
|
|
135
|
+
# NamedToolWrapper to ensure the registered name is used for tool lookup.
|
|
136
|
+
#
|
|
137
|
+
# @param name [Symbol, String] Tool name
|
|
138
|
+
# @param context [Hash] Available context for tool creation
|
|
139
|
+
# @option context [Symbol] :agent_name Agent identifier
|
|
140
|
+
# @option context [String] :directory Agent's working directory
|
|
141
|
+
# @return [RubyLLM::Tool] Instantiated tool (wrapped with registered name)
|
|
142
|
+
# @raise [ConfigurationError] If tool is unknown or has unmet requirements
|
|
143
|
+
def create(name, context = {})
|
|
144
|
+
name_sym = name.to_sym
|
|
145
|
+
tool_class = @tools[name_sym]
|
|
146
|
+
|
|
147
|
+
raise ConfigurationError, "Unknown custom tool: #{name}" unless tool_class
|
|
148
|
+
|
|
149
|
+
# Create the tool instance
|
|
150
|
+
tool = if tool_class.respond_to?(:creation_requirements)
|
|
151
|
+
requirements = tool_class.creation_requirements
|
|
152
|
+
params = extract_params(requirements, context, name)
|
|
153
|
+
tool_class.new(**params)
|
|
154
|
+
else
|
|
155
|
+
# No requirements - simple instantiation
|
|
156
|
+
tool_class.new
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Wrap with NamedToolWrapper to ensure registered name is used
|
|
160
|
+
NamedToolWrapper.new(tool, name_sym)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Unregister a custom tool
|
|
164
|
+
#
|
|
165
|
+
# @param name [Symbol, String] Tool name
|
|
166
|
+
# @return [Class, nil] The unregistered tool class, or nil if not found
|
|
167
|
+
def unregister(name)
|
|
168
|
+
@tools.delete(name.to_sym)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Clear all registered custom tools
|
|
172
|
+
#
|
|
173
|
+
# Primarily useful for testing.
|
|
174
|
+
#
|
|
175
|
+
# @return [void]
|
|
176
|
+
def clear
|
|
177
|
+
@tools.clear
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Infer tool name from class name
|
|
181
|
+
#
|
|
182
|
+
# @param tool_class [Class] Tool class
|
|
183
|
+
# @return [Symbol] Inferred tool name
|
|
184
|
+
#
|
|
185
|
+
# @example
|
|
186
|
+
# infer_name(WeatherTool) #=> :Weather
|
|
187
|
+
# infer_name(MyApp::Tools::StockPrice) #=> :StockPrice
|
|
188
|
+
# infer_name(MyApp::Tools::StockPriceTool) #=> :StockPrice
|
|
189
|
+
def infer_name(tool_class)
|
|
190
|
+
# Get the class name without module prefix
|
|
191
|
+
class_name = tool_class.name.split("::").last
|
|
192
|
+
|
|
193
|
+
# Remove "Tool" suffix if present
|
|
194
|
+
name = class_name.sub(/Tool\z/, "")
|
|
195
|
+
|
|
196
|
+
name.to_sym
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
private
|
|
200
|
+
|
|
201
|
+
# Extract required parameters from context
|
|
202
|
+
#
|
|
203
|
+
# @param requirements [Array<Symbol>] Required parameter names
|
|
204
|
+
# @param context [Hash] Available context
|
|
205
|
+
# @param tool_name [Symbol] Tool name for error messages
|
|
206
|
+
# @return [Hash] Parameters to pass to tool constructor
|
|
207
|
+
# @raise [ConfigurationError] If required parameter is missing
|
|
208
|
+
def extract_params(requirements, context, tool_name)
|
|
209
|
+
params = {}
|
|
210
|
+
|
|
211
|
+
requirements.each do |req|
|
|
212
|
+
unless context.key?(req)
|
|
213
|
+
raise ConfigurationError,
|
|
214
|
+
"Custom tool '#{tool_name}' requires '#{req}' but it was not provided. " \
|
|
215
|
+
"Ensure the tool's `creation_requirements` only includes supported keys: " \
|
|
216
|
+
":agent_name, :directory"
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
params[req] = context[req]
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
params
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
data/lib/swarm_sdk/plugin.rb
CHANGED
|
@@ -139,11 +139,11 @@ module SwarmSDK
|
|
|
139
139
|
[]
|
|
140
140
|
end
|
|
141
141
|
|
|
142
|
-
#
|
|
142
|
+
# Check if memory is configured for this agent (optional)
|
|
143
143
|
#
|
|
144
144
|
# @param agent_definition [Agent::Definition] Agent definition
|
|
145
145
|
# @return [Boolean] True if storage should be created
|
|
146
|
-
def
|
|
146
|
+
def memory_configured?(agent_definition)
|
|
147
147
|
false
|
|
148
148
|
end
|
|
149
149
|
|
|
@@ -569,7 +569,7 @@ module SwarmSDK
|
|
|
569
569
|
PluginRegistry.all.each do |plugin|
|
|
570
570
|
@swarm.agent_definitions.each do |agent_name, agent_definition|
|
|
571
571
|
# Check if this plugin needs storage for this agent
|
|
572
|
-
next unless plugin.
|
|
572
|
+
next unless plugin.memory_configured?(agent_definition)
|
|
573
573
|
|
|
574
574
|
# Get plugin config for this agent
|
|
575
575
|
config = get_plugin_config(agent_definition, plugin.name)
|
|
@@ -60,6 +60,11 @@ module SwarmSDK
|
|
|
60
60
|
# Uses the Registry factory pattern to instantiate tools based on their
|
|
61
61
|
# declared requirements. This eliminates the need for a giant case statement.
|
|
62
62
|
#
|
|
63
|
+
# Tool lookup order:
|
|
64
|
+
# 1. Plugin tools (registered via SwarmSDK::PluginRegistry)
|
|
65
|
+
# 2. Custom tools (registered via SwarmSDK.register_tool)
|
|
66
|
+
# 3. Built-in tools (SwarmSDK::Tools::Registry)
|
|
67
|
+
#
|
|
63
68
|
# File tools and TodoWrite require agent context for tracking state.
|
|
64
69
|
# Scratchpad tools require shared scratchpad instance.
|
|
65
70
|
# Plugin tools are delegated to their respective plugins.
|
|
@@ -80,7 +85,16 @@ module SwarmSDK
|
|
|
80
85
|
return create_plugin_tool(tool_name_sym, agent_name, directory, chat, agent_definition)
|
|
81
86
|
end
|
|
82
87
|
|
|
83
|
-
#
|
|
88
|
+
# Check if tool is a custom registered tool
|
|
89
|
+
if CustomToolRegistry.registered?(tool_name_sym)
|
|
90
|
+
context = {
|
|
91
|
+
agent_name: agent_name,
|
|
92
|
+
directory: directory,
|
|
93
|
+
}
|
|
94
|
+
return CustomToolRegistry.create(tool_name_sym, context)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Use Registry factory pattern for built-in tools
|
|
84
98
|
context = {
|
|
85
99
|
agent_name: agent_name,
|
|
86
100
|
directory: directory,
|
|
@@ -267,7 +281,7 @@ module SwarmSDK
|
|
|
267
281
|
def register_plugin_tools(chat, agent_name, agent_definition, explicit_tool_names)
|
|
268
282
|
PluginRegistry.all.each do |plugin|
|
|
269
283
|
# Check if plugin has storage enabled for this agent
|
|
270
|
-
next unless plugin.
|
|
284
|
+
next unless plugin.memory_configured?(agent_definition)
|
|
271
285
|
|
|
272
286
|
# Register each tool provided by the plugin
|
|
273
287
|
plugin.tools.each do |tool_name|
|
data/lib/swarm_sdk/version.rb
CHANGED
data/lib/swarm_sdk.rb
CHANGED
|
@@ -162,6 +162,149 @@ module SwarmSDK
|
|
|
162
162
|
AgentRegistry.clear
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
+
# Register a custom tool for use in swarms
|
|
166
|
+
#
|
|
167
|
+
# Provides a simple way to add tools without creating a full plugin.
|
|
168
|
+
# Tools can be registered with an explicit name or the name can be
|
|
169
|
+
# inferred from the class name.
|
|
170
|
+
#
|
|
171
|
+
# Custom tools are available to any agent that includes them in their
|
|
172
|
+
# tools configuration, just like built-in tools.
|
|
173
|
+
#
|
|
174
|
+
# @overload register_tool(tool_class)
|
|
175
|
+
# Register a tool with name inferred from class name
|
|
176
|
+
# @param tool_class [Class] Tool class (must inherit from RubyLLM::Tool)
|
|
177
|
+
# @return [Symbol] The registered tool name
|
|
178
|
+
#
|
|
179
|
+
# @overload register_tool(name, tool_class)
|
|
180
|
+
# Register a tool with explicit name
|
|
181
|
+
# @param name [Symbol, String] Tool name
|
|
182
|
+
# @param tool_class [Class] Tool class (must inherit from RubyLLM::Tool)
|
|
183
|
+
# @return [Symbol] The registered tool name
|
|
184
|
+
#
|
|
185
|
+
# @raise [ArgumentError] If tool_class doesn't inherit from RubyLLM::Tool
|
|
186
|
+
# @raise [ArgumentError] If a tool with the same name is already registered
|
|
187
|
+
# @raise [ArgumentError] If the name conflicts with a built-in or plugin tool
|
|
188
|
+
#
|
|
189
|
+
# @example Register with inferred name
|
|
190
|
+
# class WeatherTool < RubyLLM::Tool
|
|
191
|
+
# description "Get weather for a city"
|
|
192
|
+
# param :city, type: "string", required: true
|
|
193
|
+
#
|
|
194
|
+
# def execute(city:)
|
|
195
|
+
# "Weather in #{city}: Sunny, 72°F"
|
|
196
|
+
# end
|
|
197
|
+
# end
|
|
198
|
+
#
|
|
199
|
+
# SwarmSDK.register_tool(WeatherTool) # Registers as :Weather
|
|
200
|
+
#
|
|
201
|
+
# @example Register with explicit name
|
|
202
|
+
# SwarmSDK.register_tool(:GetWeather, WeatherTool)
|
|
203
|
+
#
|
|
204
|
+
# @example Tool with agent context
|
|
205
|
+
# class ContextAwareTool < RubyLLM::Tool
|
|
206
|
+
# # Declare what context the tool needs
|
|
207
|
+
# def self.creation_requirements
|
|
208
|
+
# [:agent_name, :directory]
|
|
209
|
+
# end
|
|
210
|
+
#
|
|
211
|
+
# def initialize(agent_name:, directory:)
|
|
212
|
+
# super()
|
|
213
|
+
# @agent_name = agent_name
|
|
214
|
+
# @directory = directory
|
|
215
|
+
# end
|
|
216
|
+
#
|
|
217
|
+
# description "Shows agent context"
|
|
218
|
+
# def execute
|
|
219
|
+
# "Agent: #{@agent_name} in #{@directory}"
|
|
220
|
+
# end
|
|
221
|
+
# end
|
|
222
|
+
#
|
|
223
|
+
# SwarmSDK.register_tool(ContextAwareTool)
|
|
224
|
+
#
|
|
225
|
+
# @example Use registered tool in a swarm
|
|
226
|
+
# SwarmSDK.register_tool(WeatherTool)
|
|
227
|
+
#
|
|
228
|
+
# swarm = SwarmSDK.build do
|
|
229
|
+
# name "Weather Assistant"
|
|
230
|
+
# lead :assistant
|
|
231
|
+
#
|
|
232
|
+
# agent :assistant do
|
|
233
|
+
# model "claude-sonnet-4"
|
|
234
|
+
# description "Weather helper"
|
|
235
|
+
# tools :Weather, :Read # Custom + built-in tools
|
|
236
|
+
# end
|
|
237
|
+
# end
|
|
238
|
+
#
|
|
239
|
+
# @see CustomToolRegistry For the underlying registry
|
|
240
|
+
# @see Plugin For complex tool systems requiring storage or lifecycle hooks
|
|
241
|
+
def register_tool(name_or_class, tool_class = nil)
|
|
242
|
+
if tool_class.nil?
|
|
243
|
+
# Single argument: infer name from class
|
|
244
|
+
tool_class = name_or_class
|
|
245
|
+
name = CustomToolRegistry.infer_name(tool_class)
|
|
246
|
+
else
|
|
247
|
+
# Two arguments: explicit name
|
|
248
|
+
name = name_or_class.to_sym
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
CustomToolRegistry.register(name, tool_class)
|
|
252
|
+
name
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Check if a custom tool is registered
|
|
256
|
+
#
|
|
257
|
+
# @param name [Symbol, String] Tool name
|
|
258
|
+
# @return [Boolean] true if the tool is registered
|
|
259
|
+
#
|
|
260
|
+
# @example
|
|
261
|
+
# SwarmSDK.register_tool(WeatherTool)
|
|
262
|
+
# SwarmSDK.custom_tool_registered?(:Weather) #=> true
|
|
263
|
+
# SwarmSDK.custom_tool_registered?(:Unknown) #=> false
|
|
264
|
+
def custom_tool_registered?(name)
|
|
265
|
+
CustomToolRegistry.registered?(name)
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Get all registered custom tool names
|
|
269
|
+
#
|
|
270
|
+
# @return [Array<Symbol>] List of registered custom tool names
|
|
271
|
+
#
|
|
272
|
+
# @example
|
|
273
|
+
# SwarmSDK.register_tool(WeatherTool)
|
|
274
|
+
# SwarmSDK.register_tool(StockTool)
|
|
275
|
+
# SwarmSDK.custom_tools #=> [:Weather, :Stock]
|
|
276
|
+
def custom_tools
|
|
277
|
+
CustomToolRegistry.tool_names
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Unregister a custom tool
|
|
281
|
+
#
|
|
282
|
+
# @param name [Symbol, String] Tool name to unregister
|
|
283
|
+
# @return [Class, nil] The unregistered tool class, or nil if not found
|
|
284
|
+
#
|
|
285
|
+
# @example
|
|
286
|
+
# SwarmSDK.register_tool(WeatherTool)
|
|
287
|
+
# SwarmSDK.unregister_tool(:Weather)
|
|
288
|
+
# SwarmSDK.custom_tool_registered?(:Weather) #=> false
|
|
289
|
+
def unregister_tool(name)
|
|
290
|
+
CustomToolRegistry.unregister(name)
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Clear all registered custom tools
|
|
294
|
+
#
|
|
295
|
+
# Removes all custom tool registrations. Primarily useful for testing
|
|
296
|
+
# to ensure clean state between tests.
|
|
297
|
+
#
|
|
298
|
+
# @return [void]
|
|
299
|
+
#
|
|
300
|
+
# @example In test teardown
|
|
301
|
+
# def teardown
|
|
302
|
+
# SwarmSDK.clear_custom_tools!
|
|
303
|
+
# end
|
|
304
|
+
def clear_custom_tools!
|
|
305
|
+
CustomToolRegistry.clear
|
|
306
|
+
end
|
|
307
|
+
|
|
165
308
|
# Main entry point for DSL - builds simple multi-agent swarms
|
|
166
309
|
#
|
|
167
310
|
# @return [Swarm] Always returns a Swarm instance
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: swarm_sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paulo Arruda
|
|
@@ -154,6 +154,7 @@ files:
|
|
|
154
154
|
- lib/swarm_sdk/context_compactor/token_counter.rb
|
|
155
155
|
- lib/swarm_sdk/context_management/builder.rb
|
|
156
156
|
- lib/swarm_sdk/context_management/context.rb
|
|
157
|
+
- lib/swarm_sdk/custom_tool_registry.rb
|
|
157
158
|
- lib/swarm_sdk/defaults.rb
|
|
158
159
|
- lib/swarm_sdk/events_to_messages.rb
|
|
159
160
|
- lib/swarm_sdk/hooks/adapter.rb
|