Module: RubyLLM::ActiveRecord::ChatLegacyMethods

Extended by:
ActiveSupport::Concern
Defined in:
lib/ruby_llm/active_record/acts_as_legacy.rb

Overview

Methods mixed into chat models.

Instance Method Summary collapse

Instance Method Details

#add_message(message_or_attributes) ⇒ Object



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 197

def add_message(message_or_attributes)
  llm_message = message_or_attributes.is_a?(RubyLLM::Message) ? message_or_attributes : RubyLLM::Message.new(message_or_attributes)
  content, attachments_to_persist = prepare_content_for_storage(llm_message.content)

  attrs = { role: llm_message.role, content: }
  tool_call_foreign_key = messages.klass.tool_call_foreign_key
  if llm_message.tool_call_id && tool_call_foreign_key
    tool_call_id = find_tool_call_id(llm_message.tool_call_id)
    attrs[tool_call_foreign_key] = tool_call_id if tool_call_id
  end

  message_record = messages.create!(attrs)
  persist_content(message_record, attachments_to_persist) if attachments_to_persist.present?
  persist_tool_calls(llm_message.tool_calls, message_record:) if llm_message.tool_calls.present?

  message_record
end

#ask(message = nil, with: nil) ⇒ Object Also known as: say



223
224
225
226
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 223

def ask(message = nil, with: nil, &)
  add_message(role: :user, content: build_content(message, with))
  complete(&)
end

#completeObject



230
231
232
233
234
235
236
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 230

def complete(...)
  to_llm.complete(...)
rescue RubyLLM::Error => e
  cleanup_failed_messages if @message&.persisted? && @message.content.blank?
  cleanup_orphaned_tool_results
  raise e
end

#create_user_message(content, with: nil) ⇒ Object



215
216
217
218
219
220
221
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 215

def create_user_message(content, with: nil)
  RubyLLM.logger.warn(
    '`create_user_message` is deprecated and will be removed in RubyLLM 2.0. ' \
    'Use `add_message(role: :user, content: ...)` instead.'
  )
  add_message(role: :user, content: build_content(content, with))
end

#on_end_message(&block) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 175

def on_end_message(&block)
  to_llm

  existing_callback = @chat.instance_variable_get(:@on)[:end_message]

  @chat.on_end_message do |msg|
    existing_callback&.call(msg)
    block&.call(msg)
  end
  self
end

#on_new_message(&block) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 163

def on_new_message(&block)
  to_llm

  existing_callback = @chat.instance_variable_get(:@on)[:new_message]

  @chat.on_new_message do
    existing_callback&.call
    block&.call
  end
  self
end

#on_tool_callObject



187
188
189
190
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 187

def on_tool_call(...)
  to_llm.on_tool_call(...)
  self
end

#on_tool_resultObject



192
193
194
195
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 192

def on_tool_result(...)
  to_llm.on_tool_result(...)
  self
end

#to_llm(context: nil) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 89

def to_llm(context: nil)
  # model_id is a string that RubyLLM can resolve
  @chat ||= if context
              context.chat(model: model_id)
            else
              RubyLLM.chat(model: model_id)
            end
  @chat.reset_messages!

  ordered_messages = order_messages_for_llm(messages.to_a)
  ordered_messages.each do |msg|
    @chat.add_message(msg.to_llm)
  end
  reapply_runtime_instructions(@chat)

  setup_persistence_callbacks
end

#with_context(context) ⇒ Object



143
144
145
146
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 143

def with_context(context)
  to_llm(context: context)
  self
end

#with_headersObject



153
154
155
156
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 153

def with_headers(...)
  to_llm.with_headers(...)
  self
end

#with_instructions(instructions, append: false, replace: nil) ⇒ Object



107
108
109
110
111
112
113
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 107

def with_instructions(instructions, append: false, replace: nil)
  append = append_instructions?(append:, replace:)
  persist_system_instruction(instructions, append:)

  to_llm.with_instructions(instructions, append:, replace:)
  self
end

#with_modelObject



133
134
135
136
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 133

def with_model(...)
  update(model_id: to_llm.with_model(...).model.id)
  self
end

#with_paramsObject



148
149
150
151
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 148

def with_params(...)
  to_llm.with_params(...)
  self
end

#with_runtime_instructions(instructions, append: false, replace: nil) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 115

def with_runtime_instructions(instructions, append: false, replace: nil)
  append = append_instructions?(append:, replace:)
  store_runtime_instruction(instructions, append:)

  to_llm.with_instructions(instructions, append:, replace:)
  self
end

#with_schemaObject



158
159
160
161
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 158

def with_schema(...)
  to_llm.with_schema(...)
  self
end

#with_temperatureObject



138
139
140
141
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 138

def with_temperature(...)
  to_llm.with_temperature(...)
  self
end

#with_toolObject



123
124
125
126
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 123

def with_tool(...)
  to_llm.with_tool(...)
  self
end

#with_toolsObject



128
129
130
131
# File 'lib/ruby_llm/active_record/acts_as_legacy.rb', line 128

def with_tools(...)
  to_llm.with_tools(...)
  self
end