From be834d1c581dc3d91a3b14b3930b00e245cb638a Mon Sep 17 00:00:00 2001
From: Aakash Bakhle <48802744+aakashb95@users.noreply.github.com>
Date: Thu, 2 Apr 2026 12:40:11 +0530
Subject: [PATCH] feat: captain custom tools v1 (#13890)
# Pull Request Template
## Description
Adds custom tool support to v1
## Type of change
- [x] New feature (non-breaking change which adds functionality)
## How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide
instructions so we can reproduce. Please also list any relevant details
for your test configuration.
## Checklist:
- [x] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my code
- [ ] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
---------
Co-authored-by: Claude Opus 4.6 (1M context)
Co-authored-by: Shivam Mishra
---
.../dashboard/api/captain/customTools.js | 6 ++
.../customTool/CustomToolCard.vue | 9 +-
.../customTool/CustomToolForm.vue | 86 +++++++++++++++++--
.../emptyStates/CustomToolsPageEmptyState.vue | 12 +++
.../components-next/sidebar/Sidebar.vue | 30 +++++--
app/javascript/dashboard/featureFlags.js | 1 +
.../i18n/locale/en/integrations.json | 10 ++-
.../dashboard/captain/captain.routes.js | 2 +-
.../routes/dashboard/captain/tools/Index.vue | 22 +++--
config/locales/en.yml | 1 +
config/routes.rb | 4 +-
.../captain/custom_tools_controller.rb | 24 +++++-
enterprise/app/models/captain/custom_tool.rb | 27 ++++--
enterprise/app/models/concerns/toolable.rb | 31 ++++---
.../policies/captain/custom_tool_policy.rb | 4 +
.../captain/llm/assistant_chat_service.rb | 22 ++++-
.../captain/llm/system_prompts_service.rb | 15 +++-
.../captain/tools/custom_http_tool.rb | 47 ++++++++++
.../reconcile_plan_features_service.rb | 2 +-
.../models/captain/_custom_tool.json.jbuilder | 2 +-
.../captain/custom_tools_controller_spec.rb | 7 +-
21 files changed, 307 insertions(+), 57 deletions(-)
create mode 100644 enterprise/app/services/captain/tools/custom_http_tool.rb
diff --git a/app/javascript/dashboard/api/captain/customTools.js b/app/javascript/dashboard/api/captain/customTools.js
index d0818d941..471c2846b 100644
--- a/app/javascript/dashboard/api/captain/customTools.js
+++ b/app/javascript/dashboard/api/captain/customTools.js
@@ -31,6 +31,12 @@ class CaptainCustomTools extends ApiClient {
delete(id) {
return axios.delete(`${this.url}/${id}`);
}
+
+ test(data = {}) {
+ return axios.post(`${this.url}/test`, {
+ custom_tool: data,
+ });
+ }
}
export default new CaptainCustomTools();
diff --git a/app/javascript/dashboard/components-next/captain/pageComponents/customTool/CustomToolCard.vue b/app/javascript/dashboard/components-next/captain/pageComponents/customTool/CustomToolCard.vue
index d1d1dd011..d5f1e3e52 100644
--- a/app/javascript/dashboard/components-next/captain/pageComponents/customTool/CustomToolCard.vue
+++ b/app/javascript/dashboard/components-next/captain/pageComponents/customTool/CustomToolCard.vue
@@ -101,12 +101,9 @@ const authTypeLabel = computed(() => {
-