@kodaris/krubble-app-components 1.0.126 → 1.0.127
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 +6 -13
- package/dist/chatbot.d.ts.map +1 -1
- package/dist/chatbot.js +121 -100
- package/dist/chatbot.js.map +1 -1
- package/dist/krubble-app.bundled.js +121 -100
- package/dist/krubble-app.bundled.js.map +1 -1
- package/dist/krubble-app.bundled.min.js +19 -19
- package/dist/krubble-app.bundled.min.js.map +1 -1
- package/dist/krubble-app.umd.js +121 -100
- package/dist/krubble-app.umd.js.map +1 -1
- package/dist/krubble-app.umd.min.js +21 -21
- package/dist/krubble-app.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -3470,10 +3470,9 @@ class KRChatbot extends i$3 {
|
|
|
3470
3470
|
}
|
|
3471
3471
|
}
|
|
3472
3472
|
// `this.load` is always set by here (defaulted above when the consumer didn't
|
|
3473
|
-
// supply one)
|
|
3474
|
-
//
|
|
3475
|
-
|
|
3476
|
-
resolveConversationId.then(() => load()).then((messages) => {
|
|
3473
|
+
// supply one); the `!` is because TS can't narrow the nullable property across
|
|
3474
|
+
// the promise boundary.
|
|
3475
|
+
resolveConversationId.then(() => this.load()).then((messages) => {
|
|
3477
3476
|
if (messages && messages.length) {
|
|
3478
3477
|
this.messages = messages;
|
|
3479
3478
|
}
|
|
@@ -3742,11 +3741,10 @@ class KRChatbot extends i$3 {
|
|
|
3742
3741
|
}
|
|
3743
3742
|
_saveState() {
|
|
3744
3743
|
try {
|
|
3745
|
-
// `toolDetail`
|
|
3746
|
-
//
|
|
3747
|
-
// stale conversation list.
|
|
3744
|
+
// `toolDetail` is a transient peek, not a saved view — persist only the two
|
|
3745
|
+
// real preference views so a reload never reopens a stale tool.
|
|
3748
3746
|
let persistedDrawerView = this._drawerView;
|
|
3749
|
-
if (persistedDrawerView === 'toolDetail'
|
|
3747
|
+
if (persistedDrawerView === 'toolDetail') {
|
|
3750
3748
|
persistedDrawerView = 'settings';
|
|
3751
3749
|
}
|
|
3752
3750
|
const state = {
|
|
@@ -3805,8 +3803,14 @@ class KRChatbot extends i$3 {
|
|
|
3805
3803
|
this._showToolInputs = state.showToolInputs === 'true';
|
|
3806
3804
|
this._showConfirmationInput = state.showConfirmationInput === 'true';
|
|
3807
3805
|
this._drawerOpen = state.drawerOpen === 'true';
|
|
3808
|
-
if (state.drawerView === 'settings' || state.drawerView === 'debug') {
|
|
3806
|
+
if (state.drawerView === 'settings' || state.drawerView === 'debug' || state.drawerView === 'history') {
|
|
3809
3807
|
this._drawerView = state.drawerView;
|
|
3808
|
+
// History's list isn't persisted (it can go stale); refetch it so a reload
|
|
3809
|
+
// that was on the conversations panel comes back to a populated list rather
|
|
3810
|
+
// than an empty one.
|
|
3811
|
+
if (state.drawerView === 'history') {
|
|
3812
|
+
this._loadConversations();
|
|
3813
|
+
}
|
|
3810
3814
|
}
|
|
3811
3815
|
const w = Number(state.drawerWidth);
|
|
3812
3816
|
if (w >= 300) {
|
|
@@ -4950,41 +4954,47 @@ class KRChatbot extends i$3 {
|
|
|
4950
4954
|
else {
|
|
4951
4955
|
this._drawerOpen = true;
|
|
4952
4956
|
this._drawerView = view;
|
|
4953
|
-
// Opening the history view refetches the
|
|
4954
|
-
//
|
|
4955
|
-
// shows without a reload. Ownership is enforced server-side (the endpoint
|
|
4956
|
-
// scopes to the current administrator), so we only filter to active ones.
|
|
4957
|
+
// Opening the history view refetches the list so a just-created or renamed
|
|
4958
|
+
// conversation shows without a reload.
|
|
4957
4959
|
if (view === 'history') {
|
|
4958
|
-
this.
|
|
4959
|
-
KRHttp.fetch({
|
|
4960
|
-
url: '/api/system/conversation/list',
|
|
4961
|
-
method: 'POST',
|
|
4962
|
-
body: {
|
|
4963
|
-
page: 0,
|
|
4964
|
-
size: 50,
|
|
4965
|
-
sortBy: 'lastModified',
|
|
4966
|
-
sortDirection: 'desc',
|
|
4967
|
-
filterFields: [{
|
|
4968
|
-
name: 'active',
|
|
4969
|
-
operation: 'IS',
|
|
4970
|
-
value: 'true',
|
|
4971
|
-
}],
|
|
4972
|
-
},
|
|
4973
|
-
})
|
|
4974
|
-
.then((r) => r.json())
|
|
4975
|
-
.then((res) => {
|
|
4976
|
-
this._conversations = res?.data?.content || [];
|
|
4977
|
-
})
|
|
4978
|
-
.catch(() => {
|
|
4979
|
-
this._conversations = [];
|
|
4980
|
-
})
|
|
4981
|
-
.then(() => {
|
|
4982
|
-
this._conversationsLoading = false;
|
|
4983
|
-
});
|
|
4960
|
+
this._loadConversations();
|
|
4984
4961
|
}
|
|
4985
4962
|
}
|
|
4986
4963
|
this._saveState();
|
|
4987
4964
|
}
|
|
4965
|
+
/**
|
|
4966
|
+
* Fetch the user's previous conversations for the history list, most-recently
|
|
4967
|
+
* modified first. Ownership is enforced server-side (the endpoint scopes to the
|
|
4968
|
+
* current administrator), so we only filter to active ones.
|
|
4969
|
+
*/
|
|
4970
|
+
_loadConversations() {
|
|
4971
|
+
this._conversationsLoading = true;
|
|
4972
|
+
KRHttp.fetch({
|
|
4973
|
+
url: '/api/system/conversation/list',
|
|
4974
|
+
method: 'POST',
|
|
4975
|
+
body: {
|
|
4976
|
+
page: 0,
|
|
4977
|
+
size: 50,
|
|
4978
|
+
sortBy: 'lastModified',
|
|
4979
|
+
sortDirection: 'desc',
|
|
4980
|
+
filterFields: [{
|
|
4981
|
+
name: 'active',
|
|
4982
|
+
operation: 'IS',
|
|
4983
|
+
value: 'true',
|
|
4984
|
+
}],
|
|
4985
|
+
},
|
|
4986
|
+
})
|
|
4987
|
+
.then((r) => r.json())
|
|
4988
|
+
.then((res) => {
|
|
4989
|
+
this._conversations = res?.data?.content || [];
|
|
4990
|
+
})
|
|
4991
|
+
.catch(() => {
|
|
4992
|
+
this._conversations = [];
|
|
4993
|
+
})
|
|
4994
|
+
.then(() => {
|
|
4995
|
+
this._conversationsLoading = false;
|
|
4996
|
+
});
|
|
4997
|
+
}
|
|
4988
4998
|
/**
|
|
4989
4999
|
* Switch the floating widget to a previously-created conversation (clicked in the
|
|
4990
5000
|
* history list): stop any live turn, reset the transient turn/context state, pin
|
|
@@ -5003,7 +5013,22 @@ class KRChatbot extends i$3 {
|
|
|
5003
5013
|
// one, so the header falls back to the default label).
|
|
5004
5014
|
this._conversationTitle = this._conversations.find((c) => c.conversationID === conversationID)?.title || '';
|
|
5005
5015
|
this._persistConversationId();
|
|
5006
|
-
|
|
5016
|
+
// Clear the transient, per-conversation state so it doesn't bleed into the one
|
|
5017
|
+
// we're switching to — pending confirmations, context banners, errors, the
|
|
5018
|
+
// reconnect counter, and staged composer files (the transcript is loaded below).
|
|
5019
|
+
this._pendingActions = [];
|
|
5020
|
+
this._inlineConfirm = true;
|
|
5021
|
+
this._contextWarning = '';
|
|
5022
|
+
this._contextLimitReached = false;
|
|
5023
|
+
this._contextLimitMessage = '';
|
|
5024
|
+
this._error = '';
|
|
5025
|
+
this._reconnectAttempts = 0;
|
|
5026
|
+
this._pendingConversationFiles.forEach((p) => {
|
|
5027
|
+
if (p.previewUrl) {
|
|
5028
|
+
URL.revokeObjectURL(p.previewUrl);
|
|
5029
|
+
}
|
|
5030
|
+
});
|
|
5031
|
+
this._pendingConversationFiles = [];
|
|
5007
5032
|
this._drawerOpen = false;
|
|
5008
5033
|
this._saveState();
|
|
5009
5034
|
if (this.load) {
|
|
@@ -5030,17 +5055,9 @@ class KRChatbot extends i$3 {
|
|
|
5030
5055
|
this._conversationTitle = '';
|
|
5031
5056
|
this._persistConversationId();
|
|
5032
5057
|
this.messages = [];
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
}
|
|
5037
|
-
/**
|
|
5038
|
-
* Clear the transient, per-conversation state that must not bleed across a
|
|
5039
|
-
* conversation switch/new — pending confirmations, context banners, errors, the
|
|
5040
|
-
* reconnect counter, and staged composer files. The transcript itself is set by
|
|
5041
|
-
* the caller (loaded for a switch, emptied for new).
|
|
5042
|
-
*/
|
|
5043
|
-
_resetConversationState() {
|
|
5058
|
+
// Clear the transient, per-conversation state so it doesn't bleed into the new
|
|
5059
|
+
// conversation — pending confirmations, context banners, errors, the reconnect
|
|
5060
|
+
// counter, and staged composer files.
|
|
5044
5061
|
this._pendingActions = [];
|
|
5045
5062
|
this._inlineConfirm = true;
|
|
5046
5063
|
this._contextWarning = '';
|
|
@@ -5054,6 +5071,8 @@ class KRChatbot extends i$3 {
|
|
|
5054
5071
|
}
|
|
5055
5072
|
});
|
|
5056
5073
|
this._pendingConversationFiles = [];
|
|
5074
|
+
this._drawerOpen = false;
|
|
5075
|
+
this._saveState();
|
|
5057
5076
|
}
|
|
5058
5077
|
/** Close the drawer. `_drawerView` is left intact so its content stays visible
|
|
5059
5078
|
* while the drawer slides shut. */
|
|
@@ -5936,55 +5955,58 @@ class KRChatbot extends i$3 {
|
|
|
5936
5955
|
<div class="history__empty">No previous conversations</div>
|
|
5937
5956
|
` : b `
|
|
5938
5957
|
<div class="history__list">
|
|
5939
|
-
${this._conversations.map((conversation) =>
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
'
|
|
5944
|
-
|
|
5958
|
+
${this._conversations.map((conversation) => {
|
|
5959
|
+
// Format lastModified for the row: today shows the time, this year
|
|
5960
|
+
// shows month/day, older shows month/day/year; the raw value if it
|
|
5961
|
+
// isn't a parseable date. Empty when the conversation has no date.
|
|
5962
|
+
let dateLabel = '';
|
|
5963
|
+
if (conversation.lastModified) {
|
|
5964
|
+
const date = new Date(conversation.lastModified);
|
|
5965
|
+
const now = new Date();
|
|
5966
|
+
if (isNaN(date.getTime())) {
|
|
5967
|
+
dateLabel = conversation.lastModified;
|
|
5968
|
+
}
|
|
5969
|
+
else if (date.toDateString() === now.toDateString()) {
|
|
5970
|
+
dateLabel = date.toLocaleTimeString('en-US', {
|
|
5971
|
+
hour: 'numeric',
|
|
5972
|
+
minute: '2-digit',
|
|
5973
|
+
});
|
|
5974
|
+
}
|
|
5975
|
+
else if (date.getFullYear() === now.getFullYear()) {
|
|
5976
|
+
dateLabel = date.toLocaleDateString('en-US', {
|
|
5977
|
+
month: 'short',
|
|
5978
|
+
day: 'numeric',
|
|
5979
|
+
});
|
|
5980
|
+
}
|
|
5981
|
+
else {
|
|
5982
|
+
dateLabel = date.toLocaleDateString('en-US', {
|
|
5983
|
+
month: 'short',
|
|
5984
|
+
day: 'numeric',
|
|
5985
|
+
year: 'numeric',
|
|
5986
|
+
});
|
|
5987
|
+
}
|
|
5988
|
+
}
|
|
5989
|
+
return b `
|
|
5990
|
+
<button
|
|
5991
|
+
type="button"
|
|
5992
|
+
class=${e({
|
|
5993
|
+
'history__item': true,
|
|
5994
|
+
'history__item--active': conversation.conversationID === this.conversationId,
|
|
5995
|
+
})}
|
|
5996
|
+
@click=${() => this._handleSwitchConversation(conversation.conversationID)}
|
|
5997
|
+
>
|
|
5998
|
+
<span class="history__item-title">${conversation.title || 'Untitled conversation'}</span>
|
|
5999
|
+
${dateLabel ? b `
|
|
6000
|
+
<span class="history__item-date">${dateLabel}</span>
|
|
6001
|
+
` : A}
|
|
6002
|
+
</button>
|
|
6003
|
+
`;
|
|
5945
6004
|
})}
|
|
5946
|
-
@click=${() => this._handleSwitchConversation(conversation.conversationID)}
|
|
5947
|
-
>
|
|
5948
|
-
<span class="history__item-title">${conversation.title || 'Untitled conversation'}</span>
|
|
5949
|
-
${conversation.lastModified ? b `
|
|
5950
|
-
<span class="history__item-date">${this._renderConversationDate(conversation.lastModified)}</span>
|
|
5951
|
-
` : A}
|
|
5952
|
-
</button>
|
|
5953
|
-
`)}
|
|
5954
6005
|
</div>
|
|
5955
6006
|
`}
|
|
5956
6007
|
</div>
|
|
5957
6008
|
`;
|
|
5958
6009
|
}
|
|
5959
|
-
/**
|
|
5960
|
-
* Format a conversation's lastModified for the history list: today shows the
|
|
5961
|
-
* time, this year shows month/day, older shows month/day/year. Falls back to the
|
|
5962
|
-
* raw value if it isn't a parseable date.
|
|
5963
|
-
*/
|
|
5964
|
-
_renderConversationDate(lastModified) {
|
|
5965
|
-
const date = new Date(lastModified);
|
|
5966
|
-
if (isNaN(date.getTime())) {
|
|
5967
|
-
return lastModified;
|
|
5968
|
-
}
|
|
5969
|
-
const now = new Date();
|
|
5970
|
-
if (date.toDateString() === now.toDateString()) {
|
|
5971
|
-
return date.toLocaleTimeString('en-US', {
|
|
5972
|
-
hour: 'numeric',
|
|
5973
|
-
minute: '2-digit',
|
|
5974
|
-
});
|
|
5975
|
-
}
|
|
5976
|
-
if (date.getFullYear() === now.getFullYear()) {
|
|
5977
|
-
return date.toLocaleDateString('en-US', {
|
|
5978
|
-
month: 'short',
|
|
5979
|
-
day: 'numeric',
|
|
5980
|
-
});
|
|
5981
|
-
}
|
|
5982
|
-
return date.toLocaleDateString('en-US', {
|
|
5983
|
-
month: 'short',
|
|
5984
|
-
day: 'numeric',
|
|
5985
|
-
year: 'numeric',
|
|
5986
|
-
});
|
|
5987
|
-
}
|
|
5988
6010
|
/**
|
|
5989
6011
|
* The side drawer — one sliding panel that holds the Settings, Debug, History,
|
|
5990
6012
|
* and tool-detail views. The header buttons switch `_drawerView`; the title and
|
|
@@ -6015,25 +6037,24 @@ class KRChatbot extends i$3 {
|
|
|
6015
6037
|
// In the floating widget the drawer fills the panel over the transcript (a
|
|
6016
6038
|
// full-panel view with a back button) rather than sliding in beside it — the
|
|
6017
6039
|
// panel is too narrow to show both. Inline keeps the side-drawer behavior.
|
|
6018
|
-
const fullPanel = this.variant === 'floating';
|
|
6019
6040
|
return b `
|
|
6020
6041
|
<div
|
|
6021
6042
|
class=${e({
|
|
6022
6043
|
'drawer': true,
|
|
6023
6044
|
'drawer--open': this._drawerOpen,
|
|
6024
6045
|
'drawer--resizing': this._isDrawerResizing,
|
|
6025
|
-
'drawer--full':
|
|
6046
|
+
'drawer--full': this.variant === 'floating',
|
|
6026
6047
|
})}
|
|
6027
|
-
style=${o(
|
|
6048
|
+
style=${o(this.variant === 'floating' ? {} : { width: `${this._drawerWidth}px` })}
|
|
6028
6049
|
>
|
|
6029
|
-
${
|
|
6050
|
+
${this.variant === 'floating' ? A : b `
|
|
6030
6051
|
<div
|
|
6031
6052
|
class="drawer__resize"
|
|
6032
6053
|
@mousedown=${this._handleDrawerResizeMouseDown}
|
|
6033
6054
|
></div>
|
|
6034
6055
|
`}
|
|
6035
6056
|
<div class="drawer__header">
|
|
6036
|
-
${
|
|
6057
|
+
${this.variant === 'floating' ? b `
|
|
6037
6058
|
<button
|
|
6038
6059
|
class="header-action"
|
|
6039
6060
|
@click=${this._handleCloseDrawer}
|
|
@@ -6081,7 +6102,7 @@ class KRChatbot extends i$3 {
|
|
|
6081
6102
|
New conversation
|
|
6082
6103
|
</kr-button>
|
|
6083
6104
|
` : A}
|
|
6084
|
-
${
|
|
6105
|
+
${this.variant === 'floating' ? A : b `
|
|
6085
6106
|
<button
|
|
6086
6107
|
class="header-action"
|
|
6087
6108
|
@click=${this._handleCloseDrawer}
|