import uuid from typing import Any, Optional, Dict, List from pydantic import Field from aworld.output.artifact import Artifact, ArtifactType, ArtifactAttachment CODE_FILE_EXTENSION_MAP = { "python": "py", "java": "java", "javascript": "js", "typescript": "ts", "html": "html", "css": "css", "c": "c", "cpp": "cpp", "csharp": "cs", "go": "go", "rust": "rs", "ruby": "rb", "php": "php", "swift": "swift", "kotlin": "kt", "scala": "scala", "markdown": "md", "txt": "txt", "shell": "sh", "bash": "sh", "sh": "sh", "zsh": "zsh", "powershell": "ps1", "cmd": "cmd", "bat": "bat" } class CodeArtifact(Artifact): code_interceptor: Any = Field(default=None, description="code executor type") def __init__(self, artifact_type: ArtifactType, content: Any, code_type: Optional[str], code_version: Optional[str], code_interceptor_provider: Optional[str] = None, artifact_id: Optional[str] = None, render_type: Optional[str] = None, **kwargs): # Extract filename from the first line of the content filename = self.extract_filename(content) # Initialize metadata, including any passed in kwargs metadata = { "code_type": code_type, "code_version": code_version, "code_interceptor_provider": code_interceptor_provider, "filename": filename # Store filename in metadata } # Merge additional metadata from kwargs if provided if 'metadata' in kwargs: metadata.update(kwargs['metadata']) del kwargs['metadata'] # Remove metadata from kwargs to avoid multiple values super().__init__( artifact_type=artifact_type, content=content, metadata=metadata, artifact_id=artifact_id, render_type=render_type, **kwargs ) self.archive() self.code_interceptor = self.init_code_interceptor(code_interceptor_provider) @staticmethod def extract_filename(content: Any) -> Optional[str]: """Extract filename from the first line of the code block comment.""" if isinstance(content, str): lines = content.splitlines() if lines: first_line = lines[0].strip() # Check if the first line is a shebang for bash or other interpreters if first_line in ["# /bin/bash", "#!/bin/bash", "#!/usr/bin/env bash", "#!/bin/sh", "#!/usr/bin/env python", "#!/usr/bin/env python3"]: return None # Do not return a filename # Check for common comment styles in various languages if first_line.startswith("#"): # Python, Ruby, Shell return first_line[1:].strip() # Remove the comment symbol elif first_line.startswith("//"): # Java, JavaScript, C, C++ return first_line[2:].strip() # Remove the comment symbol elif first_line.startswith("/*") and "*/" in first_line: # C, C++ return first_line.split("*/")[0][2:].strip() # Remove comment symbols elif first_line.startswith("