Tidy up #ask & #respond
This commit is contained in:
+21
-24
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user