@gitlab/duo-ui 15.3.0 → 15.4.1

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/agentic_chat/agentic_duo_chat.js +1 -1
  3. package/dist/components/agentic_chat/web_agentic_duo_chat.js +1 -1
  4. package/dist/components/chat/components/duo_chat_message/duo_chat_message.js +21 -28
  5. package/dist/components/chat/components/duo_chat_message/markdown_renderer.js +102 -0
  6. package/dist/components/chat/components/duo_chat_message/message_types/message_agent.js +5 -6
  7. package/dist/components/chat/components/duo_chat_message/message_types/message_base.js +27 -14
  8. package/dist/components/chat/components/duo_chat_message/message_types/message_tool_kv_section.js +1 -1
  9. package/dist/components/chat/components/duo_chat_message_tool_approval/components/base_tool_params.js +1 -1
  10. package/dist/components/chat/components/duo_chat_message_tool_approval/components/create_commit_tool_params.js +9 -3
  11. package/dist/components/chat/components/duo_chat_message_tool_approval/components/pre_block.js +11 -6
  12. package/dist/components/chat/components/duo_chat_message_tool_approval/components/tool_params_json_view.js +1 -1
  13. package/dist/components/chat/components/duo_chat_threads/duo_chat_threads.js +1 -1
  14. package/dist/components/chat/components/duo_chat_threads/{duo_chat_threads_skeleton.js → duo_chat_threads_skeleton_loader.js} +4 -2
  15. package/dist/components/chat/duo_chat.js +1 -1
  16. package/dist/components/chat/markdown_renderer.js +31 -5
  17. package/dist/components/chat/mock_data.js +28 -2
  18. package/dist/components/chat/web_duo_chat.js +1 -1
  19. package/dist/components/ui/duo_layout/duo_layout.js +1 -1
  20. package/dist/components.css +1 -1
  21. package/dist/components.css.map +1 -1
  22. package/dist/utils/highlight.js +483 -0
  23. package/package.json +3 -2
  24. package/src/components/agentic_chat/agentic_duo_chat.scss +2 -1
  25. package/src/components/agentic_chat/agentic_duo_chat.vue +1 -1
  26. package/src/components/agentic_chat/web_agentic_duo_chat.vue +1 -1
  27. package/src/components/chat/components/duo_chat_message/duo_chat_message.scss +15 -19
  28. package/src/components/chat/components/duo_chat_message/duo_chat_message.vue +30 -28
  29. package/src/components/chat/components/duo_chat_message/markdown_renderer.vue +71 -0
  30. package/src/components/chat/components/duo_chat_message/message_types/message_agent.vue +8 -8
  31. package/src/components/chat/components/duo_chat_message/message_types/message_base.vue +24 -14
  32. package/src/components/chat/components/duo_chat_message/message_types/message_tool_kv_section.vue +1 -1
  33. package/src/components/chat/components/duo_chat_message_tool_approval/components/base_tool_params.vue +1 -1
  34. package/src/components/chat/components/duo_chat_message_tool_approval/components/create_commit_tool_params.vue +7 -2
  35. package/src/components/chat/components/duo_chat_message_tool_approval/components/pre_block.vue +11 -6
  36. package/src/components/chat/components/duo_chat_message_tool_approval/components/tool_params_json_view.vue +1 -1
  37. package/src/components/chat/components/duo_chat_threads/duo_chat_threads.vue +1 -1
  38. package/src/components/chat/components/duo_chat_threads/{duo_chat_threads_skeleton.vue → duo_chat_threads_skeleton_loader.vue} +4 -4
  39. package/src/components/chat/duo_chat.vue +1 -1
  40. package/src/components/chat/markdown_renderer.js +37 -6
  41. package/src/components/chat/mock_data.js +30 -1
  42. package/src/components/chat/web_duo_chat.vue +1 -1
  43. package/src/components/ui/duo_layout/duo_layout.vue +1 -1
  44. package/src/utils/highlight.js +562 -0
  45. package/dist/components/chat/components/duo_chat_message_tool_approval/services/highlight.js +0 -21
  46. package/src/components/chat/components/duo_chat_message_tool_approval/services/highlight.js +0 -18
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [15.4.1](https://gitlab.com/gitlab-org/duo-ui/compare/v15.4.0...v15.4.1) (2026-01-06)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * migrate to npm trusted publishing ([c63fe65](https://gitlab.com/gitlab-org/duo-ui/commit/c63fe6575973c7e3d9cca7711be85c2836d47d26))
7
+
8
+ # [15.4.0](https://gitlab.com/gitlab-org/duo-ui/compare/v15.3.0...v15.4.0) (2025-12-15)
9
+
10
+
11
+ ### Features
12
+
13
+ * Syntax highlight markdown code blocks ([c491219](https://gitlab.com/gitlab-org/duo-ui/commit/c491219a4ae2bdce94931ecc4c8e3f5246b47ed2))
14
+
1
15
  # [15.3.0](https://gitlab.com/gitlab-org/duo-ui/compare/v15.2.0...v15.3.0) (2025-12-11)
2
16
 
3
17
 
@@ -737,7 +737,7 @@ const __vue_script__ = script;
737
737
  var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c(_vm.shouldRenderResizable ? 'vue-resizable' : 'div',{tag:"component",class:{
738
738
  'duo-chat-resizable': _vm.shouldRenderResizable,
739
739
  'non-resizable-wrapper': !_vm.shouldRenderResizable,
740
- },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:{
740
+ },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:"duo-chat gl-bottom-0 gl-flex gl-max-h-full gl-flex-col",class:{
741
741
  'resizable-content': _vm.shouldRenderResizable,
742
742
  'duo-chat-drawer': !_vm.shouldRenderResizable,
743
743
  },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,"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},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,"trusted-urls":_vm.trustedUrls},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.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.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-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,4037582087)},[_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 || !_vm.isChatAvailable || !_vm.chatState.isEnabled,"data-testid":"chat-prompt-input","placeholder":_vm.inputPlaceholder,"character-count-limit":_vm.maxPromptLength,"textarea-classes":[
@@ -760,7 +760,7 @@ var script = {
760
760
  const __vue_script__ = script;
761
761
 
762
762
  /* template */
763
- 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,"loading":_vm.loadingThreadList},on:{"new-chat":_vm.onNewChat,"select-thread":_vm.onSelectThread,"delete-thread":_vm.onDeleteThread,"close":_vm.hideChat}}):_c('transition-group',{class:[
763
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"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,"loading":_vm.loadingThreadList},on:{"new-chat":_vm.onNewChat,"select-thread":_vm.onSelectThread,"delete-thread":_vm.onDeleteThread,"close":_vm.hideChat}}):_c('transition-group',{class:[
764
764
  'duo-chat-history gl-px-4',
765
765
  _vm.$scopedSlots['custom-empty-state'] && !_vm.hasMessages && !_vm.isLoading
766
766
  ? 'gl-m-auto'
@@ -4,9 +4,9 @@ import throttle from 'lodash/throttle';
4
4
  import DuoChatContextItemSelections from '../duo_chat_context/duo_chat_context_item_selections/duo_chat_context_item_selections';
5
5
  import { SELECTED_CONTEXT_ITEMS_DEFAULT_COLLAPSED, MESSAGE_MODEL_ROLES } from '../../constants';
6
6
  import DocumentationSources from '../duo_chat_message_sources/duo_chat_message_sources';
7
- import { renderDuoChatMarkdownPreview } from '../../markdown_renderer';
8
7
  import { concatUntilEmpty, copyToClipboard } from '../utils';
9
8
  import MessageFeedback from './message_feedback';
9
+ import MarkdownRenderer from './markdown_renderer';
10
10
  import { CopyCodeElement } from './copy_code_element';
11
11
  import { InsertCodeSnippetElement } from './insert_code_snippet_element';
12
12
  import { DUO_CODE_SCRIM_BOTTOM_CLASS, DUO_CODE_SCRIM_OFFSET, DUO_CODE_SCRIM_TOP_CLASS } from './constants';
@@ -32,7 +32,8 @@ var script = {
32
32
  MessageMap,
33
33
  GlIcon,
34
34
  GlAnimatedLoaderIcon,
35
- GlButton
35
+ GlButton,
36
+ MarkdownRenderer
36
37
  },
37
38
  directives: {
38
39
  SafeHtml: GlSafeHtmlDirective,
@@ -48,10 +49,6 @@ var script = {
48
49
  default: () => element => {
49
50
  element.classList.add('duo-chat-markdown', 'duo-chat-compact-markdown');
50
51
  }
51
- },
52
- renderMarkdown: {
53
- from: 'renderMarkdown',
54
- default: () => renderDuoChatMarkdownPreview
55
52
  }
56
53
  },
57
54
  props: {
@@ -135,31 +132,25 @@ var script = {
135
132
  var _this$message$extras2;
136
133
  return Boolean((_this$message$extras2 = this.message.extras) === null || _this$message$extras2 === void 0 ? void 0 : _this$message$extras2.hasFeedback);
137
134
  },
135
+ hasContentHtml() {
136
+ var _this$message$content;
137
+ return ((_this$message$content = this.message.contentHtml) === null || _this$message$content === void 0 ? void 0 : _this$message$content.length) > 0;
138
+ },
138
139
  defaultContent() {
139
- if (this.message.contentHtml) {
140
+ if (this.hasContentHtml) {
140
141
  return this.message.contentHtml;
141
142
  }
142
- return this.renderMarkdown(this.message.content, {
143
- trustedUrls: this.trustedUrls
144
- });
143
+ return this.message.content;
145
144
  },
146
145
  messageContent() {
147
146
  if (this.isAssistantMessage && this.isChunk) {
148
- return this.renderMarkdown(concatUntilEmpty(this.messageChunks), {
149
- trustedUrls: this.trustedUrls
150
- });
147
+ return concatUntilEmpty(this.messageChunks);
151
148
  }
152
- return this.renderMarkdown(this.defaultContent, {
153
- trustedUrls: this.trustedUrls
154
- }) || this.renderMarkdown(concatUntilEmpty(this.message.chunks), {
155
- trustedUrls: this.trustedUrls
156
- });
149
+ return this.defaultContent || concatUntilEmpty(this.message.chunks);
157
150
  },
158
151
  renderedError() {
159
152
  var _this$message$errors;
160
- return this.renderMarkdown(((_this$message$errors = this.message.errors) === null || _this$message$errors === void 0 ? void 0 : _this$message$errors.join('; ')) || '', {
161
- trustedUrls: this.trustedUrls
162
- });
153
+ return (_this$message$errors = this.message.errors) === null || _this$message$errors === void 0 ? void 0 : _this$message$errors.join('; ');
163
154
  },
164
155
  error() {
165
156
  var _this$message, _this$message$errors2;
@@ -232,11 +223,12 @@ var script = {
232
223
  this.messageWatcher = null; // Ensure the watcher can't be stopped multiple times
233
224
  }
234
225
  },
235
- hydrateContentWithGFM() {
236
- if (this.isDoneStreaming && this.$refs.content) {
237
- this.$nextTick(() => {
238
- this.renderGFM(this.$refs.content);
239
- });
226
+ async hydrateContentWithGFM() {
227
+ await this.$nextTick();
228
+ if (this.isDoneStreaming) {
229
+ if (this.$refs.content) {
230
+ this.renderGFM(this.$refs.content.$el);
231
+ }
240
232
  }
241
233
  this.detectScrollableCodeBlocks();
242
234
  },
@@ -312,9 +304,10 @@ const __vue_script__ = script;
312
304
  var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{ref:"content-wrapper",staticClass:"duo-chat-message-container gl-flex gl-flex-col gl-gap-4 gl-text-base gl-break-anywhere",class:{
313
305
  'gl-pr-7': _vm.isAssistantMessage,
314
306
  'gl-justify-end gl-pl-7': _vm.isUserMessage,
315
- },on:{"insert-code-snippet":_vm.onInsertCodeSnippet,"copy-code-snippet":_vm.onCopyCodeSnippet}},[(_vm.error)?_c('div',{ref:"error-message",staticClass:"duo-chat-message-with-error gl-flex gl-bg-feedback-danger gl-p-4"},[(_vm.error)?_c('gl-icon',{staticClass:"error-icon !gl-mt-1 gl-mr-3 gl-shrink-0 gl-text-danger",attrs:{"aria-label":_vm.$options.i18n.MESSAGE_ERROR,"name":"error","size":16,"data-testid":"error"}}):_vm._e(),_vm._v(" "),_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html:[$options.safeHtmlConfigExtension]",value:(_vm.renderedError),expression:"renderedError",arg:_vm.$options.safeHtmlConfigExtension}],ref:"error-message"})],1):(_vm.isAssistantMessage || _vm.isUserMessage)?[_c('div',{staticClass:"gl-sr-only"},[_vm._v("\n "+_vm._s(_vm.isUserMessage ? _vm.$options.i18n.FROM_ME : _vm.$options.i18n.FROM_DUO)+"\n ")]),_vm._v(" "),(_vm.displaySelectedContextItems && _vm.isAssistantMessage)?_c('duo-chat-context-item-selections',{attrs:{"selections":_vm.selectedContextItems,"title":_vm.selectedContextItemsTitle,"default-collapsed":_vm.selectedContextItemsDefaultCollapsed,"variant":"assistant"},on:{"get-content":_vm.onGetContextItemContent}}):_vm._e(),_vm._v(" "),_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html:[$options.safeHtmlConfigExtension]",value:(_vm.messageContent),expression:"messageContent",arg:_vm.$options.safeHtmlConfigExtension}],ref:"content",staticClass:"duo-chat-message",class:{
307
+ 'duo-chat-message-complete': _vm.isDoneStreaming,
308
+ },on:{"insert-code-snippet":_vm.onInsertCodeSnippet,"copy-code-snippet":_vm.onCopyCodeSnippet}},[(_vm.error)?_c('div',{ref:"error-message",staticClass:"duo-chat-message-with-error gl-flex gl-bg-feedback-danger gl-p-4"},[(_vm.error)?_c('gl-icon',{staticClass:"error-icon !gl-mt-1 gl-mr-3 gl-shrink-0 gl-text-danger",attrs:{"aria-label":_vm.$options.i18n.MESSAGE_ERROR,"name":"error","size":16,"data-testid":"error"}}):_vm._e(),_vm._v(" "),(_vm.error)?_c('markdown-renderer',{ref:"error-message",staticClass:"duo-chat-message-error",attrs:{"markdown":_vm.renderedError,"trusted-urls":_vm.trustedUrls}}):_vm._e()],1):(_vm.isAssistantMessage || _vm.isUserMessage)?[_c('div',{staticClass:"gl-sr-only"},[_vm._v("\n "+_vm._s(_vm.isUserMessage ? _vm.$options.i18n.FROM_ME : _vm.$options.i18n.FROM_DUO)+"\n ")]),_vm._v(" "),(_vm.displaySelectedContextItems && _vm.isAssistantMessage)?_c('duo-chat-context-item-selections',{attrs:{"selections":_vm.selectedContextItems,"title":_vm.selectedContextItemsTitle,"default-collapsed":_vm.selectedContextItemsDefaultCollapsed,"variant":"assistant"},on:{"get-content":_vm.onGetContextItemContent}}):_vm._e(),_vm._v(" "),_c('markdown-renderer',{ref:"content",staticClass:"duo-chat-message",class:{
316
309
  'gl-bg-feedback-info gl-p-4 gl-text-feedback-info': _vm.isUserMessage,
317
- }}),_vm._v(" "),(_vm.sources)?_c('documentation-sources',{attrs:{"sources":_vm.sources}}):_vm._e(),_vm._v(" "),(_vm.isAssistantMessage)?_c('div',{staticClass:"duo-chat-message-actions -gl-ml-2 gl-flex gl-items-start gl-gap-3"},[(_vm.shouldShowCopyAction)?_c('gl-button',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip.hover",modifiers:{"hover":true}}],class:{ '!gl-text-success': _vm.copied, '!gl-text-subtle': !_vm.copied },attrs:{"title":_vm.copied ? _vm.$options.i18n.CHAT_MESSAGE_COPIED : _vm.$options.i18n.CHAT_MESSAGE_COPY,"icon":_vm.copied ? 'check-circle-filled' : 'copy-to-clipboard',"category":"tertiary","size":"small"},on:{"click":_vm.copyMessage,"focusout":function($event){_vm.copied = false;}}}):_vm._e(),_vm._v(" "),(_vm.isChunkAndNotCancelled)?_c('gl-animated-loader-icon',{attrs:{"is-on":true}}):_vm._e(),_vm._v(" "),(_vm.shouldShowFeedbackLink)?_c('message-feedback',{attrs:{"has-feedback":_vm.hasFeedback},on:{"feedback":_vm.logEvent}}):_vm._e()],1):_vm._e(),_vm._v(" "),(_vm.displaySelectedContextItems && _vm.isUserMessage)?_c('duo-chat-context-item-selections',{attrs:{"selections":_vm.selectedContextItems,"title":_vm.selectedContextItemsTitle,"default-collapsed":_vm.selectedContextItemsDefaultCollapsed,"variant":"user"},on:{"get-content":_vm.onGetContextItemContent}}):_vm._e()]:_c('message-map',{attrs:{"message":_vm.message,"with-feedback":_vm.withFeedback,"working-directory":_vm.workingDirectory,"data-testid":"workflow-message"},on:{"open-file-path":_vm.onOpenFilePath,"feedback":_vm.logEvent}})],2)};
310
+ },attrs:{"is-html":_vm.hasContentHtml,"markdown":_vm.messageContent,"trusted-urls":_vm.trustedUrls}}),_vm._v(" "),(_vm.sources)?_c('documentation-sources',{attrs:{"sources":_vm.sources}}):_vm._e(),_vm._v(" "),(_vm.isAssistantMessage)?_c('div',{staticClass:"duo-chat-message-actions -gl-ml-2 gl-flex gl-items-start gl-gap-3"},[(_vm.shouldShowCopyAction)?_c('gl-button',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip.hover",modifiers:{"hover":true}}],class:{ '!gl-text-success': _vm.copied, '!gl-text-subtle': !_vm.copied },attrs:{"title":_vm.copied ? _vm.$options.i18n.CHAT_MESSAGE_COPIED : _vm.$options.i18n.CHAT_MESSAGE_COPY,"icon":_vm.copied ? 'check-circle-filled' : 'copy-to-clipboard',"category":"tertiary","size":"small"},on:{"click":_vm.copyMessage,"focusout":function($event){_vm.copied = false;}}}):_vm._e(),_vm._v(" "),(_vm.isChunkAndNotCancelled)?_c('gl-animated-loader-icon',{attrs:{"is-on":true}}):_vm._e(),_vm._v(" "),(_vm.shouldShowFeedbackLink)?_c('message-feedback',{attrs:{"has-feedback":_vm.hasFeedback},on:{"feedback":_vm.logEvent}}):_vm._e()],1):_vm._e(),_vm._v(" "),(_vm.displaySelectedContextItems && _vm.isUserMessage)?_c('duo-chat-context-item-selections',{attrs:{"selections":_vm.selectedContextItems,"title":_vm.selectedContextItemsTitle,"default-collapsed":_vm.selectedContextItemsDefaultCollapsed,"variant":"user"},on:{"get-content":_vm.onGetContextItemContent}}):_vm._e()]:_c('message-map',{attrs:{"message":_vm.message,"with-feedback":_vm.withFeedback,"working-directory":_vm.workingDirectory,"data-testid":"workflow-message"},on:{"open-file-path":_vm.onOpenFilePath,"feedback":_vm.logEvent}})],2)};
318
311
  var __vue_staticRenderFns__ = [];
319
312
 
320
313
  /* style */
@@ -0,0 +1,102 @@
1
+ import { GlSafeHtmlDirective } from '@gitlab/ui';
2
+ import { renderDuoChatMarkdownPreview } from '../../markdown_renderer';
3
+ import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
4
+
5
+ var script = {
6
+ name: 'MarkdownRenderer',
7
+ directives: {
8
+ SafeHtml: GlSafeHtmlDirective
9
+ },
10
+ inject: {
11
+ // Note, we likely might move away from Provide/Inject for this
12
+ // and only ship the versions that are currently in the default
13
+ // See https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/3953#note_1762834219
14
+ // for more context.
15
+ renderGFM: {
16
+ from: 'renderGFM',
17
+ default: () => element => {
18
+ element.classList.add('gl-markdown', 'gl-compact-markdown', 'gl-text-sm');
19
+ }
20
+ },
21
+ renderMarkdown: {
22
+ from: 'renderMarkdown',
23
+ default: () => renderDuoChatMarkdownPreview
24
+ }
25
+ },
26
+ props: {
27
+ markdown: {
28
+ type: String,
29
+ required: false,
30
+ default: ''
31
+ },
32
+ isHtml: {
33
+ type: Boolean,
34
+ required: false,
35
+ default: false
36
+ },
37
+ trustedUrls: {
38
+ type: Array,
39
+ required: false,
40
+ default: () => []
41
+ }
42
+ },
43
+ data() {
44
+ return {
45
+ renderedMarkdown: ''
46
+ };
47
+ },
48
+ watch: {
49
+ async markdown() {
50
+ this.render();
51
+ }
52
+ },
53
+ created() {
54
+ this.render();
55
+ },
56
+ methods: {
57
+ async render() {
58
+ this.renderedMarkdown = this.isHtml ? this.markdown : await this.renderMarkdown(this.markdown, this.trustedUrls);
59
+ }
60
+ },
61
+ safeHtmlConfigExtension: {
62
+ ADD_TAGS: ['copy-code', 'insert-code-snippet']
63
+ }
64
+ };
65
+
66
+ /* script */
67
+ const __vue_script__ = script;
68
+
69
+ /* template */
70
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{directives:[{name:"safe-html",rawName:"v-safe-html:[$options.safeHtmlConfigExtension]",value:(_vm.renderedMarkdown),expression:"renderedMarkdown",arg:_vm.$options.safeHtmlConfigExtension}],ref:"content"})};
71
+ var __vue_staticRenderFns__ = [];
72
+
73
+ /* style */
74
+ const __vue_inject_styles__ = undefined;
75
+ /* scoped */
76
+ const __vue_scope_id__ = undefined;
77
+ /* module identifier */
78
+ const __vue_module_identifier__ = undefined;
79
+ /* functional template */
80
+ const __vue_is_functional_template__ = false;
81
+ /* style inject */
82
+
83
+ /* style inject SSR */
84
+
85
+ /* style inject shadow dom */
86
+
87
+
88
+
89
+ const __vue_component__ = __vue_normalize__(
90
+ { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
91
+ __vue_inject_styles__,
92
+ __vue_script__,
93
+ __vue_scope_id__,
94
+ __vue_is_functional_template__,
95
+ __vue_module_identifier__,
96
+ false,
97
+ undefined,
98
+ undefined,
99
+ undefined
100
+ );
101
+
102
+ export default __vue_component__;
@@ -1,5 +1,6 @@
1
- import { GlIcon, GlSafeHtmlDirective } from '@gitlab/ui';
1
+ import { GlIcon } from '@gitlab/ui';
2
2
  import MessageFeedback from '../message_feedback';
3
+ import MarkdownRenderer from '../markdown_renderer';
3
4
  import BaseMessage from './message_base';
4
5
  import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
5
6
 
@@ -7,11 +8,9 @@ var script = {
7
8
  name: 'DuoAgentMessage',
8
9
  components: {
9
10
  BaseMessage,
11
+ GlIcon,
10
12
  MessageFeedback,
11
- GlIcon
12
- },
13
- directives: {
14
- SafeHtml: GlSafeHtmlDirective
13
+ MarkdownRenderer
15
14
  },
16
15
  safeHtmlConfigExtension: {
17
16
  ADD_TAGS: ['copy-code', 'insert-code-snippet']
@@ -47,7 +46,7 @@ var script = {
47
46
  const __vue_script__ = script;
48
47
 
49
48
  /* template */
50
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('base-message',{staticClass:"gl-text-gray-900",attrs:{"message":_vm.message},scopedSlots:_vm._u([{key:"message",fn:function(slotProps){return [(_vm.message.title)?_c('div',{staticClass:"gl-my-3 gl-flex gl-flex-col"},[_c('div',{staticClass:"gl-flex gl-items-center gl-gap-x-2"},[(_vm.message.icon)?_c('gl-icon',{attrs:{"name":_vm.message.icon,"size":_vm.message.iconSize,"variant":_vm.message.iconVariant}}):_vm._e(),_vm._v(" "),_c('span',{staticClass:"gl-text-lg",attrs:{"data-testid":"message-title"}},[_vm._v(_vm._s(_vm.message.title))])],1)]):_vm._e(),_vm._v(" "),_vm._t("message",function(){return [_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html:[$options.safeHtmlConfigExtension]",value:(slotProps.htmlContent),expression:"slotProps.htmlContent",arg:_vm.$options.safeHtmlConfigExtension}],ref:"content",on:{"insert-code-snippet":_vm.onInsertCodeSnippet,"copy-code-snippet":_vm.onCopyCodeSnippet}})]},null,slotProps),_vm._v(" "),(_vm.withFeedback)?_c('message-feedback',{on:{"feedback":function($event){return _vm.$emit('feedback', $event)}}}):_vm._e()]}}],null,true)})};
49
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('base-message',{staticClass:"gl-text-gray-900",attrs:{"message":_vm.message},scopedSlots:_vm._u([{key:"message",fn:function(slotProps){return [(_vm.message.title)?_c('div',{staticClass:"gl-my-3 gl-flex gl-flex-col"},[_c('div',{staticClass:"gl-flex gl-items-center gl-gap-x-2"},[(_vm.message.icon)?_c('gl-icon',{attrs:{"name":_vm.message.icon,"size":_vm.message.iconSize,"variant":_vm.message.iconVariant}}):_vm._e(),_vm._v(" "),_c('span',{staticClass:"gl-text-lg",attrs:{"data-testid":"message-title"}},[_vm._v(_vm._s(_vm.message.title))])],1)]):_vm._e(),_vm._v(" "),_vm._t("message",function(){return [_c('markdown-renderer',{ref:"content",attrs:{"is-html":slotProps.isHtml,"markdown":slotProps.content},on:{"insert-code-snippet":_vm.onInsertCodeSnippet,"copy-code-snippet":_vm.onCopyCodeSnippet}})]},null,slotProps),_vm._v(" "),(_vm.withFeedback)?_c('message-feedback',{on:{"feedback":function($event){return _vm.$emit('feedback', $event)}}}):_vm._e()]}}],null,true)})};
51
50
  var __vue_staticRenderFns__ = [];
52
51
 
53
52
  /* style */
@@ -1,14 +1,14 @@
1
- import { GlIcon, GlSafeHtmlDirective, GlTooltipDirective } from '@gitlab/ui';
2
- import { renderDuoChatMarkdownPreview } from '../../../markdown_renderer';
1
+ import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
2
+ import MarkdownRenderer from '../markdown_renderer';
3
3
  import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
4
4
 
5
5
  var script = {
6
6
  name: 'DuoBaseMessage',
7
7
  components: {
8
- GlIcon
8
+ GlIcon,
9
+ MarkdownRenderer
9
10
  },
10
11
  directives: {
11
- SafeHtml: GlSafeHtmlDirective,
12
12
  GlTooltip: GlTooltipDirective
13
13
  },
14
14
  inject: {
@@ -21,10 +21,6 @@ var script = {
21
21
  default: () => element => {
22
22
  element.classList.add('gl-markdown', 'gl-compact-markdown', 'gl-text-sm');
23
23
  }
24
- },
25
- renderMarkdown: {
26
- from: 'renderMarkdown',
27
- default: () => renderDuoChatMarkdownPreview
28
24
  }
29
25
  },
30
26
  props: {
@@ -40,16 +36,32 @@ var script = {
40
36
  }
41
37
  },
42
38
  computed: {
39
+ isDoneStreaming() {
40
+ // Agentic chat format
41
+ if (Object.hasOwn(this.message, 'status')) {
42
+ return this.message.status === 'success';
43
+ }
44
+ // Classic chat format
45
+ return !this.isChunk;
46
+ },
47
+ isChunk() {
48
+ return typeof this.message.chunkId === 'number';
49
+ },
50
+ hasContentHtml() {
51
+ var _this$message, _this$message$content;
52
+ return ((_this$message = this.message) === null || _this$message === void 0 ? void 0 : (_this$message$content = _this$message.contentHtml) === null || _this$message$content === void 0 ? void 0 : _this$message$content.length) > 0;
53
+ },
43
54
  messageContent() {
44
- return this.renderMarkdown(this.message.content);
55
+ var _this$message2;
56
+ return this.hasContentHtml ? this.message.contentHtml : (_this$message2 = this.message) === null || _this$message2 === void 0 ? void 0 : _this$message2.content;
45
57
  },
46
58
  renderedError() {
47
59
  var _this$message$errors;
48
- return this.renderMarkdown(((_this$message$errors = this.message.errors) === null || _this$message$errors === void 0 ? void 0 : _this$message$errors.join('; ')) || '');
60
+ return ((_this$message$errors = this.message.errors) === null || _this$message$errors === void 0 ? void 0 : _this$message$errors.join('; ')) || '';
49
61
  },
50
62
  hasError() {
51
- var _this$message, _this$message$errors2;
52
- return Boolean((_this$message = this.message) === null || _this$message === void 0 ? void 0 : (_this$message$errors2 = _this$message.errors) === null || _this$message$errors2 === void 0 ? void 0 : _this$message$errors2.length);
63
+ var _this$message3, _this$message3$errors;
64
+ return Boolean((_this$message3 = this.message) === null || _this$message3 === void 0 ? void 0 : (_this$message3$errors = _this$message3.errors) === null || _this$message3$errors === void 0 ? void 0 : _this$message3$errors.length);
53
65
  }
54
66
  },
55
67
  mounted() {
@@ -62,7 +74,7 @@ var script = {
62
74
  hydrateContentWithGFM() {
63
75
  if (this.$refs.content) {
64
76
  this.$nextTick(() => {
65
- this.renderGFM(this.$refs.content, this.message.role);
77
+ this.renderGFM(this.$refs.content.$el, this.message.role);
66
78
  });
67
79
  }
68
80
  }
@@ -75,7 +87,8 @@ const __vue_script__ = script;
75
87
  /* template */
76
88
  var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"duo-chat-message gl-w-full gl-flex-grow gl-leading-20 gl-break-anywhere",class:{
77
89
  'gl-items-top gl-flex': _vm.hasError,
78
- }},[(_vm.hasError)?_c('gl-icon',{staticClass:"error-icon gl-border gl-mr-3 gl-mt-2 gl-shrink-0 gl-rounded-full gl-border-red-500 gl-text-red-600",attrs:{"name":"status_warning_borderless","size":16,"data-testid":"error"}}):_vm._e(),_vm._v(" "),_c('div',{ref:"content-wrapper",class:{ 'has-error': _vm.hasError }},[(_vm.hasError)?_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html",value:(_vm.renderedError),expression:"renderedError"}],ref:"error-message"}):_c('div',[_vm._t("message",function(){return [_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html",value:(_vm.messageContent),expression:"messageContent"}],ref:"content"})]},null,{ content: _vm.message.content, htmlContent: _vm.messageContent })],2)])],1)};
90
+ 'duo-chat-message-complete': _vm.isDoneStreaming,
91
+ }},[(_vm.hasError)?_c('gl-icon',{staticClass:"error-icon gl-border gl-mr-3 gl-mt-2 gl-shrink-0 gl-rounded-full gl-border-red-500 gl-text-red-600",attrs:{"name":"status_warning_borderless","size":16,"data-testid":"error"}}):_vm._e(),_vm._v(" "),_c('div',{ref:"content-wrapper",class:{ 'has-error': _vm.hasError }},[(_vm.hasError)?_c('markdown-renderer',{ref:"error-message",attrs:{"markdown":_vm.renderedError}}):_c('div',[_vm._t("message",function(){return [_c('markdown-renderer',{ref:"content",attrs:{"is-html":_vm.hasContentHtml,"markdown":_vm.messageContent}})]},null,{ content: _vm.messageContent, isHtml: _vm.hasContentHtml })],2)],1)],1)};
79
92
  var __vue_staticRenderFns__ = [];
80
93
 
81
94
  /* style */
@@ -64,7 +64,7 @@ var script = {
64
64
  const __vue_script__ = script;
65
65
 
66
66
  /* template */
67
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (_vm.hasContent)?_c('figure',{staticClass:"gl-mb-0 gl-rounded-[0.75rem] gl-bg-strong gl-p-2 forced-colors:gl-border"},[_c('figcaption',{staticClass:"gl-display-flex gl-align-items-center gl-gap-2 gl-px-4 gl-py-3 gl-font-monospace gl-text-base gl-font-semibold gl-text-subtle",attrs:{"data-testid":"tool-section-header"}},[_vm._v("\n "+_vm._s(_vm.title)+"\n ")]),_vm._v(" "),_c('pre-block',{ref:"content",staticClass:"gl-m-0 !gl-border-0",attrs:{"language":"json"}},[_vm._v(_vm._s(_vm.prettyText))])],1):_vm._e()};
67
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (_vm.hasContent)?_c('figure',{staticClass:"gl-mb-0 gl-rounded-[0.75rem] gl-bg-strong gl-p-2 forced-colors:gl-border"},[_c('figcaption',{staticClass:"gl-display-flex gl-align-items-center gl-gap-2 gl-px-4 gl-py-3 gl-font-monospace gl-text-base gl-font-semibold gl-text-subtle",attrs:{"data-testid":"tool-section-header"}},[_vm._v("\n "+_vm._s(_vm.title)+"\n ")]),_vm._v(" "),_c('pre-block',{ref:"content",staticClass:"gl-m-0 !gl-border-0",attrs:{"languages":['json']}},[_vm._v(_vm._s(_vm.prettyText))])],1):_vm._e()};
68
68
  var __vue_staticRenderFns__ = [];
69
69
 
70
70
  /* style */
@@ -206,7 +206,7 @@ var script = {
206
206
  const __vue_script__ = script;
207
207
 
208
208
  /* template */
209
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-flex gl-flex-col gl-gap-3"},[(_vm.hasMetadataProperties)?_c('div',{staticClass:"gl-flex gl-flex-wrap gl-gap-2"},_vm._l((_vm.metadataProperties),function(property){return _c('span',{key:property.key,staticClass:"gl-overflow-hidden"},[(property.type == 'url')?_c('gl-badge',{attrs:{"icon":property.icon,"href":property.value,"title":property.value}},[_c('span',{staticClass:"gl-truncate"},[_vm._v("\n "+_vm._s(property.value)+"\n ")])]):_c('gl-badge',{attrs:{"icon":_vm.processPropertyIcon(property.icon, property.value)}},[_vm._v("\n "+_vm._s(property.label)+": "+_vm._s(_vm.formatPropertyValue(property.value))+"\n ")])],1)}),0):_vm._e(),_vm._v(" "),(_vm.message)?_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html",value:(_vm.message),expression:"message"}]}):_vm._t("default"),_vm._v(" "),(_vm.message || _vm.description)?_c('gl-accordion',{staticClass:"-gl-ml-2",attrs:{"header-level":3}},[(_vm.description)?_c('gl-accordion-item',{staticClass:"gl-mb-3",attrs:{"title":_vm.accordionTitle}},[_c('pre-block',{attrs:{"language":"markdown"}},[_vm._v(_vm._s(_vm.description))])],1):_vm._e(),_vm._v(" "),(_vm.withJsonView)?_c('gl-accordion-item',{attrs:{"title":_vm.$options.i18n.EXPAND_JSON_VIEW_TITLE}},[_c('tool-params-json-view',{attrs:{"tool-params":_vm.toolParams}})],1):_vm._e()],1):(!_vm.message && !_vm.description && _vm.withJsonView)?_c('tool-params-json-view',{attrs:{"tool-params":_vm.toolParams}}):_vm._e()],2)};
209
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-flex gl-flex-col gl-gap-3"},[(_vm.hasMetadataProperties)?_c('div',{staticClass:"gl-flex gl-flex-wrap gl-gap-2"},_vm._l((_vm.metadataProperties),function(property){return _c('span',{key:property.key,staticClass:"gl-overflow-hidden"},[(property.type == 'url')?_c('gl-badge',{attrs:{"icon":property.icon,"href":property.value,"title":property.value}},[_c('span',{staticClass:"gl-truncate"},[_vm._v("\n "+_vm._s(property.value)+"\n ")])]):_c('gl-badge',{attrs:{"icon":_vm.processPropertyIcon(property.icon, property.value)}},[_vm._v("\n "+_vm._s(property.label)+": "+_vm._s(_vm.formatPropertyValue(property.value))+"\n ")])],1)}),0):_vm._e(),_vm._v(" "),(_vm.message)?_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html",value:(_vm.message),expression:"message"}]}):_vm._t("default"),_vm._v(" "),(_vm.message || _vm.description)?_c('gl-accordion',{staticClass:"-gl-ml-2",attrs:{"header-level":3}},[(_vm.description)?_c('gl-accordion-item',{staticClass:"gl-mb-3",attrs:{"title":_vm.accordionTitle}},[_c('pre-block',{attrs:{"languages":['markdown']}},[_vm._v(_vm._s(_vm.description))])],1):_vm._e(),_vm._v(" "),(_vm.withJsonView)?_c('gl-accordion-item',{attrs:{"title":_vm.$options.i18n.EXPAND_JSON_VIEW_TITLE}},[_c('tool-params-json-view',{attrs:{"tool-params":_vm.toolParams}})],1):_vm._e()],1):(!_vm.message && !_vm.description && _vm.withJsonView)?_c('tool-params-json-view',{attrs:{"tool-params":_vm.toolParams}}):_vm._e()],2)};
210
210
  var __vue_staticRenderFns__ = [];
211
211
 
212
212
  /* style */
@@ -77,7 +77,13 @@ var script = {
77
77
  });
78
78
  }
79
79
  },
80
- getActionContent(_ref2) {
80
+ getActionFileExtension(_ref2) {
81
+ let {
82
+ file_path: filePath
83
+ } = _ref2;
84
+ return filePath.split('.').pop() || 'plaintext';
85
+ },
86
+ getActionContent(_ref3) {
81
87
  let {
82
88
  action,
83
89
  content,
@@ -85,7 +91,7 @@ var script = {
85
91
  old_str: oldContent,
86
92
  new_str: newContent,
87
93
  file_path: filePath
88
- } = _ref2;
94
+ } = _ref3;
89
95
  if (!['create', 'update'].includes(action)) {
90
96
  return this.$options.i18n.ACTION_WITH_NO_CONTENT;
91
97
  }
@@ -123,7 +129,7 @@ const __vue_script__ = script;
123
129
  /* template */
124
130
  var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('base-tool-params',{attrs:{"tool-params":_vm.toolParams}},[_c('div',[_c('gl-sprintf',{attrs:{"message":_vm.branch
125
131
  ? _vm.$options.i18n.COMMIT_SUMMARY_MESSAGE
126
- : _vm.$options.i18n.COMMIT_SUMMARY_AUTO_BRANCH_MESSAGE},scopedSlots:_vm._u([(_vm.branch)?{key:"branch",fn:function(){return [_c('code',[_vm._v(_vm._s(_vm.branch))])]},proxy:true}:null],null,true)}),_vm._v("\n "+_vm._s(_vm.actionsCountMessage)+"\n ")],1),_vm._v(" "),_c('gl-accordion',{staticClass:"-gl-ml-2",attrs:{"header-level":3}},[(_vm.commitMessage)?_c('gl-accordion-item',{staticClass:"gl-mb-3",attrs:{"title":_vm.$options.i18n.READ_COMMIT_MESSAGE}},[_c('pre-block',{attrs:{"language":"markdown"}},[_vm._v(_vm._s(_vm.commitMessage))])],1):_vm._e(),_vm._v(" "),(_vm.actionsCount)?_c('gl-accordion-item',{attrs:{"title":_vm.$options.i18n.EXPAND_CHANGES}},[_c('gl-accordion',{attrs:{"header-level":4}},_vm._l((_vm.actions),function(action,index){return _c('gl-accordion-item',{key:index,staticClass:"gl-mb-3",attrs:{"title":_vm.getActionTitle(action)}},[_c('pre-block',{attrs:{"language":"diff"}},[_vm._v(_vm._s(_vm.getActionContent(action)))])],1)}),1)],1):_vm._e()],1)],1)};
132
+ : _vm.$options.i18n.COMMIT_SUMMARY_AUTO_BRANCH_MESSAGE},scopedSlots:_vm._u([(_vm.branch)?{key:"branch",fn:function(){return [_c('code',[_vm._v(_vm._s(_vm.branch))])]},proxy:true}:null],null,true)}),_vm._v("\n "+_vm._s(_vm.actionsCountMessage)+"\n ")],1),_vm._v(" "),_c('gl-accordion',{staticClass:"-gl-ml-2",attrs:{"header-level":3}},[(_vm.commitMessage)?_c('gl-accordion-item',{staticClass:"gl-mb-3",attrs:{"title":_vm.$options.i18n.READ_COMMIT_MESSAGE}},[_c('pre-block',{attrs:{"languages":['markdown']}},[_vm._v(_vm._s(_vm.commitMessage))])],1):_vm._e(),_vm._v(" "),(_vm.actionsCount)?_c('gl-accordion-item',{attrs:{"title":_vm.$options.i18n.EXPAND_CHANGES}},[_c('gl-accordion',{attrs:{"header-level":4}},_vm._l((_vm.actions),function(action,index){return _c('gl-accordion-item',{key:index,staticClass:"gl-mb-3",attrs:{"title":_vm.getActionTitle(action)}},[_c('pre-block',{attrs:{"languages":[_vm.getActionFileExtension(action), 'diff']}},[_vm._v(_vm._s(_vm.getActionContent(action)))])],1)}),1)],1):_vm._e()],1)],1)};
127
133
  var __vue_staticRenderFns__ = [];
128
134
 
129
135
  /* style */
@@ -1,7 +1,7 @@
1
1
  import { GlTooltipDirective, GlButton } from '@gitlab/ui';
2
2
  import { translate } from '../../../../../utils/i18n';
3
+ import { highlightElement } from '../../../../../utils/highlight';
3
4
  import { copyToClipboard } from '../../utils';
4
- import { highlightElement } from '../services/highlight';
5
5
  import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
6
6
 
7
7
  var script = {
@@ -13,10 +13,15 @@ var script = {
13
13
  GlButton
14
14
  },
15
15
  props: {
16
- language: {
17
- type: String,
16
+ languages: {
17
+ type: Array,
18
18
  required: false,
19
- default: 'plaintext'
19
+ default: () => []
20
+ }
21
+ },
22
+ computed: {
23
+ languageClasses() {
24
+ return this.languages.map(lang => `language-${lang}`);
20
25
  }
21
26
  },
22
27
  async mounted() {
@@ -28,7 +33,7 @@ var script = {
28
33
  try {
29
34
  const codeElement = this.$el.querySelector('code');
30
35
  if (codeElement) {
31
- highlightElement(codeElement);
36
+ highlightElement(codeElement, this.languages);
32
37
  }
33
38
  } catch (error) {
34
39
  // Silently fail if highlight.js is not available
@@ -59,7 +64,7 @@ var script = {
59
64
  const __vue_script__ = script;
60
65
 
61
66
  /* template */
62
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('pre',{staticClass:"duo-message-pre-block code code-syntax-highlight-theme !focus:gl-focus gl-border !gl-relative gl-grid gl-max-h-48 gl-overflow-auto gl-whitespace-pre-wrap gl-text-pretty gl-rounded-lg gl-border-strong !gl-p-5 gl-font-monospace gl-text-strong",attrs:{"tabindex":"0"}},[_c('span',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip.hover.focus.blur",modifiers:{"hover":true,"focus":true,"blur":true}}],staticClass:"copy-to-clipboard-button-container gl-inline-flex gl-absolute gl-right-5 gl-top-4 gl-z-1 gl-opacity-0 gl-transition-opacity",attrs:{"title":_vm.$options.i18n.COPY_TO_CLIPBOARD_TEXT}},[_vm._v("\n"),_c('gl-button',{ref:"copyToClipboardButton",attrs:{"icon":"copy-to-clipboard","aria-label":_vm.$options.i18n.COPY_TO_CLIPBOARD_TEXT},on:{"click":function($event){$event.stopPropagation();return _vm.copyToClipboard.apply(null, arguments)}}}),_vm._v("\n")],1),_vm._v("\n \n"),_c('code',{ref:"codeElement",staticClass:"!gl-leading-20 gl-break-all",class:("language-" + _vm.language)},[_vm._t("default")],2)])};
67
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('pre',{staticClass:"duo-message-pre-block code code-syntax-highlight-theme !focus:gl-focus gl-border !gl-relative gl-grid gl-max-h-48 gl-overflow-auto gl-whitespace-pre-wrap gl-text-pretty gl-rounded-lg gl-border-strong !gl-p-5 gl-font-monospace gl-text-strong",attrs:{"tabindex":"0"}},[_c('span',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip.hover.focus.blur",modifiers:{"hover":true,"focus":true,"blur":true}}],staticClass:"copy-to-clipboard-button-container gl-inline-flex gl-absolute gl-right-5 gl-top-4 gl-z-1 gl-opacity-0 gl-transition-opacity",attrs:{"title":_vm.$options.i18n.COPY_TO_CLIPBOARD_TEXT}},[_vm._v("\n"),_c('gl-button',{ref:"copyToClipboardButton",attrs:{"icon":"copy-to-clipboard","aria-label":_vm.$options.i18n.COPY_TO_CLIPBOARD_TEXT},on:{"click":function($event){$event.stopPropagation();return _vm.copyToClipboard.apply(null, arguments)}}}),_vm._v("\n")],1),_vm._v("\n \n"),_c('code',{ref:"codeElement",staticClass:"!gl-leading-20 gl-break-all",class:_vm.languageClasses},[_vm._t("default")],2)])};
63
68
  var __vue_staticRenderFns__ = [];
64
69
 
65
70
  /* style */
@@ -28,7 +28,7 @@ var script = {
28
28
  const __vue_script__ = script;
29
29
 
30
30
  /* template */
31
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('figure',{staticClass:"gl-m-0 gl-flex gl-flex-col gl-gap-2"},[_c('figcaption',{staticClass:"gl-text-subtle"},[_vm._v("\n "+_vm._s(_vm.$options.i18n.REQUEST_TEXT)+"\n ")]),_vm._v(" "),(_vm.hasToolParams)?_c('pre-block',{attrs:{"language":"json","data-testid":"tool-parameters"}},[_vm._v(_vm._s(JSON.stringify(_vm.toolParams, null, 2)))]):_c('span',{staticClass:"gl-text-sm gl-text-gray-500",attrs:{"data-testid":"no-parameters-message"}},[_vm._v("\n "+_vm._s(_vm.$options.i18n.NO_PARAMETERS_TEXT)+"\n ")])],1)};
31
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('figure',{staticClass:"gl-m-0 gl-flex gl-flex-col gl-gap-2"},[_c('figcaption',{staticClass:"gl-text-subtle"},[_vm._v("\n "+_vm._s(_vm.$options.i18n.REQUEST_TEXT)+"\n ")]),_vm._v(" "),(_vm.hasToolParams)?_c('pre-block',{attrs:{"languages":['json'],"data-testid":"tool-parameters"}},[_vm._v(_vm._s(JSON.stringify(_vm.toolParams, null, 2)))]):_c('span',{staticClass:"gl-text-sm gl-text-gray-500",attrs:{"data-testid":"no-parameters-message"}},[_vm._v("\n "+_vm._s(_vm.$options.i18n.NO_PARAMETERS_TEXT)+"\n ")])],1)};
32
32
  var __vue_staticRenderFns__ = [];
33
33
 
34
34
  /* style */
@@ -2,7 +2,7 @@ import { GlButton, GlAvatar } from '@gitlab/ui';
2
2
  import { translate, sprintf } from '../../../../utils/i18n';
3
3
  import { formatLocalizedDate } from '../../../../utils/date';
4
4
  import DuoChatThreadsEmpty from './duo_chat_threads_empty';
5
- import DuoChatThreadsSkeleton from './duo_chat_threads_skeleton';
5
+ import DuoChatThreadsSkeleton from './duo_chat_threads_skeleton_loader';
6
6
  import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
7
7
 
8
8
  const i18n = {
@@ -6,14 +6,16 @@ const i18n = {
6
6
  };
7
7
  var script = {
8
8
  name: 'DuoChatThreadsSkeleton',
9
- i18n
9
+ i18n,
10
+ groups: 3,
11
+ threadItems: 2
10
12
  };
11
13
 
12
14
  /* script */
13
15
  const __vue_script__ = script;
14
16
 
15
17
  /* template */
16
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-p-6"},[_c('span',{staticClass:"gl-sr-only",attrs:{"role":"status","aria-live":"polite","aria-atomic":"true"}},[_vm._v(_vm._s(_vm.$options.i18n.LOADING_THREADS))]),_vm._v(" "),_vm._l((3),function(groupIndex){return _c('div',{key:groupIndex,staticClass:"gl-mb-3"},[_c('div',{staticClass:"gl-animate-skeleton-loader gl-mb-3 gl-h-4 !gl-max-w-26 gl-rounded-default",staticStyle:{"animation-delay":"0ms"},attrs:{"data-testid":"chat-threads-skeleton-date-header"}}),_vm._v(" "),_vm._l((2),function(itemIndex){return _c('div',{key:("group" + groupIndex + "-item" + itemIndex),staticClass:"gl-mb-5 gl-flex gl-items-center gl-gap-3",staticStyle:{"animation-delay":"0ms"},attrs:{"data-testid":"chat-threads-skeleton-item"}},[_c('div',{staticClass:"gl-animate-skeleton-loader gl-h-8 gl-w-8 gl-shrink-0 gl-rounded-full"}),_vm._v(" "),_c('div',{staticClass:"gl-animate-skeleton-loader gl-h-5 !gl-max-w-48 gl-grow gl-rounded-default"})])})],2)})],2)};
18
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-p-6"},[_c('span',{staticClass:"gl-sr-only",attrs:{"role":"status","aria-live":"polite","aria-atomic":"true"}},[_vm._v(_vm._s(_vm.$options.i18n.LOADING_THREADS))]),_vm._v(" "),_vm._l((_vm.$options.groups),function(groupIndex){return _c('div',{key:groupIndex,staticClass:"gl-mb-3"},[_c('div',{staticClass:"gl-animate-skeleton-loader gl-mb-3 gl-h-4 !gl-max-w-26 gl-rounded-default",attrs:{"data-testid":"chat-threads-skeleton-date-header"}}),_vm._v(" "),_vm._l((_vm.$options.threadItems),function(itemIndex){return _c('div',{key:("group" + groupIndex + "-item" + itemIndex),staticClass:"gl-mb-5 gl-flex gl-items-center gl-gap-3",attrs:{"data-testid":"chat-threads-skeleton-item"}},[_c('div',{staticClass:"gl-animate-skeleton-loader gl-h-8 gl-w-8 gl-shrink-0 gl-rounded-full"}),_vm._v(" "),_c('div',{staticClass:"gl-animate-skeleton-loader gl-h-5 !gl-max-w-48 gl-grow gl-rounded-default"})])})],2)})],2)};
17
19
  var __vue_staticRenderFns__ = [];
18
20
 
19
21
  /* style */
@@ -641,7 +641,7 @@ const __vue_script__ = script;
641
641
  var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c(_vm.shouldRenderResizable ? 'vue-resizable' : 'div',{tag:"component",class:{
642
642
  'duo-chat-resizable': _vm.shouldRenderResizable,
643
643
  'non-resizable-wrapper': !_vm.shouldRenderResizable,
644
- },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:{
644
+ },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:"duo-chat gl-bottom-0 gl-flex gl-max-h-full gl-flex-col",class:{
645
645
  'resizable-content': _vm.shouldRenderResizable,
646
646
  'duo-chat-drawer': !_vm.shouldRenderResizable,
647
647
  },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,"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,"go-back-to-chat":_vm.onGoBackToChat,"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,"canceled-request-ids":_vm.canceledRequestIds,"show-delimiter":index > 0,"trusted-urls":_vm.trustedUrls},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,"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-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-relative gl-z-2 gl-shrink-0",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.displaySubmitButton)?_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","disabled":_vm.isPromptEmpty,"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,661265825)},[_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:{"data-testid":"chat-prompt-input","placeholder":_vm.inputPlaceholder,"autofocus":""},on:{"keydown":[function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"z",undefined,$event.key,undefined)){ return null; }if(!$event.ctrlKey){ return null; }if($event.shiftKey||$event.altKey||$event.metaKey){ return null; }return _vm.handleUndo.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"z",undefined,$event.key,undefined)){ return null; }if(!$event.metaKey){ return null; }if($event.ctrlKey||$event.shiftKey||$event.altKey){ return null; }return _vm.handleUndo.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"z",undefined,$event.key,undefined)){ return null; }if(!$event.ctrlKey){ return null; }if(!$event.shiftKey){ return null; }return _vm.handleRedo.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"z",undefined,$event.key,undefined)){ return null; }if(!$event.metaKey){ return null; }if(!$event.shiftKey){ return null; }return _vm.handleRedo.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"y",undefined,$event.key,undefined)){ return null; }if(!$event.ctrlKey){ return null; }return _vm.handleRedo.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"y",undefined,$event.key,undefined)){ return null; }if(!$event.metaKey){ return null; }return _vm.handleRedo.apply(null, arguments)}],"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(" "),_vm._t("footer-controls"),_vm._v(" "),_c('p',{staticClass:"gl-mb-0 gl-mt-3 gl-px-4 gl-text-sm gl-text-subtle"},[_vm._v("\n "+_vm._s(_vm.$options.i18n.CHAT_DISCLAMER)+"\n ")])],2):_vm._e()],1):_vm._e()])};