Skip to content
10 changes: 8 additions & 2 deletions lib/ruby_llm/active_record/acts_as.rb
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,15 @@ def extract_tool_call_id
end

def extract_content
return content unless respond_to?(:attachments) && attachments.attached?
text_content = if content.respond_to?(:to_plain_text)
content.to_plain_text
else
content.to_s
end

RubyLLM::Content.new(content).tap do |content_obj|
return text_content unless respond_to?(:attachments) && attachments.attached?

RubyLLM::Content.new(text_content).tap do |content_obj|
@_tempfiles = []

attachments.each do |attachment|
Expand Down
1 change: 1 addition & 0 deletions spec/dummy/config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require 'active_record/railtie'
require 'active_storage/engine'
require 'action_controller/railtie'
require 'action_text/engine'

Bundler.require(*Rails.groups)
require 'ruby_llm'
Expand Down
23 changes: 23 additions & 0 deletions spec/ruby_llm/active_record/acts_as_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,29 @@ class BotToolCall < ActiveRecord::Base # rubocop:disable Lint/ConstantDefinition
end
end

describe 'Action Text content support' do
it 'converts Action Text content to plain text' do
chat = Chat.create!(model_id: model)
action_text_content = instance_double(ActionText::RichText)
allow(action_text_content).to receive(:to_plain_text).and_return('This is rich text content')

message = chat.messages.create!(role: 'user')
allow(message).to receive(:content).and_return(action_text_content)

llm_message = message.to_llm

expect(action_text_content).to have_received(:to_plain_text)
expect(llm_message.content).to eq('This is rich text content')
end

it 'handles regular string content when to_plain_text is not available' do
chat = Chat.create!(model_id: model)
message = chat.messages.create!(role: 'user', content: 'Regular text content')
llm_message = message.to_llm
expect(llm_message.content).to eq('Regular text content')
end
end

describe 'attachment handling' do
let(:image_path) { File.expand_path('../../fixtures/ruby.png', __dir__) }
let(:pdf_path) { File.expand_path('../../fixtures/sample.pdf', __dir__) }
Expand Down