feat: add new tools

This commit is contained in:
Shivam Mishra
2025-07-15 14:22:27 +05:30
parent bdd5a77f45
commit 673669cd25
3 changed files with 174 additions and 1 deletions
+11 -1
View File
@@ -18,4 +18,14 @@
- id: update_priority
title: "Update Priority"
description: "Update conversation priority level"
icon: "exclamation-triangle"
icon: "exclamation-triangle"
- id: search_contact
title: "Search Contact"
description: "Search for a contact by email, phone number, or identifier"
icon: "search"
- id: add_label_to_conversation
title: "Add Label to Conversation"
description: "Add a label to a conversation"
icon: "tag"
@@ -0,0 +1,88 @@
class Captain::Tools::AddLabelToConversationTool < Captain::Tools::BaseAgentTool
def name
'add_label_to_conversation'
end
def display_name
'Add Label to Conversation'
end
def description
'Add a label to a conversation'
end
def execute(arguments = {})
conversation_id = arguments[:conversation_id]
label_name = arguments[:label_name]&.strip&.downcase
return error_response('Conversation ID is required') if conversation_id.blank?
return error_response('Label name is required') if label_name.blank?
conversation = find_conversation(conversation_id)
return error_response('Conversation not found') unless conversation
label = find_or_create_label(label_name)
return error_response('Failed to find or create label') unless label
add_label_to_conversation(conversation, label_name)
log_tool_usage('added_label', conversation_id: conversation_id, label: label_name)
success_response(conversation, label_name)
end
def json_schema
{
type: 'object',
properties: {
conversation_id: {
type: 'integer',
description: 'The ID of the conversation'
},
label_name: {
type: 'string',
description: 'The name of the label to add'
}
},
required: %w[conversation_id label_name]
}
end
private
def find_conversation(conversation_id)
account_scoped(Conversation).find_by(id: conversation_id)
end
def find_or_create_label(label_name)
account_scoped(Label).find_or_create_by(title: label_name)
rescue ActiveRecord::RecordInvalid => e
Rails.logger.error "Failed to create label: #{e.message}"
nil
end
def add_label_to_conversation(conversation, label_name)
conversation.add_labels(label_name)
rescue StandardError => e
Rails.logger.error "Failed to add label to conversation: #{e.message}"
raise
end
def success_response(conversation, label_name)
{
success: true,
message: "Label '#{label_name}' added to conversation ##{conversation.display_id}",
conversation_id: conversation.id,
display_id: conversation.display_id,
label: label_name,
all_labels: conversation.label_list
}
end
def error_response(message)
{
success: false,
error: message
}
end
end
@@ -0,0 +1,75 @@
class Captain::Tools::SearchContactTool < Captain::Tools::BaseAgentTool
def name
'search_contact'
end
def display_name
'Search Contact'
end
def description
'Search for a contact by email, phone number, or identifier'
end
def execute(arguments = {})
query = arguments[:query]&.strip
return error_response('Query is required') if query.blank?
contact = find_contact(query)
if contact
success_response(format_contact(contact))
else
error_response('No contact found')
end
end
def json_schema
{
type: 'object',
properties: {
query: {
type: 'string',
description: 'Email, phone number, or identifier to search for'
}
},
required: ['query']
}
end
private
def find_contact(query)
account_scoped(Contact)
.where('email = :query OR phone_number = :query OR identifier = :query', query: query)
.first
end
def format_contact(contact)
{
id: contact.id,
name: contact.name,
email: contact.email,
phone_number: contact.phone_number,
identifier: contact.identifier,
blocked: contact.blocked,
contact_type: contact.contact_type,
additional_attributes: contact.additional_attributes,
custom_attributes: contact.custom_attributes
}
end
def success_response(contact_data)
{
success: true,
contact: contact_data
}
end
def error_response(message)
{
success: false,
error: message
}
end
end