Skip to content

Commit 7cb8284

Browse files
committed
fix(serialization): restore tools message key
## About Restore the original serialized message schema for assistant tool calls by writing parsed tool metadata back under the tools key. This keeps serialized contexts aligned with the original format and adds focused coverage for tool-call round trips. ## Changes - serialize parsed message tool calls under the tools key again - update message serialization coverage to expect the original key - add a context round-trip spec for assistant tool-call payloads
1 parent 3b215c6 commit 7cb8284

3 files changed

Lines changed: 52 additions & 2 deletions

File tree

lib/llm/message.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def to_h
3838
content:,
3939
reasoning_content:,
4040
compaction: extra.compaction,
41-
tool_calls: extra.tool_calls&.map { LLM::Object === _1 ? _1.to_h : _1 },
41+
tools: extra.tool_calls&.map { LLM::Object === _1 ? _1.to_h : _1 },
4242
usage:,
4343
original_tool_calls: extra.original_tool_calls
4444
}.compact.then { preserve_nil_content(_1) }

spec/context_spec.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,56 @@
189189
expect(content.fetch(2).value.file?).to eq(true)
190190
expect(content.fetch(2).value.id).to eq("file_123")
191191
end
192+
193+
context "with assistant tool calls" do
194+
let(:message) do
195+
LLM::Message.new("assistant", nil, {
196+
tool_calls: [
197+
{id: "call_1", name: "system", arguments: {command: "date"}}
198+
],
199+
original_tool_calls: [
200+
{"id" => "call_1", "type" => "function", "function" => {"name" => "system", "arguments" => "{\"command\":\"date\"}"}}
201+
]
202+
})
203+
end
204+
before do
205+
restored
206+
end
207+
let(:restored_message) { restored.messages.first }
208+
let(:serialized_message) { JSON.parse(File.read(serialized)).fetch("messages").fetch(0) }
209+
let(:tool_calls) do
210+
restored_message.extra[:tool_calls].map do |tool|
211+
tool.to_h.merge("arguments" => tool.arguments.to_h)
212+
end
213+
end
214+
let(:original_tool_calls) do
215+
restored_message.extra[:original_tool_calls].map do |tool|
216+
tool.to_h.merge("function" => tool.function.to_h)
217+
end
218+
end
219+
220+
it "restores the message as a tool call" do
221+
expect(restored_message.tool_call?).to eq(true)
222+
end
223+
224+
it "serializes parsed tool calls under the tools key" do
225+
expect(serialized_message.fetch("tools")).to eq([
226+
{"id" => "call_1", "name" => "system", "arguments" => {"command" => "date"}}
227+
])
228+
end
229+
230+
it "round-trips parsed tool calls" do
231+
expect(tool_calls).to eq([
232+
{"id" => "call_1", "name" => "system", "arguments" => {"command" => "date"}}
233+
])
234+
end
235+
236+
it "round-trips original tool calls" do
237+
expect(original_tool_calls).to eq([
238+
{"id" => "call_1", "type" => "function", "function" => {"name" => "system", "arguments" => "{\"command\":\"date\"}"}}
239+
])
240+
end
241+
end
192242
end
193243
end
194244

spec/message_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
end
3939

4040
it "normalizes tool calls to hashes" do
41-
expect(message.to_h[:tool_calls]).to eq([{"id" => "call_1"}])
41+
expect(message.to_h[:tools]).to eq([{"id" => "call_1"}])
4242
end
4343
end
4444

0 commit comments

Comments
 (0)