allow conversations to use different agents
called agents instead of models to avoid confusion with rails modelsmain
parent
e61c88f6c9
commit
abf32bb480
|
|
@ -0,0 +1,7 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class ApplicationAgent
|
||||||
|
def prompt(_conversation)
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class DummyAgent
|
||||||
|
def prompt(_conversation)
|
||||||
|
# NOTE: Put logic for however we get a reply in this method (HTTP/RPC/IPC/etc)
|
||||||
|
# NOTE: Use the conversation record to supply necessary context for the agent.
|
||||||
|
'AI Reply'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -12,7 +12,8 @@ class ConversationsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@conversation = @current_user.conversations.new
|
# NOTE: Real application would have agent be given from params
|
||||||
|
@conversation = @current_user.conversations.new(agent: 'DummyAgent')
|
||||||
if @conversation.save
|
if @conversation.save
|
||||||
redirect_to @conversation
|
redirect_to @conversation
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ class GenerateReplyJob < ApplicationJob
|
||||||
queue_as :default
|
queue_as :default
|
||||||
|
|
||||||
def perform(conversation)
|
def perform(conversation)
|
||||||
conversation.messages.create(body: 'AI Reply', reply: true)
|
agent = conversation.agent_klass.new
|
||||||
|
reply = agent.prompt(conversation)
|
||||||
|
conversation.messages.create!(body: reply, reply: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,16 @@ class Conversation < ApplicationRecord
|
||||||
|
|
||||||
has_many :messages, dependent: :destroy
|
has_many :messages, dependent: :destroy
|
||||||
|
|
||||||
|
AGENTS = {
|
||||||
|
'DummyAgent' => DummyAgent,
|
||||||
|
}.freeze
|
||||||
|
validates :agent, presence: true, inclusion: { in: AGENTS.keys }
|
||||||
|
|
||||||
def pending_reply?
|
def pending_reply?
|
||||||
messages.last.promt?
|
messages.last.promt?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def agent_klass
|
||||||
|
AGENTS[agent]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddAgentToConversation < ActiveRecord::Migration[8.0]
|
||||||
|
def change
|
||||||
|
# NOTE: Violating Rails/NotNullColumn is fine if there's no production environment yet.
|
||||||
|
# Otherwise I usually make a migration that uses null: true,
|
||||||
|
# then backfills something reasonable, then sets null: false.
|
||||||
|
# Of course only in the case if I don't want the column to just have a default.
|
||||||
|
add_column :conversations, :agent, :string, null: false # rubocop:disable Rails/NotNullColumn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -10,11 +10,12 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[8.0].define(version: 2025_03_01_202033) do
|
ActiveRecord::Schema[8.0].define(version: 2025_03_02_065926) do
|
||||||
create_table "conversations", force: :cascade do |t|
|
create_table "conversations", force: :cascade do |t|
|
||||||
t.integer "user_id", null: false
|
t.integer "user_id", null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
|
t.string "agent", null: false
|
||||||
t.index ["user_id"], name: "index_conversations_on_user_id"
|
t.index ["user_id"], name: "index_conversations_on_user_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue