diff --git a/src/lib/helpers/types/agentTypes.js b/src/lib/helpers/types/agentTypes.js index 8d344d03..b68a9b0d 100644 --- a/src/lib/helpers/types/agentTypes.js +++ b/src/lib/helpers/types/agentTypes.js @@ -49,7 +49,8 @@ * @property {boolean} allow_routing * @property {string} icon_url - Icon * @property {string[]} profiles - The agent profiles. - * @property {string[]} utilities - The agent utilities. + * @property {boolean} merge_utility - Merge utility + * @property {AgentUtility[]} utilities - The agent utilities. * @property {Date} created_datetime * @property {Date} updated_datetime * @property {AgentLlmConfig} llm_config - LLM settings. @@ -59,10 +60,7 @@ * @property {Object[]} responses * @property {RoutingRule[]} routing_rules * @property {AgentWelcomeInfo} welcome_info - Welcome information. - * @property {boolean} editable - * @property {boolean} chatable - * @property {boolean} trainable - * @property {boolean} evaluable + * @property {string[]?} [actions] */ @@ -119,4 +117,17 @@ */ +/** + * @typedef {Object} AgentUtility + * @property {string} name + * @property {boolean} disabled + * @property {UtilityBase[]} functions + * @property {UtilityBase[]} templates + */ + +/** + * @typedef {Object} UtilityBase + * @property {string} name + */ + export default {}; \ No newline at end of file diff --git a/src/lib/helpers/utils/agent.js b/src/lib/helpers/utils/agent.js new file mode 100644 index 00000000..143e42ec --- /dev/null +++ b/src/lib/helpers/utils/agent.js @@ -0,0 +1,44 @@ +import { UserAction } from '../enums'; + +export const AgentExtensions = { + chatable: (/** @type {import('$agentTypes').AgentModel} */ agent) => { + if (agent == null || agent.id == null) { + return false; + } + + if (agent.actions == null) { + return true; + } + return agent.actions.includes(UserAction.Chat); + }, + editable: (/** @type {import('$agentTypes').AgentModel} */ agent) => { + if (agent == null || agent.id == null) { + return false; + } + + if (agent.actions == null) { + return true; + } + return agent.actions.includes(UserAction.Edit); + }, + trainable: (/** @type {import('$agentTypes').AgentModel} */ agent) => { + if (agent == null || agent.id == null) { + return false; + } + + if (agent.actions == null) { + return true; + } + return agent.actions.includes(UserAction.Train); + }, + evaluable: (/** @type {import('$agentTypes').AgentModel} */ agent) => { + if (agent == null || agent.id == null) { + return false; + } + + if (agent.actions == null) { + return true; + } + return agent.actions.includes(UserAction.Edit); + }, +}; \ No newline at end of file diff --git a/src/lib/helpers/utils/chat.js b/src/lib/helpers/utils/chat.js index 165548df..33a362bf 100644 --- a/src/lib/helpers/utils/chat.js +++ b/src/lib/helpers/utils/chat.js @@ -12,15 +12,4 @@ export function sendToChatBot(action, chatFrameId, text = null, data = null) { // @ts-ignore chatFrame.contentWindow.postMessage(content, "*"); } -} - -/** - * @param {() => void} func - */ -export function addChatBoxMountEventListener(func) { - window.addEventListener("message", e => { - if (e.data.event === 'chat-box-mounted') { - func(); - } - }); } \ No newline at end of file diff --git a/src/lib/scss/custom/pages/_agent.scss b/src/lib/scss/custom/pages/_agent.scss index 9ae91149..2845446e 100644 --- a/src/lib/scss/custom/pages/_agent.scss +++ b/src/lib/scss/custom/pages/_agent.scss @@ -37,7 +37,6 @@ i { cursor: pointer; - font-size: 18px; color: red; } } @@ -102,4 +101,91 @@ } } } +} + +.agent-utility-container { + display: flex; + flex-direction: column; + gap: 10px; + + .merge-utility { + display: flex; + gap: 3px; + + input { + outline: none !important; + box-shadow: none !important; + } + } + + .utility-wrapper { + border: 1px dotted var(--bs-primary); + border-radius: 5px; + padding: 10px; + + .utility-row { + + .utility-label { + width: 30%; + } + + .utility-value { + width: 70%; + display: flex; + gap: 5px; + + .add-list { + font-size: 20px; + } + } + + .utility-input { + width: 95%; + } + + .utility-delete { + width: 5%; + } + } + + .utility-row-primary { + display: flex; + + .utility-label { + display: flex; + gap: 10px; + + .utility-tooltip { + display: flex; + } + + input { + outline: none !important; + box-shadow: none !important; + } + } + } + + .utility-row-secondary { + display: flex; + flex-direction: column; + + .utility-content { + display: flex; + flex-direction: column; + gap: 3px; + border-top: 1px dotted var(--bs-primary); + margin-top: 10px; + padding-top: 10px; + + .utility-list-item { + display: flex; + + .utility-label { + font-size: 12px; + } + } + } + } + } } \ No newline at end of file diff --git a/src/lib/scss/custom/pages/_chat.scss b/src/lib/scss/custom/pages/_chat.scss index b9835833..e537165c 100644 --- a/src/lib/scss/custom/pages/_chat.scss +++ b/src/lib/scss/custom/pages/_chat.scss @@ -534,7 +534,6 @@ .log-collapse { overflow-y: hidden; height: fit-content; - min-height: 100px; max-height: 200px; display: -webkit-box; -webkit-box-orient: vertical; diff --git a/src/lib/services/agent-service.js b/src/lib/services/agent-service.js index bd121bbd..7005546a 100644 --- a/src/lib/services/agent-service.js +++ b/src/lib/services/agent-service.js @@ -84,10 +84,10 @@ export async function createAgent(agent) { /** * Get agent utilities - * @returns {Promise} + * @returns {Promise} */ -export async function getAgentUtilities() { - const url = endpoints.agentUtilitiesUrl; +export async function getAgentUtilityOptions() { + const url = endpoints.agentUtilityOptionsUrl; const response = await axios.get(url); return response.data; } \ No newline at end of file diff --git a/src/lib/services/api-endpoints.js b/src/lib/services/api-endpoints.js index 85ac8c79..d5ebc3ba 100644 --- a/src/lib/services/api-endpoints.js +++ b/src/lib/services/api-endpoints.js @@ -33,7 +33,7 @@ export const endpoints = { agentDetailUrl: `${host}/agent/{id}`, agentRefreshUrl: `${host}/refresh-agents`, agentCreateUrl: `${host}/agent`, - agentUtilitiesUrl: `${host}/agent/utilities`, + agentUtilityOptionsUrl: `${host}/agent/utility/options`, // agent task agentTaskListUrl: `${host}/agent/tasks`, diff --git a/src/routes/chat/[agentId]/[conversationId]/chat-box.svelte b/src/routes/chat/[agentId]/[conversationId]/chat-box.svelte index c9ceba1a..8220910d 100644 --- a/src/routes/chat/[agentId]/[conversationId]/chat-box.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/chat-box.svelte @@ -53,12 +53,13 @@ import LoadingDots from '$lib/common/LoadingDots.svelte'; import StateModal from '$lib/common/StateModal.svelte'; import LoadingToComplete from '$lib/common/LoadingToComplete.svelte'; - import ChatTextArea from './chat-util/chat-text-area.svelte'; import AudioSpeaker from '$lib/common/audio-player/AudioSpeaker.svelte'; + import { AgentExtensions } from '$lib/helpers/utils/agent'; import { utcToLocal } from '$lib/helpers/datetime'; import { replaceNewLine } from '$lib/helpers/http'; import { isAudio, isExcel, isPdf } from '$lib/helpers/utils/file'; import { ChatAction, ConversationTag, EditorType, FileSourceType, SenderAction, UserRole } from '$lib/helpers/enums'; + import ChatTextArea from './chat-util/chat-text-area.svelte'; import RichContent from './rich-content/rich-content.svelte'; import RcMessage from "./rich-content/rc-message.svelte"; import RcDisclaimer from './rich-content/rc-disclaimer.svelte'; @@ -203,7 +204,7 @@ } $: { - disableAction = !ADMIN_ROLES.includes(currentUser?.role || '') && currentUser?.id !== conversationUser?.id || !agent?.chatable; + disableAction = !ADMIN_ROLES.includes(currentUser?.role || '') && currentUser?.id !== conversationUser?.id || !AgentExtensions.chatable(agent); } setContext('chat-window-context', { @@ -1657,7 +1658,7 @@ text={message?.rich_content?.message?.text || message?.text} /> {/if} - {#if PUBLIC_LIVECHAT_ENABLE_TRAINING === 'true' && agent?.trainable} + {#if PUBLIC_LIVECHAT_ENABLE_TRAINING === 'true' && AgentExtensions.trainable(agent)} {#if message?.function}
diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rich-content.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rich-content.svelte index ea470f28..5db267eb 100644 --- a/src/routes/chat/[agentId]/[conversationId]/rich-content/rich-content.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rich-content.svelte @@ -32,9 +32,8 @@ isMultiSelect = true; } else if (richType === RichType.Generic) { options = message?.rich_content?.message?.elements; - isComplexElement = true; // @ts-ignore - // isComplexElement = message?.rich_content?.message?.elements?.some(x => x.buttons?.length > 0) || false; + isComplexElement = message?.rich_content?.message?.elements?.some(x => x.buttons?.length > 0) || false; } else if (message?.rich_content?.editor === EditorType.File) { options = message?.rich_content?.message?.buttons; } diff --git a/src/routes/page/agent/[agentId]/+page.svelte b/src/routes/page/agent/[agentId]/+page.svelte index 84cc4bd0..89421c4d 100644 --- a/src/routes/page/agent/[agentId]/+page.svelte +++ b/src/routes/page/agent/[agentId]/+page.svelte @@ -18,6 +18,8 @@ import { _ } from 'svelte-i18n' import Swal from 'sweetalert2' import { goto } from '$app/navigation'; + import AgentUtility from './agent-utility.svelte'; + import { AgentExtensions } from '$lib/helpers/utils/agent'; /** @type {import('$agentTypes').AgentModel} */ @@ -26,6 +28,8 @@ let agentFunctionCmp = null; /** @type {any} */ let agentPromptCmp = null; + /** @type {any} */ + let agentUtilityCmp = null; /** @type {boolean} */ let isLoading = false; @@ -65,6 +69,7 @@ function handleAgentUpdate() { fetchJsonContent(); fetchPrompts(); + fetchUtilties(); agent = { ...agent, @@ -72,7 +77,7 @@ instruction: agent.instruction || '', channel_instructions: agent.channel_instructions || [], profiles: agent.profiles?.filter((x, idx, self) => x?.trim()?.length > 0 && self.indexOf(x) === idx) || [], - utilities: agent.utilities?.filter((x, idx, self) => x?.trim()?.length > 0 && self.indexOf(x) === idx) || [] + utilities: agent.utilities || [] }; isLoading = true; saveAgent(agent).then(res => { @@ -110,6 +115,11 @@ agent.channel_instructions = obj.channelPrompts || []; } + function fetchUtilties() { + const list = agentUtilityCmp?.fetchUtilities(); + agent.utilities = list || []; + } + function refreshChannelPrompts() { agentPromptCmp?.refreshChannelPrompts(); } @@ -145,15 +155,17 @@
- +
-
{#if agent.routing_rules?.length > 0} {/if}
+
+ +
@@ -165,7 +177,7 @@ - {#if !!agent?.editable} + {#if !!AgentExtensions.editable(agent)}
diff --git a/src/routes/page/agent/[agentId]/agent-llm-config.svelte b/src/routes/page/agent/[agentId]/agent-llm-config.svelte index 26db5c79..9dbb3dab 100644 --- a/src/routes/page/agent/[agentId]/agent-llm-config.svelte +++ b/src/routes/page/agent/[agentId]/agent-llm-config.svelte @@ -1,8 +1,8 @@ + + + +
+
Utilities
+
+ +
+
+ toggleMergeUtility(e)} + /> +
+ Merge utilities +
+
+ +
+
+ + {#each innerUtilities as utility, uid (uid)} +
+
+
+
{`Utility #${uid + 1}`}
+
+
+ toggleUtility(e, uid)} + /> +
+
+ +
+
+
+
+
+ changeUtility(e, uid)} + > + {#each utilityOptions as option} + + {/each} + +
+
+ {}} + on:click={() => deleteUtility(uid)} + /> +
+
+
+ +
+
+ {#each utility.functions as fn, fid (fid)} +
+
+ {fid === 0 ? 'Functions' : ''} +
+
+
+ selectContent(e, uid, fid, 'function')} + > + {#each (utilityMapper[utility.name]?.functions || []) as option} + + {/each} + +
+
+ {}} + on:click={() => deleteUtilityContent(uid, fid, 'function')} + /> +
+
+
+ {/each} + + {#if utility.functions?.length < limit} +
+
+ {utility.functions.length === 0 ? 'Functions' : ''} +
+
+ {}} + on:click={() => addUtilityContent(uid, 'function')} + /> +
+
+ {/if} +
+ +
+ {#each utility.templates as tp, tid (tid)} +
+
+ {tid === 0 ? 'Templates' : ''} +
+
+
+ selectContent(e, uid, tid, 'template')} + > + {#each (utilityMapper[utility.name]?.templates || []) as option} + + {/each} + +
+
+ {}} + on:click={() => deleteUtilityContent(uid, tid, 'template')} + /> +
+
+
+ {/each} + + {#if utility.templates?.length < limit} +
+
+ {utility.templates.length === 0 ? 'Templates' : ''} +
+
+ {}} + on:click={() => addUtilityContent(uid, 'template')} + /> +
+
+ {/if} +
+
+
+ {/each} + + {#if innerUtilities.length < limit} +
+ +
+ {/if} +
+
+
\ No newline at end of file diff --git a/src/routes/page/agent/card-agent.svelte b/src/routes/page/agent/card-agent.svelte index 831639e9..0c4db673 100644 --- a/src/routes/page/agent/card-agent.svelte +++ b/src/routes/page/agent/card-agent.svelte @@ -4,6 +4,7 @@ import { format } from '$lib/helpers/datetime'; import { _ } from 'svelte-i18n'; import { LEARNER_ID } from "$lib/helpers/constants"; + import { AgentExtensions } from "$lib/helpers/utils/agent"; /** @type {import('$agentTypes').AgentModel[]} */ export let agents; @@ -78,7 +79,7 @@
  • - + {$_('Test')}
  • diff --git a/src/routes/page/roles/+page.svelte b/src/routes/page/roles/+page.svelte index 344ad98b..0d29eea1 100644 --- a/src/routes/page/roles/+page.svelte +++ b/src/routes/page/roles/+page.svelte @@ -121,7 +121,7 @@ isComplete = false; }, duration); } else { - throw "error when saving user."; + throw "error when saving role."; } }).catch(() => { isLoading = false;