Files
clientsflow/research/chatwoot/spec/lib/captain/reply_suggestion_service_spec.rb

95 lines
3.7 KiB
Ruby

require 'rails_helper'
RSpec.describe Captain::ReplySuggestionService do
subject(:service) { described_class.new(account: account, conversation_display_id: conversation.display_id, user: agent) }
let(:account) { create(:account) }
let(:agent) { create(:user, account: account, name: 'Jane Smith') }
let(:inbox) { create(:inbox, account: account) }
let(:conversation) { create(:conversation, account: account, inbox: inbox) }
let(:captured_messages) { [] }
before do
create(:installation_config, name: 'CAPTAIN_OPEN_AI_API_KEY', value: 'test-key')
create(:message, conversation: conversation, message_type: :incoming, content: 'I need help')
allow(account).to receive(:feature_enabled?).with('captain_tasks').and_return(true)
mock_response = instance_double(RubyLLM::Message, content: 'Sure, I can help!', input_tokens: 50, output_tokens: 20)
mock_chat = instance_double(RubyLLM::Chat)
mock_context = instance_double(RubyLLM::Context, chat: mock_chat)
allow(Llm::Config).to receive(:with_api_key).and_yield(mock_context)
allow(mock_chat).to receive(:with_tool).and_return(mock_chat)
allow(mock_chat).to receive(:on_end_message).and_return(mock_chat)
allow(mock_chat).to receive(:with_instructions) { |msg| captured_messages << { role: 'system', content: msg } }
allow(mock_chat).to receive(:add_message) { |args| captured_messages << args }
allow(mock_chat).to receive(:ask) do |msg|
captured_messages << { role: 'user', content: msg }
mock_response
end
end
describe '#perform' do
it 'returns the suggested reply' do
result = service.perform
expect(result[:message]).to eq('Sure, I can help!')
end
it 'formats conversation using LlmFormatter' do
service.perform
user_message = captured_messages.find { |m| m[:role] == 'user' }
expect(user_message[:content]).to include('Message History:')
expect(user_message[:content]).to include('User: I need help')
end
context 'with chat channel' do
it 'uses chat-specific instructions' do
service.perform
system_prompt = captured_messages.find { |m| m[:role] == 'system' }[:content]
expect(system_prompt).to include('CHAT conversation')
expect(system_prompt).to include('brief, conversational')
expect(system_prompt).not_to include('EMAIL conversation')
end
end
context 'with email channel' do
let(:email_channel) { create(:channel_email, account: account) }
let(:inbox) { create(:inbox, account: account, channel: email_channel) }
it 'uses email-specific instructions' do
service.perform
system_prompt = captured_messages.find { |m| m[:role] == 'system' }[:content]
expect(system_prompt).to include('EMAIL conversation')
expect(system_prompt).to include('professional email')
expect(system_prompt).not_to include('CHAT conversation')
end
context 'when agent has a signature' do
let(:agent) { create(:user, account: account, name: 'Jane Smith', message_signature: "Best,\nJane Smith") }
it 'includes the signature in the prompt' do
service.perform
system_prompt = captured_messages.find { |m| m[:role] == 'system' }[:content]
expect(system_prompt).to include("Best,\nJane Smith")
end
end
context 'when agent has no signature' do
let(:agent) { create(:user, account: account, name: 'Jane Smith', message_signature: nil) }
it 'falls back to agent name for sign-off' do
service.perform
system_prompt = captured_messages.find { |m| m[:role] == 'system' }[:content]
expect(system_prompt).to include("sign-off using the agent's name: Jane Smith")
end
end
end
end
end