@kodaris/krubble-app-components 1.0.70 → 1.0.71
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/dist/chatbot.d.ts +72 -26
- package/dist/chatbot.d.ts.map +1 -1
- package/dist/chatbot.js +299 -203
- package/dist/chatbot.js.map +1 -1
- package/dist/krubble-app.bundled.js +298 -203
- package/dist/krubble-app.bundled.js.map +1 -1
- package/dist/krubble-app.bundled.min.js +195 -147
- package/dist/krubble-app.bundled.min.js.map +1 -1
- package/dist/krubble-app.umd.js +298 -203
- package/dist/krubble-app.umd.js.map +1 -1
- package/dist/krubble-app.umd.min.js +226 -178
- package/dist/krubble-app.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -5567,7 +5567,7 @@ const ACCEPTED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/web
|
|
|
5567
5567
|
* ## Usage
|
|
5568
5568
|
* ```html
|
|
5569
5569
|
* <kr-chatbot
|
|
5570
|
-
*
|
|
5570
|
+
* label="AI Assistant"
|
|
5571
5571
|
* .send=${(params) => {
|
|
5572
5572
|
* return fetch('/api/ai/chat/stream', {
|
|
5573
5573
|
* method: 'POST',
|
|
@@ -5610,16 +5610,25 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
5610
5610
|
/**
|
|
5611
5611
|
* Callback function for sending messages. Receives the user's message and
|
|
5612
5612
|
* current conversation history. Must return a Response with a streaming SSE body.
|
|
5613
|
+
*
|
|
5614
|
+
* Optional — when not set, the chatbot uses its built-in default that streams
|
|
5615
|
+
* from the Kodaris Bedrock conversation endpoints. Set this to override.
|
|
5613
5616
|
*/
|
|
5614
5617
|
this.send = null;
|
|
5615
5618
|
/**
|
|
5616
5619
|
* Callback function called when the user clears the conversation.
|
|
5617
5620
|
* Must return a Promise — messages are only cleared if it resolves.
|
|
5621
|
+
*
|
|
5622
|
+
* Optional — when not set, the chatbot uses its built-in default that clears
|
|
5623
|
+
* the Kodaris Bedrock conversation state. Set this to override.
|
|
5618
5624
|
*/
|
|
5619
5625
|
this.clear = null;
|
|
5620
5626
|
/**
|
|
5621
5627
|
* Callback function called on init to load existing conversation messages.
|
|
5622
5628
|
* Must return a Promise that resolves with an array of KRChatbotMessage.
|
|
5629
|
+
*
|
|
5630
|
+
* Optional — when not set, the chatbot uses its built-in default that loads
|
|
5631
|
+
* existing messages from the Kodaris Bedrock conversation. Set this to override.
|
|
5623
5632
|
*/
|
|
5624
5633
|
this.load = null;
|
|
5625
5634
|
/**
|
|
@@ -5628,13 +5637,9 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
5628
5637
|
*/
|
|
5629
5638
|
this.messages = [];
|
|
5630
5639
|
/**
|
|
5631
|
-
* Header
|
|
5640
|
+
* Header label text.
|
|
5632
5641
|
*/
|
|
5633
|
-
this.
|
|
5634
|
-
/**
|
|
5635
|
-
* Header subtitle text (shown below title with a green status dot).
|
|
5636
|
-
*/
|
|
5637
|
-
this.subtitle = '';
|
|
5642
|
+
this.label = 'Kat';
|
|
5638
5643
|
/**
|
|
5639
5644
|
* Input placeholder text.
|
|
5640
5645
|
*/
|
|
@@ -5649,13 +5654,23 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
5649
5654
|
* then driven via the `open()` / `close()` / `toggle()` methods.
|
|
5650
5655
|
*/
|
|
5651
5656
|
this.hideToggle = false;
|
|
5657
|
+
/**
|
|
5658
|
+
* Layout mode.
|
|
5659
|
+
* - `'floating'` (default): the chatbot is a fixed bottom-right widget with a
|
|
5660
|
+
* toggle button, and the panel can be dragged and resized. This is the
|
|
5661
|
+
* traditional chat-widget appearance.
|
|
5662
|
+
* - `'inline'`: the chatbot drops its fixed positioning and fills its parent
|
|
5663
|
+
* container (100% width/height, no border radius/shadow, no toggle, no
|
|
5664
|
+
* drag/resize). The panel is always open. Use this to embed the chat as a
|
|
5665
|
+
* full page or panel region.
|
|
5666
|
+
*/
|
|
5667
|
+
this.variant = 'floating';
|
|
5652
5668
|
// --- @state (internal) ---
|
|
5653
5669
|
this._inputValue = '';
|
|
5654
5670
|
this._isStreaming = false;
|
|
5655
|
-
this._statusText = '';
|
|
5656
5671
|
this._error = '';
|
|
5657
5672
|
/** Images staged in the composer, before the message is sent. */
|
|
5658
|
-
this.
|
|
5673
|
+
this._pendingInternalFiles = [];
|
|
5659
5674
|
/** True while a file is being dragged over the panel (shows the drop overlay). */
|
|
5660
5675
|
this._isDraggingFile = false;
|
|
5661
5676
|
this._handleMouseMove = (e) => {
|
|
@@ -5719,12 +5734,27 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
5719
5734
|
// --- Lifecycle ---
|
|
5720
5735
|
connectedCallback() {
|
|
5721
5736
|
super.connectedCallback();
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5737
|
+
// Default to loading existing messages from the Kodaris Bedrock conversation
|
|
5738
|
+
// when the consumer hasn't provided their own `load`. The endpoint returns
|
|
5739
|
+
// messages already in KRChatbotMessage shape ({ type, content, images }), so
|
|
5740
|
+
// they pass straight through.
|
|
5741
|
+
if (!this.load) {
|
|
5742
|
+
this.load = () => KRHttp.fetch({
|
|
5743
|
+
url: '/api/system/integration/aws/bedrock/getConversationMessages',
|
|
5744
|
+
})
|
|
5745
|
+
.then((r) => r.json())
|
|
5746
|
+
.then((res) => res.data || []);
|
|
5747
|
+
}
|
|
5748
|
+
this.load().then((messages) => {
|
|
5749
|
+
if (messages && messages.length) {
|
|
5750
|
+
this.messages = messages;
|
|
5751
|
+
}
|
|
5752
|
+
}).catch(() => { });
|
|
5753
|
+
// Inline mode fills its container and is always open — the floating widget's
|
|
5754
|
+
// toggle/drag/resize state (including any persisted layout) doesn't apply.
|
|
5755
|
+
if (this.variant === 'inline') {
|
|
5756
|
+
this.opened = true;
|
|
5757
|
+
return;
|
|
5728
5758
|
}
|
|
5729
5759
|
this._restoreState();
|
|
5730
5760
|
}
|
|
@@ -5737,10 +5767,10 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
5737
5767
|
document.removeEventListener('mousemove', this._handleMouseMove);
|
|
5738
5768
|
document.removeEventListener('mouseup', this._handleMouseUp);
|
|
5739
5769
|
// Release any object URLs still held by staged attachments.
|
|
5740
|
-
this.
|
|
5770
|
+
this._pendingInternalFiles.forEach((p) => URL.revokeObjectURL(p.previewUrl));
|
|
5741
5771
|
}
|
|
5742
5772
|
updated(changed) {
|
|
5743
|
-
if (changed.has('messages')
|
|
5773
|
+
if (changed.has('messages')) {
|
|
5744
5774
|
if (!this._userHasScrolledUp && !this._isStreaming && this._messagesEl) {
|
|
5745
5775
|
requestAnimationFrame(() => {
|
|
5746
5776
|
if (this._messagesEl) {
|
|
@@ -5814,6 +5844,10 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
5814
5844
|
}
|
|
5815
5845
|
}
|
|
5816
5846
|
_handleHeaderMouseDown(e) {
|
|
5847
|
+
// Inline mode fills its parent — dragging the panel doesn't apply.
|
|
5848
|
+
if (this.variant === 'inline') {
|
|
5849
|
+
return;
|
|
5850
|
+
}
|
|
5817
5851
|
// Ignore clicks on buttons inside the header
|
|
5818
5852
|
if (e.target.closest('button')) {
|
|
5819
5853
|
return;
|
|
@@ -5839,6 +5873,10 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
5839
5873
|
document.addEventListener('mouseup', this._handleMouseUp);
|
|
5840
5874
|
}
|
|
5841
5875
|
_handleResizeMouseDown(e) {
|
|
5876
|
+
// Inline mode fills its parent — resizing the panel doesn't apply.
|
|
5877
|
+
if (this.variant === 'inline') {
|
|
5878
|
+
return;
|
|
5879
|
+
}
|
|
5842
5880
|
if (!this._panelEl) {
|
|
5843
5881
|
return;
|
|
5844
5882
|
}
|
|
@@ -6031,54 +6069,49 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6031
6069
|
name: file.name,
|
|
6032
6070
|
previewUrl: URL.createObjectURL(file),
|
|
6033
6071
|
};
|
|
6034
|
-
this.
|
|
6072
|
+
this._pendingInternalFiles = [...this._pendingInternalFiles, pending];
|
|
6035
6073
|
});
|
|
6036
6074
|
}
|
|
6037
6075
|
_removePending(localId) {
|
|
6038
|
-
const target = this.
|
|
6076
|
+
const target = this._pendingInternalFiles.find((p) => p.localId === localId);
|
|
6039
6077
|
if (target) {
|
|
6040
6078
|
URL.revokeObjectURL(target.previewUrl);
|
|
6041
6079
|
}
|
|
6042
|
-
this.
|
|
6080
|
+
this._pendingInternalFiles = this._pendingInternalFiles.filter((p) => p.localId !== localId);
|
|
6043
6081
|
}
|
|
6044
6082
|
_clearPending() {
|
|
6045
|
-
this.
|
|
6046
|
-
this.
|
|
6083
|
+
this._pendingInternalFiles.forEach((p) => URL.revokeObjectURL(p.previewUrl));
|
|
6084
|
+
this._pendingInternalFiles = [];
|
|
6047
6085
|
}
|
|
6048
|
-
/** Open the shared full-screen previewer for
|
|
6049
|
-
|
|
6086
|
+
/** Open the shared full-screen previewer for a message image. */
|
|
6087
|
+
_openImage(img) {
|
|
6050
6088
|
KRFilePreview.open({
|
|
6051
|
-
src:
|
|
6052
|
-
name:
|
|
6089
|
+
src: `/api/system/integration/aws/bedrock/conversationImage/${img.internalFileID}/view`,
|
|
6090
|
+
name: img.niceName || 'image',
|
|
6053
6091
|
});
|
|
6054
6092
|
}
|
|
6055
6093
|
/** Whether the send button is active: needs text or at least one image. */
|
|
6056
6094
|
_canSend() {
|
|
6057
|
-
return Boolean(this._inputValue.trim()) || this.
|
|
6095
|
+
return Boolean(this._inputValue.trim()) || this._pendingInternalFiles.length > 0;
|
|
6058
6096
|
}
|
|
6059
6097
|
_handleSubmit() {
|
|
6060
|
-
if (
|
|
6098
|
+
if (this._isStreaming) {
|
|
6061
6099
|
return;
|
|
6062
6100
|
}
|
|
6063
6101
|
const messageText = this._inputValue.trim();
|
|
6064
|
-
const pending = this.
|
|
6102
|
+
const pending = this._pendingInternalFiles;
|
|
6065
6103
|
// Allow sending an image with no text, but require at least one of them.
|
|
6066
6104
|
if (!messageText && !pending.length) {
|
|
6067
6105
|
return;
|
|
6068
6106
|
}
|
|
6069
|
-
// The raw files sent to the backend
|
|
6070
|
-
//
|
|
6071
|
-
//
|
|
6072
|
-
const
|
|
6073
|
-
const attachments = pending.map((p) => ({
|
|
6074
|
-
url: p.previewUrl,
|
|
6075
|
-
name: p.name,
|
|
6076
|
-
mimeType: p.file.type,
|
|
6077
|
-
}));
|
|
6107
|
+
// The raw files sent to the backend. Sent images are shown once the
|
|
6108
|
+
// conversation reloads and they come back as stored internal files; the
|
|
6109
|
+
// just-sent message itself carries text only.
|
|
6110
|
+
const internalFiles = pending.map((p) => p.file);
|
|
6078
6111
|
const submitEvent = new CustomEvent('message-submit', {
|
|
6079
6112
|
detail: {
|
|
6080
6113
|
message: messageText,
|
|
6081
|
-
|
|
6114
|
+
internalFiles,
|
|
6082
6115
|
},
|
|
6083
6116
|
bubbles: true,
|
|
6084
6117
|
composed: true,
|
|
@@ -6089,30 +6122,26 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6089
6122
|
return;
|
|
6090
6123
|
}
|
|
6091
6124
|
const userMessage = {
|
|
6092
|
-
|
|
6125
|
+
type: 'user',
|
|
6093
6126
|
content: messageText,
|
|
6094
6127
|
};
|
|
6095
|
-
if (attachments.length) {
|
|
6096
|
-
userMessage.attachments = attachments;
|
|
6097
|
-
}
|
|
6098
6128
|
this.messages = [...this.messages, userMessage];
|
|
6099
6129
|
this._inputValue = '';
|
|
6100
6130
|
this._error = '';
|
|
6101
6131
|
this._userHasScrolledUp = false;
|
|
6102
|
-
// Clear the composer
|
|
6103
|
-
|
|
6104
|
-
this.
|
|
6132
|
+
// Clear the composer and release its preview object URLs.
|
|
6133
|
+
this._pendingInternalFiles.forEach((p) => URL.revokeObjectURL(p.previewUrl));
|
|
6134
|
+
this._pendingInternalFiles = [];
|
|
6105
6135
|
// Reset textarea height
|
|
6106
6136
|
if (this._inputEl) {
|
|
6107
6137
|
this._inputEl.style.height = 'auto';
|
|
6108
6138
|
}
|
|
6109
6139
|
// Add empty assistant message to stream into
|
|
6110
6140
|
this.messages = [...this.messages, {
|
|
6111
|
-
|
|
6141
|
+
type: 'assistant',
|
|
6112
6142
|
content: '',
|
|
6113
6143
|
}];
|
|
6114
6144
|
this._isStreaming = true;
|
|
6115
|
-
this._statusText = '';
|
|
6116
6145
|
// Scroll user's message to the top (Gemini-style).
|
|
6117
6146
|
// Set min-height on the assistant message = container height so there's enough
|
|
6118
6147
|
// scroll room below the user message to push it to the top.
|
|
@@ -6134,10 +6163,34 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6134
6163
|
this._messagesEl.scrollTop = userMsgEl.offsetTop - this._messagesEl.offsetTop - 24;
|
|
6135
6164
|
}
|
|
6136
6165
|
});
|
|
6166
|
+
// Default to streaming from the Kodaris Bedrock conversation endpoints when
|
|
6167
|
+
// the consumer hasn't provided their own `send`.
|
|
6168
|
+
if (!this.send) {
|
|
6169
|
+
this.send = (params) => {
|
|
6170
|
+
// With images, post text + files as multipart; without, post plain JSON.
|
|
6171
|
+
if (params.internalFiles.length) {
|
|
6172
|
+
const form = new FormData();
|
|
6173
|
+
form.append('userText', params.message);
|
|
6174
|
+
params.internalFiles.forEach((file) => form.append('images', file));
|
|
6175
|
+
return KRHttp.fetch({
|
|
6176
|
+
url: '/api/system/integration/aws/bedrock/stream/invokeModelForConversationWithImages',
|
|
6177
|
+
method: 'POST',
|
|
6178
|
+
headers: { Accept: 'text/event-stream' },
|
|
6179
|
+
body: form,
|
|
6180
|
+
});
|
|
6181
|
+
}
|
|
6182
|
+
return KRHttp.fetch({
|
|
6183
|
+
url: '/api/system/integration/aws/bedrock/stream/invokeModelForConversationWithState',
|
|
6184
|
+
method: 'POST',
|
|
6185
|
+
headers: { Accept: 'text/event-stream' },
|
|
6186
|
+
body: { userText: params.message },
|
|
6187
|
+
});
|
|
6188
|
+
};
|
|
6189
|
+
}
|
|
6137
6190
|
this.send({
|
|
6138
6191
|
message: messageText,
|
|
6139
6192
|
messages: this.messages.slice(0, -1),
|
|
6140
|
-
|
|
6193
|
+
internalFiles,
|
|
6141
6194
|
}).then((response) => {
|
|
6142
6195
|
if (!response.ok) {
|
|
6143
6196
|
this._handleStreamError('Request failed: ' + response.status);
|
|
@@ -6163,11 +6216,15 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6163
6216
|
this._reader = null;
|
|
6164
6217
|
}
|
|
6165
6218
|
this._isStreaming = false;
|
|
6166
|
-
this._statusText = '';
|
|
6167
6219
|
}
|
|
6168
6220
|
_handleClear() {
|
|
6221
|
+
// Default to clearing the Kodaris Bedrock conversation state when the consumer
|
|
6222
|
+
// hasn't provided their own `clear`.
|
|
6169
6223
|
if (!this.clear) {
|
|
6170
|
-
|
|
6224
|
+
this.clear = () => KRHttp.fetch({
|
|
6225
|
+
url: '/api/system/integration/aws/bedrock/clearConversationWithState',
|
|
6226
|
+
method: 'POST',
|
|
6227
|
+
});
|
|
6171
6228
|
}
|
|
6172
6229
|
this.clear().then(() => {
|
|
6173
6230
|
if (this._reader) {
|
|
@@ -6176,7 +6233,6 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6176
6233
|
}
|
|
6177
6234
|
this.messages = [];
|
|
6178
6235
|
this._isStreaming = false;
|
|
6179
|
-
this._statusText = '';
|
|
6180
6236
|
this._error = '';
|
|
6181
6237
|
this._inputValue = '';
|
|
6182
6238
|
this._userHasScrolledUp = false;
|
|
@@ -6202,7 +6258,6 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6202
6258
|
this._reader.read().then((result) => {
|
|
6203
6259
|
if (result.done) {
|
|
6204
6260
|
this._isStreaming = false;
|
|
6205
|
-
this._statusText = '';
|
|
6206
6261
|
this._reader = null;
|
|
6207
6262
|
return;
|
|
6208
6263
|
}
|
|
@@ -6235,15 +6290,10 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6235
6290
|
bubbles: true,
|
|
6236
6291
|
composed: true,
|
|
6237
6292
|
}));
|
|
6238
|
-
if (data.type === '
|
|
6239
|
-
if (data.message) {
|
|
6240
|
-
this._statusText = String(data.message);
|
|
6241
|
-
}
|
|
6242
|
-
}
|
|
6243
|
-
else if (data.type === 'REASONING_PART') {
|
|
6293
|
+
if (data.type === 'REASONING_PART') {
|
|
6244
6294
|
if (data.message) {
|
|
6245
6295
|
const lastIndex = this.messages.length - 1;
|
|
6246
|
-
if (lastIndex >= 0 && this.messages[lastIndex].
|
|
6296
|
+
if (lastIndex >= 0 && this.messages[lastIndex].type === 'assistant') {
|
|
6247
6297
|
if (!this.messages[lastIndex].reasoning) {
|
|
6248
6298
|
this.messages[lastIndex].reasoning = '';
|
|
6249
6299
|
}
|
|
@@ -6254,9 +6304,8 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6254
6304
|
}
|
|
6255
6305
|
else if (data.type === 'RESPONSE_PART') {
|
|
6256
6306
|
if (data.message) {
|
|
6257
|
-
this._statusText = '';
|
|
6258
6307
|
const lastIndex = this.messages.length - 1;
|
|
6259
|
-
if (lastIndex >= 0 && this.messages[lastIndex].
|
|
6308
|
+
if (lastIndex >= 0 && this.messages[lastIndex].type === 'assistant') {
|
|
6260
6309
|
this.messages[lastIndex].content += String(data.message);
|
|
6261
6310
|
this.requestUpdate();
|
|
6262
6311
|
}
|
|
@@ -6267,7 +6316,6 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6267
6316
|
}
|
|
6268
6317
|
if (data.finished) {
|
|
6269
6318
|
this._isStreaming = false;
|
|
6270
|
-
this._statusText = '';
|
|
6271
6319
|
this._reader = null;
|
|
6272
6320
|
}
|
|
6273
6321
|
}
|
|
@@ -6281,7 +6329,6 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6281
6329
|
}
|
|
6282
6330
|
_handleStreamError(message) {
|
|
6283
6331
|
this._isStreaming = false;
|
|
6284
|
-
this._statusText = '';
|
|
6285
6332
|
this._error = message;
|
|
6286
6333
|
if (this._reader) {
|
|
6287
6334
|
this._reader.cancel();
|
|
@@ -6290,7 +6337,7 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6290
6337
|
// Remove the empty assistant message if it has no content
|
|
6291
6338
|
if (this.messages.length > 0) {
|
|
6292
6339
|
const lastMessage = this.messages[this.messages.length - 1];
|
|
6293
|
-
if (lastMessage.
|
|
6340
|
+
if (lastMessage.type === 'assistant' && !lastMessage.content) {
|
|
6294
6341
|
this.messages = this.messages.slice(0, -1);
|
|
6295
6342
|
}
|
|
6296
6343
|
}
|
|
@@ -6298,7 +6345,7 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6298
6345
|
// --- Render ---
|
|
6299
6346
|
render() {
|
|
6300
6347
|
return b `
|
|
6301
|
-
${this.hideToggle ? A : b `
|
|
6348
|
+
${(this.hideToggle || this.variant === 'inline') ? A : b `
|
|
6302
6349
|
<button
|
|
6303
6350
|
class=${e({
|
|
6304
6351
|
'toggle': true,
|
|
@@ -6349,53 +6396,52 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6349
6396
|
<span>Drop images to attach</span>
|
|
6350
6397
|
</div>
|
|
6351
6398
|
` : A}
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6399
|
+
${this.variant === 'inline' ? A : b `
|
|
6400
|
+
<div
|
|
6401
|
+
class="resize resize--n"
|
|
6402
|
+
data-dir="n"
|
|
6403
|
+
@mousedown=${this._handleResizeMouseDown}
|
|
6404
|
+
></div>
|
|
6405
|
+
<div
|
|
6406
|
+
class="resize resize--s"
|
|
6407
|
+
data-dir="s"
|
|
6408
|
+
@mousedown=${this._handleResizeMouseDown}
|
|
6409
|
+
></div>
|
|
6410
|
+
<div
|
|
6411
|
+
class="resize resize--w"
|
|
6412
|
+
data-dir="w"
|
|
6413
|
+
@mousedown=${this._handleResizeMouseDown}
|
|
6414
|
+
></div>
|
|
6415
|
+
<div
|
|
6416
|
+
class="resize resize--e"
|
|
6417
|
+
data-dir="e"
|
|
6418
|
+
@mousedown=${this._handleResizeMouseDown}
|
|
6419
|
+
></div>
|
|
6420
|
+
<div
|
|
6421
|
+
class="resize resize--nw"
|
|
6422
|
+
data-dir="nw"
|
|
6423
|
+
@mousedown=${this._handleResizeMouseDown}
|
|
6424
|
+
></div>
|
|
6425
|
+
<div
|
|
6426
|
+
class="resize resize--ne"
|
|
6427
|
+
data-dir="ne"
|
|
6428
|
+
@mousedown=${this._handleResizeMouseDown}
|
|
6429
|
+
></div>
|
|
6430
|
+
<div
|
|
6431
|
+
class="resize resize--sw"
|
|
6432
|
+
data-dir="sw"
|
|
6433
|
+
@mousedown=${this._handleResizeMouseDown}
|
|
6434
|
+
></div>
|
|
6435
|
+
<div
|
|
6436
|
+
class="resize resize--se"
|
|
6437
|
+
data-dir="se"
|
|
6438
|
+
@mousedown=${this._handleResizeMouseDown}
|
|
6439
|
+
></div>
|
|
6440
|
+
`}
|
|
6392
6441
|
<div class="header" @mousedown=${this._handleHeaderMouseDown}>
|
|
6393
6442
|
<div class="header-left">
|
|
6394
6443
|
<div class="header-info">
|
|
6395
|
-
<span class="header-title">${this.
|
|
6396
|
-
${this.subtitle ? b `
|
|
6397
|
-
<span class="header-subtitle">${this.subtitle}</span>
|
|
6398
|
-
` : A}
|
|
6444
|
+
<span class="header-title">${this.label}</span>
|
|
6399
6445
|
</div>
|
|
6400
6446
|
</div>
|
|
6401
6447
|
<div class="header-actions">
|
|
@@ -6421,77 +6467,84 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6421
6467
|
</svg>
|
|
6422
6468
|
</button>
|
|
6423
6469
|
` : A}
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
<svg
|
|
6430
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
6431
|
-
fill="none"
|
|
6432
|
-
viewBox="0 0 24 24"
|
|
6433
|
-
stroke-width="2"
|
|
6434
|
-
stroke="currentColor"
|
|
6435
|
-
class="header-action-icon"
|
|
6470
|
+
${this.variant === 'inline' ? A : b `
|
|
6471
|
+
<button
|
|
6472
|
+
class="header-action"
|
|
6473
|
+
@click=${this._handleToggle}
|
|
6474
|
+
title="Close"
|
|
6436
6475
|
>
|
|
6437
|
-
<
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6476
|
+
<svg
|
|
6477
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6478
|
+
fill="none"
|
|
6479
|
+
viewBox="0 0 24 24"
|
|
6480
|
+
stroke-width="2"
|
|
6481
|
+
stroke="currentColor"
|
|
6482
|
+
class="header-action-icon"
|
|
6483
|
+
>
|
|
6484
|
+
<path
|
|
6485
|
+
stroke-linecap="round"
|
|
6486
|
+
stroke-linejoin="round"
|
|
6487
|
+
d="M6 18 18 6M6 6l12 12"
|
|
6488
|
+
/>
|
|
6489
|
+
</svg>
|
|
6490
|
+
</button>
|
|
6491
|
+
`}
|
|
6444
6492
|
</div>
|
|
6445
6493
|
</div>
|
|
6446
6494
|
|
|
6447
6495
|
<div class="messages" @scroll=${this._handleMessagesScroll}>
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
<
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6496
|
+
<div class="messages-inner">
|
|
6497
|
+
${this.messages.length === 0 ? b `
|
|
6498
|
+
<div class="empty">
|
|
6499
|
+
<span class="empty-text">What can I help you with?</span>
|
|
6500
|
+
</div>
|
|
6501
|
+
` : A}
|
|
6502
|
+
${this.messages.map((msg) => b `
|
|
6503
|
+
<div class=${e({
|
|
6455
6504
|
'message': true,
|
|
6456
|
-
'message--user': msg.
|
|
6457
|
-
'message--assistant': msg.
|
|
6505
|
+
'message--user': msg.type === 'user',
|
|
6506
|
+
'message--assistant': msg.type === 'assistant',
|
|
6458
6507
|
})}>
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6508
|
+
${msg.reasoning ? b `
|
|
6509
|
+
<details class="reasoning">
|
|
6510
|
+
<summary>Thinking</summary>
|
|
6511
|
+
<div class="reasoning-content">${msg.reasoning}</div>
|
|
6512
|
+
</details>
|
|
6513
|
+
` : A}
|
|
6514
|
+
${msg.internalFiles && msg.internalFiles.length ? b `
|
|
6515
|
+
<div class="attachments">
|
|
6516
|
+
${msg.internalFiles.map((img) => b `
|
|
6517
|
+
<button
|
|
6518
|
+
class="attachment"
|
|
6519
|
+
type="button"
|
|
6520
|
+
title=${img.niceName || 'View image'}
|
|
6521
|
+
@click=${() => this._openImage(img)}
|
|
6522
|
+
>
|
|
6523
|
+
<img
|
|
6524
|
+
src="/api/system/integration/aws/bedrock/conversationImage/${img.internalFileID}/view"
|
|
6525
|
+
alt=${img.niceName || ''}
|
|
6526
|
+
/>
|
|
6527
|
+
</button>
|
|
6528
|
+
`)}
|
|
6529
|
+
</div>
|
|
6530
|
+
` : A}
|
|
6531
|
+
${msg.content ? b `
|
|
6532
|
+
<div class="message-content">
|
|
6533
|
+
${msg.type === 'user'
|
|
6482
6534
|
? msg.content
|
|
6483
6535
|
: o(marked.parse(msg.content, { breaks: true }))}
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6536
|
+
</div>
|
|
6537
|
+
` : A}
|
|
6538
|
+
${msg.type === 'assistant' && this._isStreaming && msg === this.messages[this.messages.length - 1] ? b `
|
|
6539
|
+
<div class="typing">
|
|
6540
|
+
<span></span>
|
|
6541
|
+
<span></span>
|
|
6542
|
+
<span></span>
|
|
6543
|
+
</div>
|
|
6544
|
+
` : A}
|
|
6545
|
+
</div>
|
|
6546
|
+
`)}
|
|
6547
|
+
</div>
|
|
6495
6548
|
</div>
|
|
6496
6549
|
|
|
6497
6550
|
${this._error ? b `
|
|
@@ -6517,9 +6570,9 @@ let KRChatbot = class KRChatbot extends i$2 {
|
|
|
6517
6570
|
` : A}
|
|
6518
6571
|
|
|
6519
6572
|
<div class="footer">
|
|
6520
|
-
${this.
|
|
6573
|
+
${this._pendingInternalFiles.length ? b `
|
|
6521
6574
|
<div class="composer-attachments">
|
|
6522
|
-
${c(this.
|
|
6575
|
+
${c(this._pendingInternalFiles, (p) => p.localId, (p) => b `
|
|
6523
6576
|
<div class="chip">
|
|
6524
6577
|
<img src=${p.previewUrl} alt=${p.name} />
|
|
6525
6578
|
<button
|
|
@@ -6708,6 +6761,28 @@ KRChatbot.styles = i$5 `
|
|
|
6708
6761
|
display: flex;
|
|
6709
6762
|
}
|
|
6710
6763
|
|
|
6764
|
+
/* Inline mode: fill the parent container instead of floating bottom-right. */
|
|
6765
|
+
:host([variant='inline']) {
|
|
6766
|
+
position: static;
|
|
6767
|
+
bottom: auto;
|
|
6768
|
+
right: auto;
|
|
6769
|
+
z-index: auto;
|
|
6770
|
+
height: 100%;
|
|
6771
|
+
}
|
|
6772
|
+
|
|
6773
|
+
:host([variant='inline']) .panel {
|
|
6774
|
+
position: relative;
|
|
6775
|
+
bottom: auto;
|
|
6776
|
+
right: auto;
|
|
6777
|
+
width: 100%;
|
|
6778
|
+
height: 100%;
|
|
6779
|
+
max-height: none;
|
|
6780
|
+
border-radius: 0;
|
|
6781
|
+
box-shadow: none;
|
|
6782
|
+
border: none;
|
|
6783
|
+
animation: none;
|
|
6784
|
+
}
|
|
6785
|
+
|
|
6711
6786
|
@keyframes chatbot-panel-in {
|
|
6712
6787
|
from {
|
|
6713
6788
|
opacity: 0;
|
|
@@ -6738,7 +6813,7 @@ KRChatbot.styles = i$5 `
|
|
|
6738
6813
|
gap: 10px;
|
|
6739
6814
|
}
|
|
6740
6815
|
|
|
6741
|
-
.header-info {
|
|
6816
|
+
.header-info {
|
|
6742
6817
|
display: flex;
|
|
6743
6818
|
flex-direction: column;
|
|
6744
6819
|
}
|
|
@@ -6748,22 +6823,6 @@ KRChatbot.styles = i$5 `
|
|
|
6748
6823
|
font-weight: 600;
|
|
6749
6824
|
}
|
|
6750
6825
|
|
|
6751
|
-
.header-subtitle {
|
|
6752
|
-
color: rgba(255, 255, 255, 0.5);
|
|
6753
|
-
font-size: 11px;
|
|
6754
|
-
display: flex;
|
|
6755
|
-
align-items: center;
|
|
6756
|
-
gap: 4px;
|
|
6757
|
-
}
|
|
6758
|
-
|
|
6759
|
-
.header-subtitle::before {
|
|
6760
|
-
content: '';
|
|
6761
|
-
width: 5px;
|
|
6762
|
-
height: 5px;
|
|
6763
|
-
background: var(--kr-chatbot-success);
|
|
6764
|
-
border-radius: 50%;
|
|
6765
|
-
}
|
|
6766
|
-
|
|
6767
6826
|
.header-actions {
|
|
6768
6827
|
display: flex;
|
|
6769
6828
|
align-items: center;
|
|
@@ -6795,17 +6854,29 @@ KRChatbot.styles = i$5 `
|
|
|
6795
6854
|
}
|
|
6796
6855
|
|
|
6797
6856
|
/* Messages */
|
|
6857
|
+
/* Full-width scroll container — keeps the scrollbar at the panel edge. */
|
|
6798
6858
|
.messages {
|
|
6799
6859
|
flex: 1;
|
|
6800
6860
|
overflow-y: auto;
|
|
6801
|
-
padding: 32px;
|
|
6802
6861
|
display: flex;
|
|
6803
6862
|
flex-direction: column;
|
|
6804
|
-
gap: 24px;
|
|
6805
6863
|
scroll-behavior: smooth;
|
|
6806
6864
|
background: white;
|
|
6807
6865
|
}
|
|
6808
6866
|
|
|
6867
|
+
/* Centered, width-capped column that actually holds the messages. */
|
|
6868
|
+
.messages-inner {
|
|
6869
|
+
flex: 1;
|
|
6870
|
+
display: flex;
|
|
6871
|
+
flex-direction: column;
|
|
6872
|
+
gap: 24px;
|
|
6873
|
+
padding: 32px;
|
|
6874
|
+
width: 100%;
|
|
6875
|
+
max-width: 768px;
|
|
6876
|
+
margin-left: auto;
|
|
6877
|
+
margin-right: auto;
|
|
6878
|
+
}
|
|
6879
|
+
|
|
6809
6880
|
.messages::-webkit-scrollbar {
|
|
6810
6881
|
width: 4px;
|
|
6811
6882
|
}
|
|
@@ -6829,7 +6900,7 @@ KRChatbot.styles = i$5 `
|
|
|
6829
6900
|
gap: 8px;
|
|
6830
6901
|
}
|
|
6831
6902
|
|
|
6832
|
-
.empty-text {
|
|
6903
|
+
.empty-text {
|
|
6833
6904
|
font-size: 14px;
|
|
6834
6905
|
color: rgb(0 0 0 / 80%);
|
|
6835
6906
|
}
|
|
@@ -6941,7 +7012,7 @@ KRChatbot.styles = i$5 `
|
|
|
6941
7012
|
word-wrap: break-word;
|
|
6942
7013
|
}
|
|
6943
7014
|
|
|
6944
|
-
.typing {
|
|
7015
|
+
.typing {
|
|
6945
7016
|
display: flex;
|
|
6946
7017
|
gap: 4px;
|
|
6947
7018
|
padding: 4px 0;
|
|
@@ -7009,6 +7080,15 @@ KRChatbot.styles = i$5 `
|
|
|
7009
7080
|
padding: 16px 16px 16px;
|
|
7010
7081
|
flex-shrink: 0;
|
|
7011
7082
|
background: white;
|
|
7083
|
+
width: 100%;
|
|
7084
|
+
max-width: 768px;
|
|
7085
|
+
margin-left: auto;
|
|
7086
|
+
margin-right: auto;
|
|
7087
|
+
}
|
|
7088
|
+
|
|
7089
|
+
/* Inline mode: keep the composer clear of the bottom edge. */
|
|
7090
|
+
:host([variant='inline']) .footer {
|
|
7091
|
+
padding-bottom: 40px;
|
|
7012
7092
|
}
|
|
7013
7093
|
|
|
7014
7094
|
.input-wrapper {
|
|
@@ -7027,6 +7107,15 @@ KRChatbot.styles = i$5 `
|
|
|
7027
7107
|
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.04);
|
|
7028
7108
|
}
|
|
7029
7109
|
|
|
7110
|
+
/* Inline mode: keep the border and add a soft floating shadow (ChatGPT/Gemini style). */
|
|
7111
|
+
:host([variant='inline']) .input-wrapper {
|
|
7112
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06), 0 8px 24px rgba(0, 0, 0, 0.1);
|
|
7113
|
+
}
|
|
7114
|
+
|
|
7115
|
+
:host([variant='inline']) .input-wrapper:focus-within {
|
|
7116
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 12px 32px rgba(0, 0, 0, 0.14);
|
|
7117
|
+
}
|
|
7118
|
+
|
|
7030
7119
|
.input-plus {
|
|
7031
7120
|
width: 34px;
|
|
7032
7121
|
height: 34px;
|
|
@@ -7134,6 +7223,12 @@ KRChatbot.styles = i$5 `
|
|
|
7134
7223
|
cursor: grabbing;
|
|
7135
7224
|
}
|
|
7136
7225
|
|
|
7226
|
+
/* Inline mode isn't draggable — don't show the grab/hand cursor. */
|
|
7227
|
+
:host([variant='inline']) .header,
|
|
7228
|
+
:host([variant='inline']) .header:active {
|
|
7229
|
+
cursor: default;
|
|
7230
|
+
}
|
|
7231
|
+
|
|
7137
7232
|
/* Drag / Resize states */
|
|
7138
7233
|
.panel--dragging,
|
|
7139
7234
|
.panel--resizing {
|
|
@@ -7285,10 +7380,7 @@ __decorate([
|
|
|
7285
7380
|
], KRChatbot.prototype, "messages", void 0);
|
|
7286
7381
|
__decorate([
|
|
7287
7382
|
n({ type: String })
|
|
7288
|
-
], KRChatbot.prototype, "
|
|
7289
|
-
__decorate([
|
|
7290
|
-
n({ type: String })
|
|
7291
|
-
], KRChatbot.prototype, "subtitle", void 0);
|
|
7383
|
+
], KRChatbot.prototype, "label", void 0);
|
|
7292
7384
|
__decorate([
|
|
7293
7385
|
n({ type: String })
|
|
7294
7386
|
], KRChatbot.prototype, "placeholder", void 0);
|
|
@@ -7305,21 +7397,24 @@ __decorate([
|
|
|
7305
7397
|
reflect: true
|
|
7306
7398
|
})
|
|
7307
7399
|
], KRChatbot.prototype, "hideToggle", void 0);
|
|
7400
|
+
__decorate([
|
|
7401
|
+
n({
|
|
7402
|
+
type: String,
|
|
7403
|
+
reflect: true
|
|
7404
|
+
})
|
|
7405
|
+
], KRChatbot.prototype, "variant", void 0);
|
|
7308
7406
|
__decorate([
|
|
7309
7407
|
r()
|
|
7310
7408
|
], KRChatbot.prototype, "_inputValue", void 0);
|
|
7311
7409
|
__decorate([
|
|
7312
7410
|
r()
|
|
7313
7411
|
], KRChatbot.prototype, "_isStreaming", void 0);
|
|
7314
|
-
__decorate([
|
|
7315
|
-
r()
|
|
7316
|
-
], KRChatbot.prototype, "_statusText", void 0);
|
|
7317
7412
|
__decorate([
|
|
7318
7413
|
r()
|
|
7319
7414
|
], KRChatbot.prototype, "_error", void 0);
|
|
7320
7415
|
__decorate([
|
|
7321
7416
|
r()
|
|
7322
|
-
], KRChatbot.prototype, "
|
|
7417
|
+
], KRChatbot.prototype, "_pendingInternalFiles", void 0);
|
|
7323
7418
|
__decorate([
|
|
7324
7419
|
r()
|
|
7325
7420
|
], KRChatbot.prototype, "_isDraggingFile", void 0);
|