diff --git a/src/lib/common/StateModal.svelte b/src/lib/common/StateModal.svelte index 271993c2..6a8e7ebb 100644 --- a/src/lib/common/StateModal.svelte +++ b/src/lib/common/StateModal.svelte @@ -201,7 +201,7 @@ remove(idx)} /> diff --git a/src/lib/common/StateSearch.svelte b/src/lib/common/StateSearch.svelte index 9f041ca7..17c681cf 100644 --- a/src/lib/common/StateSearch.svelte +++ b/src/lib/common/StateSearch.svelte @@ -58,7 +58,7 @@ removeState(idx)} /> diff --git a/src/lib/helpers/constants.js b/src/lib/helpers/constants.js index 1b21bac0..eabcaec6 100644 --- a/src/lib/helpers/constants.js +++ b/src/lib/helpers/constants.js @@ -37,10 +37,12 @@ export const FILE_EDITORS = [ EditorType.File ]; -export const LEARNER_ID = "01acc3e5-0af7-49e6-ad7a-a760bd12dc40"; -export const EVALUATOR_ID = "2cd4b805-7078-4405-87e9-2ec9aadf8a11"; -export const TRAINING_MODE = "training"; +export const LEARNER_AGENT_ID = "01acc3e5-0af7-49e6-ad7a-a760bd12dc40"; +export const EVALUATOR_AGENT_ID = "2cd4b805-7078-4405-87e9-2ec9aadf8a11"; +export const AI_PROGRAMMER_AGENT_ID = "c2a2faf6-b8b5-47fe-807b-f4714cf25dd4"; +export const RULE_TRIGGER_CODE_GENERATE_TEMPLATE = "rule-trigger-code-generate_instruction"; +export const TRAINING_MODE = "training"; export const DEFAULT_KNOWLEDGE_COLLECTION = "BotSharp"; export const IMAGE_DATA_PREFIX = 'data:image'; diff --git a/src/lib/helpers/http.js b/src/lib/helpers/http.js index 8e470866..19e8bc21 100644 --- a/src/lib/helpers/http.js +++ b/src/lib/helpers/http.js @@ -75,7 +75,8 @@ function skipLoader(config) { new RegExp('http(s*)://(.*?)/knowledge/document/(.*?)/page', 'g'), new RegExp('http(s*)://(.*?)/users', 'g'), new RegExp('http(s*)://(.*?)/instruct/chat-completion', 'g'), - new RegExp('http(s*)://(.*?)/agent/(.*?)/code-scripts', 'g') + new RegExp('http(s*)://(.*?)/agent/(.*?)/code-scripts', 'g'), + new RegExp('http(s*)://(.*?)/agent/(.*?)/code-script/generate', 'g') ]; /** @type {RegExp[]} */ @@ -111,7 +112,8 @@ function skipLoader(config) { new RegExp('http(s*)://(.*?)/logger/instruction/log/keys', 'g'), new RegExp('http(s*)://(.*?)/logger/conversation/(.*?)/content-log', 'g'), new RegExp('http(s*)://(.*?)/logger/conversation/(.*?)/state-log', 'g'), - new RegExp('http(s*)://(.*?)/mcp/server-configs', 'g') + new RegExp('http(s*)://(.*?)/mcp/server-configs', 'g'), + new RegExp('http(s*)://(.*?)/agent/(.*?)/code-scripts', 'g') ]; if (config.method === 'post' && postRegexes.some(regex => regex.test(config.url || ''))) { diff --git a/src/lib/helpers/types/agentTypes.js b/src/lib/helpers/types/agentTypes.js index d3fb5a06..be941c2a 100644 --- a/src/lib/helpers/types/agentTypes.js +++ b/src/lib/helpers/types/agentTypes.js @@ -135,6 +135,31 @@ * @property {AgentCodeScriptUpdateOptions?} [options] */ +/** + * @typedef {Object} AgentCodeScriptGenerateModel + * @property {string?} [text] + * @property {CodeProcessOptions?} [options] + */ + +/** + * @typedef {Object} CodeProcessOptions + * @property {boolean?} [save_to_db] - Whether to save the generated code to database. + * @property {string?} [script_name] - The code script name. + * @property {string?} [script_type] - The code script type. + * @property {string?} [agent_id] - The agent id. + * @property {string?} [template_name] - The template name. + * @property {any?} [data] - The template data. + * @property {string?} [provider] - The llm provider. + * @property {string?} [model] - The llm model. + */ + +/** + * @typedef {Object} CodeGenerationResult + * @property {boolean?} [success] + * @property {string?} [content] + * @property {string?} [language] + * @property {string?} [error_message] + */ /** * @typedef {Object} ChannelInstruction @@ -204,6 +229,9 @@ * @property {string} criteria * @property {string?} [displayName] * @property {boolean} disabled + * @property {any?} [output_args] + * @property {string?} [json_args] + * @property {string?} [statement] */ diff --git a/src/lib/helpers/types/instructTypes.js b/src/lib/helpers/types/instructTypes.js index c60cd137..b6ed4b3f 100644 --- a/src/lib/helpers/types/instructTypes.js +++ b/src/lib/helpers/types/instructTypes.js @@ -6,6 +6,7 @@ * @property {string?} [provider] - The LLM provider. * @property {string?} [model] - The LLM model. * @property {import('$conversationTypes').ConversationStateModel[]} [states] + * @property {CodeInstructOptions?} [codeOptions] */ /** @@ -59,4 +60,12 @@ * @property {string?} [endTime] */ +/** + * @typedef {Object} CodeInstructOptions + * @property {string?} [processor] - The code processor. + * @property {string?} [script_name] - The code script name. + * @property {string?} [script_type] - The code script type: src or test. + * @property {{key: string, value: string}[]?} [arguments] - The arguments. + */ + export default {}; \ No newline at end of file diff --git a/src/lib/helpers/utils/common.js b/src/lib/helpers/utils/common.js index 5b263aa7..e6170626 100644 --- a/src/lib/helpers/utils/common.js +++ b/src/lib/helpers/utils/common.js @@ -143,6 +143,21 @@ export function goToUrl(url, opts = {}) { goto(url, { replaceState, noScroll }); } +/** + * @param {HTMLElement | null | undefined} container + * @param {ScrollBehavior} behavior + */ +export function scrollToBottom(container, behavior = 'smooth') { + if (container) { + setTimeout(() => { + container.scrollTo({ + top: container.scrollHeight, + behavior: behavior + }); + }, 0); + } +} + /** * @param {string} str */ diff --git a/src/lib/scss/custom/pages/_agent.scss b/src/lib/scss/custom/pages/_agent.scss index c5396a2b..afa4c72d 100644 --- a/src/lib/scss/custom/pages/_agent.scss +++ b/src/lib/scss/custom/pages/_agent.scss @@ -58,7 +58,7 @@ } } } - + .list-add { font-size: 20px; @@ -94,10 +94,10 @@ @media (max-width: 423px) { height: fit-content; } - + .agent-prompt-container { height: 100%; - + .agent-prompt-header { background-color: white; padding: 15px; @@ -147,6 +147,22 @@ padding: 10px; border: 1px dashed var(--bs-primary); border-radius: 5px; + + .llm-config-item { + display: flex; + flex-wrap: wrap; + + .llm-config-label { + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; + flex: 0.25; + } + + .llm-config-input { + flex: 0.75; + } + } } .agent-utility-container { @@ -167,7 +183,7 @@ box-shadow: none !important; } } - + .utility-wrapper { border: 1px dotted var(--bs-primary); border-radius: 5px; @@ -262,12 +278,17 @@ .tooltip-inner { text-align: start; max-width: fit-content; - padding: 20px; + padding: 5px 10px; } .markdown-div { max-height: 500px; font-size: 15px; + + pre { + white-space: pre !important; + width: fit-content; + } } &.show { @@ -286,4 +307,61 @@ overflow-x: auto; scrollbar-width: thin; } -} \ No newline at end of file +} + +// Responsive adjustments for utility +@media (max-width: 1250px) { + .agent-config-container { + .llm-config-item { + flex-direction: column; + + .llm-config-label { + width: 100%; + } + + .llm-config-input { + width: 100%; + } + } + } + + .agent-utility-container { + padding: 0 5px; + + .utility-wrapper { + .utility-row-primary { + flex-direction: column; + } + + .utility-row { + .utility-label, .utility-value { + width: 100%; + } + + .utility-value { + flex-direction: column; + } + + .utility-input, .utility-delete { + width: 100%; + } + + .utility-delete { + display: flex; + justify-content: flex-end; + align-items: end; + margin-top: 6px; + } + } + + .utility-row-secondary { + .utility-content { + .utility-list-item { + flex-direction: column; + gap: 6px; + } + } + } + } + } +} diff --git a/src/lib/scss/custom/pages/_instruction.scss b/src/lib/scss/custom/pages/_instruction.scss index e6ad36b8..46d44ae9 100644 --- a/src/lib/scss/custom/pages/_instruction.scss +++ b/src/lib/scss/custom/pages/_instruction.scss @@ -57,7 +57,7 @@ justify-content: center; .instruct-setting-dropdown { - width: 60%; + width: 75%; } @media (max-width: 992px) { @@ -72,12 +72,16 @@ padding: 20px 10px; } -.instruct-state-container { +.instruct-kv-container { display: flex; flex-direction: column; gap: 10px; + max-height: 200px; + overflow-y: auto; + scrollbar-width: none; + padding-top: 20px; - .instruct-state-item { + .instruct-kv-item { display: flex; gap: 30px; justify-content: center; diff --git a/src/lib/scss/custom/pages/_knowledgebase.scss b/src/lib/scss/custom/pages/_knowledgebase.scss index 213f3247..1c683c41 100644 --- a/src/lib/scss/custom/pages/_knowledgebase.scss +++ b/src/lib/scss/custom/pages/_knowledgebase.scss @@ -22,7 +22,7 @@ } .demo-tooltip-icon { - font-size: 18px; + font-size: 15px; } .demo-tooltip-note { diff --git a/src/lib/services/agent-service.js b/src/lib/services/agent-service.js index d4d87e7b..4b6d0995 100644 --- a/src/lib/services/agent-service.js +++ b/src/lib/services/agent-service.js @@ -156,4 +156,18 @@ export async function updateAgentCodeScripts(agentId, update) { ...update }); return response.data; +} + +/** + * Generate agent code script + * @param {string} agentId + * @param {import('$agentTypes').AgentCodeScriptGenerateModel} request + * @returns {Promise} + */ +export async function generateAgentCodeScript(agentId, request) { + const url = endpoints.agentCodeScriptGenerateUrl.replace("{agentId}", agentId); + const response = await axios.post(url, { + ...request + }); + 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 1ee3cc59..17b81a9b 100644 --- a/src/lib/services/api-endpoints.js +++ b/src/lib/services/api-endpoints.js @@ -41,6 +41,7 @@ export const endpoints = { // agent code script: agentCodeScriptListUrl: `${host}/agent/{agentId}/code-scripts`, agentCodeScriptUpdateUrl: `${host}/agent/{agentId}/code-scripts`, + agentCodeScriptGenerateUrl: `${host}/agent/{agentId}/code-script/generate`, // agent task agentTaskListUrl: `${host}/agent/tasks`, diff --git a/src/routes/chat/[agentId]/+page.svelte b/src/routes/chat/[agentId]/+page.svelte index b6b11eed..857aefdf 100644 --- a/src/routes/chat/[agentId]/+page.svelte +++ b/src/routes/chat/[agentId]/+page.svelte @@ -1,14 +1,13 @@ @@ -215,14 +205,14 @@ on:change={e => toggleKnowledgeBase(e, uid)} /> -
- -
+ + -->
@@ -241,7 +231,7 @@
{}} diff --git a/src/routes/page/agent/[agentId]/agent-components/agent-mcp-tool.svelte b/src/routes/page/agent/[agentId]/agent-components/agent-mcp-tool.svelte index 3bb4fe71..d85f5624 100644 --- a/src/routes/page/agent/[agentId]/agent-components/agent-mcp-tool.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/agent-mcp-tool.svelte @@ -2,6 +2,7 @@ import { onMount } from 'svelte'; import { Card, CardBody, Input, Button } from '@sveltestrap/sveltestrap'; import { getServerConfigs } from '$lib/services/mcp-service'; + import { scrollToBottom } from '$lib/helpers/utils/common'; const limit = 100; @@ -134,7 +135,7 @@ functions: [] } ]; - scrollToBottom(); + scrollToBottom(scrollContainer); handleAgentChange(); } @@ -211,17 +212,6 @@ innerRefresh(innerMcps); handleAgentChange(); } - - function scrollToBottom() { - if (scrollContainer) { - setTimeout(() => { - scrollContainer.scrollTo({ - top: scrollContainer.scrollHeight, - behavior: 'smooth' - }); - }, 0); - } - } @@ -245,14 +235,14 @@ on:change={e => toggleMcp(e, uid)} />
-
-
+ -->
@@ -271,7 +261,7 @@
{}} @@ -321,7 +311,7 @@
{}} @@ -339,7 +329,7 @@
{}} diff --git a/src/routes/page/agent/[agentId]/agent-components/agent-rule.svelte b/src/routes/page/agent/[agentId]/agent-components/agent-rule.svelte index 3f6d3b92..da5689d0 100644 --- a/src/routes/page/agent/[agentId]/agent-components/agent-rule.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/agent-rule.svelte @@ -1,14 +1,39 @@ + resizeWindow()}/> + + +
@@ -180,14 +289,33 @@ on:change={e => toggleRule(e, uid)} />
-
- + {#if rule.statement} +
+ + + +
+ {/if}
@@ -206,7 +334,7 @@
{}} @@ -220,19 +348,69 @@
- {'Criteria'} +
+
+ {'Criteria'} +
+ {#if ADMIN_ROLES.includes(user?.role || '') && !!rule.trigger_name && !!rule.criteria?.trim()} +
+ {}} + on:click={() => compileCodeScript(rule)} + /> +
+ {/if} +
changeContent(e, uid, 'criteria')} />
-
+
+ {#if rule.json_args} +
+ + + + +
+ {/if} +
diff --git a/src/routes/page/agent/[agentId]/agent-components/agent-utility.svelte b/src/routes/page/agent/[agentId]/agent-components/agent-utility.svelte index 06230fea..40510dcb 100644 --- a/src/routes/page/agent/[agentId]/agent-components/agent-utility.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/agent-utility.svelte @@ -2,9 +2,9 @@ import { onMount } from 'svelte'; import { Card, CardBody, Input, Button } from '@sveltestrap/sveltestrap'; import { getAgentUtilityOptions } from '$lib/services/agent-service'; - import { truncateByPrefix } from '$lib/helpers/utils/common'; + import { scrollToBottom, truncateByPrefix } from '$lib/helpers/utils/common'; import Markdown from '$lib/common/markdown/Markdown.svelte'; - import BotSharpTooltip from '$lib/common/tooltip/BotSharpTooltip.svelte'; + import BotsharpTooltip from '$lib/common/tooltip/BotsharpTooltip.svelte'; const limit = 100; const prefix = "util-"; @@ -130,7 +130,7 @@ items: [] } ]; - scrollToBottom(); + scrollToBottom(scrollContainer); handleAgentChange(); } @@ -272,17 +272,6 @@ innerRefresh(innerUtilities); handleAgentChange(); } - - function scrollToBottom() { - if (scrollContainer) { - setTimeout(() => { - scrollContainer.scrollTo({ - top: scrollContainer.scrollHeight, - behavior: 'smooth' - }); - }, 0); - } - } resizeWindow()}/> @@ -311,7 +300,7 @@ data-bs-placement="top" title="Merge with entry agent utilities" > - +
{/if} @@ -332,14 +321,14 @@ on:change={e => toggleUtility(e, uid)} /> -
- -
+ + -->
@@ -359,7 +348,7 @@
{}} @@ -383,8 +372,8 @@ - - +
{/if} @@ -474,7 +462,7 @@
{}} @@ -499,7 +487,7 @@
{}} diff --git a/src/routes/page/agent/[agentId]/agent-components/llm-configs/chat-config.svelte b/src/routes/page/agent/[agentId]/agent-components/llm-configs/chat-config.svelte index 866d44b8..4940300c 100644 --- a/src/routes/page/agent/[agentId]/agent-components/llm-configs/chat-config.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/llm-configs/chat-config.svelte @@ -129,20 +129,20 @@
-
Chat
+
Chat
{#if agent.llm_config?.is_inherit} -
+
Inherited
{/if}
-
-