/** * Video Learning Module for AutoGLM Dashboard * * This module provides UI and functionality for the Video Learning Agent, * allowing users to watch and learn from short video platforms. */ const VideoLearningModule = { // Current session state currentSessionId: null, currentSessionStatus: null, videos: [], isPolling: false, // Create a new learning session async createSession(deviceId, options = {}) { const { platform = 'douyin', targetCount = 10, category = null, watchDuration = 3.0, enableAnalysis = true, } = options; try { const response = await axios.post('/api/video-learning/sessions', { device_id: deviceId, platform: platform, target_count: targetCount, category: category, watch_duration: watchDuration, enable_analysis: enableAnalysis, }); this.currentSessionId = response.data.session_id; this.startPolling(); return response.data; } catch (error) { console.error('Error creating session:', error); throw error; } }, // Start a session async startSession(sessionId) { try { const response = await axios.post(`/api/video-learning/sessions/${sessionId}/start`); return response.data; } catch (error) { console.error('Error starting session:', error); throw error; } }, // Control a session (pause/resume/stop) async controlSession(sessionId, action) { try { const response = await axios.post(`/api/video-learning/sessions/${sessionId}/control`, { action: action, }); return response.data; } catch (error) { console.error('Error controlling session:', error); throw error; } }, // Get session status async getSessionStatus(sessionId) { try { const response = await axios.get(`/api/video-learning/sessions/${sessionId}/status`); this.currentSessionStatus = response.data; return response.data; } catch (error) { console.error('Error getting session status:', error); throw error; } }, // Get session videos async getSessionVideos(sessionId) { try { const response = await axios.get(`/api/video-learning/sessions/${sessionId}/videos`); this.videos = response.data; return response.data; } catch (error) { console.error('Error getting session videos:', error); throw error; } }, // List all active sessions async listSessions() { try { const response = await axios.get('/api/video-learning/sessions'); return response.data; } catch (error) { console.error('Error listing sessions:', error); throw error; } }, // Delete a session async deleteSession(sessionId) { try { const response = await axios.delete(`/api/video-learning/sessions/${sessionId}`); if (this.currentSessionId === sessionId) { this.currentSessionId = null; this.currentSessionStatus = null; this.stopPolling(); } return response.data; } catch (error) { console.error('Error deleting session:', error); throw error; } }, // Start polling for session updates startPolling(intervalMs = 1000) { if (this.isPolling) return; this.isPolling = true; this.pollInterval = setInterval(async () => { if (this.currentSessionId) { try { await this.getSessionStatus(this.currentSessionId); await this.getSessionVideos(this.currentSessionId); // Trigger custom event for UI updates window.dispatchEvent(new CustomEvent('videoLearningUpdate', { detail: { sessionId: this.currentSessionId, status: this.currentSessionStatus, videos: this.videos, } })); // Stop polling if session is complete, but do one final update if (this.currentSessionStatus && !this.currentSessionStatus.is_active) { console.log('[VideoLearning] Session completed, doing final update...'); // Do one final update to ensure we have the latest data await this.getSessionStatus(this.currentSessionId); await this.getSessionVideos(this.currentSessionId); window.dispatchEvent(new CustomEvent('videoLearningUpdate', { detail: { sessionId: this.currentSessionId, status: this.currentSessionStatus, videos: this.videos, } })); console.log('[VideoLearning] Final update complete, stopping poll'); this.stopPolling(); } } catch (error) { console.error('Error polling session status:', error); // Don't stop polling on error, just log it } } }, intervalMs); console.log(`[VideoLearning] Started polling with ${intervalMs}ms interval`); }, // Stop polling stopPolling() { if (this.pollInterval) { clearInterval(this.pollInterval); this.pollInterval = null; console.log('[VideoLearning] Stopped polling'); } this.isPolling = false; }, // Format duration formatDuration(seconds) { if (seconds < 60) { return `${seconds.toFixed(1)}s`; } const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; return `${minutes}m ${remainingSeconds.toFixed(1)}s`; }, // Format number with K/M suffix formatNumber(num) { if (num === null || num === undefined) return 'N/A'; if (num >= 1000000) { return `${(num / 1000000).toFixed(1)}M`; } else if (num >= 1000) { return `${(num / 1000).toFixed(1)}K`; } return num.toString(); }, }; // Export for use in other modules if (typeof module !== 'undefined' && module.exports) { module.exports = VideoLearningModule; }