From 6a57878ff47ce104db51330763e231fc29a56fd8 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Tue, 1 Apr 2025 14:36:38 -0500 Subject: [PATCH 1/2] add mcp tool config --- src/lib/helpers/http.js | 3 +- src/lib/helpers/types/agentTypes.js | 19 +- src/lib/helpers/types/commonTypes.js | 6 + src/lib/helpers/types/mcpTypes.js | 8 + src/lib/services/api-endpoints.js | 4 +- src/lib/services/mcp-service.js | 12 + src/routes/page/agent/[agentId]/+page.svelte | 4 +- .../agent-components/agent-instruction.svelte | 9 +- .../agent-knowledge-base.svelte | 6 +- .../agent-components/agent-mcp-tool.svelte | 350 ++++++++++++++++++ .../agent-components/agent-overview.svelte | 12 +- .../agent-components/agent-rule.svelte | 6 +- .../agent-components/agent-template.svelte | 9 +- .../agent-components/agent-utility.svelte | 31 +- .../page/agent/[agentId]/agent-tabs.svelte | 20 +- svelte.config.js | 3 +- 16 files changed, 458 insertions(+), 44 deletions(-) create mode 100644 src/lib/helpers/types/mcpTypes.js create mode 100644 src/lib/services/mcp-service.js create mode 100644 src/routes/page/agent/[agentId]/agent-components/agent-mcp-tool.svelte diff --git a/src/lib/helpers/http.js b/src/lib/helpers/http.js index 0a6c09a0..772494bc 100644 --- a/src/lib/helpers/http.js +++ b/src/lib/helpers/http.js @@ -110,7 +110,8 @@ function skipLoader(config) { new RegExp('http(s*)://(.*?)/conversation/state/keys', 'g'), 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*)://(.*?)/logger/conversation/(.*?)/state-log', 'g'), + new RegExp('http(s*)://(.*?)/mcp/server-configs', '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 34b06f1f..161ec9b4 100644 --- a/src/lib/helpers/types/agentTypes.js +++ b/src/lib/helpers/types/agentTypes.js @@ -57,6 +57,7 @@ * @property {boolean} merge_utility - Merge utility * @property {number?} [max_message_count] * @property {AgentUtility[]} utilities - The agent utilities. + * @property {any[]} mcp_tools - The agent mcp tools * @property {AgentKnowledgeBase[]} knowledge_bases - The agent knowledge bases. * @property {Date} created_datetime * @property {Date} updated_datetime @@ -131,8 +132,16 @@ * @typedef {Object} AgentUtility * @property {string} name * @property {boolean} disabled - * @property {UtilityBase[]} functions - * @property {UtilityBase[]} templates + * @property {import('$commonTypes').NameBase[]} functions + * @property {import('$commonTypes').NameBase[]} templates + */ + +/** + * @typedef {Object} AgentMcpTool + * @property {string} name + * @property {string} server_id + * @property {boolean} disabled + * @property {import('$commonTypes').NameBase[]} functions */ /** @@ -152,12 +161,6 @@ * @property {boolean} disabled */ -/** - * @typedef {Object} UtilityBase - * @property {string} name - * @property {string?} [displayName] - */ - /** * @typedef {Object} AgentTaskSearchOption diff --git a/src/lib/helpers/types/commonTypes.js b/src/lib/helpers/types/commonTypes.js index e4125825..de0db5a0 100644 --- a/src/lib/helpers/types/commonTypes.js +++ b/src/lib/helpers/types/commonTypes.js @@ -58,4 +58,10 @@ * @property {any} payload */ +/** + * @typedef {Object} NameBase + * @property {string} name + * @property {string?} [displayName] + */ + export default {}; \ No newline at end of file diff --git a/src/lib/helpers/types/mcpTypes.js b/src/lib/helpers/types/mcpTypes.js new file mode 100644 index 00000000..58a16afe --- /dev/null +++ b/src/lib/helpers/types/mcpTypes.js @@ -0,0 +1,8 @@ +/** + * @typedef {Object} McpServerConfigModel + * @property {string} id - The server id. + * @property {string} name - The server name. + * @property {string} transportType - The transport type. + */ + +export default {}; \ No newline at end of file diff --git a/src/lib/services/api-endpoints.js b/src/lib/services/api-endpoints.js index 170df44e..1028d860 100644 --- a/src/lib/services/api-endpoints.js +++ b/src/lib/services/api-endpoints.js @@ -112,6 +112,8 @@ export const endpoints = { dashConversationInstructionUrl: `${host}/dashboard/component/conversation`, // Google geocode api - addressUrl: `${host}/address/options` + addressUrl: `${host}/address/options`, + + mcpServerConfigsUrl: `${host}/mcp/server-configs` } diff --git a/src/lib/services/mcp-service.js b/src/lib/services/mcp-service.js new file mode 100644 index 00000000..449c342d --- /dev/null +++ b/src/lib/services/mcp-service.js @@ -0,0 +1,12 @@ +import { endpoints } from '$lib/services/api-endpoints.js'; +import axios from 'axios'; + +/** + * Get mcp server configs + * @returns {Promise} + */ +export async function getServerConfigs() { + const url = endpoints.mcpServerConfigsUrl; + const response = await axios.get(url); + return response.data; +} \ No newline at end of file diff --git a/src/routes/page/agent/[agentId]/+page.svelte b/src/routes/page/agent/[agentId]/+page.svelte index 0d51b1db..ddbf636c 100644 --- a/src/routes/page/agent/[agentId]/+page.svelte +++ b/src/routes/page/agent/[agentId]/+page.svelte @@ -187,7 +187,8 @@ return data ? { utilities: data.utilities || [], knowledge_bases: data.knwoledgebases || [], - rules: data.rules || [] + rules: data.rules || [], + mcp_tools: data.mcpTools || [] } : null; } @@ -198,6 +199,7 @@ agent.utilities = data.utilities || []; agent.knowledge_bases = data.knwoledgebases || []; agent.rules = data.rules || []; + agent.mcp_tools = data.mcpTools || []; } } diff --git a/src/routes/page/agent/[agentId]/agent-components/agent-instruction.svelte b/src/routes/page/agent/[agentId]/agent-components/agent-instruction.svelte index 1530513b..ca35a3ad 100644 --- a/src/routes/page/agent/[agentId]/agent-components/agent-instruction.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/agent-instruction.svelte @@ -94,6 +94,7 @@ e.preventDefault(); const value = e.target.value; selected_instruction.instruction = value || ''; + handleAgentChange(); } function addChannel() { @@ -107,6 +108,7 @@ ]; selected_instruction = inner_instructions[inner_instructions.length-1]; + handleAgentChange(); } /** @param {string | undefined} uid */ @@ -115,6 +117,7 @@ if (selected_instruction.uid === uid) { selected_instruction = inner_instructions[0]; } + handleAgentChange(); } @@ -161,7 +164,7 @@ data-bs-placement="top" title="Add channel instruction" style="font-size: 16px;" - on:click={() => { addChannel(); handleAgentChange(); }} + on:click={() => addChannel()} > @@ -187,7 +190,7 @@ maxEditLength={20} editPlaceholder={'Type a channel here...'} onClick={() => selectChannel(inst.uid)} - onDelete={() => { deleteChannel(inst.uid); handleAgentChange(); }} + onDelete={() => deleteChannel(inst.uid)} onInput={handleAgentChange} /> {/each} @@ -199,7 +202,7 @@ style="scrollbar-width: thin; resize: none;" value={selected_instruction.instruction} rows={20} - on:input={(e) => { changePrompt(e); handleAgentChange(); }} + on:input={(e) => changePrompt(e)} placeholder="Enter your instruction" /> diff --git a/src/routes/page/agent/[agentId]/agent-components/agent-knowledge-base.svelte b/src/routes/page/agent/[agentId]/agent-components/agent-knowledge-base.svelte index 553c3911..98a5c154 100644 --- a/src/routes/page/agent/[agentId]/agent-components/agent-knowledge-base.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/agent-knowledge-base.svelte @@ -96,8 +96,8 @@ const vals = e.target.value.split("#"); found.name = vals[0]; found.type = vals[1]; - handleAgentChange(); innerRefresh(innerKnowledgeBases); + handleAgentChange(); } /** @@ -111,8 +111,8 @@ const value = e.target.value; const confidence = validateConfidenceNumber(value); found.confidence = confidence; - handleAgentChange(); innerRefresh(innerKnowledgeBases); + handleAgentChange(); } /** @param {any} e */ @@ -166,8 +166,8 @@ if (!found) return; found.disabled = !e.target.checked; - handleAgentChange(); innerRefresh(innerKnowledgeBases); + handleAgentChange(); } 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 new file mode 100644 index 00000000..61793de4 --- /dev/null +++ b/src/routes/page/agent/[agentId]/agent-components/agent-mcp-tool.svelte @@ -0,0 +1,350 @@ + + + + +
+
MCP Tools
+
+ +
+ {#each innerTools as tool, uid (uid)} +
+
+
+
{`Tool #${uid + 1}`}
+
+
+ toggleTool(e, uid)} + /> +
+
+ +
+
+
+
+
+ changeTool(e, uid)} + > + {#each [...toolOptions] as option} + + {/each} + +
+
+ {}} + on:click={() => deleteTool(uid)} + /> +
+
+
+ +
+
+
+
+ {'Server'} +
+
+
+ +
+
+
+
+
+
+ {#each tool.functions as fn, fid (fid)} +
+
+ {fid === 0 ? 'Functions' : ''} +
+
+
+ changeContent(e, uid, fid, 'function')} + /> +
+
+ {}} + on:click={() => deleteToolContent(uid, fid, 'function')} + /> +
+
+
+ {/each} + + {#if tool.functions?.length < limit} +
+
+ {tool.functions.length === 0 ? 'Functions' : ''} +
+
+ {}} + on:click={() => addToolContent(uid, 'function')} + /> +
+
+ {/if} +
+
+
+ {/each} + + {#if innerTools.length < limit} +
+ +
+ {/if} +
+
+
\ No newline at end of file diff --git a/src/routes/page/agent/[agentId]/agent-components/agent-overview.svelte b/src/routes/page/agent/[agentId]/agent-components/agent-overview.svelte index 7b4b679e..04e92970 100644 --- a/src/routes/page/agent/[agentId]/agent-components/agent-overview.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/agent-overview.svelte @@ -35,6 +35,7 @@ profiles = [...profiles, '']; agent.profiles = profiles; + handleAgentChange(); } /** @@ -43,6 +44,7 @@ function removeProfile(index) { profiles = profiles.filter((x, idx) => idx !== index); agent.profiles = profiles; + handleAgentChange(); } function addLabel() { @@ -50,6 +52,7 @@ labels = [...labels, '']; agent.labels = labels; + handleAgentChange(); } /** @@ -58,6 +61,7 @@ function removeLabel(index) { labels = labels.filter((x, idx) => idx !== index); agent.labels = labels; + handleAgentChange(); } function chatWithAgent() { @@ -192,7 +196,7 @@ role="link" tabindex="0" on:keydown={() => {}} - on:click={() => { removeProfile(index); handleAgentChange(); }} + on:click={() => removeProfile(index)} /> @@ -204,7 +208,7 @@ role="link" tabindex="0" on:keydown={() => {}} - on:click={() => { addProfile(); handleAgentChange(); }} + on:click={() => addProfile()} /> {/if} @@ -235,7 +239,7 @@ role="link" tabindex="0" on:keydown={() => {}} - on:click={() => { removeLabel(index); handleAgentChange(); }} + on:click={() => removeLabel(index)} /> @@ -247,7 +251,7 @@ role="link" tabindex="0" on:keydown={() => {}} - on:click={() => { addLabel(); handleAgentChange(); }} + on:click={() => addLabel()} /> {/if} 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 4c8d1290..6c9a14ca 100644 --- a/src/routes/page/agent/[agentId]/agent-components/agent-rule.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/agent-rule.svelte @@ -83,8 +83,8 @@ const val = e.target.value; found.trigger_name = val; - handleAgentChange(); innerRefresh(innerRules); + handleAgentChange(); } function addRule() { @@ -115,8 +115,8 @@ if (!found) return; found.disabled = !e.target.checked; - handleAgentChange(); innerRefresh(innerRules); + handleAgentChange(); } /** @@ -132,8 +132,8 @@ if (field === 'criteria') { found.criteria = val; } - handleAgentChange(); innerRefresh(innerRules); + handleAgentChange(); } diff --git a/src/routes/page/agent/[agentId]/agent-components/agent-template.svelte b/src/routes/page/agent/[agentId]/agent-components/agent-template.svelte index 2615a31b..c192d707 100644 --- a/src/routes/page/agent/[agentId]/agent-components/agent-template.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/agent-template.svelte @@ -90,6 +90,7 @@ e.preventDefault(); const value = e.target.value; selected_template.content = value || ''; + handleAgentChange(); } function addTemplate() { @@ -103,6 +104,7 @@ ]; selected_template = inner_templates[inner_templates.length-1]; + handleAgentChange(); } /** @param {string | undefined | null} uid */ @@ -113,6 +115,7 @@ ...defaultTemplate }; } + handleAgentChange(); } @@ -139,7 +142,7 @@ data-bs-placement="top" title="Add templates" style="font-size: 16px;" - on:click={() => { addTemplate(); handleAgentChange(); }} + on:click={() => addTemplate()} > @@ -165,7 +168,7 @@ maxEditLength={50} editPlaceholder={'Type a title here...'} onClick={() => selectTemplate(template.uid)} - onDelete={() => { deleteTemplate(template.uid); handleAgentChange(); }} + onDelete={() => deleteTemplate(template.uid)} onInput={() => handleAgentChange()} /> {/each} @@ -176,7 +179,7 @@ style="scrollbar-width: thin; resize: none;" value={selected_template.content} rows={15} - on:input={(e) => { changePrompt(e); handleAgentChange(); }} + on:input={(e) => changePrompt(e)} placeholder="Enter your template" /> {/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 948afecf..c119dc9e 100644 --- a/src/routes/page/agent/[agentId]/agent-components/agent-utility.svelte +++ b/src/routes/page/agent/[agentId]/agent-components/agent-utility.svelte @@ -15,9 +15,9 @@ export const fetchUtilities = () => { const candidates = innerUtilities?.filter(x => !!x.name)?.map(x => { - /** @type {import('$agentTypes').UtilityBase[]} */ + /** @type {import('$commonTypes').NameBase[]} */ const functions = []; - /** @type {import('$agentTypes').UtilityBase[]} */ + /** @type {import('$commonTypes').NameBase[]} */ const templates = []; const uniqueFns = new Set(); @@ -143,6 +143,7 @@ ...utilityMapper[name].templates?.filter(x => !!x.name) || [] ]; innerRefresh(innerUtilities); + handleAgentChange(); } function addUtility() { @@ -160,6 +161,7 @@ /** @param {number} idx */ function deleteUtility(idx) { innerUtilities = innerUtilities.filter((_, index) => index !== idx); + handleAgentChange(); } /** @@ -177,6 +179,7 @@ } innerRefresh(innerUtilities); + handleAgentChange(); } /** @@ -197,6 +200,7 @@ } innerRefresh(innerUtilities); + handleAgentChange(); } @@ -225,6 +229,7 @@ } } innerRefresh(innerUtilities); + handleAgentChange(); } /** @@ -237,6 +242,7 @@ found.disabled = !e.target.checked; innerRefresh(innerUtilities); + handleAgentChange(); } @@ -259,6 +265,7 @@ if (!!agent) { agent.merge_utility = checked; } + handleAgentChange(); } @@ -274,7 +281,7 @@ { toggleMergeUtility(e); handleAgentChange(); }} + on:change={e => { toggleMergeUtility(e);}} />
Merge utilities @@ -300,7 +307,7 @@ { toggleUtility(e, uid); handleAgentChange(); }} + on:change={e => { toggleUtility(e, uid); }} />
{ changeUtility(e, uid); handleAgentChange(); }} + on:change={e => { changeUtility(e, uid); }} > {#each utilityOptions as option} @@ -332,7 +339,7 @@ role="link" tabindex="0" on:keydown={() => {}} - on:click={() => { deleteUtility(uid); handleAgentChange(); }} + on:click={() => { deleteUtility(uid); }} />
@@ -350,7 +357,7 @@ { selectContent(e, uid, fid, 'function'); handleAgentChange(); }} + on:change={e => { selectContent(e, uid, fid, 'function'); }} > {#each (utilityMapper[utility.name]?.functions || []) as option} @@ -363,7 +370,7 @@ role="link" tabindex="0" on:keydown={() => {}} - on:click={() => { deleteUtilityContent(uid, fid, 'function'); handleAgentChange(); }} + on:click={() => { deleteUtilityContent(uid, fid, 'function'); }} /> @@ -381,7 +388,7 @@ role="link" tabindex="0" on:keydown={() => {}} - on:click={() => { addUtilityContent(uid, 'function'); handleAgentChange(); }} + on:click={() => { addUtilityContent(uid, 'function'); }} /> @@ -399,7 +406,7 @@ { selectContent(e, uid, tid, 'template'); handleAgentChange(); }} + on:change={e => { selectContent(e, uid, tid, 'template'); }} > {#each (utilityMapper[utility.name]?.templates || []) as option}