diff --git a/src/lib/helpers/enums.js b/src/lib/helpers/enums.js index a223b674..6007e0a0 100644 --- a/src/lib/helpers/enums.js +++ b/src/lib/helpers/enums.js @@ -164,4 +164,13 @@ const globalEvent = { Search: "search", Chat: "chat" }; -export const GlobalEvent = Object.freeze(globalEvent); \ No newline at end of file +export const GlobalEvent = Object.freeze(globalEvent); + +const llmModelType = { + Text: 1, + Chat: 2, + Image: 3, + Embedding: 4, + Audio: 5 +}; +export const LlmModelType = Object.freeze(llmModelType); \ No newline at end of file diff --git a/src/lib/helpers/http.js b/src/lib/helpers/http.js index 46799e05..e5003153 100644 --- a/src/lib/helpers/http.js +++ b/src/lib/helpers/http.js @@ -74,7 +74,8 @@ function skipLoader(config) { 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*)://(.*?)/users', 'g') + new RegExp('http(s*)://(.*?)/users', 'g'), + new RegExp('http(s*)://(.*?)/instruct/chat-completion', 'g') ]; /** @type {RegExp[]} */ diff --git a/src/lib/helpers/types/commonTypes.js b/src/lib/helpers/types/commonTypes.js index 009a8711..10a1188b 100644 --- a/src/lib/helpers/types/commonTypes.js +++ b/src/lib/helpers/types/commonTypes.js @@ -24,6 +24,19 @@ * @property {T[]} items - Items. */ +/** + * @typedef {Object} LlmConfigOption + * @property {number?} [type] + * @property {boolean?} [multiModal] + * @property {boolean?} [imageGeneration] + */ + +/** + * @typedef {Object} LlmConfig + * @property {string} provider + * @property {LlmModelSetting[]} models + */ + /** * @typedef {Object} LlmModelSetting * @property {string} name diff --git a/src/lib/helpers/types/conversationTypes.js b/src/lib/helpers/types/conversationTypes.js index 070b7b2a..577fe067 100644 --- a/src/lib/helpers/types/conversationTypes.js +++ b/src/lib/helpers/types/conversationTypes.js @@ -1,9 +1,3 @@ -/** - * @typedef {Object} InstructMessageModel - * @property {string} [instruction] - User provided prompt instead of predefined template. - * @property {string} [template] - The template name. - */ - /** * @typedef {Object} MessageConfig * @property {string} [taskId] - Optional task id. diff --git a/src/lib/helpers/types/instructTypes.js b/src/lib/helpers/types/instructTypes.js new file mode 100644 index 00000000..14054cf6 --- /dev/null +++ b/src/lib/helpers/types/instructTypes.js @@ -0,0 +1,17 @@ +/** + * @typedef {Object} InstructMessageModel + * @property {string} [instruction] - User provided prompt instead of predefined template. + * @property {string} [template] - The template name. + */ + +/** + * @typedef {Object} IncomingInstructRequest + * @property {string} text + * @property {string} [agentId] + * @property {string} [instruction] + * @property {string} [provider] + * @property {string} [model] + * @property {import('$conversationTypes').ConversationStateModel[]} [states] + */ + +export default {}; \ No newline at end of file diff --git a/src/lib/scss/app.scss b/src/lib/scss/app.scss index 604f0c2d..02692538 100644 --- a/src/lib/scss/app.scss +++ b/src/lib/scss/app.scss @@ -95,6 +95,7 @@ File: Main Css File @import "custom/pages/knowledgebase"; @import "custom/pages/users"; @import "custom/pages/roles"; +@import "custom/pages/instruction"; // Common @import "custom/common/animation"; diff --git a/src/lib/scss/custom/pages/_instruction.scss b/src/lib/scss/custom/pages/_instruction.scss new file mode 100644 index 00000000..3a06401c --- /dev/null +++ b/src/lib/scss/custom/pages/_instruction.scss @@ -0,0 +1,85 @@ +.instruction-container { + .text-count { + margin-top: 2px; + font-size: 10px; + } + + .instruction-result-container { + .instruction-result-body { + font-size: 15px; + padding: 5px 10px; + overflow-y: auto; + max-height: 500px; + scrollbar-width: thin; + } + } +} + +.instruction-border { + border: 1px dashed var(--bs-primary); + border-radius: 5px; +} + +.instruct-header { + font-size: 17px; + display: flex; + justify-content: space-between; +} + +.instruct-text-header { + font-size: 17px; + display: flex; + gap: 5px; +} + +.instruct-setting-container { + display: flex; + flex-wrap: wrap; + + .instruct-setting-section { + display: flex; + flex-direction: column; + gap: 20px; + } + + @media (max-width: 992px) { + .instruct-setting-section { + margin-top: 10px; + } + + .instruction-gap { + margin-top: 10px; + } + } + + .instruct-setting-item { + display: flex; + justify-content: center; + + .instruct-setting-dropdown { + width: 60%; + } + + @media (max-width: 992px) { + .instruct-setting-dropdown { + width: 100%; + } + } + } +} + +.instruct-setting-padding { + padding: 20px 10px; +} + +.instruct-state-container { + display: flex; + flex-direction: column; + gap: 10px; + + .instruct-state-item { + display: flex; + gap: 10px; + justify-content: center; + } +} \ No newline at end of file diff --git a/src/lib/services/api-endpoints.js b/src/lib/services/api-endpoints.js index 024db209..ddcf3e20 100644 --- a/src/lib/services/api-endpoints.js +++ b/src/lib/services/api-endpoints.js @@ -44,6 +44,7 @@ export const endpoints = { // agent instruct instructCompletionUrl: `${host}/instruct/{agentId}`, + chatCompletionUrl: `${host}/instruct/chat-completion`, // agent realtime interaction agentInitRealtimeSessionUrl: `${host}/agent/{agentId}/realtime/session`, @@ -73,6 +74,7 @@ export const endpoints = { // LLM provider llmProvidersUrl: `${host}/llm-providers`, llmProviderModelsUrl: `${host}/llm-provider/{provider}/models`, + llmConfigsUrl: `${host}/llm-configs`, // logging loggingFullLogUrl: `${host}/logger/full-log`, diff --git a/src/lib/services/instruct-service.js b/src/lib/services/instruct-service.js index b8c9963c..f9bf8ff3 100644 --- a/src/lib/services/instruct-service.js +++ b/src/lib/services/instruct-service.js @@ -5,9 +5,20 @@ import axios from 'axios'; /** * Execute agent instruction by template or user provided prompt. * @param {string} agentId - * @param {import('$conversationTypes').InstructMessageModel} instruction + * @param {import('$instructTypes').InstructMessageModel} instruction */ export async function executeAgentInstruction(agentId, instruction) { let url = replaceUrl(endpoints.instructCompletionUrl, {agentId: agentId}); await axios.post(url, instruction); -} \ No newline at end of file +} + + +/** + * Execute chat completion. + * @param {import('$instructTypes').IncomingInstructRequest} request + */ +export async function sendChatCompletion(request) { + const url = endpoints.chatCompletionUrl; + const response = await axios.post(url, request); + return response.data; +} diff --git a/src/lib/services/llm-provider-service.js b/src/lib/services/llm-provider-service.js index 025ab061..7d15c608 100644 --- a/src/lib/services/llm-provider-service.js +++ b/src/lib/services/llm-provider-service.js @@ -21,4 +21,24 @@ export async function getLlmProviderModels(provider) { let url = replaceUrl(endpoints.llmProviderModelsUrl, {provider: provider}); const response = await axios.get(url); return response.data; +} + + +/** + * Get llm configs + * @param {import('$commonTypes').LlmConfigOption?} [options] + * @returns {Promise} + */ +export async function getLlmConfigs(options = null) { + const url = endpoints.llmConfigsUrl; + const response = await axios.get(url, { + params: { + options: options + }, + paramsSerializer: { + dots: true, + indexes: null, + } + }); + return response.data; } \ No newline at end of file diff --git a/src/routes/page/conversation/state-search.svelte b/src/routes/page/conversation/state-search.svelte index 9067ace2..7296ae1f 100644 --- a/src/routes/page/conversation/state-search.svelte +++ b/src/routes/page/conversation/state-search.svelte @@ -53,7 +53,7 @@ placeholder="Enter a value" /> -
+
diff --git a/src/routes/page/instruction/+page.svelte b/src/routes/page/instruction/+page.svelte new file mode 100644 index 00000000..33c42a57 --- /dev/null +++ b/src/routes/page/instruction/+page.svelte @@ -0,0 +1,262 @@ + + + + + + +
+
+
+