Tidy up #ask & #respond

This commit is contained in:
Stanko K.R.
2025-08-11 17:40:55 +02:00
parent c95e8678a9
commit 8a8888c3ef
2 changed files with 37 additions and 26 deletions
+21 -24
View File
@@ -1,4 +1,6 @@
class Conversation < ApplicationRecord
class InvalidStateError < StandardError; end
include Broadcastable
belongs_to :user, class_name: "User"
@@ -16,36 +18,31 @@ class Conversation < ApplicationRecord
end
def ask(question, **attributes)
raise ArgumentError, "Question cannot be blank" if question.blank?
message = nil
with_lock do
return if thinking?
atomically_create_message(**attributes, role: :user, content: question) do
raise(InvalidStateError, "Can't ask questions while thinking") if thinking?
thinking!
message = messages.create!(**attributes, role: :user, content: question)
end
message.broadcast_create
broadcast_state_change
message
end
def respond(answer, **attributes)
raise ArgumentError, "Answer cannot be blank" if answer.blank?
message = nil
with_lock do
return unless thinking?
message = messages.create!(**attributes, role: :assistant, content: answer)
atomically_create_message(**attributes, role: :assistant, content: answer) do
raise(InvalidStateError, "Can't respond when not thinking") unless thinking?
ready!
end
message.broadcast_create
broadcast_state_change
message
end
private
def atomically_create_message(**attributes)
message = nil
with_lock do
yield
message = messages.create!(**attributes)
end
message.broadcast_create
broadcast_state_change
message
end
end
+16 -2
View File
@@ -6,10 +6,17 @@ class ConversationTest < ActiveSupport::TestCase
test "asking questions" do
conversation = users(:kevin).conversation
assert_raises(ArgumentError) do
# You can't respond to a conversation while it's in the thinking state
assert_raises(Conversation::InvalidStateError) do
conversation.respond("Ok")
end
assert_raises(ActiveRecord::RecordInvalid) do
conversation.ask("")
end
conversation.reload
assert conversation.ready?, "The conversation should be ready before a question is asked"
message = nil
@@ -28,10 +35,17 @@ class ConversationTest < ActiveSupport::TestCase
test "responding to questions" do
conversation = users(:david).conversation
assert_raises(ArgumentError) do
# You can't ask a question in a conversation that isn't ready
assert_raises(Conversation::InvalidStateError) do
conversation.ask("hi!")
end
assert_raises(ActiveRecord::RecordInvalid) do
conversation.respond("")
end
conversation.reload
assert conversation.thinking?, "The conversation should be thinking before a response is made"
message = nil