@gitlab/duo-ui 15.0.3 → 15.0.5
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 +15 -0
- package/dist/components/agentic_chat/agentic_duo_chat.js +9 -6
- package/dist/components/agentic_chat/web_agentic_duo_chat.js +25 -2
- package/dist/components/chat/components/duo_chat_header/web_duo_chat_header.js +6 -1
- package/dist/components/chat/components/duo_chat_message_tool_approval/message_tool_approval.js +23 -28
- package/package.json +1 -1
- package/src/components/agentic_chat/agentic_duo_chat.vue +10 -10
- package/src/components/agentic_chat/web_agentic_duo_chat.vue +61 -31
- package/src/components/chat/components/duo_chat_header/web_duo_chat_header.vue +17 -0
- package/src/components/chat/components/duo_chat_message_tool_approval/message_tool_approval.vue +22 -27
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## [15.0.5](https://gitlab.com/gitlab-org/duo-ui/compare/v15.0.4...v15.0.5) (2025-12-07)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Do not allow to cancel chat while tool is being processed ([41ba989](https://gitlab.com/gitlab-org/duo-ui/commit/41ba9896584762a5d0064d64a6284dd563494b46))
|
|
7
|
+
* Tool approval buttons enabled too fast ([8977579](https://gitlab.com/gitlab-org/duo-ui/commit/897757973ad54ac69a6bfb225df4c88bcda6426b))
|
|
8
|
+
|
|
9
|
+
## [15.0.4](https://gitlab.com/gitlab-org/duo-ui/compare/v15.0.3...v15.0.4) (2025-12-03)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* **DuoChat:** Add vertical centering for custom empty state slot ([922ed40](https://gitlab.com/gitlab-org/duo-ui/commit/922ed404f53c151ea5595e72d8905ecad42c8581))
|
|
15
|
+
|
|
1
16
|
## [15.0.3](https://gitlab.com/gitlab-org/duo-ui/compare/v15.0.2...v15.0.3) (2025-12-02)
|
|
2
17
|
|
|
3
18
|
|
|
@@ -305,11 +305,7 @@ var script = {
|
|
|
305
305
|
computed: {
|
|
306
306
|
canSubmit() {
|
|
307
307
|
const shouldAllowSubmit = !this.isLoading && !this.isStreaming && !this.isToolApprovalProcessing && !this.isAwaitingToolApproval;
|
|
308
|
-
|
|
309
|
-
// Fallback logic: If we're not loading, not streaming, and not awaiting approval,
|
|
310
|
-
// but isToolApprovalProcessing is stuck at true, we should still enable submit
|
|
311
|
-
const isStuckInProcessing = !this.isLoading && !this.isStreaming && !this.isAwaitingToolApproval && this.isToolApprovalProcessing;
|
|
312
|
-
return shouldAllowSubmit || isStuckInProcessing;
|
|
308
|
+
return shouldAllowSubmit;
|
|
313
309
|
},
|
|
314
310
|
shouldShowThreadList() {
|
|
315
311
|
return this.isMultithreaded && this.currentView === VIEW_TYPES.LIST;
|
|
@@ -398,6 +394,13 @@ var script = {
|
|
|
398
394
|
return Boolean(
|
|
399
395
|
// It is possible to get tool null, so we assert it is truthy to make sure there is a payload
|
|
400
396
|
lastMessage && lastMessage.message_type === 'request' && lastMessage.tool_info);
|
|
397
|
+
},
|
|
398
|
+
canCancelInternal() {
|
|
399
|
+
// Don't allow cancel while there are pending tool approvals
|
|
400
|
+
if (this.isAwaitingToolApproval) {
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
return this.canCancel;
|
|
401
404
|
}
|
|
402
405
|
},
|
|
403
406
|
watch: {
|
|
@@ -707,7 +710,7 @@ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=
|
|
|
707
710
|
},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-flex gl-max-h-full gl-flex-col",class:{
|
|
708
711
|
'resizable-content': _vm.shouldRenderResizable,
|
|
709
712
|
'duo-chat-drawer': !_vm.shouldRenderResizable,
|
|
710
|
-
},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,"session-id":_vm.sessionId,"agents":_vm.agents},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-flex gl-flex-1 gl-flex-grow gl-flex-col gl-overflow-y-auto gl-overscroll-contain gl-bg-inherit",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-mt-auto gl-px-4 gl-pb-4 gl-pt-6",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,"show-delimiter":index > 0,"with-feedback":_vm.withFeedback,"is-tool-approval-processing":_vm.isToolApprovalProcessing,"working-directory":_vm.workingDirectory},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-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-relative gl-z-2 gl-shrink-0",attrs:{"data-testid":"chat-footer"}},[(_vm.$scopedSlots['footer-panel'])?_c('div',{staticClass:"gl-relative gl-max-w-full",attrs:{"data-testid":"footer-panel-wrapper"}},[_vm._t("footer-panel")],2):_vm._e(),_vm._v(" "),(_vm.$scopedSlots['footer-actions'])?_c('div',{staticClass:"gl-my-4 gl-flex gl-items-center gl-justify-between gl-gap-x-4 gl-px-4",attrs:{"data-testid":"footer-actions-wrapper"}},[_vm._t("footer-actions")],2):_vm._e(),_vm._v(" "),_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","disabled":_vm.isPromptEmpty || !_vm.hasValidPrompt,"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,"disabled":!_vm.
|
|
713
|
+
},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,"session-id":_vm.sessionId,"agents":_vm.agents},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-flex gl-flex-1 gl-flex-grow gl-flex-col gl-overflow-y-auto gl-overscroll-contain gl-bg-inherit",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-mt-auto gl-px-4 gl-pb-4 gl-pt-6",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,"show-delimiter":index > 0,"with-feedback":_vm.withFeedback,"is-tool-approval-processing":_vm.isToolApprovalProcessing,"working-directory":_vm.workingDirectory},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-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-relative gl-z-2 gl-shrink-0",attrs:{"data-testid":"chat-footer"}},[(_vm.$scopedSlots['footer-panel'])?_c('div',{staticClass:"gl-relative gl-max-w-full",attrs:{"data-testid":"footer-panel-wrapper"}},[_vm._t("footer-panel")],2):_vm._e(),_vm._v(" "),(_vm.$scopedSlots['footer-actions'])?_c('div',{staticClass:"gl-my-4 gl-flex gl-items-center gl-justify-between gl-gap-x-4 gl-px-4",attrs:{"data-testid":"footer-actions-wrapper"}},[_vm._t("footer-actions")],2):_vm._e(),_vm._v(" "),_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","disabled":_vm.isPromptEmpty || !_vm.hasValidPrompt,"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,"disabled":!_vm.canCancelInternal},on:{"click":_vm.cancelPrompt}})]},proxy:true}],null,false,3149367298)},[_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",attrs:{"disabled":!_vm.canSubmit,"data-testid":"chat-prompt-input","placeholder":_vm.inputPlaceholder,"character-count-limit":_vm.maxPromptLength,"textarea-classes":[
|
|
711
714
|
'gl-absolute',
|
|
712
715
|
'!gl-h-full',
|
|
713
716
|
'gl-rounded-br-none',
|
|
@@ -145,6 +145,25 @@ var script = {
|
|
|
145
145
|
required: false,
|
|
146
146
|
default: ''
|
|
147
147
|
},
|
|
148
|
+
/**
|
|
149
|
+
* Chat state object that contains enablement state and optional reason message.
|
|
150
|
+
* When chat is disabled (isEnabled: false), a reason message must be provided.
|
|
151
|
+
*/
|
|
152
|
+
chatState: {
|
|
153
|
+
type: Object,
|
|
154
|
+
required: false,
|
|
155
|
+
default: () => ({
|
|
156
|
+
isEnabled: true,
|
|
157
|
+
reason: null
|
|
158
|
+
}),
|
|
159
|
+
validator: value => {
|
|
160
|
+
// If chat is disabled, reason must be provided
|
|
161
|
+
if (!value.isEnabled && !value.reason) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
},
|
|
148
167
|
/**
|
|
149
168
|
* Array of messages to display in the chat.
|
|
150
169
|
*/
|
|
@@ -725,7 +744,11 @@ var script = {
|
|
|
725
744
|
const __vue_script__ = script;
|
|
726
745
|
|
|
727
746
|
/* template */
|
|
728
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"markdown-code-block duo-chat web-only gl-bottom-0 gl-flex gl-max-h-full gl-flex-grow gl-flex-col",attrs:{"id":"chat-component","role":"complementary","data-testid":"chat-component"}},[(_vm.showHeader)?_c('web-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,"session-id":_vm.sessionId,"agents":_vm.agents,"show-studio-header":_vm.showStudioHeader},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-flex gl-flex-1 gl-flex-grow gl-flex-col gl-overflow-y-auto gl-overscroll-contain gl-bg-inherit",class:{ 'gl-border-t': !_vm.showStudioHeader },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',{
|
|
747
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"markdown-code-block duo-chat web-only gl-bottom-0 gl-flex gl-max-h-full gl-flex-grow gl-flex-col",attrs:{"id":"chat-component","role":"complementary","data-testid":"chat-component"}},[(_vm.showHeader)?_c('web-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,"info":_vm.hasMessages ? _vm.chatState.reason : '',"is-multithreaded":_vm.isMultithreaded,"current-view":_vm.currentView,"should-render-resizable":_vm.shouldRenderResizable,"badge-type":_vm.isMultithreaded ? null : _vm.badgeType,"session-id":_vm.sessionId,"agents":_vm.agents,"show-studio-header":_vm.showStudioHeader},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-flex gl-flex-1 gl-flex-grow gl-flex-col gl-overflow-y-auto gl-overscroll-contain gl-bg-inherit",class:{ 'gl-border-t': !_vm.showStudioHeader },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',{class:[
|
|
748
|
+
'duo-chat-history gl-px-4',
|
|
749
|
+
_vm.$scopedSlots['custom-empty-state']
|
|
750
|
+
? 'gl-flex gl-flex-1 gl-items-center gl-justify-center'
|
|
751
|
+
: 'gl-mt-auto gl-pb-4 gl-pt-6' ],attrs:{"mode":"out-in","tag":"section","name":"message","data-testid":"chat-messages"}},[_vm._l((_vm.conversations),function(conversation,index){return _c('duo-chat-conversation',{key:("conversation-" + index),attrs:{"enable-code-insertion":_vm.enableCodeInsertion,"messages":conversation,"show-delimiter":index > 0,"with-feedback":_vm.withFeedback,"is-tool-approval-processing":_vm.isToolApprovalProcessing,"working-directory":_vm.workingDirectory},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)?[_vm._t("custom-empty-state",function(){return [_c('div',{key:"empty-state-message",staticClass:"duo-chat-message gl-rounded-bl-none gl-leading-20 gl-text-default gl-break-anywhere",attrs:{"data-testid":"gl-duo-chat-empty-state"}},[_c('div',{staticClass:"gl-mb-[3.75rem] gl-flex gl-flex-col gl-items-center gl-justify-center gl-gap-3 gl-text-center"},[_c('h1',{staticClass:"gl-my-0 gl-text-[3.5rem]",attrs:{"data-testid":"gl-duo-chat-empty-state-emoji"}},[_vm._v("\n "+_vm._s(_vm.$options.i18n.CHAT_EMPTY_STATE_EMOJI)+"\n ")]),_vm._v(" "),(_vm.agentName)?_c('h2',{staticClass:"gl-heading-2 gl-my-0",attrs:{"data-testid":"gl-duo-chat-empty-state-greeting"}},[_vm._v("\n "+_vm._s(_vm.emptyStateGreeting)+"\n ")]):_vm._e(),_vm._v(" "),_c('h2',{staticClass:"gl-my-0 gl-text-size-h2",attrs:{"data-testid":"gl-duo-chat-empty-state-title"}},[_vm._v("\n "+_vm._s(_vm.emptyStateMainText)+"\n ")]),_vm._v(" "),_c('p',{staticClass:"gl-text-base gl-text-subtle",attrs:{"data-testid":"gl-duo-chat-empty-state-subtitle"}},[_vm._v("\n "+_vm._s(_vm.emptyStateSubText)+"\n ")])]),_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.shouldShowThreadList)?_c('footer',{staticClass:"duo-chat-drawer-footer gl-relative gl-z-2 gl-shrink-0",attrs:{"data-testid":"chat-footer"}},[_c('p',{staticClass:"gl-mb-3 gl-text-sm gl-text-subtle",class:{ 'gl-invisible': !_vm.hasAssistantMessages },attrs:{"data-testid":"chat-disclaimer"}},[_vm._v("\n "+_vm._s(_vm.$options.i18n.CHAT_DISCLAIMER)+"\n ")]),_vm._v(" "),_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('div',{staticClass:"duo-chat-input gl-relative gl-min-h-8 gl-max-w-full gl-grow gl-flex-col gl-rounded-bl-[12px] gl-rounded-br-[18px] gl-rounded-tl-[12px] gl-rounded-tr-[12px] gl-align-top forced-colors:gl-border"},[(_vm.$scopedSlots['agentic-model'] || _vm.$scopedSlots['agentic-switch'])?_c('div',{staticClass:"gl-flex gl-items-center gl-justify-between gl-gap-5 gl-border-0 gl-border-b-1 gl-border-solid gl-border-strong gl-px-4 gl-py-4 forced-colors:gl-border-none"},[_c('div',{staticClass:"duo-model-switcher gl-min-w-0 gl-max-w-full"},[_vm._t("agentic-model")],2),_vm._v(" "),_c('div',{staticClass:"duo-agent-mode-switcher gl-min-w-0 gl-max-w-full gl-shrink-0"},[_vm._t("agentic-switch")],2)]):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-h-[80px] gl-grow",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",attrs:{"disabled":!_vm.canSubmit || !_vm.isChatAvailable || !_vm.chatState.isEnabled,"data-testid":"chat-prompt-input","placeholder":_vm.inputPlaceholder,"character-count-limit":_vm.maxPromptLength,"textarea-classes":[
|
|
729
752
|
'!gl-h-full',
|
|
730
753
|
'!gl-bg-transparent',
|
|
731
754
|
'!gl-py-4',
|
|
@@ -747,7 +770,7 @@ return [(count <= _vm.promptLengthWarningCount)?_c('span',{staticClass:"gl-absol
|
|
|
747
770
|
return [_c('span',{staticClass:"gl-absolute gl-bottom-[-1.6rem] gl-right-0 gl-mt-3 gl-pr-3 gl-text-sm",class:{
|
|
748
771
|
'gl-bottom-[-5rem]': _vm.hasFooterControls,
|
|
749
772
|
'gl-bottom-[-1.6rem]': !_vm.hasFooterControls,
|
|
750
|
-
}},[_vm._v(_vm._s(_vm.overLimitCharacterCountMessage(count)))])]}}],null,false,4237892236),model:{value:(_vm.prompt),callback:function ($$v) {_vm.prompt=$$v;},expression:"prompt"}})],1),_vm._v(" "),_c('div',{staticClass:"gl-absolute gl-bottom-0 gl-right-0 gl-px-3 gl-pb-3"},[(_vm.canSubmit)?_c('gl-button',{staticClass:"!gl-rounded-full",attrs:{"icon":"paper-airplane","category":"primary","variant":"confirm","type":"submit","disabled"
|
|
773
|
+
}},[_vm._v(_vm._s(_vm.overLimitCharacterCountMessage(count)))])]}}],null,false,4237892236),model:{value:(_vm.prompt),callback:function ($$v) {_vm.prompt=$$v;},expression:"prompt"}})],1),_vm._v(" "),_c('div',{staticClass:"gl-absolute gl-bottom-0 gl-right-0 gl-px-3 gl-pb-3"},[(_vm.canSubmit)?_c('gl-button',{staticClass:"!gl-rounded-full",attrs:{"icon":"paper-airplane","category":"primary","variant":"confirm","type":"submit","disabled":!_vm.isChatAvailable || !_vm.chatState.isEnabled || _vm.isPromptEmpty || !_vm.hasValidPrompt,"data-testid":"chat-prompt-submit-button","aria-label":_vm.$options.i18n.CHAT_SUBMIT_LABEL}}):_c('gl-button',{staticClass:"!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}})],1)])]),_vm._v(" "),_vm._t("footer-controls")],2):_vm._e()],1)};
|
|
751
774
|
var __vue_staticRenderFns__ = [];
|
|
752
775
|
|
|
753
776
|
/* style */
|
|
@@ -53,6 +53,11 @@ var script = {
|
|
|
53
53
|
required: false,
|
|
54
54
|
default: ''
|
|
55
55
|
},
|
|
56
|
+
info: {
|
|
57
|
+
type: String,
|
|
58
|
+
required: false,
|
|
59
|
+
default: ''
|
|
60
|
+
},
|
|
56
61
|
isMultithreaded: {
|
|
57
62
|
type: Boolean,
|
|
58
63
|
required: false,
|
|
@@ -155,7 +160,7 @@ var script = {
|
|
|
155
160
|
const __vue_script__ = script;
|
|
156
161
|
|
|
157
162
|
/* template */
|
|
158
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('header',{staticClass:"gl-shrink-0 gl-p-0",attrs:{"data-testid":"chat-header"}},[(!_vm.showStudioHeader)?_c('div',{staticClass:"gl-flex gl-w-full gl-items-center gl-px-4 gl-py-3",attrs:{"data-testid":"chat-top-header"}},[(_vm.subtitle)?_c('h4',{staticClass:"gl-mb-0 gl-max-w-17/20 gl-flex-1 gl-shrink-0 gl-overflow-hidden gl-truncate gl-text-ellipsis gl-whitespace-nowrap gl-pr-3 gl-text-sm gl-font-normal gl-text-subtle",attrs:{"data-testid":"chat-subtitle"}},[_vm._v("\n "+_vm._s(_vm.subtitle)+"\n ")]):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-ml-auto gl-flex gl-gap-3"},[(_vm.sessionId)?_c('gl-disclosure-dropdown',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip",value:(_vm.showSessionDropdownTooltip),expression:"showSessionDropdownTooltip"}],attrs:{"icon":"ellipsis_v","category":"tertiary","text-sr-only":"","size":"small","toggle-text":_vm.$options.i18n.CHAT_DROPDOWN_MORE_OPTIONS,"items":_vm.sessionIdItems,"no-caret":""},on:{"shown":_vm.showSessionDropdown,"hidden":_vm.hideSessionDropdown}}):_vm._e(),_vm._v(" "),_c('gl-button',{attrs:{"category":"tertiary","variant":"default","icon":"close","size":"small","data-testid":"chat-close-button","aria-label":_vm.$options.i18n.CHAT_CLOSE_LABEL},on:{"click":function($event){return _vm.$emit('close')}}})],1)]):_vm._e(),_vm._v(" "),(_vm.showSubheader)?_c('div',{staticClass:"drawer-title gl-flex gl-items-center gl-justify-start gl-gap-4 gl-px-4 gl-py-3",class:{ 'gl-border-t': !_vm.showStudioHeader, 'gl-border-b': _vm.showStudioHeader },attrs:{"data-testid":"chat-subheader"}},[_c('div',{staticClass:"gl-flex gl-grow gl-gap-3"},[_c('gl-avatar',{staticClass:"gl-shrink-0",attrs:{"size":32,"entity-name":_vm.title,"shape":"circle"}}),_vm._v(" "),_c('div',{staticClass:"gl-flex gl-flex-col gl-justify-center"},[_c('h3',{staticClass:"gl-my-0 gl-line-clamp-1 gl-text-[0.875rem] gl-text-default gl-break-anywhere"},[_vm._v("\n "+_vm._s(_vm.title)+"\n ")]),_vm._v(" "),(_vm.agentHandler)?_c('p',{staticClass:"gl-my-0 gl-text-[0.75rem] gl-text-subtle"},[_vm._v("\n "+_vm._s(_vm.agentHandler)+"\n ")]):_vm._e()])],1),_vm._v(" "),_c('div',{staticClass:"gl-flex gl-gap-3"},[(_vm.isMultithreaded && _vm.activeThreadId && _vm.currentView === _vm.VIEW_TYPES.LIST)?_c('gl-button',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip"}],attrs:{"title":_vm.$options.i18n.CHAT_BACK_TO_CHAT_TOOLTIP,"data-testid":"go-back-to-chat-button","category":"tertiary","size":"small","icon":"go-back","aria-label":_vm.$options.i18n.CHAT_BACK_TO_CHAT_TOOLTIP},on:{"click":function($event){return _vm.$emit('go-back-to-chat')}}}):_vm._e()],1)]):_vm._e(),_vm._v(" "),_vm._t("subheader"),_vm._v(" "),(_vm.error)?_c('gl-alert',{key:"error",staticClass:"!gl-pl-9",attrs:{"dismissible":false,"variant":"danger","role":"alert","data-testid":"chat-error"}},[_c('span',{directives:[{name:"safe-html",rawName:"v-safe-html",value:(_vm.error),expression:"error"}]})]):_vm._e()],2)};
|
|
163
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('header',{staticClass:"gl-shrink-0 gl-p-0",attrs:{"data-testid":"chat-header"}},[(!_vm.showStudioHeader)?_c('div',{staticClass:"gl-flex gl-w-full gl-items-center gl-px-4 gl-py-3",attrs:{"data-testid":"chat-top-header"}},[(_vm.subtitle)?_c('h4',{staticClass:"gl-mb-0 gl-max-w-17/20 gl-flex-1 gl-shrink-0 gl-overflow-hidden gl-truncate gl-text-ellipsis gl-whitespace-nowrap gl-pr-3 gl-text-sm gl-font-normal gl-text-subtle",attrs:{"data-testid":"chat-subtitle"}},[_vm._v("\n "+_vm._s(_vm.subtitle)+"\n ")]):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-ml-auto gl-flex gl-gap-3"},[(_vm.sessionId)?_c('gl-disclosure-dropdown',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip",value:(_vm.showSessionDropdownTooltip),expression:"showSessionDropdownTooltip"}],attrs:{"icon":"ellipsis_v","category":"tertiary","text-sr-only":"","size":"small","toggle-text":_vm.$options.i18n.CHAT_DROPDOWN_MORE_OPTIONS,"items":_vm.sessionIdItems,"no-caret":""},on:{"shown":_vm.showSessionDropdown,"hidden":_vm.hideSessionDropdown}}):_vm._e(),_vm._v(" "),_c('gl-button',{attrs:{"category":"tertiary","variant":"default","icon":"close","size":"small","data-testid":"chat-close-button","aria-label":_vm.$options.i18n.CHAT_CLOSE_LABEL},on:{"click":function($event){return _vm.$emit('close')}}})],1)]):_vm._e(),_vm._v(" "),(_vm.showSubheader)?_c('div',{staticClass:"drawer-title gl-flex gl-items-center gl-justify-start gl-gap-4 gl-px-4 gl-py-3",class:{ 'gl-border-t': !_vm.showStudioHeader, 'gl-border-b': _vm.showStudioHeader },attrs:{"data-testid":"chat-subheader"}},[_c('div',{staticClass:"gl-flex gl-grow gl-gap-3"},[_c('gl-avatar',{staticClass:"gl-shrink-0",attrs:{"size":32,"entity-name":_vm.title,"shape":"circle"}}),_vm._v(" "),_c('div',{staticClass:"gl-flex gl-flex-col gl-justify-center"},[_c('h3',{staticClass:"gl-my-0 gl-line-clamp-1 gl-text-[0.875rem] gl-text-default gl-break-anywhere"},[_vm._v("\n "+_vm._s(_vm.title)+"\n ")]),_vm._v(" "),(_vm.agentHandler)?_c('p',{staticClass:"gl-my-0 gl-text-[0.75rem] gl-text-subtle"},[_vm._v("\n "+_vm._s(_vm.agentHandler)+"\n ")]):_vm._e()])],1),_vm._v(" "),_c('div',{staticClass:"gl-flex gl-gap-3"},[(_vm.isMultithreaded && _vm.activeThreadId && _vm.currentView === _vm.VIEW_TYPES.LIST)?_c('gl-button',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip"}],attrs:{"title":_vm.$options.i18n.CHAT_BACK_TO_CHAT_TOOLTIP,"data-testid":"go-back-to-chat-button","category":"tertiary","size":"small","icon":"go-back","aria-label":_vm.$options.i18n.CHAT_BACK_TO_CHAT_TOOLTIP},on:{"click":function($event){return _vm.$emit('go-back-to-chat')}}}):_vm._e()],1)]):_vm._e(),_vm._v(" "),_vm._t("subheader"),_vm._v(" "),(_vm.info)?_c('gl-alert',{key:"info",staticClass:"!gl-pl-9",attrs:{"dismissible":false,"variant":"info","role":"alert","data-testid":"chat-info"}},[_c('span',{directives:[{name:"safe-html",rawName:"v-safe-html",value:(_vm.info),expression:"info"}]})]):_vm._e(),_vm._v(" "),(_vm.error)?_c('gl-alert',{key:"error",staticClass:"!gl-pl-9",attrs:{"dismissible":false,"variant":"danger","role":"alert","data-testid":"chat-error"}},[_c('span',{directives:[{name:"safe-html",rawName:"v-safe-html",value:(_vm.error),expression:"error"}]})]):_vm._e()],2)};
|
|
159
164
|
var __vue_staticRenderFns__ = [];
|
|
160
165
|
|
|
161
166
|
/* style */
|
package/dist/components/chat/components/duo_chat_message_tool_approval/message_tool_approval.js
CHANGED
|
@@ -165,13 +165,14 @@ var script = {
|
|
|
165
165
|
return this.approvalStatus === TOOL_STATUS.Approved;
|
|
166
166
|
},
|
|
167
167
|
isApproving() {
|
|
168
|
-
return this.
|
|
168
|
+
return this.localProcessingState === PROCESSING_STATE.APPROVING || this.isProcessing;
|
|
169
169
|
},
|
|
170
170
|
isDenying() {
|
|
171
|
-
return this.
|
|
171
|
+
return this.localProcessingState === PROCESSING_STATE.DENYING;
|
|
172
172
|
},
|
|
173
173
|
buttonsDisabled() {
|
|
174
|
-
|
|
174
|
+
// Disable if we've taken action locally OR if parent says we're processing
|
|
175
|
+
return this.localProcessingState !== PROCESSING_STATE.NONE || this.isProcessing;
|
|
175
176
|
},
|
|
176
177
|
approveButtonText() {
|
|
177
178
|
return this.isApproving ? this.$options.i18n.APPROVING_TEXT : this.$options.i18n.APPROVE_TEXT;
|
|
@@ -197,51 +198,45 @@ var script = {
|
|
|
197
198
|
}
|
|
198
199
|
},
|
|
199
200
|
watch: {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
this.resetProcessingState();
|
|
201
|
+
approvalStatus(newVal) {
|
|
202
|
+
if (newVal === TOOL_STATUS.Approved) {
|
|
203
|
+
this.collapsed = true;
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
206
|
},
|
|
207
207
|
methods: {
|
|
208
|
-
|
|
209
|
-
if (this.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const approvalPayload = {
|
|
213
|
-
type: this.primaryApprovalOption.type || acceptedApproveToolPayloads.APPROVE_TOOL_ONCE
|
|
214
|
-
};
|
|
215
|
-
this.$emit('approve-tool', approvalPayload);
|
|
216
|
-
},
|
|
217
|
-
handlePrimaryApprove() {
|
|
218
|
-
if (this.isProcessing) return;
|
|
208
|
+
approveWithType(approvalType) {
|
|
209
|
+
if (this.localProcessingState !== PROCESSING_STATE.NONE) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
219
212
|
this.localProcessingState = PROCESSING_STATE.APPROVING;
|
|
220
213
|
this.$emit('approve-tool', {
|
|
221
|
-
type:
|
|
214
|
+
type: approvalType
|
|
222
215
|
});
|
|
223
216
|
},
|
|
217
|
+
handleApprove() {
|
|
218
|
+
const approvalType = this.primaryApprovalOption.type || acceptedApproveToolPayloads.APPROVE_TOOL_ONCE;
|
|
219
|
+
this.approveWithType(approvalType);
|
|
220
|
+
},
|
|
221
|
+
handlePrimaryApprove() {
|
|
222
|
+
this.approveWithType(this.primaryApprovalOption.type);
|
|
223
|
+
},
|
|
224
224
|
handleDropdownSelection(option) {
|
|
225
|
-
|
|
226
|
-
this.localProcessingState = PROCESSING_STATE.APPROVING;
|
|
227
|
-
this.$emit('approve-tool', {
|
|
228
|
-
type: option.type
|
|
229
|
-
});
|
|
225
|
+
this.approveWithType(option.type);
|
|
230
226
|
},
|
|
231
227
|
handleDeny() {
|
|
232
|
-
if (this.isProcessing) return;
|
|
233
228
|
this.showDenialReason = true;
|
|
234
229
|
},
|
|
235
230
|
cancelDenial() {
|
|
236
231
|
this.showDenialReason = false;
|
|
237
232
|
this.denialReason = '';
|
|
238
|
-
this.localProcessingState = PROCESSING_STATE.NONE;
|
|
239
233
|
},
|
|
240
234
|
submitDenial() {
|
|
241
|
-
if (this.
|
|
235
|
+
if (this.localProcessingState !== PROCESSING_STATE.NONE) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
242
238
|
this.localProcessingState = PROCESSING_STATE.DENYING;
|
|
243
239
|
this.$emit('deny-tool', this.denialReason || null);
|
|
244
|
-
// Don't reset state here - wait for isProcessing to change
|
|
245
240
|
},
|
|
246
241
|
resetProcessingState() {
|
|
247
242
|
this.localProcessingState = PROCESSING_STATE.NONE;
|
package/package.json
CHANGED
|
@@ -370,15 +370,7 @@ export default {
|
|
|
370
370
|
!this.isToolApprovalProcessing &&
|
|
371
371
|
!this.isAwaitingToolApproval;
|
|
372
372
|
|
|
373
|
-
|
|
374
|
-
// but isToolApprovalProcessing is stuck at true, we should still enable submit
|
|
375
|
-
const isStuckInProcessing =
|
|
376
|
-
!this.isLoading &&
|
|
377
|
-
!this.isStreaming &&
|
|
378
|
-
!this.isAwaitingToolApproval &&
|
|
379
|
-
this.isToolApprovalProcessing;
|
|
380
|
-
|
|
381
|
-
return shouldAllowSubmit || isStuckInProcessing;
|
|
373
|
+
return shouldAllowSubmit;
|
|
382
374
|
},
|
|
383
375
|
shouldShowThreadList() {
|
|
384
376
|
return this.isMultithreaded && this.currentView === VIEW_TYPES.LIST;
|
|
@@ -484,6 +476,14 @@ export default {
|
|
|
484
476
|
lastMessage && lastMessage.message_type === 'request' && lastMessage.tool_info
|
|
485
477
|
);
|
|
486
478
|
},
|
|
479
|
+
canCancelInternal() {
|
|
480
|
+
// Don't allow cancel while there are pending tool approvals
|
|
481
|
+
if (this.isAwaitingToolApproval) {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return this.canCancel;
|
|
486
|
+
},
|
|
487
487
|
},
|
|
488
488
|
watch: {
|
|
489
489
|
multiThreadedView(newView) {
|
|
@@ -1029,7 +1029,7 @@ export default {
|
|
|
1029
1029
|
class="!gl-absolute gl-bottom-2 gl-right-2 !gl-rounded-full"
|
|
1030
1030
|
data-testid="chat-prompt-cancel-button"
|
|
1031
1031
|
:aria-label="$options.i18n.CHAT_CANCEL_LABEL"
|
|
1032
|
-
:disabled="!
|
|
1032
|
+
:disabled="!canCancelInternal"
|
|
1033
1033
|
@click="cancelPrompt"
|
|
1034
1034
|
/>
|
|
1035
1035
|
</template>
|
|
@@ -210,6 +210,22 @@ export default {
|
|
|
210
210
|
required: false,
|
|
211
211
|
default: '',
|
|
212
212
|
},
|
|
213
|
+
/**
|
|
214
|
+
* Chat state object that contains enablement state and optional reason message.
|
|
215
|
+
* When chat is disabled (isEnabled: false), a reason message must be provided.
|
|
216
|
+
*/
|
|
217
|
+
chatState: {
|
|
218
|
+
type: Object,
|
|
219
|
+
required: false,
|
|
220
|
+
default: () => ({ isEnabled: true, reason: null }),
|
|
221
|
+
validator: (value) => {
|
|
222
|
+
// If chat is disabled, reason must be provided
|
|
223
|
+
if (!value.isEnabled && !value.reason) {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
return true;
|
|
227
|
+
},
|
|
228
|
+
},
|
|
213
229
|
/**
|
|
214
230
|
* Array of messages to display in the chat.
|
|
215
231
|
*/
|
|
@@ -824,6 +840,7 @@ export default {
|
|
|
824
840
|
:title="isMultithreaded && currentView === 'list' ? $options.i18n.CHAT_HISTORY_TITLE : title"
|
|
825
841
|
:subtitle="activeThreadTitleForView"
|
|
826
842
|
:error="error"
|
|
843
|
+
:info="hasMessages ? chatState.reason : ''"
|
|
827
844
|
:is-multithreaded="isMultithreaded"
|
|
828
845
|
:current-view="currentView"
|
|
829
846
|
:should-render-resizable="shouldRenderResizable"
|
|
@@ -860,7 +877,13 @@ export default {
|
|
|
860
877
|
mode="out-in"
|
|
861
878
|
tag="section"
|
|
862
879
|
name="message"
|
|
863
|
-
|
|
880
|
+
data-testid="chat-messages"
|
|
881
|
+
:class="[
|
|
882
|
+
'duo-chat-history gl-px-4',
|
|
883
|
+
$scopedSlots['custom-empty-state']
|
|
884
|
+
? 'gl-flex gl-flex-1 gl-items-center gl-justify-center'
|
|
885
|
+
: 'gl-mt-auto gl-pb-4 gl-pt-6',
|
|
886
|
+
]"
|
|
864
887
|
>
|
|
865
888
|
<duo-chat-conversation
|
|
866
889
|
v-for="(conversation, index) in conversations"
|
|
@@ -881,44 +904,49 @@ export default {
|
|
|
881
904
|
@open-file-path="onOpenFilePath"
|
|
882
905
|
/>
|
|
883
906
|
<template v-if="!hasMessages && !isLoading">
|
|
884
|
-
<
|
|
885
|
-
key="empty-state-message"
|
|
886
|
-
class="duo-chat-message gl-rounded-bl-none gl-leading-20 gl-text-default gl-break-anywhere"
|
|
887
|
-
data-testid="gl-duo-chat-empty-state"
|
|
888
|
-
>
|
|
907
|
+
<slot name="custom-empty-state">
|
|
889
908
|
<div
|
|
890
|
-
|
|
909
|
+
key="empty-state-message"
|
|
910
|
+
class="duo-chat-message gl-rounded-bl-none gl-leading-20 gl-text-default gl-break-anywhere"
|
|
911
|
+
data-testid="gl-duo-chat-empty-state"
|
|
891
912
|
>
|
|
892
|
-
<
|
|
893
|
-
|
|
894
|
-
</h1>
|
|
895
|
-
<h2
|
|
896
|
-
v-if="agentName"
|
|
897
|
-
class="gl-heading-2 gl-my-0"
|
|
898
|
-
data-testid="gl-duo-chat-empty-state-greeting"
|
|
913
|
+
<div
|
|
914
|
+
class="gl-mb-[3.75rem] gl-flex gl-flex-col gl-items-center gl-justify-center gl-gap-3 gl-text-center"
|
|
899
915
|
>
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
916
|
+
<h1 class="gl-my-0 gl-text-[3.5rem]" data-testid="gl-duo-chat-empty-state-emoji">
|
|
917
|
+
{{ $options.i18n.CHAT_EMPTY_STATE_EMOJI }}
|
|
918
|
+
</h1>
|
|
919
|
+
<h2
|
|
920
|
+
v-if="agentName"
|
|
921
|
+
class="gl-heading-2 gl-my-0"
|
|
922
|
+
data-testid="gl-duo-chat-empty-state-greeting"
|
|
923
|
+
>
|
|
924
|
+
{{ emptyStateGreeting }}
|
|
925
|
+
</h2>
|
|
926
|
+
<h2 class="gl-my-0 gl-text-size-h2" data-testid="gl-duo-chat-empty-state-title">
|
|
927
|
+
{{ emptyStateMainText }}
|
|
928
|
+
</h2>
|
|
929
|
+
<p
|
|
930
|
+
class="gl-text-base gl-text-subtle"
|
|
931
|
+
data-testid="gl-duo-chat-empty-state-subtitle"
|
|
932
|
+
>
|
|
933
|
+
{{ emptyStateSubText }}
|
|
934
|
+
</p>
|
|
935
|
+
</div>
|
|
936
|
+
<duo-chat-predefined-prompts
|
|
937
|
+
key="predefined-prompts"
|
|
938
|
+
:prompts="predefinedPrompts"
|
|
939
|
+
@click="sendPredefinedPrompt"
|
|
940
|
+
/>
|
|
908
941
|
</div>
|
|
909
|
-
|
|
910
|
-
key="predefined-prompts"
|
|
911
|
-
:prompts="predefinedPrompts"
|
|
912
|
-
@click="sendPredefinedPrompt"
|
|
913
|
-
/>
|
|
914
|
-
</div>
|
|
942
|
+
</slot>
|
|
915
943
|
</template>
|
|
916
944
|
<duo-chat-loader v-if="isLoading" key="loader" :tool-name="toolName" />
|
|
917
945
|
<div key="anchor" ref="anchor" class="scroll-anchor"></div>
|
|
918
946
|
</transition-group>
|
|
919
947
|
</div>
|
|
920
948
|
<footer
|
|
921
|
-
v-if="
|
|
949
|
+
v-if="!shouldShowThreadList"
|
|
922
950
|
data-testid="chat-footer"
|
|
923
951
|
class="duo-chat-drawer-footer gl-relative gl-z-2 gl-shrink-0"
|
|
924
952
|
>
|
|
@@ -983,7 +1011,7 @@ export default {
|
|
|
983
1011
|
<gl-form-textarea
|
|
984
1012
|
ref="prompt"
|
|
985
1013
|
v-model="prompt"
|
|
986
|
-
:disabled="!canSubmit"
|
|
1014
|
+
:disabled="!canSubmit || !isChatAvailable || !chatState.isEnabled"
|
|
987
1015
|
data-testid="chat-prompt-input"
|
|
988
1016
|
:placeholder="inputPlaceholder"
|
|
989
1017
|
:character-count-limit="maxPromptLength"
|
|
@@ -1045,7 +1073,9 @@ export default {
|
|
|
1045
1073
|
variant="confirm"
|
|
1046
1074
|
class="!gl-rounded-full"
|
|
1047
1075
|
type="submit"
|
|
1048
|
-
:disabled="
|
|
1076
|
+
:disabled="
|
|
1077
|
+
!isChatAvailable || !chatState.isEnabled || isPromptEmpty || !hasValidPrompt
|
|
1078
|
+
"
|
|
1049
1079
|
data-testid="chat-prompt-submit-button"
|
|
1050
1080
|
:aria-label="$options.i18n.CHAT_SUBMIT_LABEL"
|
|
1051
1081
|
/>
|
|
@@ -70,6 +70,11 @@ export default {
|
|
|
70
70
|
required: false,
|
|
71
71
|
default: '',
|
|
72
72
|
},
|
|
73
|
+
info: {
|
|
74
|
+
type: String,
|
|
75
|
+
required: false,
|
|
76
|
+
default: '',
|
|
77
|
+
},
|
|
73
78
|
isMultithreaded: {
|
|
74
79
|
type: Boolean,
|
|
75
80
|
required: false,
|
|
@@ -244,6 +249,18 @@ export default {
|
|
|
244
249
|
|
|
245
250
|
<slot name="subheader"></slot>
|
|
246
251
|
|
|
252
|
+
<gl-alert
|
|
253
|
+
v-if="info"
|
|
254
|
+
key="info"
|
|
255
|
+
:dismissible="false"
|
|
256
|
+
variant="info"
|
|
257
|
+
class="!gl-pl-9"
|
|
258
|
+
role="alert"
|
|
259
|
+
data-testid="chat-info"
|
|
260
|
+
>
|
|
261
|
+
<span v-safe-html="info"></span>
|
|
262
|
+
</gl-alert>
|
|
263
|
+
|
|
247
264
|
<gl-alert
|
|
248
265
|
v-if="error"
|
|
249
266
|
key="error"
|
package/src/components/chat/components/duo_chat_message_tool_approval/message_tool_approval.vue
CHANGED
|
@@ -189,13 +189,14 @@ export default {
|
|
|
189
189
|
return this.approvalStatus === TOOL_STATUS.Approved;
|
|
190
190
|
},
|
|
191
191
|
isApproving() {
|
|
192
|
-
return this.
|
|
192
|
+
return this.localProcessingState === PROCESSING_STATE.APPROVING || this.isProcessing;
|
|
193
193
|
},
|
|
194
194
|
isDenying() {
|
|
195
|
-
return this.
|
|
195
|
+
return this.localProcessingState === PROCESSING_STATE.DENYING;
|
|
196
196
|
},
|
|
197
197
|
buttonsDisabled() {
|
|
198
|
-
|
|
198
|
+
// Disable if we've taken action locally OR if parent says we're processing
|
|
199
|
+
return this.localProcessingState !== PROCESSING_STATE.NONE || this.isProcessing;
|
|
199
200
|
},
|
|
200
201
|
approveButtonText() {
|
|
201
202
|
return this.isApproving ? this.$options.i18n.APPROVING_TEXT : this.$options.i18n.APPROVE_TEXT;
|
|
@@ -221,52 +222,46 @@ export default {
|
|
|
221
222
|
},
|
|
222
223
|
},
|
|
223
224
|
watch: {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
this.resetProcessingState();
|
|
225
|
+
approvalStatus(newVal) {
|
|
226
|
+
if (newVal === TOOL_STATUS.Approved) {
|
|
227
|
+
this.collapsed = true;
|
|
228
228
|
}
|
|
229
229
|
},
|
|
230
230
|
},
|
|
231
231
|
methods: {
|
|
232
|
-
|
|
233
|
-
if (this.
|
|
232
|
+
approveWithType(approvalType) {
|
|
233
|
+
if (this.localProcessingState !== PROCESSING_STATE.NONE) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
234
236
|
|
|
235
237
|
this.localProcessingState = PROCESSING_STATE.APPROVING;
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
this.$emit('approve-tool', { type: approvalType });
|
|
239
|
+
},
|
|
240
|
+
handleApprove() {
|
|
241
|
+
const approvalType =
|
|
242
|
+
this.primaryApprovalOption.type || acceptedApproveToolPayloads.APPROVE_TOOL_ONCE;
|
|
243
|
+
this.approveWithType(approvalType);
|
|
241
244
|
},
|
|
242
245
|
handlePrimaryApprove() {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
this.localProcessingState = PROCESSING_STATE.APPROVING;
|
|
246
|
-
this.$emit('approve-tool', { type: this.primaryApprovalOption.type });
|
|
246
|
+
this.approveWithType(this.primaryApprovalOption.type);
|
|
247
247
|
},
|
|
248
248
|
handleDropdownSelection(option) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
this.localProcessingState = PROCESSING_STATE.APPROVING;
|
|
252
|
-
this.$emit('approve-tool', { type: option.type });
|
|
249
|
+
this.approveWithType(option.type);
|
|
253
250
|
},
|
|
254
251
|
handleDeny() {
|
|
255
|
-
if (this.isProcessing) return;
|
|
256
|
-
|
|
257
252
|
this.showDenialReason = true;
|
|
258
253
|
},
|
|
259
254
|
cancelDenial() {
|
|
260
255
|
this.showDenialReason = false;
|
|
261
256
|
this.denialReason = '';
|
|
262
|
-
this.localProcessingState = PROCESSING_STATE.NONE;
|
|
263
257
|
},
|
|
264
258
|
submitDenial() {
|
|
265
|
-
if (this.
|
|
259
|
+
if (this.localProcessingState !== PROCESSING_STATE.NONE) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
266
262
|
|
|
267
263
|
this.localProcessingState = PROCESSING_STATE.DENYING;
|
|
268
264
|
this.$emit('deny-tool', this.denialReason || null);
|
|
269
|
-
// Don't reset state here - wait for isProcessing to change
|
|
270
265
|
},
|
|
271
266
|
resetProcessingState() {
|
|
272
267
|
this.localProcessingState = PROCESSING_STATE.NONE;
|