let eventSource = null;
const examples = {
initialize: [
{
"jsonrpc": "2.0",
"id": "1",
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "Test Client", "version": "1.0.0"}
}
}
],
resources: [
{
"jsonrpc": "2.0",
"id": "1",
"method": "resources/list",
"params": {"base": "."}
}
],
tools: [
{
"jsonrpc": "2.0",
"id": "1",
"method": "tools/call",
"params": {
"name": "sum_values",
"arguments": {"a": 5, "b": 3}
}
}
]
};
function loadExample(type) {
const textarea = document.getElementById('requestPayload');
textarea.value = JSON.stringify(examples[type], null, 2);
}
async function sendRequest() {
const token = document.getElementById('authToken').value;
const payload = document.getElementById('requestPayload').value;
const responseDiv = document.getElementById('response');
try {
const response = await fetch('/rpc', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: payload
});
const result = await response.json();
responseDiv.innerHTML = `
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">Response</h5>
<span class="badge ${response.ok ? 'bg-success' : 'bg-danger'}">
${response.status} ${response.statusText}
</span>
</div>
<div class="card-body">
<pre class="bg-dark p-3 rounded"><code>${JSON.stringify(result, null, 2)}</code></pre>
</div>
</div>
`;
} catch (error) {
responseDiv.innerHTML = `
<div class="alert alert-danger">
<h5><i class="fas fa-exclamation-triangle me-2"></i>Error</h5>
<p>${error.message}</p>
</div>
`;
}
}
function startSSE() {
const token = document.getElementById('authToken').value;
const prompt = document.getElementById('ssePrompt').value;
const output = document.getElementById('sseOutput');
const stopBtn = document.getElementById('stopBtn');
if (eventSource) {
eventSource.close();
}
output.innerHTML = '<div class="text-info">Connecting to stream...</div>';
const url = `/events?prompt=${encodeURIComponent(prompt)}&id=test-stream&token=${encodeURIComponent(token)}`;
eventSource = new EventSource(url);
// Set headers for EventSource (Note: EventSource doesn't support custom headers directly)
// For production, consider using fetch with streaming response reader
eventSource.onopen = function() {
output.innerHTML = '<div class="text-success">Connected. Waiting for response...</div>';
stopBtn.disabled = false;
};
eventSource.addEventListener('chunk', function(event) {
const data = JSON.parse(event.data);
if (data.content) {
output.innerHTML += data.content;
output.scrollTop = output.scrollHeight;
}
});
eventSource.addEventListener('complete', function(event) {
output.innerHTML += '<div class="text-success mt-2">--- Stream completed ---</div>';
eventSource.close();
eventSource = null;
stopBtn.disabled = true;
});
eventSource.addEventListener('error', function(event) {
const data = event.data ? JSON.parse(event.data) : {error: 'Connection error'};
output.innerHTML += `<div class="text-danger mt-2">Error: ${data.error}</div>`;
eventSource.close();
eventSource = null;
stopBtn.disabled = true;
});
eventSource.onerror = function(event) {
output.innerHTML += '<div class="text-danger mt-2">Connection error occurred</div>';
stopBtn.disabled = true;
};
}
function stopSSE() {
if (eventSource) {
eventSource.close();
eventSource = null;
document.getElementById('stopBtn').disabled = true;
document.getElementById('sseOutput').innerHTML += '<div class="text-warning mt-2">--- Stream stopped by user ---</div>';
}
}
function testSSE() {
// Test with the working test endpoint first
const output = document.getElementById('sseOutput');
const stopBtn = document.getElementById('stopBtn');
if (eventSource) {
eventSource.close();
}
output.innerHTML = '<div class="text-info">Testing SSE stream without OpenAI...</div>';
eventSource = new EventSource('/test-stream');
eventSource.onopen = function() {
output.innerHTML = '<div class="text-success">Connected to test stream...</div>';
stopBtn.disabled = false;
};
eventSource.onmessage = function(event) {
output.innerHTML += '<div class="text-white">' + event.data + '</div>';
output.scrollTop = output.scrollHeight;
};
eventSource.onerror = function(event) {
output.innerHTML += '<div class="text-danger">Stream ended or error occurred</div>';
eventSource.close();
eventSource = null;
stopBtn.disabled = true;
};
}
// Handle authentication note
document.addEventListener('DOMContentLoaded', function() {
const authToken = document.getElementById('authToken');
const note = document.createElement('small');
note.className = 'form-text text-muted';
note.innerHTML = '<i class="fas fa-info-circle me-1"></i>Default token "devtoken" is provided for development. Use proper JWT tokens in production.';
authToken.parentNode.appendChild(note);
});