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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/lib/zuno/version.rb +1 -1
- data/lib/zuno.rb +19 -26
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eb25ddc2d1606495164eaf608263ab31546df25bc47b60f61858d15faaeaac7e
|
|
4
|
+
data.tar.gz: 369f67849b30fa68d81b597144171fed613dc25ebce06addff336bed2d4337ed
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
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
|
-
|
|
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" =>
|
|
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.
|
|
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.
|
|
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,
|