Quick Test Environment

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vedaya API Playground</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
        }
        
        h1 {
            color: white;
            text-align: center;
            margin-bottom: 30px;
            font-size: 2.5em;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.2);
        }
        
        .playground {
            background: white;
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
        }
        
        .tabs {
            display: flex;
            gap: 10px;
            margin-bottom: 30px;
            flex-wrap: wrap;
        }
        
        .tab {
            padding: 12px 24px;
            background: #f0f0f0;
            border: none;
            border-radius: 10px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 600;
            transition: all 0.3s;
        }
        
        .tab:hover {
            background: #e0e0e0;
        }
        
        .tab.active {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        
        .tab-content {
            display: none;
        }
        
        .tab-content.active {
            display: block;
            animation: fadeIn 0.3s;
        }
        
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }
        
        .form-group {
            margin-bottom: 20px;
        }
        
        label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #333;
        }
        
        input, textarea, select {
            width: 100%;
            padding: 12px;
            border: 2px solid #e0e0e0;
            border-radius: 8px;
            font-size: 14px;
            transition: border-color 0.3s;
        }
        
        input:focus, textarea:focus, select:focus {
            outline: none;
            border-color: #667eea;
        }
        
        textarea {
            min-height: 150px;
            resize: vertical;
            font-family: 'Monaco', 'Courier New', monospace;
        }
        
        button {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            padding: 14px 28px;
            border-radius: 8px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: transform 0.2s;
        }
        
        button:hover {
            transform: translateY(-2px);
        }
        
        button:active {
            transform: translateY(0);
        }
        
        .response {
            margin-top: 30px;
            padding: 20px;
            background: #f8f8f8;
            border-radius: 10px;
            border-left: 4px solid #667eea;
        }
        
        .response h3 {
            margin-bottom: 15px;
            color: #333;
        }
        
        .response pre {
            background: #2d2d2d;
            color: #f8f8f8;
            padding: 15px;
            border-radius: 8px;
            overflow-x: auto;
            font-size: 13px;
            line-height: 1.5;
        }
        
        .status {
            display: inline-block;
            padding: 4px 12px;
            border-radius: 20px;
            font-size: 12px;
            font-weight: 600;
            margin-left: 10px;
        }
        
        .status.success {
            background: #10b981;
            color: white;
        }
        
        .status.error {
            background: #ef4444;
            color: white;
        }
        
        .status.processing {
            background: #f59e0b;
            color: white;
        }
        
        .example-buttons {
            display: flex;
            gap: 10px;
            margin-bottom: 15px;
        }
        
        .example-btn {
            padding: 8px 16px;
            background: #f0f0f0;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 13px;
            transition: background 0.2s;
        }
        
        .example-btn:hover {
            background: #e0e0e0;
        }
        
        .loading {
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 3px solid rgba(255,255,255,.3);
            border-radius: 50%;
            border-top-color: white;
            animation: spin 1s ease-in-out infinite;
            margin-left: 10px;
        }
        
        @keyframes spin {
            to { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🚀 Vedaya API Playground</h1>
        
        <div class="playground">
            <div class="tabs">
                <button class="tab active" onclick="showTab('upload')">📤 Upload Documents</button>
                <button class="tab" onclick="showTab('status')">⏳ Pipeline Status</button>
                <button class="tab" onclick="showTab('query')">🔍 Query (OpenAI)</button>
                <button class="tab" onclick="showTab('directQuery')">💬 Direct Query</button>
                <button class="tab" onclick="showTab('graph')">🕸️ Knowledge Graph</button>
                <button class="tab" onclick="showTab('docs')">📚 List Documents</button>
            </div>
            
            <!-- Upload Documents Tab -->
            <div id="upload" class="tab-content active">
                <h2>Upload Text Documents</h2>
                <p style="margin-bottom: 20px; color: #666;">Upload text documents to create your knowledge base.</p>
                
                <div class="example-buttons">
                    <button class="example-btn" onclick="loadExample('upload', 'simple')">Simple Example</button>
                    <button class="example-btn" onclick="loadExample('upload', 'multiple')">Multiple Docs</button>
                    <button class="example-btn" onclick="loadExample('upload', 'technical')">Technical Content</button>
                </div>
                
                <div class="form-group">
                    <label for="uploadTexts">Document Contents (JSON array of strings)</label>
                    <textarea id="uploadTexts" placeholder='["Your first document content...", "Your second document..."]'></textarea>
                </div>
                
                <div class="form-group">
                    <label for="uploadSources">File Sources (optional, JSON array)</label>
                    <input type="text" id="uploadSources" placeholder='["doc1.txt", "doc2.txt"]'>
                </div>
                
                <button onclick="uploadDocuments()">Upload Documents</button>
                
                <div id="uploadResponse" class="response" style="display: none;">
                    <h3>Response <span id="uploadStatus" class="status"></span></h3>
                    <pre id="uploadResult"></pre>
                </div>
            </div>
            
            <!-- Pipeline Status Tab -->
            <div id="status" class="tab-content">
                <h2>Check Pipeline Status</h2>
                <p style="margin-bottom: 20px; color: #666;">Monitor the processing status of your documents.</p>
                
                <button onclick="checkStatus()">Check Status</button>
                
                <div id="statusResponse" class="response" style="display: none;">
                    <h3>Pipeline Status <span id="pipelineStatus" class="status"></span></h3>
                    <pre id="statusResult"></pre>
                </div>
            </div>
            
            <!-- Query (OpenAI) Tab -->
            <div id="query" class="tab-content">
                <h2>Query Using OpenAI Interface</h2>
                <p style="margin-bottom: 20px; color: #666;">Query your knowledge base using the OpenAI-compatible endpoint.</p>
                
                <div class="example-buttons">
                    <button class="example-btn" onclick="loadExample('query', 'simple')">Simple Query</button>
                    <button class="example-btn" onclick="loadExample('query', 'analysis')">Analysis Query</button>
                    <button class="example-btn" onclick="loadExample('query', 'summary')">Summary Query</button>
                </div>
                
                <div class="form-group">
                    <label for="queryModel">Model</label>
                    <select id="queryModel">
                        <option value="vedaya-hybrid">vedaya-hybrid (Combined approach)</option>
                        <option value="vedaya-naive">vedaya-naive (Keyword search)</option>
                        <option value="vedaya-local">vedaya-local (Entity-focused)</option>
                        <option value="vedaya-global">vedaya-global (Relationship-focused)</option>
                    </select>
                </div>
                
                <div class="form-group">
                    <label for="queryText">Your Question</label>
                    <textarea id="queryText" placeholder="What are the main topics in the documents?"></textarea>
                </div>
                
                <div class="form-group">
                    <label for="queryTemp">Temperature (0-1)</label>
                    <input type="number" id="queryTemp" value="0.7" min="0" max="1" step="0.1">
                </div>
                
                <div class="form-group">
                    <label for="queryTokens">Max Tokens</label>
                    <input type="number" id="queryTokens" value="500" min="50" max="2000">
                </div>
                
                <button onclick="queryOpenAI()">Send Query</button>
                
                <div id="queryResponse" class="response" style="display: none;">
                    <h3>Response <span id="queryStatus" class="status"></span></h3>
                    <pre id="queryResult"></pre>
                </div>
            </div>
            
            <!-- Direct Query Tab -->
            <div id="directQuery" class="tab-content">
                <h2>Direct Query API</h2>
                <p style="margin-bottom: 20px; color: #666;">Use the native query endpoint with more control.</p>
                
                <div class="form-group">
                    <label for="directQueryText">Query</label>
                    <textarea id="directQueryText" placeholder="Your question here..."></textarea>
                </div>
                
                <div class="form-group">
                    <label for="directMode">Mode</label>
                    <select id="directMode">
                        <option value="hybrid">Hybrid</option>
                        <option value="naive">Naive</option>
                        <option value="local">Local</option>
                        <option value="global">Global</option>
                    </select>
                </div>
                
                <div class="form-group">
                    <label for="directTopK">Top K Results</label>
                    <input type="number" id="directTopK" value="20" min="1" max="100">
                </div>
                
                <div class="form-group">
                    <label for="directResponseType">Response Type</label>
                    <select id="directResponseType">
                        <option value="Multiple Paragraphs">Multiple Paragraphs</option>
                        <option value="Single Paragraph">Single Paragraph</option>
                        <option value="Bullet Points">Bullet Points</option>
                    </select>
                </div>
                
                <button onclick="directQuery()">Send Direct Query</button>
                
                <div id="directResponse" class="response" style="display: none;">
                    <h3>Response <span id="directStatus" class="status"></span></h3>
                    <pre id="directResult"></pre>
                </div>
            </div>
            
            <!-- Knowledge Graph Tab -->
            <div id="graph" class="tab-content">
                <h2>Knowledge Graph</h2>
                <p style="margin-bottom: 20px; color: #666;">Explore entities and relationships in your knowledge base.</p>
                
                <button onclick="getGraphSummary()">Get Graph Summary</button>
                <button onclick="getEntities()" style="margin-left: 10px;">Get Entities</button>
                <button onclick="getRelationships()" style="margin-left: 10px;">Get Relationships</button>
                
                <div id="graphResponse" class="response" style="display: none;">
                    <h3>Graph Data <span id="graphStatus" class="status"></span></h3>
                    <pre id="graphResult"></pre>
                </div>
            </div>
            
            <!-- List Documents Tab -->
            <div id="docs" class="tab-content">
                <h2>Document Management</h2>
                <p style="margin-bottom: 20px; color: #666;">View and manage uploaded documents.</p>
                
                <button onclick="listDocuments()">List All Documents</button>
                <button onclick="clearDocuments()" style="margin-left: 10px; background: #ef4444;">Clear All Documents</button>
                
                <div id="docsResponse" class="response" style="display: none;">
                    <h3>Documents <span id="docsStatus" class="status"></span></h3>
                    <pre id="docsResult"></pre>
                </div>
            </div>
        </div>
    </div>
    
    <script>
        // Configuration - update these if needed
        const API_BASE = 'https://vedaya-kge.fly.dev';  // no trailing slash
        const API_KEY = '';  // leave empty if no auth, or add your token
        
        // Tab switching
        function showTab(tabName) {
            // Hide all tabs
            document.querySelectorAll('.tab-content').forEach(tab => {
                tab.classList.remove('active');
            });
            document.querySelectorAll('.tab').forEach(btn => {
                btn.classList.remove('active');
            });
            
            // Show selected tab
            document.getElementById(tabName).classList.add('active');
            event.target.classList.add('active');
        }
        
        // Load example data
        function loadExample(tab, example) {
            const examples = {
                upload: {
                    simple: {
                        texts: '["Artificial Intelligence is transforming how we work and live. Machine learning models can now understand and generate human language with remarkable accuracy."]',
                        sources: '["ai_intro.txt"]'
                    },
                    multiple: {
                        texts: '["Document 1: The history of computing began with mechanical calculators.", "Document 2: Modern computers use silicon chips to process information.", "Document 3: Quantum computing represents the next frontier in computational power."]',
                        sources: '["history.txt", "modern.txt", "quantum.txt"]'
                    },
                    technical: {
                        texts: '["Neural networks consist of interconnected nodes that process information. Deep learning uses multiple layers to extract features from data. Transformer architectures have revolutionized NLP tasks."]',
                        sources: '["ml_technical.txt"]'
                    }
                },
                query: {
                    simple: {
                        text: "What are the main topics discussed in the documents?"
                    },
                    analysis: {
                        text: "Analyze the relationships between the concepts mentioned in the knowledge base."
                    },
                    summary: {
                        text: "Provide a comprehensive summary of all the information in the documents."
                    }
                }
            };
            
            if (tab === 'upload') {
                document.getElementById('uploadTexts').value = examples.upload[example].texts;
                document.getElementById('uploadSources').value = examples.upload[example].sources;
            } else if (tab === 'query') {
                document.getElementById('queryText').value = examples.query[example].text;
            }
        }
        
        // Upload documents
        async function uploadDocuments() {
            const textsValue = document.getElementById('uploadTexts').value;
            const sourcesValue = document.getElementById('uploadSources').value;
            
            try {
                const texts = JSON.parse(textsValue);
                const sources = sourcesValue ? JSON.parse(sourcesValue) : texts.map((_, i) => `doc_${i}.txt`);
                
                showLoading('uploadResult', 'uploadStatus');
                
                const response = await fetch(`${API_BASE}/documents/texts`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${API_KEY}`
                    },
                    body: JSON.stringify({
                        texts: texts,
                        file_sources: sources
                    })
                });
                
                const data = response.ok ? await response.json() : await response.text();
                showResponse('uploadResult', 'uploadResponse', 'uploadStatus', data, response.ok);
                
                if (response.ok) {
                    // Auto-check status after upload
                    setTimeout(() => checkStatus(), 2000);
                }
            } catch (error) {
                showResponse('uploadResult', 'uploadResponse', 'uploadStatus', { error: error.message }, false);
            }
        }
        
        // Check pipeline status
        async function checkStatus() {
            try {
                showLoading('statusResult', 'pipelineStatus');
                
                const response = await fetch(`${API_BASE}/documents/pipeline_status`, {
                    headers: {
                        'Authorization': `Bearer ${API_KEY}`
                    }
                });
                
                const data = await response.json();
                showResponse('statusResult', 'statusResponse', 'pipelineStatus', data, response.ok, 
                    data.busy ? 'processing' : 'success');
            } catch (error) {
                showResponse('statusResult', 'statusResponse', 'pipelineStatus', { error: error.message }, false);
            }
        }
        
        // Query using OpenAI interface
        async function queryOpenAI() {
            const model = document.getElementById('queryModel').value;
            const text = document.getElementById('queryText').value;
            const temperature = parseFloat(document.getElementById('queryTemp').value);
            const maxTokens = parseInt(document.getElementById('queryTokens').value);
            
            try {
                showLoading('queryResult', 'queryStatus');
                
                const response = await fetch(`${API_BASE}/v1/chat/completions`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${API_KEY}`
                    },
                    body: JSON.stringify({
                        model: model,
                        messages: [{ role: 'user', content: text }],
                        temperature: temperature,
                        max_tokens: maxTokens
                    })
                });
                
                const data = await response.json();
                showResponse('queryResult', 'queryResponse', 'queryStatus', data, response.ok);
            } catch (error) {
                showResponse('queryResult', 'queryResponse', 'queryStatus', { error: error.message }, false);
            }
        }
        
        // Direct query
        async function directQuery() {
            const query = document.getElementById('directQueryText').value;
            const mode = document.getElementById('directMode').value;
            const topK = parseInt(document.getElementById('directTopK').value);
            const responseType = document.getElementById('directResponseType').value;
            
            try {
                showLoading('directResult', 'directStatus');
                
                const response = await fetch(`${API_BASE}/query`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${API_KEY}`
                    },
                    body: JSON.stringify({
                        query: query,
                        mode: mode,
                        top_k: topK,
                        response_type: responseType,
                        llm_model: 'gpt-4',
                        llm_provider: 'openai'
                    })
                });
                
                const data = await response.json();
                showResponse('directResult', 'directResponse', 'directStatus', data, response.ok);
            } catch (error) {
                showResponse('directResult', 'directResponse', 'directStatus', { error: error.message }, false);
            }
        }
        
        // Get graph summary
        async function getGraphSummary() {
            try {
                showLoading('graphResult', 'graphStatus');
                
                const response = await fetch(`${API_BASE}/knowledge_graph/summary`, {
                    headers: {
                        'Authorization': `Bearer ${API_KEY}`
                    }
                });
                
                const data = await response.json();
                showResponse('graphResult', 'graphResponse', 'graphStatus', data, response.ok);
            } catch (error) {
                showResponse('graphResult', 'graphResponse', 'graphStatus', { error: error.message }, false);
            }
        }
        
        // Get entities
        async function getEntities() {
            try {
                showLoading('graphResult', 'graphStatus');
                
                const response = await fetch(`${API_BASE}/knowledge_graph/entities`, {
                    headers: {
                        'Authorization': `Bearer ${API_KEY}`
                    }
                });
                
                const data = await response.json();
                showResponse('graphResult', 'graphResponse', 'graphStatus', data, response.ok);
            } catch (error) {
                showResponse('graphResult', 'graphResponse', 'graphStatus', { error: error.message }, false);
            }
        }
        
        // Get relationships
        async function getRelationships() {
            try {
                showLoading('graphResult', 'graphStatus');
                
                const response = await fetch(`${API_BASE}/knowledge_graph/relationships`, {
                    headers: {
                        'Authorization': `Bearer ${API_KEY}`
                    }
                });
                
                const data = await response.json();
                showResponse('graphResult', 'graphResponse', 'graphStatus', data, response.ok);
            } catch (error) {
                showResponse('graphResult', 'graphResponse', 'graphStatus', { error: error.message }, false);
            }
        }
        
        // List documents
        async function listDocuments() {
            try {
                showLoading('docsResult', 'docsStatus');
                
                const response = await fetch(`${API_BASE}/documents`, {
                    headers: {
                        'Authorization': `Bearer ${API_KEY}`
                    }
                });
                
                const data = await response.json();
                showResponse('docsResult', 'docsResponse', 'docsStatus', data, response.ok);
            } catch (error) {
                showResponse('docsResult', 'docsResponse', 'docsStatus', { error: error.message }, false);
            }
        }
        
        // Clear all documents
        async function clearDocuments() {
            if (!confirm('Are you sure you want to clear all documents? This cannot be undone.')) return;
            
            try {
                showLoading('docsResult', 'docsStatus');
                
                const response = await fetch(`${API_BASE}/documents/clear`, {
                    method: 'POST',
                    headers: {
                        'Authorization': `Bearer ${API_KEY}`
                    }
                });
                
                const data = response.ok ? { message: 'All documents cleared successfully' } : await response.text();
                showResponse('docsResult', 'docsResponse', 'docsStatus', data, response.ok);
            } catch (error) {
                showResponse('docsResult', 'docsResponse', 'docsStatus', { error: error.message }, false);
            }
        }
        
        // Helper functions
        function showLoading(resultId, statusId) {
            document.getElementById(resultId).innerHTML = '<span class="loading"></span> Processing...';
            document.getElementById(statusId).className = 'status processing';
            document.getElementById(statusId).textContent = 'Processing';
            document.getElementById(resultId).parentElement.style.display = 'block';
        }
        
        function showResponse(resultId, responseId, statusId, data, success, statusType = null) {
            const resultEl = document.getElementById(resultId);
            const statusEl = document.getElementById(statusId);
            
            resultEl.textContent = JSON.stringify(data, null, 2);
            statusEl.className = `status ${statusType || (success ? 'success' : 'error')}`;
            statusEl.textContent = statusType === 'processing' ? 'Processing' : (success ? 'Success' : 'Error');
            document.getElementById(responseId).style.display = 'block';
        }
        
        // Load initial example
        window.onload = function() {
            loadExample('upload', 'simple');
        };
    </script>
</body>
</html>

Live API Endpoints

Test these endpoints directly:

Upload Documents

curl -X POST https://vedaya-kge.fly.dev/documents/texts \
  -H "Content-Type: application/json" \
  -d '{"texts": ["Your document"]}'

Check Status

curl https://vedaya-kge.fly.dev/documents/pipeline_status

Query (OpenAI)

curl -X POST https://vedaya-kge.fly.dev/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "vedaya-hybrid", "messages": [{"role": "user", "content": "Query"}]}'

Knowledge Graph

curl https://vedaya-kge.fly.dev/knowledge_graph/summary

Quick Copy-Paste Examples

Minimal Test

import os
import requests
from openai import OpenAI

# Configure API (prefer environment variables)
API_BASE_URL = os.getenv("VEDAYA_API_BASE_URL", "https://vedaya-kge.fly.dev")
API_KEY = os.getenv("VEDAYA_API_KEY", "")

# Build headers
headers = {"Content-Type": "application/json"}
if API_KEY and API_KEY.strip() and API_KEY != "sk-mock-dummy-key":
    headers["Authorization"] = f"Bearer {API_KEY}"

# Upload
requests.post(f"{API_BASE_URL}/documents/texts", 
              json={"texts": ["Test document"]},
              headers=headers)

# Query
client = OpenAI(
    api_key=API_KEY if API_KEY else "sk-dummy",
    base_url=f"{API_BASE_URL}/v1"
)
response = client.chat.completions.create(
    model="vedaya-hybrid",
    messages=[{"role": "user", "content": "What's in the docs?"}]
)
print(response.choices[0].message.content)

Full Workflow

import os
import requests
import time
from openai import OpenAI

# Configure API (prefer environment variables)
API_BASE_URL = os.getenv("VEDAYA_API_BASE_URL", "https://vedaya-kge.fly.dev")
API_KEY = os.getenv("VEDAYA_API_KEY", "")

# Build headers
headers = {"Content-Type": "application/json"}
if API_KEY and API_KEY.strip() and API_KEY != "sk-mock-dummy-key":
    headers["Authorization"] = f"Bearer {API_KEY}"

# 1. Upload documents
docs = ["Your content here", "More content"]
requests.post(f"{API_BASE_URL}/documents/texts", 
              json={"texts": docs},
              headers=headers)

# 2. Wait for processing
for _ in range(15):
    status = requests.get(f"{API_BASE_URL}/documents/pipeline_status", headers=headers).json()
    if not status.get('busy'): break
    time.sleep(2)

# 3. Query
client = OpenAI(
    api_key=API_KEY if API_KEY else "sk-dummy",
    base_url=f"{API_BASE_URL}/v1"
)
response = client.chat.completions.create(
    model="vedaya-hybrid",
    messages=[{"role": "user", "content": "Summarize the documents"}]
)
print(response.choices[0].message.content)

Tips for Testing

  1. Fast Processing: Documents typically process in 2-5 seconds
  2. Model Selection: Use vedaya-hybrid for best results
  3. Error Handling: The API returns descriptive error messages
  4. Batch Upload: You can upload multiple documents in one request

Next Steps

  • Save the HTML code above as vedaya-playground.html and open in your browser
  • Use the Python or JavaScript classes in your own projects
  • Explore the API Reference for detailed documentation
  • Watch the Product Demo to see advanced features