zuno 1.1.1 → 1.1.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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/lib/zuno/version.rb +1 -1
  4. data/lib/zuno.rb +19 -26
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7d6ca01a3009551afda766233cc241c30eff87eb7226142552c21f9d68450d0
4
- data.tar.gz: f71bd9073d2d14829502216a82e28d4f11e4bbb1de0b9f330befb4d2a6d02757
3
+ metadata.gz: eb25ddc2d1606495164eaf608263ab31546df25bc47b60f61858d15faaeaac7e
4
+ data.tar.gz: 369f67849b30fa68d81b597144171fed613dc25ebce06addff336bed2d4337ed
5
5
  SHA512:
6
- metadata.gz: 2228bcd4b752897c4757ad869fbe92ad0c189cc24be1d265d718f80e2cc23104194c737658022b0caa35c25f98d4a94006ba19746f1b30c6fd56317d6d3cee36
7
- data.tar.gz: a24da98ad4c6ce0214e26224d6e8f65886901865df8e1c05ab1f0572028c2d7f797328388bfdf035e7cfb52ecc52c9e5e207e101165e478df517589a0505ae81
6
+ metadata.gz: 8c6e08918da4bf006a9198503598a19e90de0eae7ff82bb90753796e87f9d1bf7f74c7a8df867676b98146d51c3b651f876584b14f484010f5b6309cddea08d6
7
+ data.tar.gz: 4b49269f11c1085f343eee2c45e4aee57c82e3245f6693413e625ca027449ec494a924615beeaedec88e7cb4528559534b96bc87677f4844f730c4ff8fc48634
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.3](https://github.com/dqnamo/zuno/compare/v1.1.2...v1.1.3) (2026-04-06)
4
+
5
+ ### Bug Fixes
6
+
7
+ * avoid retrying tool blocks with keyword args after internal `ArgumentError`s so hash-style tools preserve their input payloads
8
+
9
+ ## [1.1.2](https://github.com/dqnamo/zuno/compare/v1.1.1...v1.1.2) (2026-04-06)
10
+
11
+ ### Bug Fixes
12
+
13
+ * preserve structured assistant content for tool-call turns so provider-specific metadata survives loop history replay
14
+
3
15
  ## [1.1.1](https://github.com/dqnamo/zuno/compare/v1.1.0...v1.1.1) (2026-04-06)
4
16
 
5
17
  ### Bug Fixes
data/lib/zuno/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zuno
4
- VERSION = "1.1.1"
4
+ VERSION = "1.1.3"
5
5
  end
data/lib/zuno.rb CHANGED
@@ -148,11 +148,16 @@ module Zuno
148
148
  raise ToolError, "Tool '#{name}' is missing an execute block" unless execute_proc.respond_to?(:call)
149
149
 
150
150
  symbolized_args = arguments.each_with_object({}) { |(key, value), acc| acc[key.to_sym] = value }
151
+ parameter_kinds = execute_proc.parameters.map(&:first)
152
+ accepts_keywords = parameter_kinds.any? { |kind| [:keyreq, :key, :keyrest].include?(kind) }
153
+ accepts_positionals = parameter_kinds.any? { |kind| [:req, :opt, :rest].include?(kind) }
151
154
 
152
- begin
153
- execute_proc.call(arguments)
154
- rescue ArgumentError, TypeError
155
+ if accepts_keywords && !accepts_positionals
155
156
  execute_proc.call(**symbolized_args)
157
+ elsif parameter_kinds.empty?
158
+ execute_proc.call
159
+ else
160
+ execute_proc.call(arguments)
156
161
  end
157
162
  end
158
163
  end
@@ -1118,12 +1123,6 @@ module Zuno
1118
1123
  payload["max_tokens"] = max_tokens unless max_tokens.nil?
1119
1124
  payload["tools"] = tools.values.map(&:as_provider_tool) unless tools.empty?
1120
1125
  payload["tool_choice"] = deep_stringify(tool_choice) unless tool_choice.nil?
1121
- payload["parallel_tool_calls"] = false if disable_parallel_tool_calls_by_default?(
1122
- model_id: model_id,
1123
- provider: provider,
1124
- tools: tools,
1125
- provider_options: provider_options
1126
- )
1127
1126
 
1128
1127
  request_options = reject_keys(provider_options, provider_adapter_config_keys(provider) + [ :tool_choice ])
1129
1128
  payload.merge!(deep_stringify(request_options)) if request_options.is_a?(Hash)
@@ -1131,22 +1130,6 @@ module Zuno
1131
1130
  end
1132
1131
  private_class_method :build_payload
1133
1132
 
1134
- def disable_parallel_tool_calls_by_default?(model_id:, provider:, tools:, provider_options:)
1135
- return false if tools.empty?
1136
- return false unless provider.to_sym == :ai_gateway
1137
- return false unless gemini_model?(model_id)
1138
- return false if provider_options&.key?(:parallel_tool_calls) || provider_options&.key?("parallel_tool_calls")
1139
-
1140
- true
1141
- end
1142
- private_class_method :disable_parallel_tool_calls_by_default?
1143
-
1144
- def gemini_model?(model_id)
1145
- normalized = model_id.to_s.downcase
1146
- normalized.start_with?("google/") || normalized.include?("gemini")
1147
- end
1148
- private_class_method :gemini_model?
1149
-
1150
1133
  def provider_adapter_config_keys(provider)
1151
1134
  case provider.to_sym
1152
1135
  when :openrouter
@@ -1195,12 +1178,22 @@ module Zuno
1195
1178
  def build_assistant_tool_call_message(message:, tool_calls:)
1196
1179
  {
1197
1180
  "role" => "assistant",
1198
- "content" => extract_message_text(message),
1181
+ "content" => normalize_message_content_for_history(message["content"]),
1199
1182
  "tool_calls" => tool_calls
1200
1183
  }
1201
1184
  end
1202
1185
  private_class_method :build_assistant_tool_call_message
1203
1186
 
1187
+ def normalize_message_content_for_history(content)
1188
+ case content
1189
+ when Array, Hash
1190
+ deep_stringify(content)
1191
+ else
1192
+ content
1193
+ end
1194
+ end
1195
+ private_class_method :normalize_message_content_for_history
1196
+
1204
1197
  def execute_tool_call(tool_call:, tools:, tool_call_id: nil, arguments: nil)
1205
1198
  tool_name = tool_call.dig("function", "name").to_s
1206
1199
  tool_call_id = normalize_tool_call_id(tool_call_id || tool_call["id"])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zuno
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hyperaide
@@ -85,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
85
  - !ruby/object:Gem::Version
86
86
  version: '0'
87
87
  requirements: []
88
- rubygems_version: 3.5.23
88
+ rubygems_version: 3.5.22
89
89
  signing_key:
90
90
  specification_version: 4
91
91
  summary: Ruby SDK with provider/model abstraction, single-shot generation, loops,