UNPKG

semem

Version:

Semantic Memory for Intelligent Agents

318 lines (295 loc) 10.7 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Semem Interface</title> <style> :root { --primary: #2563eb; --secondary: #475569; --success: #22c55e; --error: #ef4444; } body { font-family: system-ui, -apple-system, sans-serif; line-height: 1.5; margin: 0; padding: 2rem; color: #1f2937; } .container { max-width: 64rem; margin: 0 auto; } .tabs { display: flex; gap: 1rem; margin-bottom: 2rem; border-bottom: 2px solid #e5e7eb; padding-bottom: 0.5rem; } .tab { padding: 0.5rem 1rem; border: none; background: none; cursor: pointer; color: var(--secondary); font-weight: 500; } .tab.active { color: var(--primary); border-bottom: 2px solid var(--primary); margin-bottom: -0.5rem; } .panel { display: none; padding: 1rem; background: #f9fafb; border-radius: 0.5rem; } .panel.active { display: block; } .form-group { margin-bottom: 1rem; } label { display: block; margin-bottom: 0.5rem; font-weight: 500; } input[type="text"], textarea, select { width: 100%; padding: 0.5rem; border: 1px solid #d1d5db; border-radius: 0.375rem; margin-bottom: 0.5rem; } button { padding: 0.5rem 1rem; background: var(--primary); color: white; border: none; border-radius: 0.375rem; cursor: pointer; font-weight: 500; } button:hover { opacity: 0.9; } .response { margin-top: 1rem; padding: 1rem; background: white; border: 1px solid #e5e7eb; border-radius: 0.375rem; white-space: pre-wrap; } .success { color: var(--success); } .error { color: var(--error); } .metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-top: 1rem; } .metric-card { padding: 1rem; background: white; border: 1px solid #e5e7eb; border-radius: 0.375rem; } .metric-title { font-weight: 500; color: var(--secondary); margin-bottom: 0.5rem; } .metric-value { font-size: 1.25rem; font-weight: 600; } </style> </head> <body> <div class="container"> <h1>Semem Interface</h1> <div class="tabs"> <button class="tab active" data-panel="chat">Chat</button> <button class="tab" data-panel="store">Store</button> <button class="tab" data-panel="query">Query</button> <button class="tab" data-panel="metrics">Metrics</button> </div> <div id="chat" class="panel active"> <form id="chatForm"> <div class="form-group"> <label for="prompt">Prompt</label> <textarea id="prompt" rows="4" required></textarea> </div> <div class="form-group"> <label for="model">Model</label> <select id="model"> <option value="qwen2:1.5b">Qwen2 1.5B</option> <option value="llama2">LLaMA2</option> </select> </div> <button type="submit">Send</button> </form> <div id="chatResponse" class="response"></div> </div> <div id="store" class="panel"> <form id="storeForm"> <div class="form-group"> <label for="storeData">Data</label> <textarea id="storeData" rows="4" required></textarea> </div> <div class="form-group"> <label for="format">Format</label> <select id="format"> <option value="text">Text</option> <option value="turtle">Turtle</option> </select> </div> <button type="submit">Store</button> </form> <div id="storeResponse" class="response"></div> </div> <div id="query" class="panel"> <form id="queryForm"> <div class="form-group"> <label for="queryText">Query</label> <textarea id="queryText" rows="4" required></textarea> </div> <div class="form-group"> <label for="limit">Limit</label> <input type="number" id="limit" value="10" min="1"> </div> <button type="submit">Search</button> </form> <div id="queryResponse" class="response"></div> </div> <div id="metrics" class="panel"> <button id="refreshMetrics">Refresh</button> <div id="metricsDisplay" class="metrics"></div> </div> </div> <script> // API Configuration const API_BASE = 'http://localhost:3000/api'; const API_KEY = localStorage.getItem('semem_api_key'); // Tab Switching document.querySelectorAll('.tab').forEach(tab => { tab.addEventListener('click', () => { document.querySelectorAll('.tab, .panel').forEach(el => { el.classList.remove('active'); }); tab.classList.add('active'); document.getElementById(tab.dataset.panel).classList.add('active'); }); }); // API Helpers async function apiRequest(endpoint, options = {}) { const defaultOptions = { headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY } }; try { const response = await fetch(`${API_BASE}${endpoint}`, { ...defaultOptions, ...options }); if (!response.ok) { throw new Error(`API Error: ${response.status}`); } return await response.json(); } catch (error) { console.error('API Request failed:', error); throw error; } } function showResponse(elementId, data, isError = false) { const element = document.getElementById(elementId); element.className = `response ${isError ? 'error' : 'success'}`; element.textContent = typeof data === 'string' ? data : JSON.stringify(data, null, 2); } // Chat Form document.getElementById('chatForm').addEventListener('submit', async (e) => { e.preventDefault(); const prompt = document.getElementById('prompt').value; const model = document.getElementById('model').value; try { const response = await apiRequest('/chat', { method: 'POST', body: JSON.stringify({ prompt, model }) }); showResponse('chatResponse', response.data); } catch (error) { showResponse('chatResponse', error.message, true); } }); // Store Form document.getElementById('storeForm').addEventListener('submit', async (e) => { e.preventDefault(); const data = document.getElementById('storeData').value; const format = document.getElementById('format').value; try { const response = await apiRequest('/store', { method: 'POST', body: JSON.stringify({ content: data, format }) }); showResponse('storeResponse', 'Data stored successfully'); } catch (error) { showResponse('storeResponse', error.message, true); } }); // Query Form document.getElementById('queryForm').addEventListener('submit', async (e) => { e.preventDefault(); const query = document.getElementById('queryText').value; const limit = document.getElementById('limit').value; try { const response = await apiRequest(`/query?text=${encodeURIComponent(query)}&limit=${limit}`); showResponse('queryResponse', response.data); } catch (error) { showResponse('queryResponse', error.message, true); } }); // Metrics Display async function updateMetrics() { try { const response = await apiRequest('/metrics'); const metrics = response.data; const metricsHtml = Object.entries(metrics) .map(([key, value]) => ` <div class="metric-card"> <div class="metric-title">${key}</div> <div class="metric-value">${ typeof value === 'object' ? JSON.stringify(value) : value }</div> </div> `).join(''); document.getElementById('metricsDisplay').innerHTML = metricsHtml; } catch (error) { document.getElementById('metricsDisplay').innerHTML = ` <div class="error">Failed to load metrics: ${error.message}</div> `; } } document.getElementById('refreshMetrics').addEventListener('click', updateMetrics); // Initial metrics load if (document.getElementById('metrics').classList.contains('active')) { updateMetrics(); } </script> </body> </html>