feat(ee): Add Captain features (#10665)

Migration Guide: https://chwt.app/v4/migration

This PR imports all the work related to Captain into the EE codebase. Captain represents the AI-based features in Chatwoot and includes the following key components:

- Assistant: An assistant has a persona, the product it would be trained on. At the moment, the data at which it is trained is from websites. Future integrations on Notion documents, PDF etc. This PR enables connecting an assistant to an inbox. The assistant would run the conversation every time before transferring it to an agent.
- Copilot for Agents: When an agent is supporting a customer, we will be able to offer additional help to lookup some data or fetch information from integrations etc via copilot.
- Conversation FAQ generator: When a conversation is resolved, the Captain integration would identify questions which were not in the knowledge base.
- CRM memory: Learns from the conversations and identifies important information about the contact.

---------

Co-authored-by: Vishnu Narayanan <vishnu@chatwoot.com>
Co-authored-by: Sojan <sojan@pepalo.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
This commit is contained in:
Pranav
2025-01-14 16:15:47 -08:00
committed by GitHub
parent 7b31b5ad6e
commit d070743383
184 changed files with 6666 additions and 2242 deletions

View File

@@ -0,0 +1,77 @@
class Captain::Copilot::ChatService
def initialize(assistant, config)
@assistant = assistant
@conversation_history = config[:conversation_history]
@previous_messages = config[:previous_messages]
build_agent
register_search_documentation
end
def execute(input)
@agent.execute(input, conversation_history_context)
end
private
def build_agent
@agent = Captain::Agent.new(
name: 'Support Copilot',
config: {
description: 'an AI assistant helping support agents',
messages: @previous_messages,
persona: 'You are an AI copilot for customer support agents',
goal: "
Your goal is help the support agents with meaningful responses based on the knowledge you have
and you can gather using tools provided about the product or service.
",
secrets: {
OPENAI_API_KEY: InstallationConfig.find_by!(name: 'CAPTAIN_OPEN_AI_API_KEY').value
},
max_iterations: 2
}
)
end
def conversation_history_context
"
Message History with the user is below:
#{@conversation_history}
"
end
def register_search_documentation
tool = Captain::Tool.new(
name: 'search_documentation',
config: {
description: "Use this function to get documentation on functionalities you don't know about.",
properties: {
search_query: {
type: 'string',
description: 'The search query to look up in the documentation.',
required: true
}
},
memory: {
assistant_id: @assistant.id,
account_id: @assistant.account_id
}
}
)
register_tool tool
end
def register_tool(tool)
tool.register_method do |inputs, _, memory|
assistant = Captain::Assistant.find(memory[:assistant_id])
assistant
.responses
.search(inputs['search_query'])
.map do |response|
"\n\nQuestion: #{response[:question]}\nAnswer: #{response[:answer]}"
end.join
end
@agent.register_tool tool
end
end