Class: AssistantMessage
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- AssistantMessage
- Includes:
- PgSearch::Model
- Defined in:
- app/models/assistant_message.rb
Overview
== Schema Information
Table name: assistant_messages
Database name: primary
id :bigint not null, primary key
cache_until_here :boolean default(FALSE), not null
citations :jsonb
compacted_content :text
content :text
content_raw :json
finish_reason :string
grounding_assessment :jsonb
model_id :string
provider :string
role :string not null
thinking_signature :text
thinking_text :text
created_at :datetime not null
updated_at :datetime not null
assistant_conversation_id :bigint not null
sender_id :bigint
Indexes
index_assistant_messages_on_assistant_conversation_id (assistant_conversation_id)
index_assistant_messages_on_provider_and_model_id (provider,model_id)
index_assistant_messages_on_role (role)
index_assistant_messages_on_sender_id (sender_id)
Foreign Keys
fk_rails_... (assistant_conversation_id => assistant_conversations.id)
Token and cost figures are NOT columns here any more — RubyLLM 2.0 keeps a
per-attempt ledger in ruby_llm_usage_entries, reachable as message.tokens
/ message.cost (nil when the message recorded no usage).
Constant Summary collapse
- LEGACY_OPPORTUNITY_BRIEFING_PREFIX =
Prefix used to identify legacy opportunity briefing prompts.
'Prepare an on-demand sales briefing'
Constants included from Models::Schedulable
Models::Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
- #assistant_conversation ⇒ AssistantConversation readonly
- #role ⇒ String readonly
Has many collapse
-
#assistant_tool_calls ⇒ ActiveRecord::Relation<AssistantToolCall>
Tool calls moved into RubyLLM-owned storage in 2.0.
Has one collapse
Belongs to collapse
Class Method Summary collapse
-
.assistant_messages ⇒ ActiveRecord::Relation<AssistantMessage>
A relation of AssistantMessages that are assistant messages.
-
.by_sender ⇒ ActiveRecord::Relation<AssistantMessage>
A relation of AssistantMessages that are by sender.
-
.system_messages ⇒ ActiveRecord::Relation<AssistantMessage>
A relation of AssistantMessages that are system messages.
-
.user_messages ⇒ ActiveRecord::Relation<AssistantMessage>
A relation of AssistantMessages that are user messages.
-
.with_thinking ⇒ ActiveRecord::Relation<AssistantMessage>
A relation of AssistantMessages that are with thinking.
Instance Method Summary collapse
-
#template_initiated? ⇒ Boolean
Application-generated prompts are persisted as user turns for LLM history, but should not be presented as if a rep typed their full internal payload.
Methods inherited from ApplicationRecord
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
Methods included from Models::Schedulable
Methods included from Models::AfterCommittable
Methods included from Models::EventPublishable
Instance Attribute Details
#assistant_conversation ⇒ AssistantConversation (readonly)
81 |
# File 'app/models/assistant_message.rb', line 81 validates :assistant_conversation, presence: true |
#role ⇒ String (readonly)
79 |
# File 'app/models/assistant_message.rb', line 79 validates :role, presence: true |
Class Method Details
.assistant_messages ⇒ ActiveRecord::Relation<AssistantMessage>
A relation of AssistantMessages that are assistant messages. Active Record Scope
88 |
# File 'app/models/assistant_message.rb', line 88 scope :assistant_messages, -> { where(role: 'assistant') } |
.by_sender ⇒ ActiveRecord::Relation<AssistantMessage>
A relation of AssistantMessages that are by sender. Active Record Scope
91 |
# File 'app/models/assistant_message.rb', line 91 scope :by_sender, ->(party_id) { where(sender_id: party_id) } |
.system_messages ⇒ ActiveRecord::Relation<AssistantMessage>
A relation of AssistantMessages that are system messages. Active Record Scope
89 |
# File 'app/models/assistant_message.rb', line 89 scope :system_messages, -> { where(role: 'system') } |
.user_messages ⇒ ActiveRecord::Relation<AssistantMessage>
A relation of AssistantMessages that are user messages. Active Record Scope
87 |
# File 'app/models/assistant_message.rb', line 87 scope :user_messages, -> { where(role: 'user') } |
.with_thinking ⇒ ActiveRecord::Relation<AssistantMessage>
A relation of AssistantMessages that are with thinking. Active Record Scope
90 |
# File 'app/models/assistant_message.rb', line 90 scope :with_thinking, -> { where.not(thinking_text: nil) } |
Instance Method Details
#assistant_parent_tool_call ⇒ AssistantToolCall?
69 70 |
# File 'app/models/assistant_message.rb', line 69 has_one :assistant_parent_tool_call, -> { where(result_type: AssistantToolCall::MESSAGE_TYPE) }, class_name: 'AssistantToolCall', foreign_key: :result_id, inverse_of: :result |
#assistant_tool_calls ⇒ ActiveRecord::Relation<AssistantToolCall>
Tool calls moved into RubyLLM-owned storage in 2.0. AssistantToolCall is now
the application's read model over that table (see the class for why) — these
two associations keep the app's own names so the seam holds. dependent: is
deliberately absent: acts_as_message's own ruby_llm_tool_calls association
already destroys/nullifies the same rows.
Do not call the result-side association parent_tool_call: RubyLLM's
MessageMethods defines that name and returns a RubyLLM::ToolCall value object,
shadowing ActiveRecord's generated association method. Keeping the record and
value-object names distinct prevents integer row ids from being confused with
provider ids such as toolu_... during replay (AppSignal #3808 / #3830).
66 67 |
# File 'app/models/assistant_message.rb', line 66 has_many :assistant_tool_calls, -> { where(message_type: AssistantToolCall::MESSAGE_TYPE).order(:id) }, class_name: 'AssistantToolCall', foreign_key: :message_id, inverse_of: :assistant_message |
#parent_tool_call ⇒ AssistantToolCall?
72 73 |
# File 'app/models/assistant_message.rb', line 72 has_one :parent_tool_call, -> { where(result_type: AssistantToolCall::MESSAGE_TYPE) }, class_name: 'AssistantToolCall', foreign_key: :result_id, deprecated: true |
#sender ⇒ Party?
76 |
# File 'app/models/assistant_message.rb', line 76 belongs_to :sender, class_name: 'Party', optional: true |
#template_initiated? ⇒ Boolean
Application-generated prompts are persisted as user turns for LLM history,
but should not be presented as if a rep typed their full internal payload.
101 102 103 104 105 106 |
# File 'app/models/assistant_message.rb', line 101 def template_initiated? return false unless role == 'user' && content.present? return false unless assistant_conversation assistant_conversation.template_prompt?(content) || legacy_opportunity_briefing_prompt? end |