@gitlab/ui 78.9.0 → 78.10.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## [78.10.1](https://gitlab.com/gitlab-org/gitlab-ui/compare/v78.10.0...v78.10.1) (2024-04-09)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **GlLabel:** Add fallback value to focus ring CSS variable ([2f3c184](https://gitlab.com/gitlab-org/gitlab-ui/commit/2f3c184818c3c16cd825558ea69b92adfa90d640))
7
+
8
+ # [78.10.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v78.9.0...v78.10.0) (2024-04-08)
9
+
10
+
11
+ ### Features
12
+
13
+ * **GlDuoChat:** detect streaming based on chunkId ([6cdfe5c](https://gitlab.com/gitlab-org/gitlab-ui/commit/6cdfe5cd823ed0e832a5ec51870421ff4c532dbc))
14
+ * **GlDuoChatMessage:** Handle streaming in the component ([082ab86](https://gitlab.com/gitlab-org/gitlab-ui/commit/082ab867597972bb18ba5287ac69126f38e17619))
15
+
1
16
  # [78.9.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v78.8.1...v78.9.0) (2024-04-04)
2
17
 
3
18
 
@@ -6,6 +6,7 @@ import { MESSAGE_MODEL_ROLES } from '../../constants';
6
6
  import DocumentationSources from '../duo_chat_message_sources/duo_chat_message_sources';
7
7
  import { renderDuoChatMarkdownPreview } from '../../markdown_renderer';
8
8
  import { CopyCodeElement } from './copy_code_element';
9
+ import { concatUntilEmpty } from './utils';
9
10
  import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
10
11
 
11
12
  const i18n = {
@@ -18,12 +19,6 @@ const i18n = {
18
19
  BETTER_RESPONSE: 'How the response might better meet your needs.'
19
20
  }
20
21
  };
21
- const concatUntilEmpty = arr => {
22
- if (!arr) return '';
23
- let end = arr.findIndex(el => !el);
24
- if (end < 0) end = arr.length;
25
- return arr.slice(0, end).join('');
26
- };
27
22
  var script = {
28
23
  name: 'GlDuoChatMessage',
29
24
  safeHtmlConfigExtension: {
@@ -72,10 +67,16 @@ var script = {
72
67
  data() {
73
68
  return {
74
69
  didWhat: '',
75
- improveWhat: ''
70
+ improveWhat: '',
71
+ messageWatcher: null,
72
+ // imperatively set up watcher on message
73
+ messageChunks: []
76
74
  };
77
75
  },
78
76
  computed: {
77
+ isChunk() {
78
+ return typeof this.message.chunkId === 'number';
79
+ },
79
80
  isAssistantMessage() {
80
81
  return this.message.role.toLowerCase() === MESSAGE_MODEL_ROLES.assistant;
81
82
  },
@@ -90,12 +91,18 @@ var script = {
90
91
  var _this$message$extras2;
91
92
  return (_this$message$extras2 = this.message.extras) === null || _this$message$extras2 === void 0 ? void 0 : _this$message$extras2.hasFeedback;
92
93
  },
93
- messageContent() {
94
+ defaultContent() {
94
95
  if (this.message.errors.length > 0) return this.renderMarkdown(this.message.errors.join('; '));
95
96
  if (this.message.contentHtml) {
96
97
  return this.message.contentHtml;
97
98
  }
98
- return this.renderMarkdown(this.message.content || concatUntilEmpty(this.message.chunks));
99
+ return this.renderMarkdown(this.message.content);
100
+ },
101
+ messageContent() {
102
+ if (this.isAssistantMessage && this.isChunk) {
103
+ return this.renderMarkdown(concatUntilEmpty(this.messageChunks));
104
+ }
105
+ return this.defaultContent || this.renderMarkdown(concatUntilEmpty(this.message.chunks));
99
106
  }
100
107
  },
101
108
  beforeCreate() {
@@ -104,15 +111,39 @@ var script = {
104
111
  }
105
112
  },
106
113
  mounted() {
107
- this.$nextTick(this.hydrateContentWithGFM);
114
+ if (this.isAssistantMessage) {
115
+ // The watcher has to be created imperatively here
116
+ // to give an opportunity to remove it after
117
+ // the complete message has arrived
118
+ this.messageWatcher = this.$watch('message', this.manageMessageUpdate);
119
+ }
120
+ this.setChunks();
121
+ this.hydrateContentWithGFM();
108
122
  },
109
123
  updated() {
110
- this.$nextTick(this.hydrateContentWithGFM);
124
+ this.hydrateContentWithGFM();
111
125
  },
112
126
  methods: {
113
- async hydrateContentWithGFM() {
114
- if (this.message.contentHtml) {
115
- this.renderGFM(this.$refs.content);
127
+ setChunks() {
128
+ if (this.isChunk) {
129
+ const {
130
+ chunkId,
131
+ content
132
+ } = this.message;
133
+ this.$set(this.messageChunks, chunkId - 1, content);
134
+ } else {
135
+ this.messageChunks = [];
136
+ }
137
+ },
138
+ stopWatchingMessage() {
139
+ if (this.messageWatcher) {
140
+ this.messageWatcher(); // Stop watching the message prop
141
+ this.messageWatcher = null; // Ensure the watcher can't be stopped multiple times
142
+ }
143
+ },
144
+ hydrateContentWithGFM() {
145
+ if (!this.isChunk) {
146
+ this.$nextTick(this.renderGFM(this.$refs.content));
116
147
  }
117
148
  },
118
149
  logEvent(e) {
@@ -122,6 +153,12 @@ var script = {
122
153
  improveWhat: this.improveWhat,
123
154
  message: this.message
124
155
  });
156
+ },
157
+ manageMessageUpdate() {
158
+ this.setChunks();
159
+ if (!this.isChunk) {
160
+ this.stopWatchingMessage();
161
+ }
125
162
  }
126
163
  },
127
164
  i18n
@@ -0,0 +1,8 @@
1
+ const concatUntilEmpty = arr => {
2
+ if (!arr) return '';
3
+ let end = arr.findIndex(el => !el);
4
+ if (end < 0) end = arr.length;
5
+ return arr.slice(0, end).join('');
6
+ };
7
+
8
+ export { concatUntilEmpty };
@@ -215,8 +215,8 @@ var script = {
215
215
  return this.isLoading || this.isStreaming;
216
216
  },
217
217
  isStreaming() {
218
- var _this$lastMessage2, _this$lastMessage2$ch, _this$lastMessage3;
219
- return Boolean(((_this$lastMessage2 = this.lastMessage) === null || _this$lastMessage2 === void 0 ? void 0 : (_this$lastMessage2$ch = _this$lastMessage2.chunks) === null || _this$lastMessage2$ch === void 0 ? void 0 : _this$lastMessage2$ch.length) > 0 && !((_this$lastMessage3 = this.lastMessage) !== null && _this$lastMessage3 !== void 0 && _this$lastMessage3.content));
218
+ var _this$lastMessage2, _this$lastMessage2$ch, _this$lastMessage3, _this$lastMessage4;
219
+ return Boolean(((_this$lastMessage2 = this.lastMessage) === null || _this$lastMessage2 === void 0 ? void 0 : (_this$lastMessage2$ch = _this$lastMessage2.chunks) === null || _this$lastMessage2$ch === void 0 ? void 0 : _this$lastMessage2$ch.length) > 0 && !((_this$lastMessage3 = this.lastMessage) !== null && _this$lastMessage3 !== void 0 && _this$lastMessage3.content) || typeof ((_this$lastMessage4 = this.lastMessage) === null || _this$lastMessage4 === void 0 ? void 0 : _this$lastMessage4.chunkId) === 'number');
220
220
  },
221
221
  filteredSlashCommands() {
222
222
  const caseInsensitivePrompt = this.prompt.toLowerCase();
@@ -28,6 +28,20 @@ const MOCK_RESPONSE_MESSAGE = {
28
28
  errors: [],
29
29
  timestamp: '2021-04-21T12:00:00.000Z'
30
30
  };
31
+ const generateSeparateChunks = n => {
32
+ const res = [];
33
+ for (let i = 1; i <= n; i += 1) {
34
+ res.push({
35
+ chunkId: i,
36
+ content: `chunk #${i}`,
37
+ role: MESSAGE_MODEL_ROLES.assistant,
38
+ requestId: '987',
39
+ errors: [],
40
+ timestamp: '2021-04-21T12:00:00.000Z'
41
+ });
42
+ }
43
+ return res;
44
+ };
31
45
  const MOCK_RESPONSE_MESSAGE_FOR_STREAMING = {
32
46
  id: '123',
33
47
  content: `To change your password in GitLab:
@@ -51,7 +65,6 @@ const MOCK_RESPONSE_MESSAGE_FOR_STREAMING = {
51
65
  ~~~
52
66
  which is rendered while streaming.
53
67
  `,
54
- contentHtml: '',
55
68
  role: 'assistant',
56
69
  extras: {},
57
70
  requestId: '987',
@@ -81,7 +94,7 @@ function generateMockResponseChunks() {
81
94
  ...MOCK_RESPONSE_MESSAGE_FOR_STREAMING,
82
95
  requestId,
83
96
  content: MOCK_RESPONSE_MESSAGE_FOR_STREAMING.content.substring(start, end),
84
- chunkId
97
+ chunkId: chunkId + 1
85
98
  };
86
99
 
87
100
  // eslint-disable-next-line no-await-in-loop
@@ -101,8 +114,9 @@ function generateMockResponseChunks() {
101
114
  }
102
115
  const MOCK_USER_PROMPT_MESSAGE = {
103
116
  id: '456',
117
+ chunkId: null,
104
118
  content: 'How to create a new template?',
105
- contentHtml: '',
119
+ contentHtml: '<p>How to create a new template?</p>',
106
120
  role: MESSAGE_MODEL_ROLES.user,
107
121
  requestId: '987',
108
122
  errors: [],
@@ -135,4 +149,4 @@ const SLASH_COMMANDS = [{
135
149
  description: 'Explain the selected snippet.'
136
150
  }];
137
151
 
138
- export { MOCK_RESPONSE_MESSAGE, MOCK_RESPONSE_MESSAGE_FOR_STREAMING, MOCK_USER_PROMPT_MESSAGE, SLASH_COMMANDS, generateMockResponseChunks, renderGFM, renderMarkdown };
152
+ export { MOCK_RESPONSE_MESSAGE, MOCK_RESPONSE_MESSAGE_FOR_STREAMING, MOCK_USER_PROMPT_MESSAGE, SLASH_COMMANDS, generateMockResponseChunks, generateSeparateChunks, renderGFM, renderMarkdown };