agent.ts
1 import { defineStore } from 'pinia' 2 import { v4 as uuidv4 } from 'uuid' 3 import { useMcpStore, FunctionType } from '@/renderer/store/mcp' 4 5 export interface AgentConfig { 6 selectedNode: any[] 7 name: string 8 prompt: string 9 } 10 11 export const AGENTS_DEFAULTS = { 12 selectedNode: [], 13 name: 'Agent Default', 14 prompt: '' 15 } 16 17 export interface AgentStoreState { 18 agents: AgentConfig[] 19 allTools: any[] 20 selected: number | null 21 revised: number[] 22 } 23 24 export const useAgentStore = defineStore('agentStore', { 25 state: (): AgentStoreState => ({ 26 agents: [{ ...AGENTS_DEFAULTS }], 27 allTools: [], 28 revised: [0], // Selection in Agent Config Page 29 selected: null // Selection in Chat Config Page 30 }), 31 persist: { 32 exclude: ['revised', 'allTools'] 33 }, 34 getters: { 35 hasTools(state) { 36 return state.allTools.some((obj) => obj.tools.length > 0) 37 }, 38 getRevised(state) { 39 const agent = state.revised[0] 40 if (Number.isInteger(agent)) { 41 const revised: AgentConfig = state.agents[agent] 42 return revised 43 } else { 44 return null 45 } 46 }, 47 getUnrevised(state) { 48 const selectedIndex = Number.isInteger(state.revised[0]) ? state.revised[0] : -1 49 return state.agents.filter((_agent, index) => index !== selectedIndex) 50 } 51 }, 52 actions: { 53 resetState() { 54 this.$reset() 55 }, 56 addAgent() { 57 this.agents.push({ ...AGENTS_DEFAULTS, name: `Agent ${uuidv4()}` }) 58 }, 59 genId(server: string, name: string) { 60 return JSON.stringify({ 61 server, 62 name 63 }) 64 }, 65 getId(id: string) { 66 return JSON.parse(id) 67 }, 68 getColor(id: string) { 69 const str = JSON.parse(id).server 70 let hash = 0 71 for (let i = 0; i < str.length; i++) { 72 hash = str.charCodeAt(i) + ((hash << 5) - hash) 73 } 74 75 const r = hash & 0xff 76 const g = (hash >> 8) & 0xff 77 const b = (hash >> 16) & 0xff 78 79 const color = `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).padStart(6, '0')}` 80 return color 81 }, 82 getAbbr(input: string) { 83 const words = input.split(/(?=[A-Z])|[\s-_]+/) 84 const abbreviation = words.map((word) => word.charAt(0).toUpperCase()).join('') 85 return abbreviation.slice(0, 2) 86 }, 87 getPrompt: function () { 88 if (Number.isInteger(this.selected)) { 89 return this.agents[this.selected as number].prompt 90 } else { 91 return '' 92 } 93 }, 94 getTools: async function () { 95 const mcpStore = useMcpStore() 96 if (Number.isInteger(this.selected)) { 97 const selectedTools = this.agents[this.selected as number].selectedNode 98 if (selectedTools.length === 0) { 99 return [] 100 } else { 101 console.log('Current selected tools: ', selectedTools) 102 const parsedToolServers: string[] = [] 103 104 const parsedToolNames = selectedTools.map((serverName) => { 105 try { 106 const parsed = JSON.parse(serverName) 107 if (parsed.server !== undefined) { 108 if (!parsedToolServers.includes(parsed.server)) { 109 parsedToolServers.push(parsed.server) 110 } 111 } 112 // const result = parsed?.(); 113 // return result?.catch(() => null) ?? null; 114 return parsed.name 115 } catch (_error) { 116 return null 117 } 118 }) 119 120 const listedTools = await mcpStore.listServerTools(parsedToolServers) 121 122 const filteredTools = listedTools.filter((tool: FunctionType) => 123 parsedToolNames.includes(tool.function.name) 124 ) 125 126 console.log('Current valid tools: ', listedTools, filteredTools) 127 128 return filteredTools 129 } 130 } else { 131 return mcpStore.listTools() 132 } 133 } 134 } 135 })