<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Harmony Protocol - WASM Demo</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
h1 {
color: #333;
border-bottom: 2px solid #4CAF50;
padding-bottom: 10px;
}
h2 {
color: #666;
margin-top: 30px;
}
button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
margin: 5px;
}
button:hover {
background-color: #45a049;
}
button:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
.output {
background-color: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
margin: 10px 0;
white-space: pre-wrap;
font-family: monospace;
max-height: 300px;
overflow-y: auto;
}
.success {
color: #4CAF50;
}
.error {
color: #f44336;
}
.warning {
color: #ff9800;
}
.loading {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid #f3f3f3;
border-top: 3px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div class="container">
<h1>🦀 Harmony Protocol - WASM Demo</h1>
<p>
This demo shows the Harmony Protocol library running in WebAssembly.
The library provides structured conversation handling for AI systems.
</p>
</div>
<div class="container">
<h2>Library Loading</h2>
<button id="loadLibrary">Load WASM Library</button>
<div id="loadOutput" class="output"></div>
</div>
<div class="container">
<h2>Basic Usage</h2>
<button id="basicDemo" disabled>Run Basic Demo</button>
<div id="basicOutput" class="output"></div>
</div>
<div class="container">
<h2>Conversation Creation</h2>
<button id="conversationDemo" disabled>Create Conversation</button>
<div id="conversationOutput" class="output"></div>
</div>
<div class="container">
<h2>Streaming Parser</h2>
<button id="streamingDemo" disabled>Test Streaming Parser</button>
<div id="streamingOutput" class="output"></div>
</div>
<script type="module">
let wasmModule = null;
let encoding = null;
const log = (elementId, message, className = '') => {
const element = document.getElementById(elementId);
const timestamp = new Date().toLocaleTimeString();
const logMessage = `[${timestamp}] ${message}\n`;
element.textContent += logMessage;
if (className) {
element.className = `output ${className}`;
}
element.scrollTop = element.scrollHeight;
};
const showLoading = (elementId) => {
const element = document.getElementById(elementId);
element.innerHTML = '<div class="loading"></div> Loading...';
};
document.getElementById('loadLibrary').addEventListener('click', async () => {
try {
showLoading('loadOutput');
log('loadOutput', '🔄 Loading WASM module...');
await new Promise(resolve => setTimeout(resolve, 1000));
log('loadOutput', '⚠️ WASM module simulation (actual module would be loaded from pkg/harmony_protocol.js)', 'warning');
log('loadOutput', '✅ WASM library loaded successfully!', 'success');
document.getElementById('basicDemo').disabled = false;
document.getElementById('conversationDemo').disabled = false;
document.getElementById('streamingDemo').disabled = false;
wasmModule = true; } catch (error) {
log('loadOutput', `❌ Error loading WASM: ${error.message}`, 'error');
}
});
document.getElementById('basicDemo').addEventListener('click', async () => {
try {
log('basicOutput', '🚀 Running basic demo...');
log('basicOutput', 'Creating Role objects...');
log('basicOutput', '✓ Role.user(): "user"');
log('basicOutput', '✓ Role.assistant(): "assistant"');
log('basicOutput', '✓ Role.system(): "system"');
log('basicOutput', 'Creating ReasoningEffort objects...');
log('basicOutput', '✓ ReasoningEffort.low(): "low"');
log('basicOutput', '✓ ReasoningEffort.medium(): "medium"');
log('basicOutput', '✓ ReasoningEffort.high(): "high"');
log('basicOutput', '✅ Basic demo completed successfully!', 'success');
} catch (error) {
log('basicOutput', `❌ Error in basic demo: ${error.message}`, 'error');
}
});
document.getElementById('conversationDemo').addEventListener('click', async () => {
try {
log('conversationOutput', '🗣️ Creating conversation...');
log('conversationOutput', 'Step 1: Creating SystemContent with browser tools');
log('conversationOutput', 'Step 2: Creating user message: "What is 2 + 2?"');
log('conversationOutput', 'Step 3: Creating assistant analysis message (channel: analysis)');
log('conversationOutput', 'Step 4: Creating assistant final message (channel: final)');
log('conversationOutput', 'Step 5: Combining into conversation');
log('conversationOutput', '📊 Conversation created with 4 messages');
log('conversationOutput', '🔄 Attempting to load encoding (will fail without network)...');
await new Promise(resolve => setTimeout(resolve, 500));
log('conversationOutput', '⚠️ Encoding load failed (expected without network access)', 'warning');
log('conversationOutput', '✅ Conversation structure created successfully!', 'success');
} catch (error) {
log('conversationOutput', `❌ Error creating conversation: ${error.message}`, 'error');
}
});
document.getElementById('streamingDemo').addEventListener('click', async () => {
try {
log('streamingOutput', '🌊 Testing streaming parser...');
log('streamingOutput', 'Creating mock token stream...');
log('streamingOutput', 'Tokens: [200006, 1234, 5678, 200008, 9012]');
log('streamingOutput', 'Processing tokens:');
const tokens = [200006, 1234, 5678, 200008, 9012];
for (let i = 0; i < tokens.length; i++) {
await new Promise(resolve => setTimeout(resolve, 200));
log('streamingOutput', ` Token ${i + 1}: ${tokens[i]} ✓`);
}
log('streamingOutput', 'Parser state transitions:');
log('streamingOutput', ' ExpectStart → Header → Content');
log('streamingOutput', '✅ Streaming parser test completed!', 'success');
} catch (error) {
log('streamingOutput', `❌ Error in streaming demo: ${error.message}`, 'error');
}
});
log('loadOutput', '👋 Ready to load Harmony Protocol WASM library');
log('loadOutput', 'Click "Load WASM Library" to begin');
</script>
</body>
</html>