-
-
Notifications
You must be signed in to change notification settings - Fork 365
Description
Basic checks
- I searched existing issues - this hasn't been reported
- I can reproduce this consistently
- This is a RubyLLM bug, not my application code
What's broken?
In cleanup_orphaned_tool_results, we ensure that our associations are properly built by comparing the tool call message's tool_calls to the foreign keys on the tool call message's tool results. The name of the foreign key column is hardcoded as :tool_call_id, but a custom association may result in a different column name.
In those cases, the call to pluck(:tool_call_id) returns the string tool_call_id column from the tool call table. Those ids will never match the expected ids plucked from the message's tool calls, which leads us to falsely believe that we have orphaned tool results. That forces us to destroy tool results that should have been preserved.
How to reproduce
Create custom associations for messages and tool calls, with custom foreign key columns:
ActiveRecord::Migration.create_table :chat_messages, force: true do |t|
t.references :chat
...
t.references :chat_tool_call
t.timestamps
end
ActiveRecord::Migration.create_table :chat_tool_calls, force: true do |t|
t.references :chat_message
t.string :tool_call_id
t.string :name
t.json :arguments
t.timestamps
end
class Chat::Message < ActiveRecord::Base
acts_as_message tool_calls: :chat_tool_calls, tool_call_class: "Chat::ToolCall", tool_calls_foreign_key: "chat_message_id"
end
class Chat::ToolCall < ActiveRecord::Base
acts_as_tool_call message: :chat_message, message_class: "Chat::Message", message_foreign_key: "chat_message_id", result: :result, result_class: "Chat::Message", result_foreign_key: "chat_tool_call_id"
end
Create a chat message, with a tool call and result, then force an error (or call cleanup_orphaned_tool_results directly)
Expected behavior
The tool call and result should be persisted in the database and associated with the chat message.
What actually happened
The tool call and result are destroyed.
Environment
Ruby 4.0
RubyLLM 1.11.0