import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { agentApi } from '@/apis/agent_api' import { handleChatError } from '@/utils/errorHandler' import { useUserStore } from '@/stores/user' export const useAgentStore = defineStore('agent', () => { const userStore = useUserStore() // ==================== 状态定义 ==================== // 智能体相关状态 const agents = ref([]) const selectedAgentId = ref(null) const defaultAgentId = ref(null) // 智能体配置相关状态 const agentConfig = ref({}) const originalAgentConfig = ref({}) // 智能体详情相关状态 const agentDetails = ref({}) // 存储每个智能体的详细信息(含 configurable_items) // 加载状态 const isLoadingAgents = ref(false) const isLoadingConfig = ref(false) const isLoadingTools = ref(false) const isLoadingAgentDetail = ref(false) // 错误状态 const error = ref(null) // 初始化状态 const isInitialized = ref(false) const isInitializing = ref(false) // ==================== 计算属性 ==================== const selectedAgent = computed(() => selectedAgentId.value ? agents.value.find(a => a.id === selectedAgentId.value) : null ) const defaultAgent = computed(() => defaultAgentId.value ? agents.value.find(a => a.id === defaultAgentId.value) : agents.value[0] ) const agentsList = computed(() => agents.value) const isDefaultAgent = computed(() => selectedAgentId.value === defaultAgentId.value) const configurableItems = computed(() => { const agentId = selectedAgentId.value if (!agentId || !agentDetails.value[agentId] || !agentDetails.value[agentId].configurable_items) { return {} } const agentConfigurableItems = agentDetails.value[agentId].configurable_items const items = { ...agentConfigurableItems } Object.keys(items).forEach(key => { const item = items[key] if (item && item.x_oap_ui_config) { items[key] = { ...item, ...item.x_oap_ui_config } delete items[key].x_oap_ui_config } }) return items }) // 工具相关状态 const availableTools = computed(() => { return configurableItems.value.tools?.options || [] }) const hasConfigChanges = computed(() => JSON.stringify(agentConfig.value) !== JSON.stringify(originalAgentConfig.value) ) // ==================== 方法 ==================== /** * 初始化 store */ async function initialize() { if (isInitialized.value) return // 防止并发初始化 if (isInitializing.value) return isInitializing.value = true try { await fetchAgents() await fetchDefaultAgent() if (!selectedAgentId.value || !agents.value.find(a => a.id === selectedAgentId.value)) { if (defaultAgentId.value && agents.value.find(a => a.id === defaultAgentId.value)) { await selectAgent(defaultAgentId.value) } else if (agents.value.length > 0) { const firstAgentId = agents.value[0].id await selectAgent(firstAgentId) } } else { console.log('Condition FALSE: Persisted selected agent is valid. Keeping it.') // 确保已缓存的智能体详细信息存在 if (selectedAgentId.value && !agentDetails.value[selectedAgentId.value]) { try { await fetchAgentDetail(selectedAgentId.value) } catch (err) { console.warn(`Failed to fetch agent detail for ${selectedAgentId.value}:`, err) } } } if (selectedAgentId.value) { if (userStore.isAdmin) { await loadAgentConfig() } } isInitialized.value = true } catch (err) { console.error('Failed to initialize agent store:', err) handleChatError(err, 'initialize') error.value = err.message } finally { isInitializing.value = false } } /** * 获取智能体列表 */ async function fetchAgents() { isLoadingAgents.value = true error.value = null try { const response = await agentApi.getAgents() agents.value = response.agents } catch (err) { console.error('Failed to fetch agents:', err) handleChatError(err, 'fetch') error.value = err.message throw err } finally { isLoadingAgents.value = false } } /** * 获取单个智能体的详细信息(包含配置选项) * @param {string} agentId - 智能体ID */ async function fetchAgentDetail(agentId) { if (!agentId) return // 如果已经缓存了详细信息,直接返回 if (agentDetails.value[agentId]) { return agentDetails.value[agentId] } isLoadingAgentDetail.value = true error.value = null try { const response = await agentApi.getAgentDetail(agentId) agentDetails.value[agentId] = response // availableTools.value[agentId] = response.available_tools || [] return response } catch (err) { console.error(`Failed to fetch agent detail for ${agentId}:`, err) handleChatError(err, 'fetch') error.value = err.message throw err } finally { isLoadingAgentDetail.value = false } } /** * 获取默认智能体 */ async function fetchDefaultAgent() { try { const response = await agentApi.getDefaultAgent() defaultAgentId.value = response.default_agent_id } catch (err) { console.error('Failed to fetch default agent:', err) handleChatError(err, 'fetch') error.value = err.message } } /** * 设置默认智能体 */ async function setDefaultAgent(agentId) { try { await agentApi.setDefaultAgent(agentId) defaultAgentId.value = agentId } catch (err) { console.error('Failed to set default agent:', err) handleChatError(err, 'save') error.value = err.message throw err } } /** * 选择智能体 */ async function selectAgent(agentId) { if (agents.value.find(a => a.id === agentId)) { selectedAgentId.value = agentId // 清空之前的配置 agentConfig.value = {} originalAgentConfig.value = {} // 自动获取智能体详细信息(包含 configurable_items) try { await fetchAgentDetail(agentId) } catch (err) { console.warn(`Failed to fetch agent detail for ${agentId}:`, err) // 不抛出错误,允许继续选择智能体 } } } /** * 加载智能体配置 */ async function loadAgentConfig(agentId = null) { if (!userStore.isAdmin) return const targetAgentId = agentId || selectedAgentId.value if (!targetAgentId) return isLoadingConfig.value = true error.value = null try { const response = await agentApi.getAgentConfig(targetAgentId) agentConfig.value = { ...response.config } originalAgentConfig.value = { ...response.config } } catch (err) { console.error('Failed to load agent config:', err) handleChatError(err, 'load') error.value = err.message throw err } finally { isLoadingConfig.value = false } } /** * 保存智能体配置 */ async function saveAgentConfig(agentId = null) { const targetAgentId = agentId || selectedAgentId.value if (!targetAgentId) return try { await agentApi.saveAgentConfig(targetAgentId, agentConfig.value) originalAgentConfig.value = { ...agentConfig.value } } catch (err) { console.error('Failed to save agent config:', err) handleChatError(err, 'save') error.value = err.message throw err } } /** * 重置智能体配置 */ function resetAgentConfig() { agentConfig.value = { ...originalAgentConfig.value } } /** * 更新配置项 */ function updateConfigItem(key, value) { agentConfig.value[key] = value } /** * 更新智能体配置(支持批量更新) */ function updateAgentConfig(updates) { Object.assign(agentConfig.value, updates) } /** * 获取工具列表 */ async function fetchTools() { isLoadingTools.value = true error.value = null console.error('[DEPRECATED] THIS METHOD IS DEPRECATED. USE fetchAgentDetail INSTEAD.') console.error('[DEPRECATED] fetchTools: selectedAgentId.value =', selectedAgentId.value) } /** * 清除错误状态 */ function clearError() { error.value = null } /** * 重置 store 状态 */ function reset() { agents.value = [] selectedAgentId.value = null defaultAgentId.value = null agentConfig.value = {} originalAgentConfig.value = {} agentDetails.value = {} availableTools.value = [] isLoadingAgents.value = false isLoadingConfig.value = false isLoadingTools.value = false isLoadingAgentDetail.value = false error.value = null isInitialized.value = false isInitializing.value = false } return { // 状态 agents, selectedAgentId, defaultAgentId, agentConfig, originalAgentConfig, agentDetails, availableTools, isLoadingAgents, isLoadingConfig, isLoadingTools, isLoadingAgentDetail, error, isInitialized, // 计算属性 selectedAgent, defaultAgent, agentsList, isDefaultAgent, configurableItems, hasConfigChanges, // 方法 initialize, fetchAgents, fetchAgentDetail, fetchDefaultAgent, setDefaultAgent, selectAgent, loadAgentConfig, saveAgentConfig, resetAgentConfig, updateConfigItem, updateAgentConfig, fetchTools, clearError, reset } }, { // 持久化配置 persist: { key: 'agent-store', storage: localStorage, paths: ['selectedAgentId', 'defaultAgentId'] } })