module RubyLLM::ActiveRecord::MessageMethods
Maps an application-owned message record onto RubyLLM’s public Message API while keeping accounting and tool-call rows private to the gem.
Public Instance Methods
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 102 def cache_ttl optional_column(:cache_ttl) if cache_until_here? end
Returns the cache lifetime given to the message’s boundary, or nil when the chat’s caching policy applies.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 81 def cache_until_here(ttl: nil) attributes = { cache_until_here: true } attributes[:cache_ttl] = ttl if ttl || has_attribute?(:cache_ttl) update!(attributes) association(chat_association_name).target&.refresh_messages self end
Marks the message as a prompt cache boundary and returns it. Pass ttl: to give the boundary its own cache lifetime, as RubyLLM::Message#cache_until_here describes. The chat that returned the message sends the boundary with its next request.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 90 def cache_until_here? optional_column(:cache_until_here) || false end
Returns true if the message is a prompt cache boundary.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 28 def chunk(content, index:) ChunkMethods.attach(RubyLLM::Chunk.new(role: :assistant, content:, index:), self) end
Returns an assistant RubyLLM::Chunk with content at position index that streams into this message, as the chunks a persisted chat yields do, so it answers message and broadcast. Use it to stand in for a streamed reply in tests:
chunk = message.chunk("Hello", index: 0) chunk.broadcast
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 115 def citations Array(optional_column(:citations)).map { |citation| RubyLLM::Citation.from_h(citation) } end
Returns the citations as an array of RubyLLM::Citation.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 210 def content_filtered? to_llm.content_filtered? end
Returns true if a provider safety filter stopped the response.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 130 def cost records = ruby_llm_usage_records RubyLLM::Cost.aggregate(records.map(&:cost), complete: records.all?(&:cost_available?)) end
Returns the cost across every attempt that produced the message, as a RubyLLM::Cost.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 190 def finish_reason optional_column(:finish_reason)&.to_sym end
Returns why the model stopped, as the Symbol RubyLLM::Message#finish_reason reports.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 200 def max_tokens? to_llm.max_tokens? end
Returns true if a token limit stopped the response.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 149 def mcp_result record = ruby_llm_parent_tool_call data = record[:mcp_result] if record&.has_attribute?(:mcp_result) RubyLLM::MCP::Result.load(data) if data end
Returns the RubyLLM::MCP::Result kept for an MCP tool with a UI, as RubyLLM::Message#mcp_result does, or nil. It persists on the tool call, so the UI renders again after a reload.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 68 def model to_llm.model end
Returns the model ID from the last successful attempt, or nil.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 73 def model_info to_llm.model_info end
Returns the model from the registry, or nil if it is unknown.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 142 def parent_tool_call ruby_llm_parent_tool_call&.to_llm end
Returns the tool call this message answers, or nil.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 215 def parsed text = extract_content return if text.nil? || text.empty? JSON.parse(text) end
Returns the content parsed as JSON, or nil when the message has no text.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 120 def server_tool_calls Array(optional_column(:server_tool_calls)).map { |call| RubyLLM::ServerToolCall.from_h(call) } end
Returns the provider-executed tool steps as an array of RubyLLM::ServerToolCall.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 195 def stopped? to_llm.stopped? end
Returns true if the model finished normally without requesting tools.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 107 def thinking RubyLLM::Thinking.build( text: optional_column(:thinking_text), signature: optional_column(:thinking_signature) ) end
Returns the reasoning the model returned as a RubyLLM::Thinking, or nil.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 34 def to_llm entries = ruby_llm_usage_entries RubyLLM::Message.new( role: role.to_sym, content: extract_content, attachments: extract_attachments, thinking: thinking, citations: citations, server_tool_calls: server_tool_calls, raw_content: optional_column(:raw_content), raw_reasoning: optional_column(:raw_reasoning), phase: optional_column(:phase), usage_entries: entries, cost: (cost if entries.any?), tool_calls: tool_calls, tool_call_id: parent_tool_call&.id, provider_call_id: parent_tool_call&.provider_call_id, mcp_result: mcp_result, finish_reason: optional_column(:finish_reason), model: entries.reverse.find(&:succeeded?)&.model, cache_until_here: cache_until_here?, cache_ttl: cache_ttl ) end
Converts this record to a RubyLLM::Message. The message carries the recorded cost, so RubyLLM::Message#to_h exports it.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 172 def to_partial_path partial_prefix = self.class.name.underscore.pluralize role_partial = if tool_call? 'tool_calls' elsif role.to_s == 'tool' 'tool' else role.to_s.presence || 'assistant' end "#{partial_prefix}/#{role_partial}" end
Returns the partial path for the message by role, such as messages/assistant or messages/tool_calls.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 125 def tokens RubyLLM::Tokens.aggregate(ruby_llm_usages.map(&:tokens)) end
Returns the token usage across every attempt that produced the message.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 161 def tool_call? ruby_llm_tool_calls.any? end
Returns true if the message carries tool calls.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 205 def tool_call_stop? to_llm.tool_call_stop? end
Returns true if the model stopped to request tool calls.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 136 def tool_calls records = preloaded_records(:ruby_llm_tool_calls) || ruby_llm_tool_calls records.to_h { |record| [record.tool_call_id, record.to_llm] } end
Returns the tool calls as RubyLLM::ToolCall values keyed by call id.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 185 def tool_error_message payload_error_message(extract_content) end
Returns the error text of a failed tool result, or nil.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 166 def tool_result? ruby_llm_parent_tool_call.present? end
Returns true if the message answers a tool call.
Source
# File lib/ruby_llm/active_record/message_methods.rb, line 156 def tool_results ruby_llm_tool_calls.filter_map(&:result) end
Returns the message records that answer this message’s tool calls.