diff --git a/config/agents/tools.yml b/config/agents/tools.yml index 4d1823b33..ee0a7695e 100644 --- a/config/agents/tools.yml +++ b/config/agents/tools.yml @@ -18,4 +18,14 @@ - id: update_priority title: "Update Priority" description: "Update conversation priority level" - icon: "exclamation-triangle" \ No newline at end of file + 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" \ No newline at end of file diff --git a/enterprise/lib/captain/tools/add_label_to_conversation_tool.rb b/enterprise/lib/captain/tools/add_label_to_conversation_tool.rb new file mode 100644 index 000000000..d47c07897 --- /dev/null +++ b/enterprise/lib/captain/tools/add_label_to_conversation_tool.rb @@ -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 \ No newline at end of file diff --git a/enterprise/lib/captain/tools/search_contact_tool.rb b/enterprise/lib/captain/tools/search_contact_tool.rb new file mode 100644 index 000000000..25329b0f3 --- /dev/null +++ b/enterprise/lib/captain/tools/search_contact_tool.rb @@ -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 \ No newline at end of file