swarm_sdk 2.7.11 → 2.7.12

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: bcabd24d5d88debcf61b86803b61996a60a8d56dac5ca56c1952478df8725079
4
- data.tar.gz: 1c661fd7c839822ce4cddcfbb499ed8700b3311b45d6f791e94e3b4fb9965dd3
3
+ metadata.gz: 700ee5f9b81c58e030024d664a7c3e27db84c705c876493678c89371f803158a
4
+ data.tar.gz: b2a4e2d7dc72208bff64b9c8d5f72dbe9d2772ae5f2f61d8abf3973d5855867c
5
5
  SHA512:
6
- metadata.gz: eec76f06fd85bbfe4bfc124473760ef9a3a84dd69aae3abb3de018b18b817882b5b1d23e1708cd9dce7f04abff433bec60eb436d7e5939a8925ef84f44a88005
7
- data.tar.gz: 5b71b6839d87d0010525a5dcf708424a8a585ed59472a384af0d13b5e2992e760f9ee15e9707c63ce0023e3aef3e19c373e333fa1d6dfd3bcb87dc59b9dd76c3
6
+ metadata.gz: 7e375f31f8419422c3b93065f0fa525d63ae063865b2dd62032ac42ff4e9f827111f5cf1dc13cc18e27e215e9e1a0924965791155f553d5af9261f53580680e4
7
+ data.tar.gz: f44a0e73852254048fe7219efed8db620bc41f4d274bfd938997ac5281a79c6cfa575e3be7631e404bbd84acfc3dd25649130a06fa10b85d4cac6a0099007d11
@@ -62,6 +62,7 @@ module SwarmSDK
62
62
  @memory_config = nil
63
63
  @shared_across_delegations = nil # nil = not set (will default to false in Definition)
64
64
  @streaming = nil # nil = not set (will use global config default)
65
+ @thinking = nil # nil = not set (extended thinking disabled)
65
66
  @context_management_config = nil # Context management DSL hooks
66
67
  end
67
68
 
@@ -372,6 +373,38 @@ module SwarmSDK
372
373
  !@streaming.nil?
373
374
  end
374
375
 
376
+ # Configure extended thinking for this agent
377
+ #
378
+ # Extended thinking allows models to reason through complex problems before responding.
379
+ # For Anthropic models, specify a budget (token count). For OpenAI models, specify effort.
380
+ # Both can be specified for cross-provider compatibility.
381
+ #
382
+ # @param effort [Symbol, String, nil] Reasoning effort level (:low, :medium, :high) — used by OpenAI
383
+ # @param budget [Integer, nil] Token budget for thinking — used by Anthropic
384
+ # @return [self] Returns self for method chaining
385
+ #
386
+ # @example Anthropic thinking with budget
387
+ # thinking budget: 10_000
388
+ #
389
+ # @example OpenAI reasoning effort
390
+ # thinking effort: :high
391
+ #
392
+ # @example Cross-provider (both)
393
+ # thinking effort: :high, budget: 10_000
394
+ def thinking(effort: nil, budget: nil)
395
+ raise ArgumentError, "thinking requires :effort or :budget" if effort.nil? && budget.nil?
396
+
397
+ @thinking = { effort: effort, budget: budget }.compact
398
+ self
399
+ end
400
+
401
+ # Check if thinking has been explicitly set
402
+ #
403
+ # @return [Boolean] true if thinking was explicitly configured
404
+ def thinking_set?
405
+ !@thinking.nil?
406
+ end
407
+
375
408
  # Configure context management handlers
376
409
  #
377
410
  # Define custom handlers for context warning thresholds (60%, 80%, 90%).
@@ -552,6 +585,7 @@ module SwarmSDK
552
585
  agent_config[:memory] = @memory_config if @memory_config
553
586
  agent_config[:shared_across_delegations] = @shared_across_delegations unless @shared_across_delegations.nil?
554
587
  agent_config[:streaming] = @streaming unless @streaming.nil?
588
+ agent_config[:thinking] = @thinking if @thinking
555
589
 
556
590
  # Convert DSL hooks to HookDefinition format
557
591
  agent_config[:hooks] = convert_hooks_to_definitions if @hooks.any?
@@ -189,10 +189,11 @@ module SwarmSDK
189
189
  # Try to fetch real model info for accurate context tracking
190
190
  fetch_real_model_info(model_id)
191
191
 
192
- # Configure system prompt, parameters, and headers
192
+ # Configure system prompt, parameters, headers, and thinking
193
193
  configure_system_prompt(system_prompt) if system_prompt
194
194
  configure_parameters(parameters)
195
195
  configure_headers(custom_headers)
196
+ configure_thinking(definition[:thinking])
196
197
 
197
198
  # Setup around_tool_execution hook for SwarmSDK orchestration
198
199
  setup_tool_execution_hook
@@ -986,6 +987,12 @@ module SwarmSDK
986
987
  emit_non_retryable_error(e, "UnknownAPIError")
987
988
  return build_error_message(e)
988
989
 
990
+ # === CATEGORY A (CONTINUED): PROGRAMMING ERRORS ===
991
+ rescue ArgumentError, TypeError, NameError => e
992
+ # Programming errors (wrong keywords, type mismatches) - won't fix by retrying
993
+ emit_non_retryable_error(e, e.class.name)
994
+ return build_error_message(e)
995
+
989
996
  # === CATEGORY C: NETWORK/OTHER ERRORS ===
990
997
  rescue StandardError => e
991
998
  # Network errors, timeouts, unknown errors - retry with delays
@@ -224,6 +224,22 @@ module SwarmSDK
224
224
  RubyLLM.logger.debug("SwarmSDK: Enabled native Responses API support")
225
225
  end
226
226
 
227
+ # Configure extended thinking on the RubyLLM chat instance
228
+ #
229
+ # @param thinking_config [Hash, nil] Thinking configuration with :effort and/or :budget
230
+ # @return [self]
231
+ #
232
+ # @example
233
+ # configure_thinking(budget: 10_000)
234
+ # configure_thinking(effort: :high)
235
+ # configure_thinking(effort: :high, budget: 10_000)
236
+ def configure_thinking(thinking_config)
237
+ return self unless thinking_config
238
+
239
+ @llm_chat.with_thinking(**thinking_config)
240
+ self
241
+ end
242
+
227
243
  # Configure LLM parameters with proper temperature normalization
228
244
  #
229
245
  # @param params [Hash] Parameter hash
@@ -42,7 +42,8 @@ module SwarmSDK
42
42
  :hooks,
43
43
  :plugin_configs,
44
44
  :shared_across_delegations,
45
- :streaming
45
+ :streaming,
46
+ :thinking
46
47
 
47
48
  attr_accessor :bypass_permissions, :max_concurrent_tools
48
49
 
@@ -114,6 +115,9 @@ module SwarmSDK
114
115
  # Streaming configuration (default: true from global config)
115
116
  @streaming = config.fetch(:streaming, SwarmSDK.config.streaming)
116
117
 
118
+ # Extended thinking configuration (nil = disabled)
119
+ @thinking = config[:thinking]
120
+
117
121
  # Build system prompt after directory and memory are set
118
122
  @system_prompt = build_full_system_prompt(config[:system_prompt])
119
123
 
@@ -450,6 +450,10 @@ module SwarmSDK
450
450
  if !all_agents_hash[:streaming].nil? && !agent_builder.streaming_set?
451
451
  agent_builder.streaming(all_agents_hash[:streaming])
452
452
  end
453
+
454
+ if all_agents_hash[:thinking] && !agent_builder.thinking_set?
455
+ agent_builder.thinking(**all_agents_hash[:thinking])
456
+ end
453
457
  end
454
458
 
455
459
  # Validate all_agents filesystem tools
@@ -100,6 +100,7 @@ module SwarmSDK
100
100
  coding_agent(all_agents_cfg[:coding_agent]) unless all_agents_cfg[:coding_agent].nil?
101
101
  disable_default_tools(all_agents_cfg[:disable_default_tools]) unless all_agents_cfg[:disable_default_tools].nil?
102
102
  streaming(all_agents_cfg[:streaming]) unless all_agents_cfg[:streaming].nil?
103
+ thinking(**all_agents_cfg[:thinking]) if all_agents_cfg[:thinking]
103
104
 
104
105
  if all_agents_hks.any?
105
106
  all_agents_hks.each do |event, hook_specs|
@@ -164,6 +165,7 @@ module SwarmSDK
164
165
  disable_default_tools(config[:disable_default_tools]) unless config[:disable_default_tools].nil?
165
166
  shared_across_delegations(config[:shared_across_delegations]) unless config[:shared_across_delegations].nil?
166
167
  streaming(config[:streaming]) unless config[:streaming].nil?
168
+ thinking(**config[:thinking]) if config[:thinking]
167
169
 
168
170
  if config[:tools]&.any?
169
171
  tool_names = config[:tools].map { |t| t.is_a?(Hash) ? t[:name] : t }
@@ -207,17 +207,19 @@ module RubyLLM
207
207
 
208
208
  # Perform the actual LLM request
209
209
  def perform_llm_request(messages_to_send, &block)
210
- @provider.complete(
211
- messages_to_send,
210
+ kwargs = {
212
211
  tools: @tools,
213
212
  temperature: @temperature,
214
213
  model: @model,
215
214
  params: @params,
216
215
  headers: @headers,
217
216
  schema: @schema,
218
- thinking: @thinking,
219
- &wrap_streaming_block(&block)
220
- )
217
+ }
218
+ # Only pass thinking when explicitly configured via with_thinking
219
+ # to maintain compatibility with providers that don't support this keyword
220
+ kwargs[:thinking] = @thinking if @thinking
221
+
222
+ @provider.complete(messages_to_send, **kwargs, &wrap_streaming_block(&block))
221
223
  rescue ArgumentError => e
222
224
  raise ArgumentError,
223
225
  "#{e.message} — provider #{@provider.class.name} does not support this parameter " \
@@ -36,6 +36,7 @@ module SwarmSDK
36
36
  @coding_agent = nil
37
37
  @disable_default_tools = nil
38
38
  @streaming = nil
39
+ @thinking = nil
39
40
  end
40
41
 
41
42
  # Set model for all agents
@@ -99,6 +100,16 @@ module SwarmSDK
99
100
  @streaming = value
100
101
  end
101
102
 
103
+ # Configure extended thinking for all agents
104
+ #
105
+ # @param effort [Symbol, String, nil] Reasoning effort (:low, :medium, :high) — OpenAI
106
+ # @param budget [Integer, nil] Token budget for thinking — Anthropic
107
+ def thinking(effort: nil, budget: nil)
108
+ raise ArgumentError, "thinking requires :effort or :budget" if effort.nil? && budget.nil?
109
+
110
+ @thinking = { effort: effort, budget: budget }.compact
111
+ end
112
+
102
113
  # Add tools that all agents will have
103
114
  def tools(*tool_names)
104
115
  @tools_list.concat(tool_names)
@@ -174,6 +185,7 @@ module SwarmSDK
174
185
  coding_agent: @coding_agent,
175
186
  disable_default_tools: @disable_default_tools,
176
187
  streaming: @streaming,
188
+ thinking: @thinking,
177
189
  tools: @tools_list,
178
190
  permissions: @permissions_config,
179
191
  }.compact
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SwarmSDK
4
- VERSION = "2.7.11"
4
+ VERSION = "2.7.12"
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.7.11
4
+ version: 2.7.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paulo Arruda