swarm_sdk 2.0.2 → 2.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2cedd1197d0fea1e52b40531ecb6d6f030524436c3164c109bce37da1db883b
4
- data.tar.gz: ac77a97bd54374a9049de888e0dfc4a1b1c99d5a4fdc2c01fabe20e54a7cd83b
3
+ metadata.gz: 9aba64a75c41f9957bb3e11afbe0dd5a5fc6422793fda5d3fb829ac0042cbe18
4
+ data.tar.gz: 4f403fb7d107fa712a8b847775fea1140a03904cf066b8e848b914f4b3c573e3
5
5
  SHA512:
6
- metadata.gz: 9d1dfdd64d1247e15a3fea9ce56b0d28657e85a5f9d706d1a2ce9c72700226cf443dcdc691596710d2e948816a3fb5d93fe1520f3bc798df78a2b6a91e9a2085
7
- data.tar.gz: b54ae2918f3cb04eb2a49a80faecc2aac1a878cd14828cc3287705eae22ba4da09780c8e38a54c5d048cf4eb1fec75e523dc609192758f6ad60294467d68df01
6
+ metadata.gz: 204b9d889968b2d582557b06169d02828abd4c365b00e2a6551cc7f4c44a2ec7ae452a55d1e25b59fdc8a0b10c486c365cce2b2332d02f0d54b502ec6667af75
7
+ data.tar.gz: ae46da01755ef0c98b162c7c2be3c51ba8831dbbdd10301f937e0eed0260f9694b7514658d437e9d65d9cc58e06d7a877600ec29fd48eb773eec8514d74440b1
@@ -44,7 +44,7 @@ module SwarmSDK
44
44
  @headers = {}
45
45
  @timeout = nil
46
46
  @mcp_servers = []
47
- @include_default_tools = true
47
+ @disable_default_tools = nil # nil = include all default tools
48
48
  @bypass_permissions = false
49
49
  @coding_agent = nil # nil = not set (will default to false in Definition)
50
50
  @assume_model_exists = nil
@@ -124,9 +124,19 @@ module SwarmSDK
124
124
  @mcp_servers << server_config
125
125
  end
126
126
 
127
- # Set include_default_tools flag (deprecated - use tools method with include_default parameter)
128
- def include_default_tools(enabled)
129
- @include_default_tools = enabled
127
+ # Disable default tools
128
+ #
129
+ # @param value [Boolean, Array<Symbol>]
130
+ # - true: Disable ALL default tools
131
+ # - Array of symbols: Disable specific tools (e.g., [:Think, :TodoWrite])
132
+ #
133
+ # @example Disable all default tools
134
+ # disable_default_tools true
135
+ #
136
+ # @example Disable specific tools
137
+ # disable_default_tools [:Think, :TodoWrite]
138
+ def disable_default_tools(value)
139
+ @disable_default_tools = value
130
140
  end
131
141
 
132
142
  # Set bypass_permissions flag
@@ -188,7 +198,8 @@ module SwarmSDK
188
198
  def tools(*tool_names, include_default: true, replace: false)
189
199
  @tools = Set.new if replace
190
200
  @tools.merge(tool_names.map(&:to_sym))
191
- @include_default_tools = include_default
201
+ # When include_default is false, disable all default tools
202
+ @disable_default_tools = true unless include_default
192
203
  end
193
204
 
194
205
  # Add tools from all_agents configuration
@@ -342,7 +353,7 @@ module SwarmSDK
342
353
  agent_config[:headers] = @headers if @headers.any?
343
354
  agent_config[:timeout] = @timeout if @timeout
344
355
  agent_config[:mcp_servers] = @mcp_servers if @mcp_servers.any?
345
- agent_config[:include_default_tools] = @include_default_tools
356
+ agent_config[:disable_default_tools] = @disable_default_tools unless @disable_default_tools.nil?
346
357
  agent_config[:bypass_permissions] = @bypass_permissions
347
358
  agent_config[:coding_agent] = @coding_agent
348
359
  agent_config[:assume_model_exists] = @assume_model_exists unless @assume_model_exists.nil?
@@ -38,7 +38,7 @@ module SwarmSDK
38
38
  :parameters,
39
39
  :headers,
40
40
  :timeout,
41
- :include_default_tools,
41
+ :disable_default_tools,
42
42
  :coding_agent,
43
43
  :default_permissions,
44
44
  :agent_permissions,
@@ -77,8 +77,11 @@ module SwarmSDK
77
77
  # This prevents RubyLLM from trying to validate models in its registry
78
78
  @assume_model_exists = true
79
79
 
80
- # include_default_tools defaults to true if not specified
81
- @include_default_tools = config.key?(:include_default_tools) ? config[:include_default_tools] : true
80
+ # disable_default_tools can be:
81
+ # - nil/not set: include all default tools (default behavior)
82
+ # - true: disable ALL default tools
83
+ # - Array of symbols: disable specific tools (e.g., [:Think, :TodoWrite])
84
+ @disable_default_tools = config[:disable_default_tools]
82
85
 
83
86
  # coding_agent defaults to false if not specified
84
87
  # When true, includes the base system prompt for coding tasks
@@ -117,7 +120,7 @@ module SwarmSDK
117
120
  {
118
121
  name: @name,
119
122
  description: @description,
120
- model: @model,
123
+ model: SwarmSDK::Models.resolve_alias(@model), # Resolve model aliases
121
124
  directory: @directory,
122
125
  tools: @tools,
123
126
  delegates_to: @delegates_to,
@@ -130,7 +133,7 @@ module SwarmSDK
130
133
  headers: @headers,
131
134
  timeout: @timeout,
132
135
  bypass_permissions: @bypass_permissions,
133
- include_default_tools: @include_default_tools,
136
+ disable_default_tools: @disable_default_tools,
134
137
  coding_agent: @coding_agent,
135
138
  assume_model_exists: @assume_model_exists,
136
139
  max_concurrent_tools: @max_concurrent_tools,
@@ -224,7 +227,7 @@ module SwarmSDK
224
227
  else
225
228
  rendered_base
226
229
  end
227
- elsif @include_default_tools
230
+ elsif default_tools_enabled?
228
231
  # Non-coding agent: optionally include TODO/Scratchpad sections if default tools available
229
232
  non_coding_base = render_non_coding_base_prompt
230
233
 
@@ -242,6 +245,13 @@ module SwarmSDK
242
245
  end
243
246
  end
244
247
 
248
+ # Check if default tools are enabled (i.e., not disabled)
249
+ #
250
+ # @return [Boolean] True if default tools should be included
251
+ def default_tools_enabled?
252
+ @disable_default_tools != true
253
+ end
254
+
245
255
  def render_base_system_prompt
246
256
  cwd = @directory || Dir.pwd
247
257
  platform = RUBY_PLATFORM
@@ -116,6 +116,11 @@ module SwarmSDK
116
116
  return unless @config[:swarm]
117
117
 
118
118
  @all_agents_config = @config[:swarm][:all_agents] || {}
119
+
120
+ # Convert disable_default_tools array elements to symbols
121
+ if @all_agents_config[:disable_default_tools].is_a?(Array)
122
+ @all_agents_config[:disable_default_tools] = @all_agents_config[:disable_default_tools].map(&:to_sym)
123
+ end
119
124
  end
120
125
 
121
126
  def load_hooks_config
@@ -212,6 +217,9 @@ module SwarmSDK
212
217
  # Merge headers: all_agents.headers + agent.headers
213
218
  # Agent values override all_agents values for same keys
214
219
  merged[:headers] = (merged[:headers] || {}).merge(value || {})
220
+ when :disable_default_tools
221
+ # Convert array elements to symbols if it's an array
222
+ merged[key] = value.is_a?(Array) ? value.map(&:to_sym) : value
215
223
  else
216
224
  # For everything else (model, provider, base_url, timeout, coding_agent, etc.),
217
225
  # agent value overrides all_agents value
@@ -278,7 +278,7 @@ module SwarmSDK
278
278
  # Don't apply assume_model_exists from markdown - let DSL overrides or auto-enable handle it
279
279
  # builder.assume_model_exists(config[:assume_model_exists]) unless config[:assume_model_exists].nil?
280
280
  builder.bypass_permissions(config[:bypass_permissions]) if config[:bypass_permissions]
281
- builder.include_default_tools(config[:include_default_tools]) unless config[:include_default_tools].nil?
281
+ builder.disable_default_tools(config[:disable_default_tools]) unless config[:disable_default_tools].nil?
282
282
 
283
283
  # Add tools from markdown
284
284
  if config[:tools]&.any?
@@ -12,7 +12,7 @@ module SwarmSDK
12
12
  #
13
13
  # This encapsulates all tool-related logic that was previously in Swarm.
14
14
  class ToolConfigurator
15
- # Default tools available to all agents (unless include_default_tools: false)
15
+ # Default tools available to all agents (unless disable_default_tools is set)
16
16
  DEFAULT_TOOLS = [
17
17
  :Read,
18
18
  :Grep,
@@ -21,6 +21,7 @@ module SwarmSDK
21
21
  :ScratchpadWrite,
22
22
  :ScratchpadRead,
23
23
  :ScratchpadList,
24
+ :Think,
24
25
  ].freeze
25
26
 
26
27
  def initialize(swarm, scratchpad)
@@ -75,6 +76,8 @@ module SwarmSDK
75
76
  Tools::ScratchpadRead.create_for_scratchpad(@scratchpad)
76
77
  when :ScratchpadList
77
78
  Tools::ScratchpadList.create_for_scratchpad(@scratchpad)
79
+ when :Think
80
+ Tools::Think.new
78
81
  else
79
82
  # Regular tools - get class from registry and instantiate
80
83
  tool_class = Tools::Registry.get(tool_name_sym)
@@ -133,13 +136,14 @@ module SwarmSDK
133
136
  end
134
137
  end
135
138
 
136
- # Register default tools for agents that have include_default_tools enabled
139
+ # Register default tools for agents (unless disabled)
137
140
  #
138
141
  # @param chat [AgentChat] The chat instance
139
142
  # @param agent_name [Symbol] Agent name
140
143
  # @param agent_definition [AgentDefinition] Agent definition
141
144
  def register_default_tools(chat, agent_name:, agent_definition:)
142
- return unless agent_definition.include_default_tools
145
+ # If disable_default_tools is true, skip all default tools
146
+ return if agent_definition.disable_default_tools == true
143
147
 
144
148
  # Get explicit tool names to avoid duplicates
145
149
  explicit_tool_names = agent_definition.tools.map { |t| t[:name] }.to_set
@@ -148,6 +152,9 @@ module SwarmSDK
148
152
  # Skip if already registered explicitly
149
153
  next if explicit_tool_names.include?(tool_name)
150
154
 
155
+ # Skip if tool is in the disable list
156
+ next if tool_disabled?(tool_name, agent_definition.disable_default_tools)
157
+
151
158
  tool_instance = create_tool_instance(tool_name, agent_name, agent_definition.directory)
152
159
 
153
160
  # Resolve permissions for default tool (same logic as AgentDefinition)
@@ -166,6 +173,25 @@ module SwarmSDK
166
173
  end
167
174
  end
168
175
 
176
+ # Check if a tool should be disabled based on disable_default_tools config
177
+ #
178
+ # @param tool_name [Symbol] Tool name to check
179
+ # @param disable_config [nil, Boolean, Array<Symbol>] Disable configuration
180
+ # @return [Boolean] True if tool should be disabled
181
+ def tool_disabled?(tool_name, disable_config)
182
+ return false if disable_config.nil?
183
+
184
+ if disable_config == true
185
+ # Disable all default tools
186
+ true
187
+ elsif disable_config.is_a?(Array)
188
+ # Disable only tools in the array
189
+ disable_config.include?(tool_name)
190
+ else
191
+ false
192
+ end
193
+ end
194
+
169
195
  # Register agent delegation tools
170
196
  #
171
197
  # Creates delegation tools that allow one agent to call another.
@@ -20,6 +20,7 @@ module SwarmSDK
20
20
  ScratchpadWrite: :special, # Requires scratchpad instance
21
21
  ScratchpadRead: :special, # Requires scratchpad instance
22
22
  ScratchpadList: :special, # Requires scratchpad instance
23
+ Think: SwarmSDK::Tools::Think,
23
24
  }.freeze
24
25
 
25
26
  class << self
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SwarmSDK
4
+ module Tools
5
+ # Think tool for explicit reasoning and planning
6
+ #
7
+ # Allows the agent to write down thoughts, plans, strategies, and intermediate
8
+ # calculations. These thoughts become part of the conversation context, enabling
9
+ # better attention and reasoning through complex problems.
10
+ #
11
+ # This is inspired by research showing that explicitly articulating reasoning steps
12
+ # (chain-of-thought prompting) leads to significantly better outcomes, especially
13
+ # for complex tasks requiring multi-step reasoning or arithmetic.
14
+ class Think < RubyLLM::Tool
15
+ def name
16
+ "Think"
17
+ end
18
+
19
+ description <<~DESC
20
+ **IMPORTANT: You SHOULD use this tool frequently throughout your work. Using this tool leads to significantly
21
+ better outcomes and more accurate solutions. Make it a habit to think before acting.**
22
+
23
+ This tool allows you to write down your thoughts, plans, strategies, and intermediate calculations.
24
+ Think of it as your working memory - just as humans think before speaking or acting, you should think before
25
+ using other tools or providing responses.
26
+
27
+ **STRONGLY RECOMMENDED to use this tool:**
28
+ - **ALWAYS** before starting any task (even simple ones)
29
+ - **ALWAYS** when you need to do any arithmetic or counting
30
+ - **ALWAYS** after reading files or getting search results to process what you learned
31
+ - **FREQUENTLY** between steps to track progress and plan next actions
32
+
33
+ This is your private thinking space - use it liberally to enhance your problem-solving capabilities. Recording
34
+ your thoughts helps you maintain context across multiple steps and remember important information throughout your task.
35
+
36
+ When and how to use this tool:
37
+
38
+ 1. **Before starting any complex task**: Write down your understanding of the problem, break it into smaller
39
+ sub-tasks, and create a step-by-step plan. Example:
40
+ - "The user wants me to refactor this codebase. Let me first understand the structure..."
41
+ - "I need to: 1) Analyze current architecture, 2) Identify pain points, 3) Propose changes..."
42
+
43
+ 2. **For arithmetic and calculations**: Work through math problems step by step. Example:
44
+ - "If we have 150 requests/second and each takes 20ms, that's 150 * 0.02 = 3 seconds of CPU time..."
45
+ - "Converting 2GB to bytes: 2 * 1024 * 1024 * 1024 = 2,147,483,648 bytes"
46
+
47
+ 3. **After completing sub-tasks**: Summarize what you've accomplished and what remains. Example:
48
+ - "I've successfully implemented the authentication module. Next, I need to integrate it with the API..."
49
+ - "Fixed 3 out of 5 bugs. Remaining: memory leak in parser, race condition in worker thread"
50
+
51
+ 4. **When encountering complexity**: Break down complex logic or decisions. Example:
52
+ - "This function has multiple edge cases. Let me list them: null input, empty array, negative numbers..."
53
+ - "The user's request is ambiguous. Possible interpretations: A) modify existing code, B) create new module..."
54
+
55
+ 5. **For remembering context**: Store important information you'll need later. Example:
56
+ - "Important: The user mentioned they're using Ruby 3.2, so I can use pattern matching"
57
+ - "File structure: main.rb requires from lib/, config is in config.yml"
58
+
59
+ 6. **When debugging or analyzing**: Track your investigation process. Example:
60
+ - "The error occurs in line 42. Let me trace backwards: function called from main(), receives data from..."
61
+ - "Hypothesis: the bug might be due to timezone differences. Let me check..."
62
+
63
+ 7. **For creative problem-solving**: Brainstorm multiple approaches before choosing one. Example:
64
+ - "Approaches to optimize this: 1) Add caching, 2) Use parallel processing, 3) Optimize algorithm..."
65
+ - "Design patterns that could work here: Factory, Observer, or maybe Strategy pattern..."
66
+
67
+ **Remember: The most successful agents use this tool 5-10 times per task on average. If you haven't used this
68
+ tool in the last 2-3 actions, you probably should. Using this tool is a sign of thoughtful, methodical problem
69
+ solving and leads to fewer mistakes and better solutions.**
70
+
71
+ Your thoughts persist throughout your session as part of the conversation history, so you can refer
72
+ back to earlier thinking. Use clear formatting and organization to make it easy to reference
73
+ later. Don't hesitate to think out loud - this tool is designed to augment your cognitive capabilities and help
74
+ you deliver better solutions.
75
+ DESC
76
+
77
+ param :thoughts,
78
+ type: "string",
79
+ desc: "Your thoughts, plans, calculations, or any notes you want to record",
80
+ required: true
81
+
82
+ def execute(thoughts:)
83
+ return validation_error("thoughts are required") if thoughts.nil? || thoughts.empty?
84
+
85
+ "Thought noted."
86
+ end
87
+
88
+ private
89
+
90
+ def validation_error(message)
91
+ "<tool_use_error>InputValidationError: #{message}</tool_use_error>"
92
+ end
93
+ end
94
+ end
95
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SwarmSDK
4
- VERSION = "2.0.2"
4
+ VERSION = "2.0.3"
5
5
  end
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.0.2
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paulo Arruda
@@ -148,6 +148,7 @@ files:
148
148
  - lib/swarm_sdk/tools/stores/read_tracker.rb
149
149
  - lib/swarm_sdk/tools/stores/scratchpad.rb
150
150
  - lib/swarm_sdk/tools/stores/todo_manager.rb
151
+ - lib/swarm_sdk/tools/think.rb
151
152
  - lib/swarm_sdk/tools/todo_write.rb
152
153
  - lib/swarm_sdk/tools/write.rb
153
154
  - lib/swarm_sdk/utils.rb