claude_swarm 1.0.7 → 1.0.9

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: 9c8e0f8bb459a909a37216a620952bf08315a2943216865bee2890cd870bbd1c
4
- data.tar.gz: 73315162dc30338385e89423fd9c509ab051b4caf4dbb0ba1d8ebbb681bbc3b2
3
+ metadata.gz: 1b5d5d686096a33cf7a16511f728091f92e2bb33d9c5eeacdf430718a1a8548e
4
+ data.tar.gz: 63e3445e6279abc98b4202b582cfc48a4e17b610339241ba0872532a61174697
5
5
  SHA512:
6
- metadata.gz: 4ca20259cbe8dc8ac5b9a0b7adb2c7454af0e375e6d397e52407a991b0690dffe8c4365c37f9b3653c1f0c38dce7af4bb3afeca0151d5ba3b8185276355ca500
7
- data.tar.gz: 97d0b2aa55a3df7178ff0bc25b923403402e6fd08f7b15a517c6aa775bd4dca1c9983a0bcaa392186844d684459f63c357aa1aba92ad09db5e83d791d54d0031
6
+ metadata.gz: 8521d7386607e3391915dfeb68f82ca9df8361566832724fe8e59357444137530a4b825e9c665f328a6157a0ee6a7202ad536409e59253d4f7fdb909482bc178
7
+ data.tar.gz: c34358c386fac205277cab662b3041330b5006878520f8c8ae265a316bc239e71d396e5ed4ea77c897bc7bf5b465eddf810cb227be13ba189cc27169496e6d78
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## [1.0.9]
2
+
3
+ ### Added
4
+ - **Zero Data Retention (ZDR) support for OpenAI Responses API**: Added ZDR mode to disable conversation continuity for privacy-focused use cases
5
+ - New `zdr` configuration parameter (boolean) that can be set in YAML configuration files
6
+ - When enabled, sets `previous_response_id` to nil, ensuring each API call is independent
7
+ - Supported in Configuration, CLI (`--zdr` flag), and MCP generator
8
+
9
+ ## [1.0.8]
10
+
11
+ ### Changed
12
+ - **Removed model-specific parameter restrictions for OpenAI**: Simplified parameter handling by allowing OpenAI's API to validate parameters instead of enforcing client-side restrictions
13
+ - Removed validation that prevented using `temperature` with o-series models
14
+ - Removed validation that restricted `reasoning_effort` to only o-series models
15
+ - Eliminated `O_SERIES_MODEL_PATTERN` constant and related model pattern matching logic
16
+ - Parameters are now passed to the API as-is when provided, allowing flexibility as OpenAI's model capabilities evolve
17
+ - Reduces maintenance burden when new models are released
18
+ - API errors provide authoritative feedback for invalid parameter combinations
19
+
20
+ ### Fixed
21
+
1
22
  ## [1.0.7]
2
23
 
3
24
  ### Fixed
data/docs/v1/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/claude_swarm.svg?cache_bust1=1.0.1)](https://badge.fury.io/rb/claude_swarm)
4
4
  [![CI](https://github.com/parruda/claude-swarm/actions/workflows/ci.yml/badge.svg)](https://github.com/parruda/claude-swarm/actions/workflows/ci.yml)
5
+ [![Mentioned in Awesome Claude Code](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/hesreallyhim/awesome-claude-code)
6
+
5
7
 
6
8
  > **Note**: This is the documentation for Claude Swarm v1, which uses a multi-process architecture with Claude Code instances. For new projects, we recommend using [SwarmSDK v2](../v2/README.md) which offers a single-process architecture, better performance, and more features.
7
9
 
@@ -370,6 +372,7 @@ When using `provider: openai`, the following additional fields are available:
370
372
  - **openai_token_env**: Environment variable name for OpenAI API key (default: "OPENAI_API_KEY")
371
373
  - **base_url**: Custom base URL for OpenAI API (optional)
372
374
  - **reasoning_effort**: Reasoning effort for O-series models only - "low", "medium", or "high"
375
+ - **zdr**: Zero Data Retention mode (boolean) - when set to `true`, disables conversation continuity by setting `previous_response_id` to nil (responses API only)
373
376
 
374
377
  **Important Notes:**
375
378
 
@@ -426,6 +429,15 @@ reasoning_instance:
426
429
  reasoning_effort: medium # Only for O-series models
427
430
  api_version: responses # Can use either API version
428
431
  prompt: "You are a reasoning assistant for complex problem solving"
432
+
433
+ # Instance with Zero Data Retention mode
434
+ zdr_instance:
435
+ description: "Privacy-focused assistant with no conversation memory"
436
+ provider: openai
437
+ model: gpt-4o
438
+ api_version: responses # ZDR only works with responses API
439
+ zdr: true # Disables conversation continuity
440
+ prompt: "You are a privacy-focused assistant that handles sensitive data"
429
441
  ```
430
442
 
431
443
  ### MCP Server Types
@@ -36,6 +36,7 @@ module ClaudeSwarm
36
36
  openai_token_env: instance_config[:openai_token_env],
37
37
  base_url: instance_config[:base_url],
38
38
  reasoning_effort: instance_config[:reasoning_effort],
39
+ zdr: instance_config[:zdr],
39
40
  )
40
41
  else
41
42
  # Default Claude behavior - always use SDK
@@ -172,6 +172,10 @@ module ClaudeSwarm
172
172
  method_option :reasoning_effort,
173
173
  type: :string,
174
174
  desc: "Reasoning effort for OpenAI models"
175
+ method_option :zdr,
176
+ type: :boolean,
177
+ default: false,
178
+ desc: "Enable ZDR for OpenAI models"
175
179
  def mcp_serve
176
180
  # Validate reasoning_effort if provided
177
181
  if options[:reasoning_effort]
@@ -181,14 +185,6 @@ module ClaudeSwarm
181
185
  exit(1)
182
186
  end
183
187
 
184
- # Validate it's used with an o-series model
185
- model = options[:model]
186
- unless model&.match?(ClaudeSwarm::Configuration::O_SERIES_MODEL_PATTERN)
187
- error("reasoning_effort is only supported for o-series models (o1, o1 Preview, o1-mini, o1-pro, o3, o3-mini, o3-pro, o3-deep-research, o4-mini, o4-mini-deep-research, etc.)")
188
- error("Current model: #{model}")
189
- exit(1)
190
- end
191
-
192
188
  # Validate the value
193
189
  unless ClaudeSwarm::Configuration::VALID_REASONING_EFFORTS.include?(options[:reasoning_effort])
194
190
  error("reasoning_effort must be 'low', 'medium', or 'high'")
@@ -196,16 +192,6 @@ module ClaudeSwarm
196
192
  end
197
193
  end
198
194
 
199
- # Validate temperature is not used with o-series models
200
- if options[:temperature] && options[:provider] == "openai"
201
- model = options[:model]
202
- if model&.match?(ClaudeSwarm::Configuration::O_SERIES_MODEL_PATTERN)
203
- error("temperature parameter is not supported for o-series models (#{model})")
204
- error("O-series models use deterministic reasoning and don't accept temperature settings")
205
- exit(1)
206
- end
207
- end
208
-
209
195
  instance_config = {
210
196
  name: options[:name],
211
197
  directory: options[:directory],
@@ -226,6 +212,7 @@ module ClaudeSwarm
226
212
  openai_token_env: options[:openai_token_env],
227
213
  base_url: options[:base_url],
228
214
  reasoning_effort: options[:reasoning_effort],
215
+ zdr: options[:zdr],
229
216
  }
230
217
 
231
218
  begin
@@ -4,15 +4,13 @@ module ClaudeSwarm
4
4
  class Configuration
5
5
  # Frozen constants for validation
6
6
  VALID_PROVIDERS = ["claude", "openai"].freeze
7
- OPENAI_SPECIFIC_FIELDS = ["temperature", "api_version", "openai_token_env", "base_url", "reasoning_effort"].freeze
7
+ OPENAI_SPECIFIC_FIELDS = ["temperature", "api_version", "openai_token_env", "base_url", "reasoning_effort", "zdr"].freeze
8
8
  VALID_API_VERSIONS = ["chat_completion", "responses"].freeze
9
9
  VALID_REASONING_EFFORTS = ["low", "medium", "high"].freeze
10
10
 
11
11
  # Regex patterns
12
12
  ENV_VAR_PATTERN = /\$\{([^}]+)\}/
13
13
  ENV_VAR_WITH_DEFAULT_PATTERN = /\$\{([^:}]+)(:=([^}]*))?\}/
14
- O_SERIES_MODEL_PATTERN = /^(o\d+(\s+(Preview|preview))?(-pro|-mini|-deep-research|-mini-deep-research)?|gpt-5(-mini|-nano)?)$/
15
-
16
14
  attr_reader :config, :config_path, :swarm, :swarm_name, :main_instance, :instances, :base_dir
17
15
 
18
16
  def initialize(config_path, base_dir: nil, options: {})
@@ -165,7 +163,6 @@ module ClaudeSwarm
165
163
 
166
164
  # Parse provider (optional, defaults to claude)
167
165
  provider = config["provider"]
168
- model = config["model"]
169
166
 
170
167
  # Validate provider value if specified
171
168
  if provider && !VALID_PROVIDERS.include?(provider)
@@ -183,17 +180,6 @@ module ClaudeSwarm
183
180
  unless VALID_REASONING_EFFORTS.include?(config["reasoning_effort"])
184
181
  raise Error, "Instance '#{name}' has invalid reasoning_effort '#{config["reasoning_effort"]}'. Must be 'low', 'medium', or 'high'"
185
182
  end
186
-
187
- # Validate it's only used with o-series or gpt-5 models
188
- # Support patterns like: o1, o1-mini, o1-pro, o1 Preview, o3-deep-research, o4-mini-deep-research, gpt-5, gpt-5-mini, gpt-5-nano, etc.
189
- unless model&.match?(O_SERIES_MODEL_PATTERN)
190
- raise Error, "Instance '#{name}' has reasoning_effort but model '#{model}' is not an o-series or gpt-5 model (o1, o1 Preview, o1-mini, o1-pro, o3, o3-mini, o3-pro, o3-deep-research, o4-mini, o4-mini-deep-research, gpt-5, gpt-5-mini, gpt-5-nano, etc.)"
191
- end
192
- end
193
-
194
- # Validate temperature is not used with o-series or gpt-5 models when provider is openai
195
- if provider == "openai" && config["temperature"] && model&.match?(O_SERIES_MODEL_PATTERN)
196
- raise Error, "Instance '#{name}' has temperature parameter but model '#{model}' is an o-series or gpt-5 model. O-series and gpt-5 models use deterministic reasoning and don't accept temperature settings"
197
183
  end
198
184
 
199
185
  # Validate OpenAI-specific fields only when provider is not "openai"
@@ -246,6 +232,7 @@ module ClaudeSwarm
246
232
  instance_config[:openai_token_env] = config["openai_token_env"] || "OPENAI_API_KEY"
247
233
  instance_config[:base_url] = config["base_url"]
248
234
  instance_config[:reasoning_effort] = config["reasoning_effort"] if config["reasoning_effort"]
235
+ instance_config[:zdr] = config["zdr"] if config.key?("zdr")
249
236
  # Default vibe to true for OpenAI instances if not specified
250
237
  instance_config[:vibe] = true if config["vibe"].nil?
251
238
  elsif config["vibe"].nil?
@@ -174,6 +174,7 @@ module ClaudeSwarm
174
174
  args.push("--api-version", instance[:api_version]) if instance[:api_version]
175
175
  args.push("--openai-token-env", instance[:openai_token_env]) if instance[:openai_token_env]
176
176
  args.push("--base-url", instance[:base_url]) if instance[:base_url]
177
+ args.push("--zdr", instance[:zdr].to_s) if instance.key?(:zdr)
177
178
  end
178
179
  end
179
180
 
@@ -5,7 +5,7 @@ module ClaudeSwarm
5
5
  class ChatCompletion
6
6
  MAX_TURNS_WITH_TOOLS = 100_000 # virtually infinite
7
7
 
8
- def initialize(openai_client:, mcp_client:, available_tools:, executor:, instance_name:, model:, temperature: nil, reasoning_effort: nil)
8
+ def initialize(openai_client:, mcp_client:, available_tools:, executor:, instance_name:, model:, temperature: nil, reasoning_effort: nil, zdr: false)
9
9
  @openai_client = openai_client
10
10
  @mcp_client = mcp_client
11
11
  @available_tools = available_tools
@@ -14,6 +14,7 @@ module ClaudeSwarm
14
14
  @model = model
15
15
  @temperature = temperature
16
16
  @reasoning_effort = reasoning_effort
17
+ @zdr = zdr # Not used in chat_completion API, but kept for compatibility
17
18
  @conversation_messages = []
18
19
  end
19
20
 
@@ -67,17 +68,8 @@ module ClaudeSwarm
67
68
  messages: messages,
68
69
  }
69
70
 
70
- # Only add temperature for non-o-series models
71
- # O-series models don't support temperature parameter
72
- if @temperature && !@model.match?(ClaudeSwarm::Configuration::O_SERIES_MODEL_PATTERN)
73
- parameters[:temperature] = @temperature
74
- end
75
-
76
- # Only add reasoning_effort for o-series models
77
- # reasoning_effort is only supported by o-series models: o1, o1 Preview, o1-mini, o1-pro, o3, o3-mini, o3-pro, o3-deep-research, o4-mini, o4-mini-deep-research, etc.
78
- if @reasoning_effort && @model.match?(ClaudeSwarm::Configuration::O_SERIES_MODEL_PATTERN)
79
- parameters[:reasoning_effort] = @reasoning_effort
80
- end
71
+ parameters[:temperature] = @temperature if @temperature
72
+ parameters[:reasoning_effort] = @reasoning_effort if @reasoning_effort
81
73
 
82
74
  # Add tools if available
83
75
  parameters[:tools] = @mcp_client.to_openai_tools if @available_tools&.any? && @mcp_client
@@ -31,7 +31,7 @@ module ClaudeSwarm
31
31
  instance_name: nil, instance_id: nil, calling_instance: nil, calling_instance_id: nil,
32
32
  claude_session_id: nil, additional_directories: [], debug: false,
33
33
  temperature: nil, api_version: "chat_completion", openai_token_env: "OPENAI_API_KEY",
34
- base_url: nil, reasoning_effort: nil)
34
+ base_url: nil, reasoning_effort: nil, zdr: false)
35
35
  # Call parent initializer for common attributes
36
36
  super(
37
37
  working_directory: working_directory,
@@ -52,6 +52,7 @@ module ClaudeSwarm
52
52
  @api_version = api_version
53
53
  @base_url = base_url
54
54
  @reasoning_effort = reasoning_effort
55
+ @zdr = zdr
55
56
 
56
57
  # Conversation state for maintaining context
57
58
  @conversation_messages = []
@@ -162,6 +163,7 @@ module ClaudeSwarm
162
163
  model: @model,
163
164
  temperature: @temperature,
164
165
  reasoning_effort: @reasoning_effort,
166
+ zdr: @zdr,
165
167
  }
166
168
 
167
169
  if @api_version == "responses"
@@ -5,7 +5,7 @@ module ClaudeSwarm
5
5
  class Responses
6
6
  MAX_TURNS_WITH_TOOLS = 100_000 # virtually infinite
7
7
 
8
- def initialize(openai_client:, mcp_client:, available_tools:, executor:, instance_name:, model:, temperature: nil, reasoning_effort: nil)
8
+ def initialize(openai_client:, mcp_client:, available_tools:, executor:, instance_name:, model:, temperature: nil, reasoning_effort: nil, zdr: false)
9
9
  @openai_client = openai_client
10
10
  @mcp_client = mcp_client
11
11
  @available_tools = available_tools
@@ -14,6 +14,7 @@ module ClaudeSwarm
14
14
  @model = model
15
15
  @temperature = temperature
16
16
  @reasoning_effort = reasoning_effort
17
+ @zdr = zdr
17
18
  @system_prompt = nil
18
19
  end
19
20
 
@@ -46,17 +47,8 @@ module ClaudeSwarm
46
47
  model: @model,
47
48
  }
48
49
 
49
- # Only add temperature for non-o-series models
50
- # O-series models don't support temperature parameter
51
- unless @model.match?(ClaudeSwarm::Configuration::O_SERIES_MODEL_PATTERN)
52
- parameters[:temperature] = @temperature
53
- end
54
-
55
- # Only add reasoning effort for o-series models
56
- # reasoning is only supported by o-series models: o1, o1 Preview, o1-mini, o1-pro, o3, o3-mini, o3-pro, o3-deep-research, o4-mini, o4-mini-deep-research, etc.
57
- if @reasoning_effort && @model.match?(ClaudeSwarm::Configuration::O_SERIES_MODEL_PATTERN)
58
- parameters[:reasoning] = { effort: @reasoning_effort }
59
- end
50
+ parameters[:temperature] = @temperature if @temperature
51
+ parameters[:reasoning] = { effort: @reasoning_effort } if @reasoning_effort
60
52
 
61
53
  # On first call, use string input (can include system prompt)
62
54
  # On subsequent calls with function results, use array input
@@ -67,6 +59,7 @@ module ClaudeSwarm
67
59
  else
68
60
  input
69
61
  end
62
+ conversation_array << { role: "user", content: parameters[:input] }
70
63
  else
71
64
  # Follow-up call with conversation array (function calls + outputs)
72
65
  parameters[:input] = conversation_array
@@ -79,8 +72,8 @@ module ClaudeSwarm
79
72
  @executor.logger.info { "Conversation item IDs: #{conversation_ids.inspect}" }
80
73
  end
81
74
 
82
- # Add previous response ID for conversation continuity
83
- parameters[:previous_response_id] = previous_response_id if previous_response_id
75
+ # Add previous response ID for conversation continuity (unless zdr is enabled)
76
+ parameters[:previous_response_id] = @zdr ? nil : previous_response_id
84
77
 
85
78
  # Add tools if available
86
79
  if @available_tools&.any?
@@ -115,7 +108,7 @@ module ClaudeSwarm
115
108
  @executor.logger.error { "Request parameters: #{JsonHandler.pretty_generate!(parameters)}" }
116
109
 
117
110
  # Try to extract and log the response body for better debugging
118
- if e.respond_to?(:response)
111
+ if e.respond_to?(:response) && e.response
119
112
  begin
120
113
  error_body = e.response[:body]
121
114
  @executor.logger.error { "Error response body: #{error_body}" }
@@ -131,7 +124,7 @@ module ClaudeSwarm
131
124
  error: {
132
125
  class: e.class.to_s,
133
126
  message: e.message,
134
- response_body: e.respond_to?(:response) ? e.response[:body] : nil,
127
+ response_body: e.respond_to?(:response) && e.response ? e.response[:body] : nil,
135
128
  backtrace: e.backtrace.first(5),
136
129
  },
137
130
  })
@@ -155,33 +148,21 @@ module ClaudeSwarm
155
148
 
156
149
  # Handle response based on output structure
157
150
  output = response["output"]
158
-
159
151
  if output.nil?
160
152
  @executor.logger.error { "No output in response" }
161
153
  return "Error: No output in OpenAI response"
162
154
  end
163
155
 
164
156
  # Check if output is an array (as per documentation)
165
- if output.is_a?(Array) && !output.empty?
157
+ if output.is_a?(Array) && output.any?
158
+ new_conversation = conversation_array.dup
159
+ new_conversation.concat(output)
166
160
  # Check if there are function calls
167
161
  function_calls = output.select { |item| item["type"] == "function_call" }
168
-
169
162
  if function_calls.any?
170
- # Check if we already have a conversation going
171
- if conversation_array.empty?
172
- # First depth - build new conversation
173
- new_conversation = build_conversation_with_outputs(function_calls)
174
- else
175
- # Subsequent depth - append to existing conversation
176
- # Don't re-add function calls, just add the new ones and their outputs
177
- new_conversation = conversation_array.dup
178
- append_new_outputs(function_calls, new_conversation)
179
- end
180
-
181
- # Recursively process with updated conversation
163
+ append_new_outputs(function_calls, new_conversation)
182
164
  process_responses_api(nil, new_conversation, response_id, depth + 1)
183
165
  else
184
- # Look for text response
185
166
  extract_text_response(output)
186
167
  end
187
168
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClaudeSwarm
4
- VERSION = "1.0.7"
4
+ VERSION = "1.0.9"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: claude_swarm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.7
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paulo Arruda