When I demo'd the gem in class today, I ended up with something like this:
# Get all the older messages for this topic from the db
the_topic = the_message.topic
the_history = the_topic.messages.order(:created_at)
# Reconstruct an AI::Chat from scratch
chat = OpenAI::Chat.new
the_history.each do |a_message|
if a_message.role == "system"
chat.system(a_message.content)
elsif a_message.role == "user"
chat.user(a_message.content)
else
chat.assistant(a_message.content)
end
end
# Get the next assistant message
next_message = Message.new
next_message.topic_id = the_topic.id
next_message.role = "assistant"
next_message.content = chat.assistant!
next_message.save
I think it would be nice if:
We could directly assign a hash as a message:
chat.message({ :role => "user", :content => "stuff" })
chat.message({ :role => "user", :content => "stuff", :image => an_imagelike })
chat.message({ :role => "user", :content => "stuff", :images => array_of_imagelikes })
Interwoven text and images:
chat.message({
:role => :user,
:content => [
{"image" => "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/Eubalaena_glacialis_with_calf.jpg/215px-Eubalaena_glacialis_with_calf.jpg"},
{"text" => "What is in the above image? What is in the below image?"},
{"image" => "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Elephant_Diversity.jpg/305px-Elephant_Diversity.jpg"},
{"text" => "What are the differences between the images?"}
]
})
We can directly assign any object:
... assuming that thing responds to thing.role/thing[:role] and thing.content/thing[:content]. It will also check thing.image/thing.images, unless prevented with the image: false option: chat.message(thing, image: false).
And, we could allow for custom mappings:
chat.message(thing, :role => "kind", :content => :body)
chat.message(thing, :image => "pic" )
chat.message(thing, :images => "photos") # assumes that each object returned by `send("photos") responds to `:image`
chat.message(thing, :images => "photos", :source => "pic_url" )
Once we have such a method message() implemented, system(), user(), and assistant() could delegate to it. And it should be straightforward to add messages():
def messages(collection, options = nil)
collection.each { message(_1, options) }
end
Hopefully this would allow for passing an ActiveRecord::Relation:
chat.messages(topic.messages.order(:created_at)
chat.assistant!
I started working on this here, but I think the above implementation would be better than what I started there.
When I demo'd the gem in class today, I ended up with something like this:
I think it would be nice if:
We could directly assign a hash as a message:
Interwoven text and images:
We can directly assign any object:
... assuming that
thingresponds tothing.role/thing[:role]andthing.content/thing[:content]. It will also checkthing.image/thing.images, unless prevented with theimage: falseoption:chat.message(thing, image: false).And, we could allow for custom mappings:
Once we have such a method
message()implemented,system(),user(), andassistant()could delegate to it. And it should be straightforward to addmessages():Hopefully this would allow for passing an
ActiveRecord::Relation:I started working on this here, but I think the above implementation would be better than what I started there.