@gitlab/duo-ui 9.1.0 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
# [10.0.0](https://gitlab.com/gitlab-org/duo-ui/compare/v9.1.1...v10.0.0) (2025-07-02)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* agentic chat resolve input not clearing after submission ([68c9dee](https://gitlab.com/gitlab-org/duo-ui/commit/68c9deeda19073fdce046544b4adc3f826189ec0))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
* The chat input would remain populated after sending a
|
|
12
|
+
message due to a race condition where the textarea was disabled before
|
|
13
|
+
the prompt could be cleared. This happened because `canSubmit = [secure]`
|
|
14
|
+
executed before `setPromptAndFocus()` completed its async DOM update.
|
|
15
|
+
|
|
16
|
+
## [9.1.1](https://gitlab.com/gitlab-org/duo-ui/compare/v9.1.0...v9.1.1) (2025-07-02)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
* propagate the open-file event for agentic chat ([72d21a7](https://gitlab.com/gitlab-org/duo-ui/commit/72d21a7f1d5ca33db9da4599c28455f9ea95f5f3))
|
|
22
|
+
|
|
1
23
|
# [9.1.0](https://gitlab.com/gitlab-org/duo-ui/compare/v9.0.1...v9.1.0) (2025-07-01)
|
|
2
24
|
|
|
3
25
|
|
|
@@ -2,7 +2,7 @@ import throttle from 'lodash/throttle';
|
|
|
2
2
|
import VueResizable from 'vue-resizable';
|
|
3
3
|
import { GlButton, GlAlert, GlFormInputGroup, GlFormTextarea, GlForm, GlExperimentBadge, GlCard, GlDropdownItem, GlSafeHtmlDirective } from '@gitlab/ui';
|
|
4
4
|
import { translate } from '../../utils/i18n';
|
|
5
|
-
import { badgeTypes, badgeTypeValidator, CHAT_RESET_MESSAGE, CHAT_INCLUDE_MESSAGE, MESSAGE_MODEL_ROLES,
|
|
5
|
+
import { badgeTypes, badgeTypeValidator, CHAT_RESET_MESSAGE, CHAT_INCLUDE_MESSAGE, MESSAGE_MODEL_ROLES, CHAT_BASE_COMMANDS } from '../chat/constants';
|
|
6
6
|
import { VIEW_TYPES } from '../chat/components/duo_chat_header/constants';
|
|
7
7
|
import DuoChatLoader from '../chat/components/duo_chat_loader/duo_chat_loader';
|
|
8
8
|
import DuoChatPredefinedPrompts from '../chat/components/duo_chat_predefined_prompts/duo_chat_predefined_prompts';
|
|
@@ -427,26 +427,35 @@ var script = {
|
|
|
427
427
|
this.$emit('chat-cancel');
|
|
428
428
|
this.setPromptAndFocus();
|
|
429
429
|
},
|
|
430
|
-
sendChatPrompt() {
|
|
430
|
+
async sendChatPrompt() {
|
|
431
431
|
if (!this.canSubmit || this.contextItemsMenuIsOpen) {
|
|
432
432
|
return;
|
|
433
433
|
}
|
|
434
434
|
if (this.prompt) {
|
|
435
|
-
|
|
435
|
+
// Store these before any async operations that might clear the prompt
|
|
436
|
+
const trimmedPrompt = this.prompt.trim();
|
|
437
|
+
const lowerCasePrompt = this.prompt.toLowerCase().trim();
|
|
438
|
+
if (lowerCasePrompt.startsWith(CHAT_INCLUDE_MESSAGE) && this.hasContextItemSelectionMenu) {
|
|
436
439
|
this.contextItemsMenuIsOpen = true;
|
|
437
440
|
return;
|
|
438
441
|
}
|
|
439
|
-
if (![CHAT_RESET_MESSAGE, CHAT_CLEAR_MESSAGE, CHAT_NEW_MESSAGE].includes(this.caseInsensitivePrompt)) {
|
|
440
|
-
this.canSubmit = false;
|
|
441
|
-
}
|
|
442
442
|
|
|
443
443
|
/**
|
|
444
444
|
* Emitted when a new user prompt should be sent out.
|
|
445
445
|
*
|
|
446
446
|
* @param {String} prompt The user prompt to send.
|
|
447
447
|
*/
|
|
448
|
-
this.$emit('send-chat-prompt',
|
|
449
|
-
|
|
448
|
+
this.$emit('send-chat-prompt', trimmedPrompt);
|
|
449
|
+
|
|
450
|
+
// Always clear the prompt after sending, regardless of the command type
|
|
451
|
+
await this.setPromptAndFocus();
|
|
452
|
+
|
|
453
|
+
// Check if it was a special command using the stored value (before clearing)
|
|
454
|
+
if (!CHAT_BASE_COMMANDS.includes(lowerCasePrompt)) {
|
|
455
|
+
// Wait for all reactive updates to complete before setting canSubmit
|
|
456
|
+
await this.$nextTick();
|
|
457
|
+
this.canSubmit = false;
|
|
458
|
+
}
|
|
450
459
|
}
|
|
451
460
|
},
|
|
452
461
|
sendPredefinedPrompt(prompt) {
|
|
@@ -614,10 +623,24 @@ var script = {
|
|
|
614
623
|
this.$emit('delete-thread', threadId);
|
|
615
624
|
},
|
|
616
625
|
onApproveToolCall() {
|
|
626
|
+
/**
|
|
627
|
+
* Emitted when a user approves a tool call.
|
|
628
|
+
*/
|
|
617
629
|
this.$emit('approve-tool');
|
|
618
630
|
},
|
|
619
631
|
onDenyToolCall(reason) {
|
|
632
|
+
/**
|
|
633
|
+
* Emitted when a user denies a tool call.
|
|
634
|
+
* @param {String} reason The reason for denying the tool call.
|
|
635
|
+
*/
|
|
620
636
|
this.$emit('deny-tool', reason);
|
|
637
|
+
},
|
|
638
|
+
onOpenFilePath(filePath) {
|
|
639
|
+
/**
|
|
640
|
+
* Emitted when a file path link is clicked in a chat message.
|
|
641
|
+
* @param {String} filePath The file path to open
|
|
642
|
+
*/
|
|
643
|
+
this.$emit('open-file-path', filePath);
|
|
621
644
|
}
|
|
622
645
|
},
|
|
623
646
|
i18n
|
|
@@ -633,7 +656,7 @@ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=
|
|
|
633
656
|
},attrs:{"width":_vm.shouldRenderResizable ? _vm.dimensions.width : null,"height":_vm.shouldRenderResizable ? _vm.dimensions.height : null,"max-width":_vm.shouldRenderResizable ? _vm.dimensions.maxWidth : null,"max-height":_vm.shouldRenderResizable ? _vm.dimensions.maxHeight : null,"min-width":_vm.shouldRenderResizable ? _vm.dimensions.minWidth : null,"left":_vm.shouldRenderResizable ? _vm.dimensions.left : null,"top":_vm.shouldRenderResizable ? _vm.dimensions.top : null,"fit-parent":true,"min-height":_vm.shouldRenderResizable ? _vm.dimensions.minHeight : null,"active":_vm.shouldRenderResizable ? ['l', 't', 'lt'] : null},on:{"resize:end":_vm.updateSize}},[(!_vm.isHidden)?_c('aside',{staticClass:"markdown-code-block duo-chat gl-bottom-0 gl-max-h-full gl-flex gl-flex-col",class:{
|
|
634
657
|
'resizable-content': _vm.shouldRenderResizable,
|
|
635
658
|
'duo-chat-drawer': !_vm.shouldRenderResizable,
|
|
636
|
-
},attrs:{"id":"chat-component","role":"complementary","data-testid":"chat-component"}},[(_vm.showHeader)?_c('duo-chat-header',{ref:"header",attrs:{"active-thread-id":_vm.activeThreadId,"title":_vm.isMultithreaded && _vm.currentView === 'list' ? _vm.$options.i18n.CHAT_HISTORY_TITLE : _vm.title,"subtitle":_vm.activeThreadTitleForView,"error":_vm.error,"is-multithreaded":_vm.isMultithreaded,"current-view":_vm.currentView,"should-render-resizable":_vm.shouldRenderResizable,"badge-type":_vm.isMultithreaded ? null : _vm.badgeType},on:{"go-back":_vm.onGoBack,"new-chat":_vm.onNewChat,"close":_vm.hideChat},scopedSlots:_vm._u([{key:"subheader",fn:function(){return [_vm._t("subheader")]},proxy:true}],null,true)}):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-overflow-y-auto gl-flex gl-flex-col gl-flex-1 gl-flex-grow gl-bg-inherit gl-overscroll-contain",attrs:{"data-testid":"chat-history"},on:{"scroll":_vm.handleScrollingThrottled}},[(_vm.shouldShowThreadList)?_c('duo-chat-threads',{attrs:{"threads":_vm.threadList,"preferred-locale":_vm.preferredLocale},on:{"new-chat":_vm.onNewChat,"select-thread":_vm.onSelectThread,"delete-thread":_vm.onDeleteThread,"close":_vm.hideChat}}):_c('transition-group',{staticClass:"duo-chat-history gl-p-5 gl-mt-auto",attrs:{"mode":"out-in","tag":"section","name":"message"}},[_vm._l((_vm.conversations),function(conversation,index){return _c('duo-chat-conversation',{key:("conversation-" + index),attrs:{"enable-code-insertion":_vm.enableCodeInsertion,"messages":conversation,"canceled-request-ids":_vm.canceledRequestIds,"show-delimiter":index > 0,"with-feedback":_vm.withFeedback,"is-tool-approval-processing":_vm.isToolApprovalProcessing},on:{"track-feedback":_vm.onTrackFeedback,"insert-code-snippet":_vm.onInsertCodeSnippet,"copy-code-snippet":_vm.onCopyCodeSnippet,"copy-message":_vm.onCopyMessage,"get-context-item-content":_vm.onGetContextItemContent,"approve-tool":_vm.onApproveToolCall,"deny-tool":_vm.onDenyToolCall}})}),_vm._v(" "),(!_vm.hasMessages && !_vm.isLoading)?[_c('div',{key:"empty-state-message",staticClass:"duo-chat-message gl-rounded-bl-none gl-border-1 gl-border-solid gl-border-gray-50 gl-bg-gray-10 gl-p-4 gl-leading-20 gl-text-gray-900 gl-break-anywhere",attrs:{"data-testid":"gl-duo-chat-empty-state"}},[(_vm.emptyStateTitle)?_c('p',{staticClass:"gl-m-0",attrs:{"data-testid":"gl-duo-chat-empty-state-title"}},[_vm._v("\n "+_vm._s(_vm.emptyStateTitle)+"\n ")]):_vm._e(),_vm._v(" "),_c('duo-chat-predefined-prompts',{key:"predefined-prompts",attrs:{"prompts":_vm.predefinedPrompts},on:{"click":_vm.sendPredefinedPrompt}})],1)]:_vm._e(),_vm._v(" "),(_vm.isLoading)?_c('duo-chat-loader',{key:"loader",attrs:{"tool-name":_vm.toolName}}):_vm._e(),_vm._v(" "),_c('div',{key:"anchor",ref:"anchor",staticClass:"scroll-anchor"})],2)],1),_vm._v(" "),(_vm.isChatAvailable && !_vm.shouldShowThreadList)?_c('footer',{staticClass:"duo-chat-drawer-footer gl-border-0 gl-bg-default gl-pb-3 gl-shrink-0 gl-relative gl-z-2",class:{ 'duo-chat-drawer-body-scrim-on-footer': !_vm.scrolledToBottom },attrs:{"data-testid":"chat-footer"}},[_c('gl-form',{attrs:{"data-testid":"chat-prompt-form"},on:{"submit":function($event){$event.stopPropagation();$event.preventDefault();return _vm.sendChatPrompt.apply(null, arguments)}}},[_c('div',{staticClass:"gl-relative gl-max-w-full"},[_vm._t("context-items-menu",null,{"isOpen":_vm.contextItemsMenuIsOpen,"onClose":_vm.closeContextItemsMenuOpen,"setRef":_vm.setContextItemsMenuRef,"focusPrompt":_vm.focusChatInput})],2),_vm._v(" "),_c('gl-form-input-group',{scopedSlots:_vm._u([{key:"append",fn:function(){return [(_vm.canSubmit)?_c('gl-button',{staticClass:"!gl-absolute gl-bottom-2 gl-right-2 !gl-rounded-full",attrs:{"icon":"paper-airplane","category":"primary","variant":"confirm","type":"submit","data-testid":"chat-prompt-submit-button","aria-label":_vm.$options.i18n.CHAT_SUBMIT_LABEL}}):_c('gl-button',{staticClass:"!gl-absolute gl-bottom-2 gl-right-2 !gl-rounded-full",attrs:{"icon":"stop","category":"primary","variant":"default","data-testid":"chat-prompt-cancel-button","aria-label":_vm.$options.i18n.CHAT_CANCEL_LABEL},on:{"click":_vm.cancelPrompt}})]},proxy:true}],null,false,3738248012)},[_c('div',{staticClass:"duo-chat-input gl-min-h-8 gl-max-w-full gl-grow gl-align-top",attrs:{"data-value":_vm.prompt}},[(_vm.shouldShowSlashCommands)?_c('gl-card',{ref:"commands",staticClass:"slash-commands !gl-absolute gl-w-full -gl-translate-y-full gl-list-none gl-pl-0 gl-shadow-md",attrs:{"body-class":"!gl-p-2"}},_vm._l((_vm.filteredSlashCommands),function(command,index){return _c('gl-dropdown-item',{key:command.name,class:{ 'active-command': index === _vm.activeCommandIndex },on:{"click":function($event){return _vm.selectSlashCommand(index)}},nativeOn:{"mouseenter":function($event){_vm.activeCommandIndex = index;}}},[_c('span',{staticClass:"gl-flex gl-justify-between"},[_c('span',{staticClass:"gl-block"},[_vm._v(_vm._s(command.name))]),_vm._v(" "),_c('small',{staticClass:"gl-pl-3 gl-text-right gl-italic gl-text-subtle"},[_vm._v(_vm._s(command.description))])])])}),1):_vm._e(),_vm._v(" "),_c('gl-form-textarea',{ref:"prompt",staticClass:"gl-absolute !gl-h-full gl-rounded-br-none gl-rounded-tr-none !gl-bg-transparent !gl-py-4 !gl-shadow-none",class:{ 'gl-truncate': !_vm.prompt },attrs:{"disabled":!_vm.canSubmit,"data-testid":"chat-prompt-input","placeholder":_vm.inputPlaceholder,"autofocus":""},on:{"compositionend":_vm.compositionEnd},nativeOn:{"keydown":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"enter",13,$event.key,"Enter")){ return null; }if($event.ctrlKey||$event.shiftKey||$event.altKey||$event.metaKey){ return null; }$event.preventDefault();},"keyup":function($event){return _vm.onInputKeyup.apply(null, arguments)}},model:{value:(_vm.prompt),callback:function ($$v) {_vm.prompt=$$v;},expression:"prompt"}})],1)])],1),_vm._v(" "),_c('p',{staticClass:"gl-mb-0 gl-mt-3 gl-px-4 gl-text-sm gl-text-secondary"},[_vm._v("\n "+_vm._s(_vm.$options.i18n.CHAT_DISCLAMER)+"\n ")])],1):_vm._e()],1):_vm._e()])};
|
|
659
|
+
},attrs:{"id":"chat-component","role":"complementary","data-testid":"chat-component"}},[(_vm.showHeader)?_c('duo-chat-header',{ref:"header",attrs:{"active-thread-id":_vm.activeThreadId,"title":_vm.isMultithreaded && _vm.currentView === 'list' ? _vm.$options.i18n.CHAT_HISTORY_TITLE : _vm.title,"subtitle":_vm.activeThreadTitleForView,"error":_vm.error,"is-multithreaded":_vm.isMultithreaded,"current-view":_vm.currentView,"should-render-resizable":_vm.shouldRenderResizable,"badge-type":_vm.isMultithreaded ? null : _vm.badgeType},on:{"go-back":_vm.onGoBack,"new-chat":_vm.onNewChat,"close":_vm.hideChat},scopedSlots:_vm._u([{key:"subheader",fn:function(){return [_vm._t("subheader")]},proxy:true}],null,true)}):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-overflow-y-auto gl-flex gl-flex-col gl-flex-1 gl-flex-grow gl-bg-inherit gl-overscroll-contain",attrs:{"data-testid":"chat-history"},on:{"scroll":_vm.handleScrollingThrottled}},[(_vm.shouldShowThreadList)?_c('duo-chat-threads',{attrs:{"threads":_vm.threadList,"preferred-locale":_vm.preferredLocale},on:{"new-chat":_vm.onNewChat,"select-thread":_vm.onSelectThread,"delete-thread":_vm.onDeleteThread,"close":_vm.hideChat}}):_c('transition-group',{staticClass:"duo-chat-history gl-p-5 gl-mt-auto",attrs:{"mode":"out-in","tag":"section","name":"message"}},[_vm._l((_vm.conversations),function(conversation,index){return _c('duo-chat-conversation',{key:("conversation-" + index),attrs:{"enable-code-insertion":_vm.enableCodeInsertion,"messages":conversation,"canceled-request-ids":_vm.canceledRequestIds,"show-delimiter":index > 0,"with-feedback":_vm.withFeedback,"is-tool-approval-processing":_vm.isToolApprovalProcessing},on:{"track-feedback":_vm.onTrackFeedback,"insert-code-snippet":_vm.onInsertCodeSnippet,"copy-code-snippet":_vm.onCopyCodeSnippet,"copy-message":_vm.onCopyMessage,"get-context-item-content":_vm.onGetContextItemContent,"approve-tool":_vm.onApproveToolCall,"deny-tool":_vm.onDenyToolCall,"open-file-path":_vm.onOpenFilePath}})}),_vm._v(" "),(!_vm.hasMessages && !_vm.isLoading)?[_c('div',{key:"empty-state-message",staticClass:"duo-chat-message gl-rounded-bl-none gl-border-1 gl-border-solid gl-border-gray-50 gl-bg-gray-10 gl-p-4 gl-leading-20 gl-text-gray-900 gl-break-anywhere",attrs:{"data-testid":"gl-duo-chat-empty-state"}},[(_vm.emptyStateTitle)?_c('p',{staticClass:"gl-m-0",attrs:{"data-testid":"gl-duo-chat-empty-state-title"}},[_vm._v("\n "+_vm._s(_vm.emptyStateTitle)+"\n ")]):_vm._e(),_vm._v(" "),_c('duo-chat-predefined-prompts',{key:"predefined-prompts",attrs:{"prompts":_vm.predefinedPrompts},on:{"click":_vm.sendPredefinedPrompt}})],1)]:_vm._e(),_vm._v(" "),(_vm.isLoading)?_c('duo-chat-loader',{key:"loader",attrs:{"tool-name":_vm.toolName}}):_vm._e(),_vm._v(" "),_c('div',{key:"anchor",ref:"anchor",staticClass:"scroll-anchor"})],2)],1),_vm._v(" "),(_vm.isChatAvailable && !_vm.shouldShowThreadList)?_c('footer',{staticClass:"duo-chat-drawer-footer gl-border-0 gl-bg-default gl-pb-3 gl-shrink-0 gl-relative gl-z-2",class:{ 'duo-chat-drawer-body-scrim-on-footer': !_vm.scrolledToBottom },attrs:{"data-testid":"chat-footer"}},[_c('gl-form',{attrs:{"data-testid":"chat-prompt-form"},on:{"submit":function($event){$event.stopPropagation();$event.preventDefault();return _vm.sendChatPrompt.apply(null, arguments)}}},[_c('div',{staticClass:"gl-relative gl-max-w-full"},[_vm._t("context-items-menu",null,{"isOpen":_vm.contextItemsMenuIsOpen,"onClose":_vm.closeContextItemsMenuOpen,"setRef":_vm.setContextItemsMenuRef,"focusPrompt":_vm.focusChatInput})],2),_vm._v(" "),_c('gl-form-input-group',{scopedSlots:_vm._u([{key:"append",fn:function(){return [(_vm.canSubmit)?_c('gl-button',{staticClass:"!gl-absolute gl-bottom-2 gl-right-2 !gl-rounded-full",attrs:{"icon":"paper-airplane","category":"primary","variant":"confirm","type":"submit","data-testid":"chat-prompt-submit-button","aria-label":_vm.$options.i18n.CHAT_SUBMIT_LABEL}}):_c('gl-button',{staticClass:"!gl-absolute gl-bottom-2 gl-right-2 !gl-rounded-full",attrs:{"icon":"stop","category":"primary","variant":"default","data-testid":"chat-prompt-cancel-button","aria-label":_vm.$options.i18n.CHAT_CANCEL_LABEL},on:{"click":_vm.cancelPrompt}})]},proxy:true}],null,false,3738248012)},[_c('div',{staticClass:"duo-chat-input gl-min-h-8 gl-max-w-full gl-grow gl-align-top",attrs:{"data-value":_vm.prompt}},[(_vm.shouldShowSlashCommands)?_c('gl-card',{ref:"commands",staticClass:"slash-commands !gl-absolute gl-w-full -gl-translate-y-full gl-list-none gl-pl-0 gl-shadow-md",attrs:{"body-class":"!gl-p-2"}},_vm._l((_vm.filteredSlashCommands),function(command,index){return _c('gl-dropdown-item',{key:command.name,class:{ 'active-command': index === _vm.activeCommandIndex },on:{"click":function($event){return _vm.selectSlashCommand(index)}},nativeOn:{"mouseenter":function($event){_vm.activeCommandIndex = index;}}},[_c('span',{staticClass:"gl-flex gl-justify-between"},[_c('span',{staticClass:"gl-block"},[_vm._v(_vm._s(command.name))]),_vm._v(" "),_c('small',{staticClass:"gl-pl-3 gl-text-right gl-italic gl-text-subtle"},[_vm._v(_vm._s(command.description))])])])}),1):_vm._e(),_vm._v(" "),_c('gl-form-textarea',{ref:"prompt",staticClass:"gl-absolute !gl-h-full gl-rounded-br-none gl-rounded-tr-none !gl-bg-transparent !gl-py-4 !gl-shadow-none",class:{ 'gl-truncate': !_vm.prompt },attrs:{"disabled":!_vm.canSubmit,"data-testid":"chat-prompt-input","placeholder":_vm.inputPlaceholder,"autofocus":""},on:{"compositionend":_vm.compositionEnd},nativeOn:{"keydown":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"enter",13,$event.key,"Enter")){ return null; }if($event.ctrlKey||$event.shiftKey||$event.altKey||$event.metaKey){ return null; }$event.preventDefault();},"keyup":function($event){return _vm.onInputKeyup.apply(null, arguments)}},model:{value:(_vm.prompt),callback:function ($$v) {_vm.prompt=$$v;},expression:"prompt"}})],1)])],1),_vm._v(" "),_c('p',{staticClass:"gl-mb-0 gl-mt-3 gl-px-4 gl-text-sm gl-text-secondary"},[_vm._v("\n "+_vm._s(_vm.$options.i18n.CHAT_DISCLAMER)+"\n ")])],1):_vm._e()],1):_vm._e()])};
|
|
637
660
|
var __vue_staticRenderFns__ = [];
|
|
638
661
|
|
|
639
662
|
/* style */
|
|
@@ -2,6 +2,7 @@ const CHAT_RESET_MESSAGE = '/reset';
|
|
|
2
2
|
const CHAT_CLEAR_MESSAGE = '/clear';
|
|
3
3
|
const CHAT_NEW_MESSAGE = '/new';
|
|
4
4
|
const CHAT_INCLUDE_MESSAGE = '/include';
|
|
5
|
+
const CHAT_BASE_COMMANDS = [CHAT_RESET_MESSAGE, CHAT_CLEAR_MESSAGE, CHAT_NEW_MESSAGE];
|
|
5
6
|
const LOADING_TRANSITION_DURATION = 7500;
|
|
6
7
|
const DOCUMENTATION_SOURCE_TYPES = {
|
|
7
8
|
HANDBOOK: {
|
|
@@ -29,4 +30,4 @@ const SELECTED_CONTEXT_ITEMS_DEFAULT_COLLAPSED = true;
|
|
|
29
30
|
const badgeTypes = ['experiment', 'beta', null];
|
|
30
31
|
const badgeTypeValidator = value => badgeTypes.includes(value);
|
|
31
32
|
|
|
32
|
-
export { CHAT_CLEAR_MESSAGE, CHAT_INCLUDE_MESSAGE, CHAT_NEW_MESSAGE, CHAT_RESET_MESSAGE, DOCUMENTATION_SOURCE_TYPES, LOADING_TRANSITION_DURATION, MESSAGE_MODEL_ROLES, SELECTED_CONTEXT_ITEMS_DEFAULT_COLLAPSED, badgeTypeValidator, badgeTypes };
|
|
33
|
+
export { CHAT_BASE_COMMANDS, CHAT_CLEAR_MESSAGE, CHAT_INCLUDE_MESSAGE, CHAT_NEW_MESSAGE, CHAT_RESET_MESSAGE, DOCUMENTATION_SOURCE_TYPES, LOADING_TRANSITION_DURATION, MESSAGE_MODEL_ROLES, SELECTED_CONTEXT_ITEMS_DEFAULT_COLLAPSED, badgeTypeValidator, badgeTypes };
|
package/package.json
CHANGED
|
@@ -20,9 +20,8 @@ import {
|
|
|
20
20
|
badgeTypes,
|
|
21
21
|
badgeTypeValidator,
|
|
22
22
|
CHAT_RESET_MESSAGE,
|
|
23
|
-
CHAT_CLEAR_MESSAGE,
|
|
24
|
-
CHAT_NEW_MESSAGE,
|
|
25
23
|
CHAT_INCLUDE_MESSAGE,
|
|
24
|
+
CHAT_BASE_COMMANDS,
|
|
26
25
|
MESSAGE_MODEL_ROLES,
|
|
27
26
|
} from '../chat/constants';
|
|
28
27
|
import { VIEW_TYPES } from '../chat/components/duo_chat_header/constants';
|
|
@@ -501,35 +500,36 @@ export default {
|
|
|
501
500
|
this.$emit('chat-cancel');
|
|
502
501
|
this.setPromptAndFocus();
|
|
503
502
|
},
|
|
504
|
-
sendChatPrompt() {
|
|
503
|
+
async sendChatPrompt() {
|
|
505
504
|
if (!this.canSubmit || this.contextItemsMenuIsOpen) {
|
|
506
505
|
return;
|
|
507
506
|
}
|
|
508
507
|
if (this.prompt) {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
508
|
+
// Store these before any async operations that might clear the prompt
|
|
509
|
+
const trimmedPrompt = this.prompt.trim();
|
|
510
|
+
const lowerCasePrompt = this.prompt.toLowerCase().trim();
|
|
511
|
+
|
|
512
|
+
if (lowerCasePrompt.startsWith(CHAT_INCLUDE_MESSAGE) && this.hasContextItemSelectionMenu) {
|
|
513
513
|
this.contextItemsMenuIsOpen = true;
|
|
514
514
|
return;
|
|
515
515
|
}
|
|
516
516
|
|
|
517
|
-
if (
|
|
518
|
-
![CHAT_RESET_MESSAGE, CHAT_CLEAR_MESSAGE, CHAT_NEW_MESSAGE].includes(
|
|
519
|
-
this.caseInsensitivePrompt
|
|
520
|
-
)
|
|
521
|
-
) {
|
|
522
|
-
this.canSubmit = false;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
517
|
/**
|
|
526
518
|
* Emitted when a new user prompt should be sent out.
|
|
527
519
|
*
|
|
528
520
|
* @param {String} prompt The user prompt to send.
|
|
529
521
|
*/
|
|
530
|
-
this.$emit('send-chat-prompt',
|
|
522
|
+
this.$emit('send-chat-prompt', trimmedPrompt);
|
|
531
523
|
|
|
532
|
-
|
|
524
|
+
// Always clear the prompt after sending, regardless of the command type
|
|
525
|
+
await this.setPromptAndFocus();
|
|
526
|
+
|
|
527
|
+
// Check if it was a special command using the stored value (before clearing)
|
|
528
|
+
if (!CHAT_BASE_COMMANDS.includes(lowerCasePrompt)) {
|
|
529
|
+
// Wait for all reactive updates to complete before setting canSubmit
|
|
530
|
+
await this.$nextTick();
|
|
531
|
+
this.canSubmit = false;
|
|
532
|
+
}
|
|
533
533
|
}
|
|
534
534
|
},
|
|
535
535
|
sendPredefinedPrompt(prompt) {
|
|
@@ -689,11 +689,25 @@ export default {
|
|
|
689
689
|
this.$emit('delete-thread', threadId);
|
|
690
690
|
},
|
|
691
691
|
onApproveToolCall() {
|
|
692
|
+
/**
|
|
693
|
+
* Emitted when a user approves a tool call.
|
|
694
|
+
*/
|
|
692
695
|
this.$emit('approve-tool');
|
|
693
696
|
},
|
|
694
697
|
onDenyToolCall(reason) {
|
|
698
|
+
/**
|
|
699
|
+
* Emitted when a user denies a tool call.
|
|
700
|
+
* @param {String} reason The reason for denying the tool call.
|
|
701
|
+
*/
|
|
695
702
|
this.$emit('deny-tool', reason);
|
|
696
703
|
},
|
|
704
|
+
onOpenFilePath(filePath) {
|
|
705
|
+
/**
|
|
706
|
+
* Emitted when a file path link is clicked in a chat message.
|
|
707
|
+
* @param {String} filePath The file path to open
|
|
708
|
+
*/
|
|
709
|
+
this.$emit('open-file-path', filePath);
|
|
710
|
+
},
|
|
697
711
|
},
|
|
698
712
|
i18n,
|
|
699
713
|
};
|
|
@@ -787,6 +801,7 @@ export default {
|
|
|
787
801
|
@get-context-item-content="onGetContextItemContent"
|
|
788
802
|
@approve-tool="onApproveToolCall"
|
|
789
803
|
@deny-tool="onDenyToolCall"
|
|
804
|
+
@open-file-path="onOpenFilePath"
|
|
790
805
|
/>
|
|
791
806
|
<template v-if="!hasMessages && !isLoading">
|
|
792
807
|
<div
|
|
@@ -3,6 +3,8 @@ export const CHAT_CLEAR_MESSAGE = '/clear';
|
|
|
3
3
|
export const CHAT_NEW_MESSAGE = '/new';
|
|
4
4
|
export const CHAT_INCLUDE_MESSAGE = '/include';
|
|
5
5
|
|
|
6
|
+
export const CHAT_BASE_COMMANDS = [CHAT_RESET_MESSAGE, CHAT_CLEAR_MESSAGE, CHAT_NEW_MESSAGE];
|
|
7
|
+
|
|
6
8
|
export const LOADING_TRANSITION_DURATION = 7500;
|
|
7
9
|
|
|
8
10
|
export const DOCUMENTATION_SOURCE_TYPES = {
|