From d7db152f7b92d2f1f81aa26d8e1bf30111bca4bb Mon Sep 17 00:00:00 2001 From: Pranav Date: Sat, 28 Feb 2026 09:02:20 +0300 Subject: [PATCH] Add workflows inside captain --- .../captain/workflows/NodeConfigPanel.vue | 12 ++ .../captain/workflows/NodePalette.vue | 20 +-- .../captain/workflows/WorkflowToolbar.vue | 29 ---- .../captain/workflows/nodes/ActionNode.vue | 18 +-- .../workflows/nodes/CollectInputNode.vue | 27 ++++ .../captain/workflows/nodes/ConditionNode.vue | 6 +- .../captain/workflows/nodes/ShopifyNode.vue | 6 +- .../i18n/locale/en/integrations.json | 15 +-- .../captain/assistants/workflows/Editor.vue | 46 ++++++- .../captain/assistants/workflows/Index.vue | 12 -- app/javascript/entrypoints/dashboard.js | 1 + ...e_resume_to_captain_workflow_executions.rb | 6 + db/schema.rb | 4 +- .../conversation/response_builder_job.rb | 6 +- .../jobs/captain/workflows/execution_job.rb | 7 - enterprise/app/listeners/captain_listener.rb | 35 ----- enterprise/app/models/captain/workflow.rb | 3 - .../app/models/captain/workflow_execution.rb | 2 +- .../captain/llm/assistant_chat_service.rb | 19 ++- .../captain/llm/system_prompts_service.rb | 36 ++++- .../app/services/captain/tools/base_tool.rb | 3 +- .../captain/tools/execute_workflow_service.rb | 65 +++++++++ .../captain/workflows/execution_service.rb | 124 ++++++++++++++++-- .../captain/workflows/node_registry.rb | 4 +- .../workflows/nodes/collect_input_node.rb | 11 ++ 25 files changed, 359 insertions(+), 158 deletions(-) create mode 100644 app/javascript/dashboard/components-next/captain/workflows/nodes/CollectInputNode.vue create mode 100644 db/migrate/20260227100003_add_pause_resume_to_captain_workflow_executions.rb delete mode 100644 enterprise/app/jobs/captain/workflows/execution_job.rb create mode 100644 enterprise/app/services/captain/tools/execute_workflow_service.rb create mode 100644 enterprise/app/services/captain/workflows/nodes/collect_input_node.rb diff --git a/app/javascript/dashboard/components-next/captain/workflows/NodeConfigPanel.vue b/app/javascript/dashboard/components-next/captain/workflows/NodeConfigPanel.vue index 48ffc80c4..c836d3909 100644 --- a/app/javascript/dashboard/components-next/captain/workflows/NodeConfigPanel.vue +++ b/app/javascript/dashboard/components-next/captain/workflows/NodeConfigPanel.vue @@ -64,6 +64,18 @@ const FIELD_CONFIGS = { label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.CONFIG.PRIORITY', }, ], + collect_input: [ + { + key: 'input_key', + component: 'input', + label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.CONFIG.INPUT_KEY', + }, + { + key: 'prompt', + component: 'textarea', + label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.CONFIG.PROMPT', + }, + ], condition: [ { key: 'attribute', diff --git a/app/javascript/dashboard/components-next/captain/workflows/NodePalette.vue b/app/javascript/dashboard/components-next/captain/workflows/NodePalette.vue index a192af8e4..78ce763a3 100644 --- a/app/javascript/dashboard/components-next/captain/workflows/NodePalette.vue +++ b/app/javascript/dashboard/components-next/captain/workflows/NodePalette.vue @@ -5,23 +5,13 @@ const { t } = useI18n(); const NODE_CATEGORIES = [ { - label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.PALETTE.TRIGGERS', - color: 'n-teal', - icon: 'i-lucide-zap', + label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.PALETTE.INTERACTIVE', + color: 'n-violet', + icon: 'i-lucide-message-circle-question', nodes: [ { - type: 'trigger_conversation_created', - label: - 'CAPTAIN.ASSISTANTS.WORKFLOWS.NODES.TRIGGER_CONVERSATION_CREATED', - }, - { - type: 'trigger_message_created', - label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.NODES.TRIGGER_MESSAGE_CREATED', - }, - { - type: 'trigger_conversation_resolved', - label: - 'CAPTAIN.ASSISTANTS.WORKFLOWS.NODES.TRIGGER_CONVERSATION_RESOLVED', + type: 'collect_input', + label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.NODES.COLLECT_INPUT', }, ], }, diff --git a/app/javascript/dashboard/components-next/captain/workflows/WorkflowToolbar.vue b/app/javascript/dashboard/components-next/captain/workflows/WorkflowToolbar.vue index 01dbafbaf..e374ed059 100644 --- a/app/javascript/dashboard/components-next/captain/workflows/WorkflowToolbar.vue +++ b/app/javascript/dashboard/components-next/captain/workflows/WorkflowToolbar.vue @@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n'; import Button from 'dashboard/components-next/button/Button.vue'; import Input from 'dashboard/components-next/input/Input.vue'; import Switch from 'dashboard/components-next/switch/Switch.vue'; -import SelectMenu from 'dashboard/components-next/selectmenu/SelectMenu.vue'; const props = defineProps({ workflow: { type: Object, default: () => ({}) }, @@ -15,7 +14,6 @@ const { t } = useI18n(); const name = ref(''); const description = ref(''); -const triggerEvent = ref('conversation_created'); const enabled = ref(false); watch( @@ -24,38 +22,16 @@ watch( if (val && val.id) { name.value = val.name || ''; description.value = val.description || ''; - triggerEvent.value = val.trigger_event || 'conversation_created'; enabled.value = val.enabled || false; } }, { immediate: true } ); -const TRIGGER_OPTIONS = [ - { - value: 'conversation_created', - label: t('CAPTAIN.ASSISTANTS.WORKFLOWS.TRIGGERS.CONVERSATION_CREATED'), - }, - { - value: 'message_created', - label: t('CAPTAIN.ASSISTANTS.WORKFLOWS.TRIGGERS.MESSAGE_CREATED'), - }, - { - value: 'conversation_resolved', - label: t('CAPTAIN.ASSISTANTS.WORKFLOWS.TRIGGERS.CONVERSATION_RESOLVED'), - }, -]; - -const triggerLabel = () => { - const option = TRIGGER_OPTIONS.find(o => o.value === triggerEvent.value); - return option ? option.label : triggerEvent.value; -}; - const save = () => { emit('save', { name: name.value, description: description.value, - trigger_event: triggerEvent.value, enabled: enabled.value, }); }; @@ -72,11 +48,6 @@ const save = () => { class="max-w-xs" :placeholder="t('CAPTAIN.ASSISTANTS.WORKFLOWS.TOOLBAR.NAME_PLACEHOLDER')" /> -
{{ t('CAPTAIN.ASSISTANTS.WORKFLOWS.TOOLBAR.ENABLED') }} diff --git a/app/javascript/dashboard/components-next/captain/workflows/nodes/ActionNode.vue b/app/javascript/dashboard/components-next/captain/workflows/nodes/ActionNode.vue index c6f891b44..f0b78f7ee 100644 --- a/app/javascript/dashboard/components-next/captain/workflows/nodes/ActionNode.vue +++ b/app/javascript/dashboard/components-next/captain/workflows/nodes/ActionNode.vue @@ -8,22 +8,16 @@ defineProps({