diff --git a/openhands/runtime/builder/docker.py b/openhands/runtime/builder/docker.py index ebb623c6f1..050471a67e 100644 --- a/openhands/runtime/builder/docker.py +++ b/openhands/runtime/builder/docker.py @@ -19,16 +19,19 @@ class DockerRuntimeBuilder(RuntimeBuilder): version_info = self.docker_client.version() server_version = version_info.get('Version', '').replace('-', '.') - self.is_podman = version_info.get('Components')[0].get('Name').startswith('Podman') - if tuple(map(int, server_version.split('.')[:2])) < (18, 9) and not self.is_podman: + self.is_podman = ( + version_info.get('Components')[0].get('Name').startswith('Podman') + ) + if ( + tuple(map(int, server_version.split('.')[:2])) < (18, 9) + and not self.is_podman + ): raise AgentRuntimeBuildError( 'Docker server version must be >= 18.09 to use BuildKit' ) if self.is_podman and tuple(map(int, server_version.split('.')[:2])) < (4, 9): - raise AgentRuntimeBuildError( - 'Podman server version must be >= 4.9.0' - ) + raise AgentRuntimeBuildError('Podman server version must be >= 4.9.0') self.rolling_logger = RollingLogger(max_lines=10) @@ -37,7 +40,9 @@ class DockerRuntimeBuilder(RuntimeBuilder): """Check if Docker Buildx is available""" try: result = subprocess.run( - ['docker' if not is_podman else 'podman', 'buildx', 'version'], capture_output=True, text=True + ['docker' if not is_podman else 'podman', 'buildx', 'version'], + capture_output=True, + text=True, ) return result.returncode == 0 except FileNotFoundError: @@ -74,16 +79,16 @@ class DockerRuntimeBuilder(RuntimeBuilder): self.docker_client = docker.from_env() version_info = self.docker_client.version() server_version = version_info.get('Version', '').split('+')[0].replace('-', '.') - self.is_podman = version_info.get('Components')[0].get('Name').startswith('Podman') + self.is_podman = ( + version_info.get('Components')[0].get('Name').startswith('Podman') + ) if tuple(map(int, server_version.split('.'))) < (18, 9) and not self.is_podman: raise AgentRuntimeBuildError( 'Docker server version must be >= 18.09 to use BuildKit' ) if self.is_podman and tuple(map(int, server_version.split('.'))) < (4, 9): - raise AgentRuntimeBuildError( - 'Podman server version must be >= 4.9.0' - ) + raise AgentRuntimeBuildError('Podman server version must be >= 4.9.0') if not DockerRuntimeBuilder.check_buildx(self.is_podman): # when running openhands in a container, there might not be a "docker" diff --git a/openhands/runtime/impl/docker/docker_runtime.py b/openhands/runtime/impl/docker/docker_runtime.py index adc2579731..57f8b2f826 100644 --- a/openhands/runtime/impl/docker/docker_runtime.py +++ b/openhands/runtime/impl/docker/docker_runtime.py @@ -333,7 +333,10 @@ class DockerRuntime(ActionExecutionClient): if exposed_ports: for exposed_port in exposed_ports.keys(): exposed_port = int(exposed_port.split('/tcp')[0]) - if exposed_port != self._host_port and exposed_port != self._vscode_port: + if ( + exposed_port != self._host_port + and exposed_port != self._vscode_port + ): self._app_ports.append(exposed_port) self.api_url = f'{self.config.sandbox.local_runtime_url}:{self._container_port}' diff --git a/openhands/runtime/utils/vscode-extensions/memory-monitor/README.md b/openhands/runtime/utils/vscode-extensions/memory-monitor/README.md index d66b746696..b33ed8aa81 100644 --- a/openhands/runtime/utils/vscode-extensions/memory-monitor/README.md +++ b/openhands/runtime/utils/vscode-extensions/memory-monitor/README.md @@ -45,4 +45,4 @@ This extension is part of the OpenHands project. To modify or extend it: ## License -This extension is licensed under the MIT license. \ No newline at end of file +This extension is licensed under the MIT license. diff --git a/openhands/runtime/utils/vscode-extensions/memory-monitor/extension.js b/openhands/runtime/utils/vscode-extensions/memory-monitor/extension.js index a0ba135c7c..eb684cccbf 100644 --- a/openhands/runtime/utils/vscode-extensions/memory-monitor/extension.js +++ b/openhands/runtime/utils/vscode-extensions/memory-monitor/extension.js @@ -4,30 +4,30 @@ const MemoryMonitor = require('./memory_monitor'); function activate(context) { // Create memory monitor instance const memoryMonitor = new MemoryMonitor(); - + // Store the context in the memory monitor memoryMonitor.context = context; - + // Register memory monitor start command let startMonitorCommand = vscode.commands.registerCommand('openhands-memory-monitor.startMemoryMonitor', function () { memoryMonitor.start(); }); - + // Register memory monitor stop command let stopMonitorCommand = vscode.commands.registerCommand('openhands-memory-monitor.stopMemoryMonitor', function () { memoryMonitor.stop(); }); - + // Register memory details command let showMemoryDetailsCommand = vscode.commands.registerCommand('openhands-memory-monitor.showMemoryDetails', function () { memoryMonitor.showDetails(); }); - + // Add all commands to subscriptions context.subscriptions.push(startMonitorCommand); context.subscriptions.push(stopMonitorCommand); context.subscriptions.push(showMemoryDetailsCommand); - + // Start memory monitoring by default memoryMonitor.start(); } @@ -39,4 +39,4 @@ function deactivate() { module.exports = { activate, deactivate -} \ No newline at end of file +} diff --git a/openhands/runtime/utils/vscode-extensions/memory-monitor/memory_monitor.js b/openhands/runtime/utils/vscode-extensions/memory-monitor/memory_monitor.js index b8ebe21546..4c595105fe 100644 --- a/openhands/runtime/utils/vscode-extensions/memory-monitor/memory_monitor.js +++ b/openhands/runtime/utils/vscode-extensions/memory-monitor/memory_monitor.js @@ -21,15 +21,15 @@ class MemoryMonitor { this.isMonitoring = true; this.statusBarItem.show(); - + // Initial update this.updateMemoryInfo(); - + // Set interval for updates this.intervalId = setInterval(() => { this.updateMemoryInfo(); }, interval); - + vscode.window.showInformationMessage('Memory monitoring started'); } @@ -41,7 +41,7 @@ class MemoryMonitor { this.isMonitoring = false; clearInterval(this.intervalId); this.statusBarItem.hide(); - + vscode.window.showInformationMessage('Memory monitoring stopped'); } @@ -49,18 +49,18 @@ class MemoryMonitor { const totalMem = os.totalmem(); const freeMem = os.freemem(); const usedMem = totalMem - freeMem; - + // Calculate memory usage percentage const memUsagePercent = Math.round((usedMem / totalMem) * 100); - + // Format memory values to MB const usedMemMB = Math.round(usedMem / (1024 * 1024)); const totalMemMB = Math.round(totalMem / (1024 * 1024)); - + // Update status bar this.statusBarItem.text = `$(pulse) Mem: ${memUsagePercent}%`; this.statusBarItem.tooltip = `Memory Usage: ${usedMemMB}MB / ${totalMemMB}MB`; - + // Store memory data in history this.memoryHistory.push({ timestamp: new Date(), @@ -69,7 +69,7 @@ class MemoryMonitor { memUsagePercent, processMemory: process.memoryUsage() }); - + // Limit history length if (this.memoryHistory.length > this.maxHistoryLength) { this.memoryHistory.shift(); @@ -86,7 +86,7 @@ class MemoryMonitor { enableScripts: true } ); - + // Set up message handler for real-time updates panel.webview.onDidReceiveMessage( message => { @@ -97,60 +97,60 @@ class MemoryMonitor { undefined, this.context ? this.context.subscriptions : [] ); - + // Initial update this.updateWebviewContent(panel); - + // Handle panel disposal panel.onDidDispose(() => { // Clean up any resources if needed }, null, this.context ? this.context.subscriptions : []); } - + updateWebviewContent(panel) { // Get system memory info const totalMem = os.totalmem(); const freeMem = os.freemem(); const usedMem = totalMem - freeMem; - + // Format memory values const usedMemMB = Math.round(usedMem / (1024 * 1024)); const freeMemMB = Math.round(freeMem / (1024 * 1024)); const totalMemMB = Math.round(totalMem / (1024 * 1024)); - + // Get process memory usage const processMemory = process.memoryUsage(); const rss = Math.round(processMemory.rss / (1024 * 1024)); const heapTotal = Math.round(processMemory.heapTotal / (1024 * 1024)); const heapUsed = Math.round(processMemory.heapUsed / (1024 * 1024)); - + // Get process information this.processMonitor.getProcessInfo((error, processInfo) => { if (error) { console.error('Error getting process info:', error); return; } - + // Create HTML content for the webview const htmlContent = this.generateHtmlReport( - usedMemMB, freeMemMB, totalMemMB, + usedMemMB, freeMemMB, totalMemMB, rss, heapTotal, heapUsed, processInfo ); - + // Set the webview's HTML content panel.webview.html = htmlContent; }); } - + generateHtmlReport(usedMemMB, freeMemMB, totalMemMB, rss, heapTotal, heapUsed, processInfo) { // Create memory usage history data for chart const memoryLabels = this.memoryHistory.map((entry, index) => index); const memoryData = this.memoryHistory.map(entry => entry.memUsagePercent); - const heapData = this.memoryHistory.map(entry => + const heapData = this.memoryHistory.map(entry => Math.round(entry.processMemory.heapUsed / (1024 * 1024)) ); - + // Format process info table let processTable = ''; if (processInfo && processInfo.processes) { @@ -174,7 +174,7 @@ class MemoryMonitor { `; } - + return ` @@ -237,7 +237,7 @@ class MemoryMonitor {