From c83e2c6abc4b78abfab3dafc816f30269955dbc6 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Tue, 24 Sep 2024 15:32:49 -0500 Subject: [PATCH] refine chat --- src/lib/helpers/http.js | 5 +- src/lib/scss/custom/pages/_chat.scss | 8 +- src/lib/scss/custom/pages/_knowledgebase.scss | 23 ++- src/lib/services/api-endpoints.js | 3 +- src/lib/services/knowledge-base-service.js | 16 +- .../[conversationId]/chat-box.svelte | 159 +++++++++--------- .../rich-content/rc-complex-options.svelte | 30 ++-- .../rich-content/rc-plain-options.svelte | 34 ++-- .../rich-content/rich-content.svelte | 2 + .../collection/collection-create-modal.svelte | 58 +++++-- .../knowledge-base/documents/+page.svelte | 7 +- .../question-answer/+page.svelte | 7 +- 12 files changed, 215 insertions(+), 137 deletions(-) diff --git a/src/lib/helpers/http.js b/src/lib/helpers/http.js index 03727618..3055fe62 100644 --- a/src/lib/helpers/http.js +++ b/src/lib/helpers/http.js @@ -60,7 +60,7 @@ function skipLoader(config) { new RegExp('http(s*)://(.*?)/knowledge/vector/(.*?)/page', 'g'), new RegExp('http(s*)://(.*?)/knowledge/(.*?)/search', 'g'), new RegExp('http(s*)://(.*?)/knowledge/vector/(.*?)/create', 'g'), - new RegExp('http(s*)://(.*?)/knowledge/document/(.*?)/page', 'g') + new RegExp('http(s*)://(.*?)/knowledge/document/(.*?)/page', 'g'), ]; const putRegexes = [ @@ -80,7 +80,8 @@ function skipLoader(config) { new RegExp('http(s*)://(.*?)/address/options(.*?)', 'g'), new RegExp('http(s*)://(.*?)/conversation/(.*?)/files/(.*?)', 'g'), new RegExp('http(s*)://(.*?)/llm-provider/(.*?)/models', 'g'), - new RegExp('http(s*)://(.*?)/knowledge/vector/collections', 'g') + new RegExp('http(s*)://(.*?)/knowledge/vector/collections', 'g'), + new RegExp('http(s*)://(.*?)/knowledge/vector/(.*?)/exist', 'g') ]; if (config.method === 'post' && postRegexes.some(regex => regex.test(config.url || ''))) { diff --git a/src/lib/scss/custom/pages/_chat.scss b/src/lib/scss/custom/pages/_chat.scss index e545e573..f757b389 100644 --- a/src/lib/scss/custom/pages/_chat.scss +++ b/src/lib/scss/custom/pages/_chat.scss @@ -704,6 +704,10 @@ min-width: 50px; border-radius: 10px; } + + .link-option:hover { + text-decoration: underline; + } } .complex-option-container { @@ -750,8 +754,8 @@ border-radius: 10px; } - .btn-link { - background-color: unset !important; + .link-option:hover { + text-decoration: underline; } } } diff --git a/src/lib/scss/custom/pages/_knowledgebase.scss b/src/lib/scss/custom/pages/_knowledgebase.scss index a1a00819..4249370e 100644 --- a/src/lib/scss/custom/pages/_knowledgebase.scss +++ b/src/lib/scss/custom/pages/_knowledgebase.scss @@ -66,7 +66,7 @@ } .confidence-box { - width: 40%; + width: 100%; } .input-text { @@ -375,3 +375,24 @@ } } } + + +.vector-collection-create-container { + .collection-input { + .invalid-input { + border-color: var(--bs-danger); + } + + .collection-note { + display: flex; + } + + .valid { + justify-content: flex-end; + } + + .invalid { + justify-content: space-between; + } + } +} \ No newline at end of file diff --git a/src/lib/services/api-endpoints.js b/src/lib/services/api-endpoints.js index 4329f887..3f2733e0 100644 --- a/src/lib/services/api-endpoints.js +++ b/src/lib/services/api-endpoints.js @@ -59,7 +59,8 @@ export const endpoints = { loggingStateLogUrl: `${host}/logger/conversation/{conversationId}/state-log`, // knowledge base - vectorKnowledgeCollectionsUrl: `${host}/knowledge/vector/collections`, + vectorCollectionExistUrl: `${host}/knowledge/vector/{collection}/exist`, + vectorCollectionsUrl: `${host}/knowledge/vector/collections`, vectorKnowledgePageListUrl: `${host}/knowledge/vector/{collection}/page`, vectorKnowledgeSearchUrl: `${host}/knowledge/vector/{collection}/search`, vectorKnowledgeCreateUrl: `${host}/knowledge/vector/{collection}/create`, diff --git a/src/lib/services/knowledge-base-service.js b/src/lib/services/knowledge-base-service.js index 17f7800b..78dc837f 100644 --- a/src/lib/services/knowledge-base-service.js +++ b/src/lib/services/knowledge-base-service.js @@ -2,12 +2,26 @@ import { replaceUrl } from '$lib/helpers/http.js'; import { endpoints } from './api-endpoints.js'; import axios from 'axios'; + +/** + * @param {string} collection + * @returns {Promise} + */ +export async function existVectorCollection(collection) { + const url = replaceUrl(endpoints.vectorCollectionExistUrl, { + collection: collection + }); + + const response = await axios.get(url); + return response.data; +} + /** * @param {string} type * @returns {Promise} */ export async function getVectorKnowledgeCollections(type) { - const url = endpoints.vectorKnowledgeCollectionsUrl; + const url = endpoints.vectorCollectionsUrl; const response = await axios.get(url, { params: { type: type diff --git a/src/routes/chat/[agentId]/[conversationId]/chat-box.svelte b/src/routes/chat/[agentId]/[conversationId]/chat-box.svelte index 951609da..41bd052f 100644 --- a/src/routes/chat/[agentId]/[conversationId]/chat-box.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/chat-box.svelte @@ -278,6 +278,8 @@ async function refresh() { // trigger UI render dialogs = dialogs?.map(item => { return { ...item }; }) || []; + lastBotMsg = null; + await tick(); lastBotMsg = findLastBotMessage(dialogs); lastMsg = dialogs.slice(-1)[0]; assignMessageDisclaimer(dialogs) @@ -415,6 +417,7 @@ /** @param {import('$conversationTypes').ConversationMessageDeleteModel} data */ function onConversationMessageDeleted(data) { if (!!!data?.message_id) return; + truncateDialogs(data.message_id); } @@ -863,7 +866,7 @@ } /** @param {string} messageId */ - function truncateDialogs(messageId) { + async function truncateDialogs(messageId) { const foundIdx = dialogs.findIndex(x => x.message_id === messageId); if (foundIdx < 0) return false; dialogs = dialogs.filter((x, idx) => idx < foundIdx); @@ -1137,85 +1140,85 @@
    {#each Object.entries(groupedDialogs) as [createDate, dialogGroup]} -
  • -
    - {createDate} -
    -
  • - {#each dialogGroup as message} -
  • -
    - {#if USER_SENDERS.includes(message.sender?.role)} -
    -
    {}} - on:click={() => directToLog(message.message_id)} - > -
    -
    {@html replaceNewLine(message.text)}
    +
  • +
    + {createDate} +
    +
  • + {#each dialogGroup as message} +
  • +
    + {#if USER_SENDERS.includes(message.sender?.role)} +
    +
    {}} + on:click={() => directToLog(message.message_id)} + > +
    +
    {@html replaceNewLine(message.text)}
    +
    +

    + + {utcToLocal(message.created_at, 'hh:mm A')} +

    +
    + {#if !!message.post_action_disclaimer} + + {/if} + {#if !!message.is_chat_message || !!message.has_message_files} + getConversationFiles(params.conversationId, message.message_id, FileSourceType.User)} + /> + {/if}
    -

    - - {utcToLocal(message.created_at, 'hh:mm A')} -

    + {#if !isLite} + + + + + + editMessage(e, message)}>Edit + resendMessage(e, message)}>Resend + deleteMessage(e, message.message_id)}>Delete + + + {/if} + {:else} +
    + {#if message.sender.role == UserRole.Client} + avatar + {:else} + avatar + {/if} +
    +
    + + {#if message?.message_id === lastBotMsg?.message_id} + + {/if} + {#if !!message.is_chat_message || !!message.has_message_files} + getConversationFiles(params.conversationId, message.message_id, FileSourceType.Bot)} + /> + {/if} +
    + {/if}
    - {#if !!message.post_action_disclaimer} - - {/if} - {#if !!message.is_chat_message || !!message.has_message_files} - getConversationFiles(params.conversationId, message.message_id, FileSourceType.User)} - /> - {/if} -
- {#if !isLite} - - - - - - editMessage(e, message)}>Edit - resendMessage(e, message)}>Resend - deleteMessage(e, message.message_id)}>Delete - - - {/if} - {:else} -
- {#if message.sender.role == UserRole.Client} - avatar - {:else} - avatar - {/if} -
-
- - {#if message?.message_id === lastBotMsg?.message_id} - - {/if} - {#if !!message.is_chat_message || !!message.has_message_files} - getConversationFiles(params.conversationId, message.message_id, FileSourceType.Bot)} - /> - {/if} -
- {/if} - - - {/each} + + {/each} {/each} {#if isThinking} diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-complex-options.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-complex-options.svelte index f81f3808..2142ced2 100644 --- a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-complex-options.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-complex-options.svelte @@ -72,6 +72,12 @@ */ function handleClickOption(e, option) { e.preventDefault(); + + if (option.type === ElementType.Web && option.url) { + window.open(option.url); + return; + } + innerConfirm(option?.title, option?.payload); } @@ -111,23 +117,13 @@ {#if card.options?.length > 0}
{#each card.options as option, i (i)} - {#if option.type === ElementType.Web && option.url} - - {:else} - - {/if} + {/each}
{/if} diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-plain-options.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-plain-options.svelte index c65a7a3b..81484262 100644 --- a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-plain-options.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-plain-options.svelte @@ -74,6 +74,11 @@ function handleClickOption(e, option, index) { e.preventDefault(); + if (option.type === ElementType.Web && option.url) { + window.open(option.url); + return; + } + if (!isMultiSelect) { innerConfirm(option?.title, option?.payload); } else { @@ -146,26 +151,17 @@ {#if plainOptions || fileOption}
{#each plainOptions as option, index} - {#if option.type === ElementType.Web && option.url} - - {:else} - - {/if} + + {/each} {#if plainOptions && isMultiSelect}