main
rb 44 lines 1.37 KB
Raw
1 # frozen_string_literal: true
2
3 # A siGit Code Cloud Session: a named, resumable conversation persisted so it
4 # follows the user across devices. Owns its messages in order; `model` is the
5 # neutral cloud tier wire id (onde-fast/balanced/large), never an upstream name.
6 class CloudSession < ApplicationRecord
7 belongs_to :user
8 has_many :cloud_messages, -> { order(:created_at, :id) }, dependent: :destroy
9
10 validates :title, presence: true, length: { maximum: 200 }
11 validates :model, presence: true
12
13 before_validation :default_title
14
15 # Append a message and bump the session's activity timestamp so the list stays
16 # ordered by most-recent. Auto-titles the session from the first user message
17 # while it still has the default title.
18 def append_message!(role:, content:)
19 message = nil
20 transaction do
21 message = cloud_messages.create!(role: role, content: content.to_s)
22 retitle_from(content) if role == "user" && default_title?
23 update!(last_message_at: message.created_at)
24 end
25 message
26 end
27
28 private
29
30 def default_title
31 self.title = "New session" if title.blank?
32 end
33
34 def default_title?
35 title.blank? || title == "New session"
36 end
37
38 def retitle_from(content)
39 snippet = content.to_s.strip.split("\n").first.to_s.strip
40 return if snippet.blank?
41
42 self.title = snippet.length > 80 ? "#{snippet[0, 80].rstrip}…" : snippet
43 end
44 end