From 8daf6cf6cbba1246f98a59ce474b6bd633646f46 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(() => {
-