From 6609f7637a478ef4110091609b4009fd0f627cff Mon Sep 17 00:00:00 2001 From: Pranav Date: Sun, 11 May 2025 01:09:03 -0700 Subject: [PATCH] Move conversation fetch as a tool --- .../components/copilot/CopilotContainer.vue | 14 +------ .../captain/process_copilot_message_job.rb | 9 +++-- .../services/captain/copilot/chat_service.rb | 32 +++++++++++---- .../tools/copilot/get_conversation_service.rb | 40 +++++++++++++++++++ 4 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 enterprise/app/services/captain/tools/copilot/get_conversation_service.rb diff --git a/app/javascript/dashboard/components/copilot/CopilotContainer.vue b/app/javascript/dashboard/components/copilot/CopilotContainer.vue index fd10489dc..4f4f311c6 100644 --- a/app/javascript/dashboard/components/copilot/CopilotContainer.vue +++ b/app/javascript/dashboard/components/copilot/CopilotContainer.vue @@ -6,22 +6,12 @@ import CopilotActionCableConnector from 'dashboard/helpers/CopilotActionCableCon import { useMapGetter } from 'dashboard/composables/store'; import { useUISettings } from 'dashboard/composables/useUISettings'; -const props = defineProps({ - conversationId: { - type: [Number, String, null], - default: null, - }, - conversationInboxType: { - type: String, - default: '', - }, -}); - const store = useStore(); const currentUser = useMapGetter('getCurrentUser'); const assistants = useMapGetter('captainAssistants/getRecords'); const inboxAssistant = useMapGetter('getCopilotAssistant'); const { uiSettings, updateUISettings } = useUISettings(); +const currentChat = useMapGetter('getSelectedChat'); const getUIState = useMapGetter('uiState/getUIState'); const isSidebarOpen = computed(() => getUIState.value('isCopilotSidebarOpen')); @@ -79,7 +69,7 @@ const sendMessage = message => { copilotConnector.value.sendMessage({ assistantId: activeAssistant.value.id, - conversationId: props.conversationId, + conversationId: currentChat.value?.id, previousHistory: messages.value .filter(m => m.role !== 'assistant_thinking') .map(m => ({ diff --git a/enterprise/app/jobs/captain/process_copilot_message_job.rb b/enterprise/app/jobs/captain/process_copilot_message_job.rb index da8064dbc..19800b998 100644 --- a/enterprise/app/jobs/captain/process_copilot_message_job.rb +++ b/enterprise/app/jobs/captain/process_copilot_message_job.rb @@ -35,9 +35,12 @@ class Captain::ProcessCopilotMessageJob < ApplicationJob Captain::Copilot::ChatService.new( @assistant, previous_messages: previous_history || [], - conversation_history: conversation&.to_llm_text, - language: @account.locale_english_name, - stream_writer: ->(data) { broadcast_response(data) } + stream_writer: ->(data) { broadcast_response(data) }, + additional_info: { + language: @account.locale_english_name, + conversation_id: conversation&.display_id, + contact_id: conversation&.contact_id + } ).generate_response(message) end diff --git a/enterprise/app/services/captain/copilot/chat_service.rb b/enterprise/app/services/captain/copilot/chat_service.rb index 469a91f6e..37de6f0fa 100644 --- a/enterprise/app/services/captain/copilot/chat_service.rb +++ b/enterprise/app/services/captain/copilot/chat_service.rb @@ -7,19 +7,33 @@ class Captain::Copilot::ChatService < Llm::BaseOpenAiService super() @assistant = assistant @tool_registry = Captain::ToolRegistryService.new(@assistant) - @language = config[:language] || 'english' - @messages = build_initial_messages(config) @stream_writer = config[:stream_writer] + setup_additional_info(config) + register_tools + @messages = build_initial_messages(config) + end + + def setup_additional_info(config) + additional_info = config[:additional_info] || {} + @language = additional_info[:language] || 'english' + @conversation_id = additional_info[:conversation_id] + @contact_id = additional_info[:contact_id] + end + + def register_tools + @tool_registry.register_tool(Captain::Tools::Copilot::GetConversationService) end def build_initial_messages(config) messages = [system_message] - messages << conversation_history_context if config[:conversation_history].present? - messages + (config[:previous_messages] || []) + messages += (config[:previous_messages] || []) + messages << current_viewing_history if @conversation_id + messages end def generate_response(input) @messages << { role: 'user', content: input } if input.present? + Rails.logger.info("[CAPTAIN][CopilotChatService] Initial Prompt: #{@messages}") response = request_chat_completion Rails.logger.info("[CAPTAIN][CopilotChatService] Incrementing response usage for #{@assistant.account.id}") @assistant.account.increment_response_usage @@ -42,14 +56,16 @@ class Captain::Copilot::ChatService < Llm::BaseOpenAiService } end - def conversation_history_context - return if @conversation_history.blank? + def current_viewing_history + return unless @conversation_id { role: 'system', content: <<~HISTORY.strip - Message History with the user is below: - #{@conversation_history} + You are currently viewing the conversation with the user with the following details: + Conversation ID: #{@conversation_id} + Contact ID: #{@contact_id} + Account ID: #{@assistant.account.id} HISTORY } end diff --git a/enterprise/app/services/captain/tools/copilot/get_conversation_service.rb b/enterprise/app/services/captain/tools/copilot/get_conversation_service.rb new file mode 100644 index 000000000..c564f8ced --- /dev/null +++ b/enterprise/app/services/captain/tools/copilot/get_conversation_service.rb @@ -0,0 +1,40 @@ +class Captain::Tools::Copilot::GetConversationService < Captain::Tools::BaseService + def name + 'get_conversation' + end + + def description + 'Get details of a conversation including messages and contact information' + end + + def parameters + { + type: 'object', + properties: { + conversation_id: { + type: 'string', + description: 'The ID of the conversation to retrieve' + }, + account_id: { + type: 'string', + description: 'The ID of the account the conversation belongs to' + } + }, + required: %w[conversation_id account_id] + } + end + + def execute(arguments) + conversation_id = arguments['conversation_id'] + account_id = arguments['account_id'] + + Rails.logger.info { "[CAPTAIN][GetConversation] #{conversation_id}, #{account_id}" } + + return 'Missing required parameters' if conversation_id.blank? || account_id.blank? + + conversation = Conversation.find_by(display_id: conversation_id, account_id: account_id) + return 'Conversation not found' unless conversation + + conversation.to_llm_text + end +end