Spaces:
Sleeping
Sleeping
| /** | |
| * SAAP API Client - HuggingFace Deployment Compatible | |
| * Automatically detects environment and uses correct base URL | |
| */ | |
| import axios from 'axios'; | |
| // π Environment-aware base URL detection | |
| const getApiBaseUrl = () => { | |
| // Production HuggingFace Spaces deployment | |
| if (window.location.hostname.includes('hf.space')) { | |
| return '/api/v1'; // Relative path - nginx routes to backend | |
| } | |
| // Local development | |
| if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { | |
| return 'http://localhost:8000/api/v1'; | |
| } | |
| // Network development (IP-based) | |
| if (window.location.hostname.match(/^\d+\.\d+\.\d+\.\d+$/)) { | |
| return `http://${window.location.hostname}:8000/api/v1`; | |
| } | |
| // Fallback: relative path | |
| return '/api/v1'; | |
| }; | |
| const API_BASE_URL = getApiBaseUrl(); | |
| console.log('π§ SAAP API Configuration:'); | |
| console.log(` Environment: ${window.location.hostname}`); | |
| console.log(` API Base URL: ${API_BASE_URL}`); | |
| // Create axios instance with base configuration | |
| const apiClient = axios.create({ | |
| baseURL: API_BASE_URL, | |
| timeout: 120000, // π ErhΓΆht auf 2 Minuten fΓΌr Multi-Agent Chat (Jane β Spezialist Delegation) | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| withCredentials: false, // Changed from true for HuggingFace | |
| }); | |
| // Request interceptor for logging | |
| apiClient.interceptors.request.use( | |
| (config) => { | |
| console.log(`π API Request: ${config.method?.toUpperCase()} ${config.url}`); | |
| console.log(`π Full URL: ${config.baseURL}${config.url}`); | |
| return config; | |
| }, | |
| (error) => { | |
| console.error('β Request Error:', error); | |
| return Promise.reject(error); | |
| } | |
| ); | |
| // Response interceptor for error handling | |
| apiClient.interceptors.response.use( | |
| (response) => { | |
| console.log(`β API Response: ${response.status} ${response.config.url}`); | |
| return response; | |
| }, | |
| (error) => { | |
| if (error.response) { | |
| console.error('β API Error:', { | |
| status: error.response.status, | |
| data: error.response.data, | |
| message: error.message | |
| }); | |
| } else if (error.request) { | |
| console.error('β Network Error: No response received', error.message); | |
| } else { | |
| console.error('β Request Setup Error:', error.message); | |
| } | |
| return Promise.reject(error); | |
| } | |
| ); | |
| // API Methods | |
| const saapApi = { | |
| // Agent Management | |
| async getAgents() { | |
| const response = await apiClient.get('/agents'); | |
| return response.data; | |
| }, | |
| async getAgent(agentId) { | |
| const response = await apiClient.get(`/agents/${agentId}`); | |
| return response.data; | |
| }, | |
| async createAgent(agentData) { | |
| const response = await apiClient.post('/agents', agentData); | |
| return response.data; | |
| }, | |
| async updateAgent(agentId, agentData) { | |
| const response = await apiClient.put(`/agents/${agentId}`, agentData); | |
| return response.data; | |
| }, | |
| async deleteAgent(agentId) { | |
| const response = await apiClient.delete(`/agents/${agentId}`); | |
| return response.data; | |
| }, | |
| // Agent Lifecycle | |
| async startAgent(agentId) { | |
| const response = await apiClient.post(`/agents/${agentId}/start`); | |
| return response.data; | |
| }, | |
| async stopAgent(agentId) { | |
| const response = await apiClient.post(`/agents/${agentId}/stop`); | |
| return response.data; | |
| }, | |
| // Agent Communication | |
| async sendMessage(agentId, message) { | |
| const response = await apiClient.post(`/agents/${agentId}/chat`, { | |
| message: message, | |
| timestamp: Date.now() | |
| }); | |
| return response.data; | |
| }, | |
| // Multi-Agent System | |
| async multiAgentChat(message, options = {}) { | |
| const response = await apiClient.post('/multi-agent/chat', { | |
| user_message: message, | |
| ...options | |
| }); | |
| return response.data; | |
| }, | |
| async getMultiAgentStatus() { | |
| const response = await apiClient.get('/multi-agent/status'); | |
| return response.data; | |
| }, | |
| // Templates | |
| async getAgentTemplates() { | |
| const response = await apiClient.get('/templates/agents'); | |
| return response.data; | |
| }, | |
| async createAgentFromTemplate(templateName) { | |
| const response = await apiClient.post(`/templates/agents/${templateName}`); | |
| return response.data; | |
| }, | |
| // Health Check | |
| async healthCheck() { | |
| const response = await apiClient.get('/health'); | |
| return response.data; | |
| }, | |
| }; | |
| // WebSocket connection for real-time updates | |
| class SaapWebSocket { | |
| constructor() { | |
| this.ws = null; | |
| this.reconnectAttempts = 0; | |
| this.maxReconnectAttempts = 5; | |
| this.reconnectDelay = 1000; | |
| this.listeners = new Map(); | |
| } | |
| connect() { | |
| const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; | |
| const wsHost = window.location.hostname.includes('hf.space') | |
| ? window.location.host | |
| : 'localhost:8000'; | |
| const wsUrl = `${wsProtocol}//${wsHost}/ws`; | |
| console.log(`π Connecting to WebSocket: ${wsUrl}`); | |
| this.ws = new WebSocket(wsUrl); | |
| this.ws.onopen = () => { | |
| console.log('β WebSocket connected'); | |
| this.reconnectAttempts = 0; | |
| this.emit('connected', {}); | |
| }; | |
| this.ws.onmessage = (event) => { | |
| try { | |
| const data = JSON.parse(event.data); | |
| console.log('π¨ WebSocket message:', data); | |
| this.emit('message', data); | |
| } catch (error) { | |
| console.error('β WebSocket message parse error:', error); | |
| } | |
| }; | |
| this.ws.onerror = (error) => { | |
| console.error('β WebSocket error:', error); | |
| this.emit('error', error); | |
| }; | |
| this.ws.onclose = () => { | |
| console.log('β WebSocket disconnected'); | |
| this.emit('disconnected', {}); | |
| this.attemptReconnect(); | |
| }; | |
| } | |
| attemptReconnect() { | |
| if (this.reconnectAttempts < this.maxReconnectAttempts) { | |
| this.reconnectAttempts++; | |
| const delay = this.reconnectDelay * this.reconnectAttempts; | |
| console.log(`π Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`); | |
| setTimeout(() => this.connect(), delay); | |
| } else { | |
| console.error('β Max reconnection attempts reached'); | |
| } | |
| } | |
| on(event, callback) { | |
| if (!this.listeners.has(event)) { | |
| this.listeners.set(event, []); | |
| } | |
| this.listeners.get(event).push(callback); | |
| } | |
| emit(event, data) { | |
| if (this.listeners.has(event)) { | |
| this.listeners.get(event).forEach(callback => callback(data)); | |
| } | |
| } | |
| send(data) { | |
| if (this.ws && this.ws.readyState === WebSocket.OPEN) { | |
| this.ws.send(JSON.stringify(data)); | |
| } else { | |
| console.error('β WebSocket not connected'); | |
| } | |
| } | |
| disconnect() { | |
| if (this.ws) { | |
| this.ws.close(); | |
| this.ws = null; | |
| } | |
| } | |
| } | |
| const saapWebSocket = new SaapWebSocket(); | |
| // Export both default and named for compatibility | |
| export default saapApi; | |
| export { saapApi, saapWebSocket }; | |