diff --git a/autogpt_platform/backend/backend/blocks/code_executor.py b/autogpt_platform/backend/backend/blocks/code_executor.py index e39b760895..4b0e4941ac 100644 --- a/autogpt_platform/backend/backend/blocks/code_executor.py +++ b/autogpt_platform/backend/backend/blocks/code_executor.py @@ -92,8 +92,8 @@ class CodeExecutionResult(MainCodeExecutionResult): class BaseE2BExecutorMixin: """Shared implementation methods for E2B executor blocks.""" - # Default output directory for file extraction - OUTPUT_DIR = "/output" + # Default working directory in E2B sandboxes + WORKING_DIR = "/home/user" async def execute_code( self, @@ -115,8 +115,8 @@ class BaseE2BExecutorMixin: 3. Connect to existing sandbox and execute (ExecuteCodeStepBlock) Args: - extract_files: If True and execution_context provided, extract files from - /output directory and store to workspace. + extract_files: If True and execution_context provided, extract files + created/modified during execution and store to workspace. """ # noqa sandbox = None files: list[SandboxFileOutput] = [] @@ -131,13 +131,16 @@ class BaseE2BExecutorMixin: sandbox = await AsyncSandbox.create( api_key=api_key, template=template_id, timeout=timeout ) - # Create /output directory for file extraction - if extract_files: - await sandbox.commands.run(f"mkdir -p {self.OUTPUT_DIR}") if setup_commands: for cmd in setup_commands: await sandbox.commands.run(cmd) + # Capture timestamp before execution to scope file extraction + start_timestamp = None + if extract_files: + ts_result = await sandbox.commands.run("date -u +%Y-%m-%dT%H:%M:%S") + start_timestamp = ts_result.stdout.strip() if ts_result.stdout else None + # Execute the code execution = await sandbox.run_code( code, @@ -153,13 +156,13 @@ class BaseE2BExecutorMixin: stdout_logs = "".join(execution.logs.stdout) stderr_logs = "".join(execution.logs.stderr) - # Extract files from /output if requested + # Extract files created/modified during this execution if extract_files and execution_context: files = await extract_and_store_sandbox_files( sandbox=sandbox, - working_directory=self.OUTPUT_DIR, + working_directory=self.WORKING_DIR, execution_context=execution_context, - since_timestamp=None, # Get all files in /output + since_timestamp=start_timestamp, text_only=False, # Include binary files too ) @@ -277,7 +280,7 @@ class ExecuteCodeBlock(Block, BaseE2BExecutorMixin): stderr_logs: str = SchemaField(description="Standard error logs from execution") files: list[SandboxFileOutput] = SchemaField( description=( - "Files written to /output directory during execution. " + "Files created or modified during execution. " "Each file has path, name, content, and workspace_ref (if stored)." ), ) diff --git a/autogpt_platform/backend/backend/util/sandbox_files.py b/autogpt_platform/backend/backend/util/sandbox_files.py index 42f13eeb9f..70c255df0b 100644 --- a/autogpt_platform/backend/backend/util/sandbox_files.py +++ b/autogpt_platform/backend/backend/util/sandbox_files.py @@ -5,7 +5,9 @@ This module provides common file extraction and workspace storage functionality for blocks that run code in E2B sandboxes (Claude Code, Code Executor, etc.). """ +import base64 import logging +import mimetypes import shlex from dataclasses import dataclass from typing import TYPE_CHECKING @@ -217,18 +219,13 @@ async def store_sandbox_files( else: content_str = f"[Binary file: {len(file.content)} bytes]" + # Build data URI (needed for storage and as binary fallback) + mime_type = mimetypes.guess_type(file.name)[0] or "application/octet-stream" + data_uri = f"data:{mime_type};base64,{base64.b64encode(file.content).decode()}" + # Try to store in workspace workspace_ref: str | None = None try: - # Convert bytes to data URI for store_media_file - import base64 - import mimetypes - - mime_type = mimetypes.guess_type(file.name)[0] or "application/octet-stream" - data_uri = ( - f"data:{mime_type};base64,{base64.b64encode(file.content).decode()}" - ) - result = await store_media_file( file=MediaFileType(data_uri), execution_context=execution_context, diff --git a/docs/integrations/block-integrations/misc.md b/docs/integrations/block-integrations/misc.md index d14be006b0..ad6300ae88 100644 --- a/docs/integrations/block-integrations/misc.md +++ b/docs/integrations/block-integrations/misc.md @@ -215,7 +215,7 @@ The sandbox includes pip and npm pre-installed. Set timeout to limit execution t | response | Text output (if any) of the main execution result | str | | stdout_logs | Standard output logs from execution | str | | stderr_logs | Standard error logs from execution | str | -| files | Files written to /output directory during execution. Each file has path, name, content, and workspace_ref (if stored). | List[SandboxFileOutput] | +| files | Files created or modified during execution. Each file has path, name, content, and workspace_ref (if stored). | List[SandboxFileOutput] | ### Possible use case