/** * SAAP Agent Store - Pinia State Management * Centralized state management for SAAP agent operations */ import { defineStore } from 'pinia' import { ref, computed } from 'vue' import saapApi, { saapWebSocket } from '@/services/saapApi' export const useAgentStore = defineStore('agents', () => { // ========================================== // STATE // ========================================== const agents = ref([]) const isLoading = ref(false) const isConnected = ref(false) const error = ref(null) const systemInfo = ref(null) const lastUpdate = ref(null) // Agent-specific loading states const agentLoading = ref(new Map()) // Chat messages storage const chatMessages = ref(new Map()) // ========================================== // GETTERS (Computed) // ========================================== const activeAgents = computed(() => agents.value.filter(agent => agent.status === 'active') ) const inactiveAgents = computed(() => agents.value.filter(agent => agent.status === 'inactive') ) const startingAgents = computed(() => agents.value.filter(agent => agent.status === 'starting') ) const errorAgents = computed(() => agents.value.filter(agent => agent.status === 'error') ) const totalAgents = computed(() => agents.value.length) const agentById = computed(() => (id) => agents.value.find(agent => agent.id === id) ) const connectionStatus = computed(() => ({ isConnected: isConnected.value, status: isConnected.value ? 'connected' : 'disconnected', className: isConnected.value ? 'status-connected' : 'status-disconnected', text: isConnected.value ? 'Connected' : 'Disconnected' })) // Agent statistics const agentStats = computed(() => ({ total: totalAgents.value, active: activeAgents.value.length, inactive: inactiveAgents.value.length, starting: startingAgents.value.length, error: errorAgents.value.length })) // ========================================== // ACTIONS // ========================================== /** * Initialize store and WebSocket connection */ async function initialize() { console.log('๐Ÿš€ Initializing SAAP Agent Store...') try { // Setup WebSocket listeners setupWebSocketListeners() // Connect to WebSocket saapWebSocket.connect() // Load initial data await Promise.all([ loadAgents(), loadSystemInfo() ]) console.log('โœ… SAAP Agent Store initialized successfully') } catch (err) { console.error('โŒ Store initialization failed:', err) setError('Failed to initialize SAAP Platform') } } /** * Setup WebSocket event listeners */ function setupWebSocketListeners() { saapWebSocket.on('connected', () => { console.log('โœ… WebSocket connected') isConnected.value = true clearError() }) saapWebSocket.on('disconnected', () => { console.log('๐Ÿ”Œ WebSocket disconnected') isConnected.value = false }) saapWebSocket.on('error', (error) => { console.error('โŒ WebSocket error:', error) isConnected.value = false setError('WebSocket connection failed') }) saapWebSocket.on('message', (data) => { handleWebSocketMessage(data) }) } /** * Handle incoming WebSocket messages */ function handleWebSocketMessage(data) { console.log('๐Ÿ“จ Processing WebSocket message:', data) // Handle different message types if (typeof data === 'string') { // Handle echo messages or simple strings console.log('Echo received:', data) } else if (data && data.type) { // Handle structured messages switch (data.type) { case 'agent_update': updateAgentFromWebSocket(data.agent) break case 'agent_status': updateAgentStatus(data.agent_id, data.status) break case 'chat_message': addChatMessage(data.agent_id, data.message, data.response) break default: console.log('Unknown message type:', data.type) } } } /** * Load all agents from API */ async function loadAgents() { setLoading(true) try { const response = await saapApi.getAgents() agents.value = Array.isArray(response) ? response : [] lastUpdate.value = new Date().toISOString() console.log(`๐Ÿ“‹ Loaded ${agents.value.length} agents`) clearError() } catch (err) { console.error('โŒ Failed to load agents:', err) setError('Failed to load agents') agents.value = [] } finally { setLoading(false) } } /** * Load system information */ async function loadSystemInfo() { try { const info = await saapApi.getSystemInfo() systemInfo.value = info console.log('๐Ÿ“Š System info loaded:', info) } catch (err) { console.error('โŒ Failed to load system info:', err) setError('Failed to load system information') } } /** * Start an agent */ async function startAgent(agentId) { setAgentLoading(agentId, true) try { const response = await saapApi.startAgent(agentId) console.log(`โ–ถ๏ธ Agent ${agentId} started:`, response) // Update local state updateAgentStatus(agentId, 'starting') // Reload agents to get updated state setTimeout(() => loadAgents(), 1000) return response } catch (err) { console.error(`โŒ Failed to start agent ${agentId}:`, err) setError(`Failed to start agent: ${agentId}`) throw err } finally { setAgentLoading(agentId, false) } } /** * Stop an agent */ async function stopAgent(agentId) { setAgentLoading(agentId, true) try { const response = await saapApi.stopAgent(agentId) console.log(`โน๏ธ Agent ${agentId} stopped:`, response) // Update local state updateAgentStatus(agentId, 'inactive') return response } catch (err) { console.error(`โŒ Failed to stop agent ${agentId}:`, err) setError(`Failed to stop agent: ${agentId}`) throw err } finally { setAgentLoading(agentId, false) } } /** * Send message to agent */ async function chatWithAgent(agentId, message) { setAgentLoading(agentId, true) try { const response = await saapApi.chatWithAgent(agentId, message) console.log(`๐Ÿ’ฌ Chat with ${agentId}:`, response) // Store chat message addChatMessage(agentId, message, response.response) return response } catch (err) { console.error(`โŒ Failed to chat with agent ${agentId}:`, err) setError(`Failed to communicate with agent: ${agentId}`) throw err } finally { setAgentLoading(agentId, false) } } /** * Create agent from template */ async function createAgentFromTemplate(templateName) { setLoading(true) try { const response = await saapApi.createAgentFromTemplate(templateName) console.log(`โœจ Agent created from template ${templateName}:`, response) // Reload agents await loadAgents() return response } catch (err) { console.error(`โŒ Failed to create agent from template ${templateName}:`, err) setError(`Failed to create agent from template: ${templateName}`) throw err } finally { setLoading(false) } } // ========================================== // HELPER FUNCTIONS // ========================================== /** * Update agent status */ function updateAgentStatus(agentId, status) { const agent = agents.value.find(a => a.id === agentId) if (agent) { agent.status = status console.log(`๐Ÿ”„ Agent ${agentId} status updated to: ${status}`) } } /** * Update agent from WebSocket message */ function updateAgentFromWebSocket(agentData) { const index = agents.value.findIndex(a => a.id === agentData.id) if (index !== -1) { agents.value[index] = { ...agents.value[index], ...agentData } console.log(`๐Ÿ”„ Agent ${agentData.id} updated from WebSocket`) } } /** * Add chat message to history */ function addChatMessage(agentId, message, response) { if (!chatMessages.value.has(agentId)) { chatMessages.value.set(agentId, []) } const messages = chatMessages.value.get(agentId) messages.push({ id: Date.now(), user_message: message, agent_response: response?.content || response, timestamp: new Date().toISOString() }) // Keep only last 100 messages per agent if (messages.length > 100) { messages.splice(0, messages.length - 100) } } /** * Set loading state */ function setLoading(loading) { isLoading.value = loading } /** * Set agent-specific loading state */ function setAgentLoading(agentId, loading) { agentLoading.value.set(agentId, loading) } /** * Check if agent is loading */ function isAgentLoading(agentId) { return agentLoading.value.get(agentId) || false } /** * Set error state */ function setError(errorMessage) { error.value = errorMessage console.error('Store Error:', errorMessage) } /** * Clear error state */ function clearError() { error.value = null } /** * Get chat messages for agent */ function getChatMessages(agentId) { return chatMessages.value.get(agentId) || [] } /** * Refresh all data */ async function refresh() { await Promise.all([ loadAgents(), loadSystemInfo() ]) } /** * Cleanup store (disconnect WebSocket) */ function cleanup() { console.log('๐Ÿงน Cleaning up SAAP Agent Store...') saapWebSocket.disconnect() isConnected.value = false } // ========================================== // RETURN STORE INTERFACE // ========================================== return { // State agents, isLoading, isConnected, error, systemInfo, lastUpdate, // Getters activeAgents, inactiveAgents, startingAgents, errorAgents, totalAgents, agentById, connectionStatus, agentStats, // Actions initialize, loadAgents, loadSystemInfo, startAgent, stopAgent, chatWithAgent, createAgentFromTemplate, refresh, cleanup, // Helper functions isAgentLoading, getChatMessages, clearError } })