Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc86f93879 | ||
|
|
baf860016f | ||
|
|
ecc4f1403d | ||
|
|
6ea17e700f | ||
|
|
da58cbd24a | ||
|
|
a31f95cf45 | ||
|
|
d932156dec | ||
|
|
2cbc14e366 | ||
|
|
548360583e |
@@ -78,7 +78,7 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob
|
||||
end
|
||||
|
||||
def handoff_requested?
|
||||
@response['response'] == 'conversation_handoff'
|
||||
@response['action'] == 'handoff'
|
||||
end
|
||||
|
||||
def process_action(action)
|
||||
@@ -97,9 +97,10 @@ class Captain::Conversation::ResponseBuilderJob < ApplicationJob
|
||||
end
|
||||
|
||||
def create_handoff_message
|
||||
create_outgoing_message(
|
||||
@assistant.config['handoff_message'].presence || I18n.t('conversations.captain.handoff')
|
||||
)
|
||||
handoff_message = @response&.dig('response').presence ||
|
||||
@assistant.config['handoff_message'].presence ||
|
||||
I18n.t('conversations.captain.handoff')
|
||||
create_outgoing_message(handoff_message)
|
||||
end
|
||||
|
||||
def create_messages
|
||||
|
||||
@@ -94,8 +94,9 @@ class Captain::Assistant::AgentRunnerService
|
||||
|
||||
def error_response(error_message)
|
||||
{
|
||||
'response' => 'conversation_handoff',
|
||||
'reasoning' => "Error occurred: #{error_message}"
|
||||
'response' => 'Transferring to another agent for further assistance.',
|
||||
'reasoning' => "Error occurred: #{error_message}",
|
||||
'action' => 'handoff'
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -194,14 +194,25 @@ class Captain::Llm::SystemPromptsService
|
||||
- Do not share anything outside of the context provided.
|
||||
- Add the reasoning why you arrived at the answer
|
||||
- Your answers will always be formatted in a valid JSON hash, as shown below. Never respond in non-JSON format.
|
||||
#{config['instructions'] || ''}
|
||||
#{config['instructions'].present? ? "\n [Custom Instructions]\n #{config['instructions']}\n" : ''}
|
||||
|
||||
```json
|
||||
{
|
||||
reasoning: '',
|
||||
response: '',
|
||||
"reasoning": "",
|
||||
"response": "",
|
||||
"action": "continue" | "offer_handoff" | "handoff"
|
||||
}
|
||||
```
|
||||
- If the answer is not provided in context sections, Respond to the customer and ask whether they want to talk to another support agent . If they ask to Chat with another agent, return `conversation_handoff' as the response in JSON response
|
||||
The action field MUST be one of:
|
||||
- "continue": Default. Use for normal conversation flow.
|
||||
- "offer_handoff": Use when a handoff scenario is triggered (by custom instructions, inability to help, user frustration, or complex situations). Your response MUST ask the user if they would like to be connected to a support agent. Do NOT transfer yet - wait for their confirmation.
|
||||
- "handoff": Use ONLY when:
|
||||
• User has confirmed after you offered a handoff, OR
|
||||
• User explicitly requests human support unprompted (in any language)
|
||||
Never use handoff for scenarios where the bot decides a handoff is needed - use offer_handoff instead.
|
||||
|
||||
When action is "handoff", your response field MUST contain a message letting the user know they'll be connected to support.
|
||||
This message MUST be in the same language as the user's message.
|
||||
#{'- You MUST provide numbered citations at the appropriate places in the text.' if config['feature_citation']}
|
||||
SYSTEM_PROMPT_MESSAGE
|
||||
end
|
||||
|
||||
@@ -57,11 +57,13 @@ module Enterprise::MessageTemplates::HookExecutionService
|
||||
return unless conversation.pending?
|
||||
|
||||
Rails.logger.info("Captain limit exceeded, performing handoff mid-conversation for conversation: #{conversation.id}")
|
||||
handoff_message = inbox.captain_assistant&.config&.dig('handoff_message').presence ||
|
||||
'Transferring to another agent for further assistance.'
|
||||
conversation.messages.create!(
|
||||
message_type: :outgoing,
|
||||
account_id: conversation.account.id,
|
||||
inbox_id: conversation.inbox.id,
|
||||
content: 'Transferring to another agent for further assistance.'
|
||||
content: handoff_message
|
||||
)
|
||||
conversation.bot_handoff!
|
||||
send_out_of_office_message_after_handoff
|
||||
|
||||
@@ -251,7 +251,7 @@ RSpec.describe Captain::Conversation::ResponseBuilderJob, type: :job do
|
||||
closed_all_day: true,
|
||||
open_all_day: false
|
||||
)
|
||||
allow(mock_llm_chat_service).to receive(:generate_response).and_return({ 'response' => 'conversation_handoff' })
|
||||
allow(mock_llm_chat_service).to receive(:generate_response).and_return({ 'action' => 'handoff' })
|
||||
end
|
||||
|
||||
it 'sends out of office message after handoff' do
|
||||
@@ -275,7 +275,7 @@ RSpec.describe Captain::Conversation::ResponseBuilderJob, type: :job do
|
||||
open_all_day: true,
|
||||
closed_all_day: false
|
||||
)
|
||||
allow(mock_llm_chat_service).to receive(:generate_response).and_return({ 'response' => 'conversation_handoff' })
|
||||
allow(mock_llm_chat_service).to receive(:generate_response).and_return({ 'action' => 'handoff' })
|
||||
end
|
||||
|
||||
it 'does not send out of office message after handoff' do
|
||||
@@ -321,7 +321,7 @@ RSpec.describe Captain::Conversation::ResponseBuilderJob, type: :job do
|
||||
closed_all_day: true,
|
||||
open_all_day: false
|
||||
)
|
||||
allow(mock_llm_chat_service).to receive(:generate_response).and_return({ 'response' => 'conversation_handoff' })
|
||||
allow(mock_llm_chat_service).to receive(:generate_response).and_return({ 'action' => 'handoff' })
|
||||
end
|
||||
|
||||
it 'does not send out of office message' do
|
||||
|
||||
@@ -148,8 +148,9 @@ RSpec.describe Captain::Assistant::AgentRunnerService do
|
||||
result = service.generate_response(message_history: message_history)
|
||||
|
||||
expect(result).to eq({
|
||||
'response' => 'conversation_handoff',
|
||||
'reasoning' => 'Error occurred: Test error'
|
||||
'response' => 'Transferring to another agent for further assistance.',
|
||||
'reasoning' => 'Error occurred: Test error',
|
||||
'action' => 'handoff'
|
||||
})
|
||||
end
|
||||
|
||||
@@ -169,7 +170,8 @@ RSpec.describe Captain::Assistant::AgentRunnerService do
|
||||
result = service.generate_response(message_history: message_history)
|
||||
|
||||
expect(result).to eq({
|
||||
'response' => 'conversation_handoff',
|
||||
'response' => 'Transferring to another agent for further assistance.',
|
||||
'action' => 'handoff',
|
||||
'reasoning' => 'Error occurred: Test error'
|
||||
})
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user