sheikh-llm / templates /chat.html
root
Revamp app with chat studio and tooling
94c8770
{% extends "base.html" %}
{% block title %}Chat Interface - Sheikh LLM Studio{% endblock %}
{% block content %}
<div class="container">
<div class="card">
<h1><i class="fas fa-comments"></i> AI Chat Interface</h1>
<p>Chat with multiple AI models and use advanced tools</p>
</div>
<div class="card">
<div class="chat-container" style="display: grid; grid-template-columns: 1fr 300px; gap: 2rem;">
<div class="chat-messages" id="chatMessages" style="height: 500px; overflow-y: auto; border: 1px solid #e1e5e9; border-radius: 10px; padding: 1rem; background: #f8f9fa;">
<div class="welcome-message">
<div style="text-align: center; color: #666; margin-top: 2rem;">
<i class="fas fa-robot fa-3x" style="color: #667eea; margin-bottom: 1rem;"></i>
<h3>Welcome to Sheikh LLM Chat!</h3>
<p>Select a model and start chatting. You can also use tools like web search and code execution.</p>
</div>
</div>
</div>
<div class="controls-panel">
<div style="margin-bottom: 1.5rem;">
<label for="modelSelect"><strong>Select Model:</strong></label>
<select id="modelSelect" class="btn" style="width: 100%; margin-top: 0.5rem;">
<option value="mistral-small">Mistral Small (24B)</option>
<option value="mistral-large">Mistral Large</option>
<option value="mistral-7b">Mistral 7B</option>
<option value="baby-grok">Baby Grok (1.5B)</option>
</select>
</div>
<div style="margin-bottom: 1.5rem;">
<label><strong>Tools:</strong></label>
<div style="display: flex; flex-direction: column; gap: 0.5rem; margin-top: 0.5rem;">
<button class="btn" onclick="useTool('search')" style="background: #10b981;">
<i class="fas fa-search"></i> Web Search
</button>
<button class="btn" onclick="useTool('code')" style="background: #f59e0b;">
<i class="fas fa-code"></i> Code Execution
</button>
</div>
</div>
<div style="margin-bottom: 1.5rem;">
<label><strong>Parameters:</strong></label>
<div style="margin-top: 0.5rem;">
<label>Max Tokens: <span id="maxTokensValue">500</span></label>
<input type="range" id="maxTokens" min="100" max="2000" value="500" style="width: 100%; margin: 0.5rem 0;">
<label>Temperature: <span id="tempValue">0.7</span></label>
<input type="range" id="temperature" min="0" max="1" step="0.1" value="0.7" style="width: 100%; margin: 0.5rem 0;">
</div>
</div>
</div>
</div>
<div style="display: flex; gap: 1rem; margin-top: 1rem;">
<input type="text" id="messageInput" placeholder="Type your message here..." style="flex: 1; padding: 1rem; border: 1px solid #e1e5e9; border-radius: 8px;" onkeypress="if(event.key === 'Enter') sendMessage()">
<button class="btn" onclick="sendMessage()" style="padding: 1rem 2rem;">
<i class="fas fa-paper-plane"></i> Send
</button>
</div>
</div>
</div>
<script>
let chatHistory = [];
function updateSliderValues() {
document.getElementById('maxTokensValue').textContent = document.getElementById('maxTokens').value;
document.getElementById('tempValue').textContent = document.getElementById('temperature').value;
}
document.getElementById('maxTokens').addEventListener('input', updateSliderValues);
document.getElementById('temperature').addEventListener('input', updateSliderValues);
function addMessage(role, content) {
const messagesDiv = document.getElementById('chatMessages');
const messageDiv = document.createElement('div');
messageDiv.className = `message ${role}`;
messageDiv.innerHTML = `
<div style="margin: 1rem 0; padding: 1rem; border-radius: 10px; ${role === 'user' ? 'background: #667eea; color: white; margin-left: 2rem;' : 'background: white; border: 1px solid #e1e5e9; margin-right: 2rem;'}">
<strong>${role === 'user' ? 'You' : 'AI'}:</strong>
<div>${content}</div>
<small style="opacity: 0.7; font-size: 0.8rem;">${new Date().toLocaleTimeString()}</small>
</div>
`;
messagesDiv.appendChild(messageDiv);
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
async function sendMessage() {
const input = document.getElementById('messageInput');
const message = input.value.trim();
if (!message) return;
addMessage('user', message);
input.value = '';
const model = document.getElementById('modelSelect').value;
const maxTokens = document.getElementById('maxTokens').value;
const temperature = document.getElementById('temperature').value;
try {
const response = await fetch('/api/chat', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
message: message,
model: model,
max_tokens: parseInt(maxTokens),
temperature: parseFloat(temperature),
stream: false
})
});
const data = await response.json();
if (response.ok && data.status === 'success') {
addMessage('assistant', data.response);
} else {
addMessage('assistant', `Error: ${data.detail || 'Unknown error'}`);
}
} catch (error) {
addMessage('assistant', `Connection error: ${error.message}`);
}
}
async function useTool(tool) {
const message = prompt(`Enter parameters for ${tool}:`);
if (!message) return;
try {
const endpoint = tool === 'search' ? '/api/tools/search' : '/api/tools/code';
const response = await fetch(endpoint, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
tool: tool === 'search' ? 'web_search' : 'execute_python',
parameters: { query: message, code: message }
})
});
const data = await response.json();
addMessage('assistant', `Tool result (${tool}): ${JSON.stringify(data, null, 2)}`);
} catch (error) {
addMessage('assistant', `Tool error: ${error.message}`);
}
}
updateSliderValues();
document.getElementById('messageInput').focus();
</script>
{% endblock %}