Skip to main content
Glama

ShallowCodeResearch_code_runner_wrapper

Execute code in a managed sandbox environment with async execution and warm pool support. Provides user-friendly error handling for code execution results.

Instructions

Wrapper for CodeRunnerAgent that uses async execution with warm pool. Ensures a sandbox is spawned if not already present, waits for readiness, and then executes the code. Provides user-friendly error messages. Returns: The execution result or user-friendly error message

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
code_or_objNoThe code string or object to be executed

Implementation Reference

  • app.py:789-829 (handler)
    The main handler function for the code runner tool. It wraps the CodeRunnerAgent's async execution, ensures the sandbox pool is ready, handles warmup delays, and provides user-friendly error messages.
    def code_runner_wrapper(code_or_obj) -> str: """ Wrapper for CodeRunnerAgent that uses async execution with warm pool. Ensures a sandbox is spawned if not already present, waits for readiness, and then executes the code. Provides user-friendly error messages. Args: code_or_obj: The code string or object to be executed Returns: str: The execution result or user-friendly error message """ try: import asyncio async def ensure_and_run(): # Ensure the sandbox pool is initialized and ready await code_runner._ensure_pool_initialized() # Wait for at least one sandbox to be available pool_status = await get_sandbox_pool_status() user_message = pool_status.get("user_message", "") if pool_status.get("status") == "warming_up": return f"{user_message}\n\nPlease try again in a moment once the environment is ready." # Run the code in the sandbox return await code_runner.run_code_async(code_or_obj) return asyncio.run(ensure_and_run()) except CodeExecutionError as e: error_msg = str(e) if "Failed to get sandbox" in error_msg or "timeout" in error_msg.lower(): return ( "🔄 The code execution environment is still starting up. Please wait a moment and try again.\n\n" "This is normal for the first execution after startup (can take 1-2 minutes)." ) return error_msg except Exception as e: logger.error(f"Code runner wrapper error: {e}") return f"Error: {str(e)}"
  • app.py:1028-1036 (registration)
    Gradio Interface registration that exposes the code_runner_wrapper as an MCP tool via api_name="agent_code_runner_service". This is likely prefixed or named as ShallowCodeResearch_code_runner_wrapper in the MCP context.
    with gr.Tab("Agent: Code Runner", scale=1): gr.Interface( fn=code_runner_wrapper, inputs=[gr.Textbox(label="Code to Execute", lines=12, placeholder="Enter Python code to run…")], outputs=gr.Textbox(label="Execution Output", lines=12), title="Code Runner Agent", description="Executes Python code in a secure environment and returns the output.", api_name="agent_code_runner_service", )
  • Core asynchronous code execution logic in CodeRunnerAgent. Handles code preparation, package installation, safety shims, sandbox execution via Modal, and retry logic on sandbox failure.
    @track_performance(operation_name="async_code_execution") @rate_limited("modal") async def run_code_async(self, code_or_obj) -> str: """ Execute Python code or a code object in a Modal sandbox asynchronously. This method supports both string code and compiled code objects, ensuring that the code is executed in a secure, isolated environment with safety checks. Args: code_or_obj (str or types.CodeType): The Python code to execute, either as a string or a compiled code object Returns: str: The output of the executed code, including any print statements """ await self._ensure_pool_initialized() if isinstance(code_or_obj, str): payload = code_or_obj elif isinstance(code_or_obj, types.CodeType): b64 = base64.b64encode(marshal.dumps(code_or_obj)).decode() payload = textwrap.dedent(f""" import base64, marshal, types, traceback code = marshal.loads(base64.b64decode({b64!r})) try: exec(code, {{'__name__': '__main__'}}) except Exception: traceback.print_exc() """).lstrip() else: raise CodeExecutionError("Input must be str or types.CodeType") # Analyze code for required packages start_analysis = time.time() required_packages = self._analyze_code_dependencies(payload) analysis_time = time.time() - start_analysis if analysis_time > 0.1: # Only log if analysis takes significant time logger.info(f"Code dependency analysis took {analysis_time:.2f}s") # Add safety shim safe_code = self._add_safety_shim(payload) filename = "temp_user_code.py" write_cmd = f"cat > {filename} <<'EOF'\n{safe_code}\nEOF" try: async with self.sandbox_pool.get_sandbox() as sb: try: # Install additional packages if needed if required_packages: install_start = time.time() await self._install_packages_in_sandbox(sb, required_packages) install_time = time.time() - install_start logger.info(f"Package installation took {install_time:.2f}s") logger.info(f"Writing code to sandbox file: {filename}") sb.exec("bash", "-c", write_cmd) logger.info(f"Executing code from file: {filename}") exec_start = time.time() proc = sb.exec("python", filename) exec_time = time.time() - exec_start logger.info(f"Code execution took {exec_time:.2f}s") output = "" if hasattr(proc, "stdout") and hasattr(proc.stdout, "read"): output = proc.stdout.read() if hasattr(proc, "stderr") and hasattr(proc.stderr, "read"): output += proc.stderr.read() else: output = str(proc) logger.info("Async code execution completed successfully (warm pool)") return output except Exception as e: if "finished" in str(e) or "NOT_FOUND" in str(e): logger.warning(f"Sandbox died during use, terminating: {e}") try: result = sb.terminate() if asyncio.iscoroutine(result): await result except Exception as term_e: logger.warning(f"Failed to terminate sandbox after error: {term_e}") async with self.sandbox_pool.get_sandbox() as new_sb: # Re-install packages if needed for retry if required_packages: await self._install_packages_in_sandbox(new_sb, required_packages) new_sb.exec("bash", "-c", write_cmd) proc = new_sb.exec("python", filename) output = "" if hasattr(proc, "stdout") and hasattr(proc.stdout, "read"): output = proc.stdout.read() if hasattr(proc, "stderr") and hasattr(proc.stderr, "read"): output += proc.stderr.read() else: output = str(proc) logger.info("Async code execution completed successfully on retry") return output else: logger.error(f"Async code execution failed: {e}") raise CodeExecutionError(f"Error executing code in Modal sandbox: {str(e)}") except CodeExecutionError: raise except asyncio.TimeoutError: logger.error("Async code execution timed out") raise CodeExecutionError("Code execution timed out after 30 seconds") except Exception as e: logger.error(f"Async code execution failed: {str(e)}") raise CodeExecutionError(f"Error executing code in Modal sandbox: {str(e)}")
  • app.py:22-152 (helper)
    Import and global instantiation of the CodeRunnerAgent used by the wrapper.
    from mcp_hub.agents import ( QuestionEnhancerAgent, WebSearchAgent, LLMProcessorAgent, CitationFormatterAgent, CodeGeneratorAgent, CodeRunnerAgent, OrchestratorAgent, ) # Import advanced features with graceful fallback ADVANCED_FEATURES_AVAILABLE = False try: from mcp_hub.performance_monitoring import metrics_collector, track_performance, track_api_call from mcp_hub.health_monitoring import health_monitor ADVANCED_FEATURES_AVAILABLE = True logger.info("Advanced features loaded successfully") except ImportError as e: logger.info(f"Advanced features not available: {e}") logger.info("Running with basic features only") # Create dummy decorators for backward compatibility def track_performance(operation_name: str = None): def decorator(func): return func return decorator def track_api_call(service_name: str): def decorator(func): return func return decorator def rate_limited(service: str = "default", timeout: float = 10.0): def decorator(func): return func return decorator def circuit_protected(service: str = "default"): def decorator(func): return func return decorator def cached(ttl: int = 300): def decorator(func): return func return decorator # Performance tracking wrapper def with_performance_tracking(operation_name: str): """ Add performance tracking and metrics collection to any function (sync or async). This decorator wraps both synchronous and asynchronous functions to collect execution time, success/failure metrics, and error counts. It integrates with the advanced monitoring system when available. Args: operation_name (str): The name of the operation to track in metrics Returns: function: A decorator function that can wrap sync or async functions """ def decorator(func): if asyncio.iscoroutinefunction(func): @wraps(func) async def async_wrapper(*args, **kwargs): start_time = time.time() try: result = await func(*args, **kwargs) success = True error = None except Exception as e: success = False error = str(e) raise finally: duration = time.time() - start_time if ADVANCED_FEATURES_AVAILABLE: metrics_collector.record_metric(f"{operation_name}_duration", duration, {"success": str(success), "operation": operation_name}) if not success: metrics_collector.increment_counter(f"{operation_name}_errors", 1, {"operation": operation_name, "error": error}) logger.info(f"Operation {operation_name} completed in {duration:.2f}s (success: {success})") return result return async_wrapper else: @wraps(func) def wrapper(*args, **kwargs): start_time = time.time() try: result = func(*args, **kwargs) success = True error = None except Exception as e: success = False error = str(e) raise finally: duration = time.time() - start_time if ADVANCED_FEATURES_AVAILABLE: metrics_collector.record_metric(f"{operation_name}_duration", duration, {"success": str(success), "operation": operation_name}) if not success: metrics_collector.increment_counter(f"{operation_name}_errors", 1, {"operation": operation_name, "error": error}) logger.info(f"Operation {operation_name} completed in {duration:.2f}s (success: {success})") return result return wrapper return decorator # Import all agents from the new modular structure from mcp_hub.agents import ( QuestionEnhancerAgent, WebSearchAgent, LLMProcessorAgent, CitationFormatterAgent, CodeGeneratorAgent, CodeRunnerAgent, OrchestratorAgent ) # Initialize individual agents question_enhancer = QuestionEnhancerAgent() web_search = WebSearchAgent() llm_processor = LLMProcessorAgent() citation_formatter = CitationFormatterAgent() code_generator = CodeGeneratorAgent() code_runner = CodeRunnerAgent()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/CodeHalwell/gradio-mcp-agent-hack'

If you have feedback or need assistance with the MCP directory API, please join our Discord server