From 82f5dbe6c1d204453752c0bb7052c16a41b0c0b2 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 13 Jan 2026 14:29:11 +0530 Subject: [PATCH] feat: reply editor follow-up (#13106) Co-authored-by: aakashb95 --- app/javascript/dashboard/api/captain/tasks.js | 21 +++ .../components/widgets/AIAssistanceModal.vue | 3 +- .../widgets/WootWriter/CopilotMenuBar.vue | 9 +- .../WootWriter/CopilotReplyBottomPanel.vue | 24 +-- .../components/widgets/WootWriter/Editor.vue | 1 - .../conversation/CopilotEditorSection.vue | 14 +- .../widgets/conversation/ReplyBox.vue | 11 +- app/javascript/dashboard/composables/useAI.js | 43 ++++- .../dashboard/composables/useCopilotReply.js | 48 +++++- .../dashboard/composables/utils/useKbd.js | 21 ++- .../i18n/locale/en/conversation.json | 2 +- .../dashboard/i18n/locale/en/general.json | 2 + app/policies/captain/tasks_policy.rb | 4 + config/routes.rb | 1 + .../v1/accounts/captain/tasks_controller.rb | 15 +- lib/captain/base_task_service.rb | 30 +++- lib/captain/follow_up_service.rb | 98 +++++++++++ lib/captain/label_suggestion_service.rb | 4 + lib/integrations/openai/processor_service.rb | 152 ----------------- spec/lib/captain/base_task_service_spec.rb | 33 ++++ spec/lib/captain/follow_up_service_spec.rb | 157 ++++++++++++++++++ 21 files changed, 507 insertions(+), 186 deletions(-) create mode 100644 lib/captain/follow_up_service.rb delete mode 100644 lib/integrations/openai/processor_service.rb create mode 100644 spec/lib/captain/follow_up_service_spec.rb diff --git a/app/javascript/dashboard/api/captain/tasks.js b/app/javascript/dashboard/api/captain/tasks.js index 85fd47e39..eaeeb3ea2 100644 --- a/app/javascript/dashboard/api/captain/tasks.js +++ b/app/javascript/dashboard/api/captain/tasks.js @@ -108,6 +108,27 @@ class TasksAPI extends ApiClient { { signal } ); } + + /** + * Sends a follow-up message to continue refining a previous task result. + * @param {Object} options - The follow-up options. + * @param {Object} options.followUpContext - The follow-up context from a previous task. + * @param {string} options.message - The follow-up message/request from the user. + * @param {string} [options.conversationId] - The conversation ID for Langfuse session tracking. + * @param {AbortSignal} [signal] - AbortSignal to cancel the request. + * @returns {Promise} A promise that resolves with the follow-up response and updated follow-up context. + */ + followUp({ followUpContext, message, conversationId }, signal) { + return axios.post( + `${this.url}/follow_up`, + { + follow_up_context: followUpContext, + message, + conversation_display_id: conversationId, + }, + { signal } + ); + } } export default new TasksAPI(); diff --git a/app/javascript/dashboard/components/widgets/AIAssistanceModal.vue b/app/javascript/dashboard/components/widgets/AIAssistanceModal.vue index 3cd945208..9ac3cb0c0 100644 --- a/app/javascript/dashboard/components/widgets/AIAssistanceModal.vue +++ b/app/javascript/dashboard/components/widgets/AIAssistanceModal.vue @@ -50,7 +50,8 @@ export default { async generateAIContent(type = 'improve') { this.isGenerating = true; - this.generatedContent = await this.processEvent(type); + const { message } = await this.processEvent(type); + this.generatedContent = message; this.isGenerating = false; }, applyText() { diff --git a/app/javascript/dashboard/components/widgets/WootWriter/CopilotMenuBar.vue b/app/javascript/dashboard/components/widgets/WootWriter/CopilotMenuBar.vue index 22dc5d0d2..17d8e0488 100644 --- a/app/javascript/dashboard/components/widgets/WootWriter/CopilotMenuBar.vue +++ b/app/javascript/dashboard/components/widgets/WootWriter/CopilotMenuBar.vue @@ -10,7 +10,7 @@ import DropdownBody from 'next/dropdown-menu/base/DropdownBody.vue'; import Icon from 'next/icon/Icon.vue'; -const props = defineProps({ +defineProps({ hasSelection: { type: Boolean, default: false, @@ -28,7 +28,12 @@ const replyMode = useMapGetter('draftMessages/getReplyEditorMode'); // Selection-based menu items (when text is selected) const menuItems = computed(() => { const items = []; - if (props.hasSelection) { + // for now, we don't allow improving just aprt of the selection + // we will add this feature later. Once we do, we can revert the change + const hasSelection = false; + // const hasSelection = props.hasSelection + + if (hasSelection) { items.push({ label: t( 'INTEGRATION_SETTINGS.OPEN_AI.REPLY_OPTIONS.IMPROVE_REPLY_SELECTION' diff --git a/app/javascript/dashboard/components/widgets/WootWriter/CopilotReplyBottomPanel.vue b/app/javascript/dashboard/components/widgets/WootWriter/CopilotReplyBottomPanel.vue index 6336d56b2..e23cdbf7e 100644 --- a/app/javascript/dashboard/components/widgets/WootWriter/CopilotReplyBottomPanel.vue +++ b/app/javascript/dashboard/components/widgets/WootWriter/CopilotReplyBottomPanel.vue @@ -1,35 +1,37 @@