computer-agent / scripts_and_styling.py
M-Rique's picture
Add streaming, more robust logs
8b6a4c9
SANDBOX_HTML_TEMPLATE = """
<style>
@import url('https://fonts.googleapis.com/css2?family=Oxanium:[email protected]&display=swap');
</style>
<h1 style="color:var(--color-accent);margin:0;">Open Computer Agent - <i>Powered by <a href="https://github.com/huggingface/smolagents">smolagents</a></i><h1>
<div class="sandbox-container" style="margin:0;">
<div class="status-bar">
<div class="status-indicator {status_class}"></div>
<div class="status-text">{status_text}</div>
</div>
<iframe id="sandbox-iframe"
src="{stream_url}"
class="sandbox-iframe"
style="display: block;"
allowfullscreen>
</iframe>
<img src="https://huggingface.co/datasets/mfarre/servedfiles/resolve/main/blue_screen_of_death.gif" class="bsod-image" style="display: none;"/>
<img src="https://huggingface.co/datasets/m-ric/images/resolve/main/HUD_thom.png" class="sandbox-frame" />
</div>
"""
SANDBOX_CSS_TEMPLATE = """
.modal-container {
margin: var(--size-16) auto!important;
}
.sandbox-container {
position: relative;
width: 910px;
overflow: hidden;
margin: auto;
}
.sandbox-container {
height: 800px;
}
.sandbox-frame {
display: none;
position: absolute;
top: 0;
left: 0;
width: 910px;
height: 800px;
pointer-events:none;
}
.sandbox-iframe, .bsod-image {
position: absolute;
width: <<WIDTH>>px;
height: <<HEIGHT>>px;
border: 4px solid #444444;
transform-origin: 0 0;
}
/* Colored label for task textbox */
.primary-color-label label span {
font-weight: bold;
color: var(--color-accent);
}
/* Status indicator light */
.status-bar {
display: flex;
flex-direction: row;
align-items: center;
flex-align:center;
z-index: 100;
}
.status-indicator {
width: 15px;
height: 15px;
border-radius: 50%;
}
.status-text {
font-size: 16px;
font-weight: bold;
padding-left: 8px;
text-shadow: none;
}
.status-interactive {
background-color: #2ecc71;
animation: blink 2s infinite;
}
.status-view-only {
background-color: #e74c3c;
}
.status-error {
background-color: #e74c3c;
animation: blink-error 1s infinite;
}
@keyframes blink-error {
0% { background-color: rgba(231, 76, 60, 1); }
50% { background-color: rgba(231, 76, 60, 0.4); }
100% { background-color: rgba(231, 76, 60, 1); }
}
@keyframes blink {
0% { background-color: rgba(46, 204, 113, 1); } /* Green at full opacity */
50% { background-color: rgba(46, 204, 113, 0.4); } /* Green at 40% opacity */
100% { background-color: rgba(46, 204, 113, 1); } /* Green at full opacity */
}
#chatbot {
height:1000px!important;
}
#chatbot .role {
max-width:95%
}
#chatbot .bubble-wrap {
overflow-y: visible;
}
.logo-container {
display: flex;
flex-direction: column;
align-items: flex-start;
width: 100%;
box-sizing: border-box;
gap: 5px;
.logo-item {
display: flex;
align-items: center;
padding: 0 30px;
gap: 10px;
text-decoration: none!important;
color: #f59e0b;
font-size:17px;
}
.logo-item:hover {
color: #935f06!important;
}
"""
FOOTER_HTML = """
<h3 style="text-align: center; margin-top:50px;"><i>Powered by open source:</i></h2>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div class="logo-container">
<a class="logo-item" href="https://github.com/huggingface/smolagents"><i class="fa fa-github"></i>smolagents</a>
<a class="logo-item" href="https://huggingface.co/Qwen/Qwen2-VL-72B-Instruct"><i class="fa fa-github"></i>Qwen2-VL-72B</a>
<a class="logo-item" href="https://github.com/e2b-dev/desktop"><i class="fa fa-github"></i>E2B Desktop</a>
</div>
"""
CUSTOM_JS = """function() {
document.body.classList.add('dark');
// Function to check if sandbox is timing out
const checkSandboxTimeout = function() {
const timeElement = document.getElementById('sandbox-creation-time');
if (timeElement) {
const creationTime = parseFloat(timeElement.getAttribute('data-time'));
const timeoutValue = parseFloat(timeElement.getAttribute('data-timeout'));
const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds
const elapsedTime = currentTime - creationTime;
console.log("Sandbox running for: " + elapsedTime + " seconds of " + timeoutValue + " seconds");
// If we've exceeded the timeout, show BSOD
if (elapsedTime >= timeoutValue) {
console.log("Sandbox timeout! Showing BSOD");
showBSOD('Error');
// Don't set another timeout, we're done checking
return;
}
}
// Continue checking every 5 seconds
setTimeout(checkSandboxTimeout, 5000);
};
const showBSOD = function(statusText = 'Error') {
console.log("Showing BSOD with status: " + statusText);
const iframe = document.getElementById('sandbox-iframe');
const bsod = document.getElementById('bsod-image');
if (iframe && bsod) {
iframe.style.display = 'none';
bsod.style.display = 'block';
// Update status indicator
const statusIndicator = document.querySelector('.status-indicator');
const statusTextElem = document.querySelector('.status-text');
if (statusIndicator) {
statusIndicator.className = 'status-indicator status-error';
}
if (statusTextElem) {
statusTextElem.innerText = statusText;
}
}
};
const resetBSOD = function() {
console.log("Resetting BSOD display");
const iframe = document.getElementById('sandbox-iframe');
const bsod = document.getElementById('bsod-image');
if (iframe && bsod) {
if (bsod.style.display === 'block') {
// BSOD is currently showing, reset it
iframe.style.display = 'block';
bsod.style.display = 'none';
console.log("BSOD reset complete");
return true; // Indicates reset was performed
}
}
return false; // No reset needed
};
// Function to monitor for error messages
const monitorForErrors = function() {
console.log("Error monitor started");
const resultsInterval = setInterval(function() {
const resultsElements = document.querySelectorAll('textarea, .output-text');
for (let elem of resultsElements) {
const content = elem.value || elem.innerText || '';
if (content.includes('Error running agent')) {
console.log("Error detected!");
showBSOD('Error');
clearInterval(resultsInterval);
break;
}
}
}, 1000);
};
// Start monitoring for timeouts immediately
checkSandboxTimeout();
// Start monitoring for errors
setTimeout(monitorForErrors, 3000);
// Also monitor for errors after button clicks
document.addEventListener('click', function(e) {
if (e.target.tagName === 'BUTTON') {
if (e.target.innerText === "Let's go!") {
resetBSOD();
}
setTimeout(monitorForErrors, 3000);
}
});
// Set up an interval to click the refresh button every 5 seconds
setInterval(function() {
const btn = document.getElementById('refresh-log-btn');
if (btn) btn.click();
}, 5000);
// Force dark mode
const params = new URLSearchParams(window.location.search);
if (!params.has('__theme')) {
params.set('__theme', 'dark');
window.location.search = params.toString();
}
}
"""
def apply_theme(minimalist_mode: bool):
if not minimalist_mode:
return """
<style>
.sandbox-frame {
display: block!important;
}
.sandbox-iframe, .bsod-image {
/* top: 73px; */
top: 99px;
/* left: 74px; */
left: 110px;
}
.sandbox-iframe {
transform: scale(0.535);
}
.status-bar {
position: absolute;
bottom: 88px;
left: 355px;
}
.status-text {
color: #fed244;
}
</style>
"""
else:
return """
<style>
.sandbox-container {
height: 700px!important;
}
.sandbox-iframe {
transform: scale(0.7);
}
</style>
"""