brute 6.1.4 → 6.1.5
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/lib/brute/message_transport/open_router.rb +38 -0
- data/lib/brute/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fe1e1cc4c5d064aba3ae09ac3cce887a9b116b7ebd52ccefedb6a1e8287050c2
|
|
4
|
+
data.tar.gz: af8a28e3643305f90f59eef3878e8ac1618ccad54b15cdafed63f33773d4d717
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 29b0f666931c9891647bf88a1d8ebf6e750c75d94782e53b73d404fd36401a70273dd0fcf9d156e34b6ac5fda952b49f851e1b3f8e29f291d544c1614680a9d6
|
|
7
|
+
data.tar.gz: 5babc3e4185d9d68ca6f86613cbe03116adb5af0483d16f04f6a5b517d4233b46f6a458df3b67b985d038852619865dc36ecf695e9b3bf379503cd7ddb6585a9
|
|
@@ -37,6 +37,10 @@ module Brute
|
|
|
37
37
|
# wire's: whatever goes out under these keys is put there here.
|
|
38
38
|
hash.delete(:reasoning)
|
|
39
39
|
|
|
40
|
+
if message.tool_call?
|
|
41
|
+
hash[:tool_calls] = message.tool_calls.map { |call| call_block(call) }
|
|
42
|
+
end
|
|
43
|
+
|
|
40
44
|
reasoning = message.reasoning
|
|
41
45
|
|
|
42
46
|
if reasoning&.detailed?
|
|
@@ -47,6 +51,16 @@ module Brute
|
|
|
47
51
|
end
|
|
48
52
|
end
|
|
49
53
|
|
|
54
|
+
# The inverse of wrap_tool_call: the wire keeps the name and the
|
|
55
|
+
# arguments under `function`, and the arguments as a JSON string.
|
|
56
|
+
def self.call_block(call)
|
|
57
|
+
{
|
|
58
|
+
id: call.id,
|
|
59
|
+
type: "function",
|
|
60
|
+
function: { name: call.name, arguments: JSON.generate(call.arguments) },
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
|
|
50
64
|
# Each type names its own payload: reasoning text carries `text` and the
|
|
51
65
|
# `signature` that verifies it, a summary carries `summary`, and an
|
|
52
66
|
# encrypted item carries `data`. Written under the wrong key the payload
|
|
@@ -170,6 +184,30 @@ describe "brute/message_transport/open_router" do
|
|
|
170
184
|
Brute::MessageTransport::OpenRouter.dump(m).should == { role: :user, content: "hi" }
|
|
171
185
|
end
|
|
172
186
|
|
|
187
|
+
it "dumps a tool call as the wire wants it, and reads its own output back" do
|
|
188
|
+
call = Brute::ToolCall.new(id: "call_1", name: "search", arguments: { "query" => "cheese" })
|
|
189
|
+
dumped = Brute::MessageTransport::OpenRouter.dump(
|
|
190
|
+
Brute::Message.new(role: :assistant, content: "", tool_calls: [call]),
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
dumped[:tool_calls].should == [
|
|
194
|
+
{ id: "call_1", type: "function", function: { name: "search", arguments: '{"query":"cheese"}' } },
|
|
195
|
+
]
|
|
196
|
+
|
|
197
|
+
echoed = Struct.new(:choices).new([{ "message" => {
|
|
198
|
+
"role" => "assistant", "content" => "", "tool_calls" => dumped[:tool_calls],
|
|
199
|
+
} }])
|
|
200
|
+
back = Brute::MessageTransport::OpenRouter.new(echoed).wrap_each.to_a.first.tool_calls.first
|
|
201
|
+
|
|
202
|
+
back.id.should == "call_1"
|
|
203
|
+
back.name.should == "search"
|
|
204
|
+
back.arguments.should == { "query" => "cheese" }
|
|
205
|
+
|
|
206
|
+
Brute::MessageTransport::OpenRouter.dump(
|
|
207
|
+
Brute::Message.new(role: :user, content: "hi"),
|
|
208
|
+
).key?(:tool_calls).should.be.false
|
|
209
|
+
end
|
|
210
|
+
|
|
173
211
|
it "wraps a response's choice messages with symbolised roles, dropping provider extras" do
|
|
174
212
|
fake_response = Struct.new(:choices).new([
|
|
175
213
|
{ "message" => { "role" => "assistant", "content" => "hi there",
|
data/lib/brute/version.rb
CHANGED