├── karpathy ├── __init__.py ├── .env.example ├── agent.py ├── tools.py ├── instructions.yaml └── utils.py ├── .gitignore ├── pyproject.toml ├── start.py ├── LICENSE └── README.md /karpathy/__init__.py: -------------------------------------------------------------------------------- 1 | from . import agent 2 | 3 | # Export the agent for ADK web discovery 4 | root_agent = agent.main_agent 5 | -------------------------------------------------------------------------------- /karpathy/.env.example: -------------------------------------------------------------------------------- 1 | # API Keys for Karpathy Agent 2 | # Copy this file to .env and fill in your actual API keys 3 | 4 | # OpenRouter API Key (required) This allows you to define any model you like for the agents 5 | # Get your API key from: https://openrouter.ai/ 6 | OPENROUTER_API_KEY=your_openrouter_api_key_here 7 | 8 | 9 | 10 | # LLMs 11 | AGENT_MODEL="openrouter/openai/gpt-5.1" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Environment 2 | .env 3 | 4 | 5 | # Python 6 | __pycache__/ 7 | *.py[cod] 8 | *.so 9 | *.egg-info/ 10 | dist/ 11 | build/ 12 | 13 | # Virtual environments 14 | venv/ 15 | .venv/ 16 | env/ 17 | 18 | # uv 19 | uv.lock 20 | 21 | # Testing 22 | .pytest_cache/ 23 | .coverage 24 | htmlcov/ 25 | 26 | # IDEs 27 | .vscode/ 28 | .idea/ 29 | *.swp 30 | .DS_Store 31 | 32 | # Project specific 33 | sandbox/ 34 | 35 | # Modal 36 | .modal/ 37 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "karpathy" 3 | version = "0.1.0" 4 | description = "Karpathy: An agentic Machine Learning Engineer" 5 | readme = "README.md" 6 | requires-python = ">=3.13" 7 | dependencies = [ 8 | "claude-agent-sdk>=0.1.6", 9 | "google-adk>=1.18.0", 10 | "litellm>=1.79.3", 11 | "markitdown[all]>=0.1.3", 12 | "mcp>=1.21.1", 13 | "modal>=1.2.2", 14 | "openai>=2.8.0", 15 | "pydantic>=2.12.4", 16 | "python-dotenv>=1.2.1", 17 | ] 18 | -------------------------------------------------------------------------------- /karpathy/agent.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from dotenv import load_dotenv 4 | from google.adk.agents import LlmAgent 5 | from google.adk.models.lite_llm import LiteLlm 6 | 7 | from .tools import delegate_task 8 | from .utils import load_instructions 9 | 10 | load_dotenv() 11 | 12 | # Configuration 13 | MODEL = os.getenv("AGENT_MODEL") 14 | 15 | # Main agent 16 | main_agent = LlmAgent( 17 | name="MainAgent", 18 | model=LiteLlm(model=MODEL), 19 | description="The main agent that makes sure the user's machine learning requests are successfully fulfilled", 20 | instruction=load_instructions("main_agent"), 21 | tools=[delegate_task], 22 | output_key="final_output", 23 | ) -------------------------------------------------------------------------------- /start.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Simple startup script for Karpathy agent. 4 | Runs sandbox setup and then starts the ADK web interface. 5 | """ 6 | import subprocess 7 | import sys 8 | from karpathy.utils import setup_sandbox 9 | 10 | 11 | def main(): 12 | """Run setup and start the ADK web interface.""" 13 | print("Starting Karpathy agent...") 14 | 15 | # Step 1: Setup sandbox 16 | print("\nSetting up sandbox...") 17 | try: 18 | setup_sandbox() 19 | except Exception as e: 20 | print(f"Error setting up sandbox: {e}") 21 | sys.exit(1) 22 | 23 | # Step 2: Start ADK web interface 24 | print("\nStarting ADK web interface...") 25 | try: 26 | subprocess.run(["adk", "web"], check=True) 27 | except KeyboardInterrupt: 28 | print("\nShutting down...") 29 | except Exception as e: 30 | print(f"Error starting ADK web: {e}") 31 | sys.exit(1) 32 | 33 | 34 | if __name__ == "__main__": 35 | main() 36 | 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 K-Dense 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /karpathy/tools.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from dataclasses import asdict 3 | 4 | from dotenv import load_dotenv 5 | 6 | from .utils import load_instructions 7 | 8 | load_dotenv("karpathy/.env") 9 | 10 | COMMON_INSTRUCTIONS = load_instructions("common_instructions") 11 | 12 | 13 | async def delegate_task( 14 | prompt: str, 15 | append_system_prompt: str, 16 | ): 17 | """Delegate a task to an expert 18 | 19 | Args: 20 | prompt: The prompt describing the task to delegate 21 | append_system_prompt: The system prompt describing the expert 22 | Returns: 23 | The result of the delegation with todos tracking and progress updates 24 | """ 25 | # Import here to avoid Pydantic schema generation issues at module load time 26 | from claude_agent_sdk import ( 27 | AssistantMessage, 28 | ClaudeAgentOptions, 29 | ResultMessage, 30 | ToolUseBlock, 31 | query, 32 | ) 33 | 34 | result = None 35 | query_gen = query( 36 | prompt=f"{COMMON_INSTRUCTIONS}\n\nUser Prompt: {prompt}", 37 | options=ClaudeAgentOptions( 38 | system_prompt={ 39 | "type": "preset", 40 | "preset": "claude_code", 41 | "append": append_system_prompt, 42 | }, # Use the preset 43 | setting_sources=["user", "project"], 44 | cwd="sandbox", 45 | permission_mode="bypassPermissions", 46 | ), 47 | ) 48 | 49 | try: 50 | async for message in query_gen: 51 | # Print tool use blocks 52 | if isinstance(message, AssistantMessage): 53 | for block in message.content: 54 | if isinstance(block, ToolUseBlock): 55 | if block.name == "Skill": 56 | print( 57 | f"Using the skill: {block.input.get('skill', 'unknown')}" 58 | ) 59 | else: 60 | print(f"Using the tool: {block.name}") 61 | 62 | # Check for ResultMessage and return the result 63 | elif isinstance(message, ResultMessage): 64 | result = asdict(message) 65 | finally: 66 | # Explicitly close the async generator 67 | await query_gen.aclose() 68 | 69 | return result 70 | 71 | 72 | if __name__ == "__main__": 73 | # result = asyncio.run(conduct_research("What is the capital of France?")) 74 | # print(result) 75 | result = asyncio.run( 76 | delegate_task( 77 | "What Skills are available?", 78 | "You are a helpful assistant", 79 | ) 80 | ) 81 | print(result) 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Karpathy 2 | 3 | > **Note:** For more advanced capabilities and end-to-end machine learning, visit [www.k-dense.ai](https://www.k-dense.ai). 4 | 5 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 6 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/K-Dense-AI/karpathy/pulls) 7 | 8 | An agentic Machine Learning Engineer that trains state-of-the-art ML models using Claude Code SDK and Google ADK. This is a very simple implemenation demonstraing the power of Claude Scientific Skills for machine learning. 9 | 10 | ## Prerequisites 11 | 12 | - Python 3.13 or higher 13 | - [uv](https://github.com/astral-sh/uv) package manager 14 | - Claude Code installed and authenticated (see [installation guide](https://www.claude.com/product/claude-code)) 15 | 16 | ## Setup 17 | 18 | ### 1. Clone the Repository 19 | 20 | ```bash 21 | git clone https://github.com/K-Dense-AI/karpathy.git 22 | cd karpathy 23 | ``` 24 | 25 | ### 2. Install Dependencies 26 | 27 | Install dependencies using `uv`: 28 | 29 | ```bash 30 | uv sync 31 | ``` 32 | 33 | ### 3. Environment Variables 34 | 35 | Create a `.env` file in the `karpathy` directory with your API keys: 36 | 37 | ```bash 38 | OPENROUTER_API_KEY=your_openrouter_api_key_here 39 | AGENT_MODEL=your_model_name_here 40 | ``` 41 | 42 | The `OPENROUTER_API_KEY` is required for the agent to function properly. 43 | 44 | This is the same environment variable that will be copied to the `sandbox` directory so the agents can use any API keys you provide here. 45 | 46 | ## Quick Start 47 | 48 | Run the startup script to set up the sandbox and start the ADK web interface: 49 | 50 | ```bash 51 | python start.py 52 | ``` 53 | 54 | This automatically: 55 | 1. Creates a `sandbox` directory with scientific skills from Claude Scientific Skills 56 | 2. Sets up a Python virtual environment with ML packages (PyTorch, transformers, scikit-learn, etc.) 57 | 3. Copies your `.env` file to the sandbox 58 | 4. Starts the ADK web interface 59 | 5. Navigate to **http://localhost:8000** in your browser 60 | 6. Select `karpathy` in the top left under 'Select an agent' 61 | 7. All outputs will be in the `sandbox` directory so continue to monitor that as you converse with the agent 62 | 63 | **Note:** Any files you want the agent to use (datasets, scripts, etc.) should be manually added to the `sandbox` directory. 64 | 65 | ## Community 66 | 67 | Join our K-Dense Slack community to connect with other users, share ideas, and get support: 68 | 69 | **[Join K-Dense Slack Community](https://join.slack.com/t/k-densecommunity/shared_invite/zt-3iajtyls1-EwmkwIZk0g_o74311Tkf5g)** 70 | 71 | ## Claude Scientific Skills 72 | 73 | This repository is designed to work with the **[Claude Scientific Skills](https://github.com/K-Dense-AI/claude-scientific-skills)** collection of ready-to-use scientific tools and workflows ([link](https://github.com/K-Dense-AI/claude-scientific-skills)). The `start.py` setup script creates a `sandbox` that includes scientific skills from this collection so the `karpathy` agent can leverage specialized ML libraries and scientific workflows. For full details on the skills themselves, see the upstream repository’s README and documentation [here](https://github.com/K-Dense-AI/claude-scientific-skills). 74 | 75 | ## Manual Usage 76 | 77 | To set up the sandbox without starting the web interface: 78 | 79 | ```bash 80 | python -m karpathy.utils 81 | ``` 82 | 83 | **Note:** Any files you want the agent to use (datasets, scripts, etc.) should be manually added to the `sandbox` directory. 84 | 85 | To run the ADK web interface manually: 86 | 87 | ```bash 88 | adk web 89 | ``` 90 | 91 | Then navigate to **http://localhost:8000** in your browser. 92 | 93 | ## Enhanced ML Capabilities 94 | 95 | If you want substantially more powerful ML capabilities through a multi-agentic system, sign up for [www.k-dense.ai](https://www.k-dense.ai). Currently in closed beta, launching publicly in December 2025. 96 | 97 | ## Upcoming Features 98 | 99 | - **Modal sandbox integration** - Choose any type of compute you want 100 | - **K-Dense Web features** - We might make some features from K-Dense Web available here based on interest 101 | 102 | ## Star History 103 | 104 | [![Star History Chart](https://api.star-history.com/svg?repos=K-Dense-AI/karpathy&type=date&legend=top-left)](https://www.star-history.com/#K-Dense-AI/karpathy&type=date&legend=top-left) 105 | 106 | ## Disclaimer 107 | 108 | This project is **not** endorsed by or affiliated with Andrej Karpathy. The name is used as a tribute and out of deep respect for his contributions to AI and technical leadership. -------------------------------------------------------------------------------- /karpathy/instructions.yaml: -------------------------------------------------------------------------------- 1 | main_agent: | 2 | **Overview** 3 | You are Karpathy: an agentic Machine Learning Engineer focused on designing, running, and improving state-of-the-art ML experiments. 4 | Your primary goal is to take the user's high-level intent and turn it into concrete ML work: data preparation, model design, training, evaluation, and deployment/serving. 5 | 6 | **Scope & filesystem rules** 7 | - All code execution and file writes MUST happen inside the `sandbox` directory. 8 | - Keep the `sandbox` organized: group experiments, configs, and notes in clearly named subdirectories. 9 | 10 | **How to approach each user request** 11 | - First, restate the user's goal in your own words and clarify assumptions if needed. 12 | - Then, decide whether this is: 13 | - A **conceptual question** → answer directly, possibly with small code snippets. 14 | - A **project / experiment task** → create or refine a plan and orchestrate experts to execute it. 15 | - For project tasks, follow this loop: 16 | 1. Check existing artifacts in `sandbox` (`plan.md`, `research.md`, previous runs, prior data, .md files, datasets, etc.). 17 | 2. Use `Plan Creator` (and optionally `Plan Reviewer`) to produce or refine a clear, step-by-step plan. 18 | 3. Delegate to the appropriate experts to implement the plan. 19 | 4. Inspect outputs (files, logs, metrics) and decide next actions. 20 | 5. Repeat until the user's goal is clearly satisfied or you can explain why it cannot currently be done. 21 | 22 | **Tooling & delegation** 23 | - Use `delegate_task` to work with experts. For each delegation, clearly specify: 24 | - The expert to use. 25 | - The concrete subgoal. 26 | - The inputs (paths, configs, previous artifacts). 27 | - The expected outputs and where to save them. 28 | - You may run multiple delegations in parallel when they are independent (e.g. different hyperparameter sweeps or unrelated research questions). 29 | - Avoid delegating everything by default; pick the minimal set of experts needed for the current step. 30 | - If you need to efficiently inspect what's in the `sandbox` directory, delegate that to too. 31 | 32 | **Expert team (use only what you need)** 33 | - `Plan Creator`: Creates comprehensive plans to achieve user goals. Saves to `plan.md`. 34 | - `Plan Reviewer`: Reviews `plan.md` for completeness and quality. 35 | - `Research Agent`: Researches topics using the `perplexity-search` skill. Saves findings to `research.md`. 36 | - `Data Discoverer`: Discovers and describes datasets. Saves to `dataset_description.md`. Uses `markitdown` and `exploratory-data-analysis` skills and custom code to read formats and perform EDA. 37 | - `Data Engineer`: Prepares and manages datasets (cleaning, splitting, versioning) for experiments. 38 | - `Experiment Manager`: Designs and runs experiments (sweeps, ablations), tracking configurations and results. 39 | - `Evaluation Agent`: Defines metrics, evaluates models, and compares baselines against new runs. 40 | - `Code Planner`: Designs code architecture and approach. Saves to `code_plan.md`. 41 | - `Code Reviewer`: Reviews `code_plan.md` for correctness and completeness. 42 | - `Code Writer`: Implements code according to the plan. 43 | - `Code Executor`: Runs and tests the code. 44 | - `Infra & Modal Operator`: Sets up and manages compute and infra (e.g., Modal jobs, environments, and scaling). 45 | - `Reviewer`: Monitors progress and provides feedback in `feedback.md`. 46 | - Create new experts as needed to complete the task. 47 | 48 | Orchestrate these experts in cycles until the request is complete. Create additional experts only when clearly necessary. 49 | 50 | **Communication & endings** 51 | - When you delegate, briefly tell the user which expert you are using and what that expert will do. 52 | - Keep explanations concise but informative; prefer concrete file paths, commands, and next steps. 53 | - When you consider a task done, summarize: 54 | - What was done. 55 | - Where the key artifacts live in `sandbox`. 56 | - How to reproduce or extend the work. 57 | 58 | common_instructions: | 59 | Always use available Skills when relevant. If no suitable skill exists, complete the task yourself. 60 | Prefer Skills relevant to machine learning such as pytorch, pytorch-lightning, transformers, pytorch-geometric, scikit-learn, etc. 61 | 62 | **Environment & dependencies** 63 | - Use the Python environment in the `sandbox` directory. 64 | - Manage dependencies with `uv` inside `sandbox` (e.g. adding to a local `pyproject.toml` when needed). 65 | - Keep dependencies minimal and documented in project files. 66 | 67 | **Configs, secrets, and external resources** 68 | - Read environment variables from `.env` in the `sandbox` directory (typically contains API keys provided by the user). 69 | - Handle secrets carefully: never print full secrets into logs or files. 70 | - Use the `markitdown` Skill to read various file types (PDF, DOCX, PPTX, etc.) and the `exploratory-data-analysis` Skill for data exploration when appropriate. 71 | 72 | **Resource awareness** 73 | - If you are an expert responsible for code planning, writing, or execution, make sure to use `get-available-resources` before you start. 74 | - Design experiments and jobs with resource limits in mind (CPU, memory, GPU, time). 75 | 76 | **Quality & iteration** 77 | - Prefer small, well-defined steps and verify outputs frequently. 78 | - When something fails, inspect error messages, adjust the plan, and try again rather than giving up. 79 | - Be explicit about limitations or uncertainties so the user understands remaining risks. -------------------------------------------------------------------------------- /karpathy/utils.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | import subprocess 3 | import shutil 4 | import tempfile 5 | from pathlib import Path 6 | 7 | 8 | def load_instructions(agent_name: str) -> str: 9 | """Load instructions from the YAML file.""" 10 | # Get the directory where this file is located 11 | current_dir = Path(__file__).parent 12 | instructions_path = current_dir / "instructions.yaml" 13 | with open(instructions_path, "r", encoding="utf-8") as f: 14 | data = yaml.safe_load(f) 15 | return data[agent_name] 16 | 17 | 18 | def download_scientific_skills( 19 | target_dir: str = "sandbox/.claude/skills", 20 | github_repo: str = "K-Dense-AI/claude-scientific-skills", 21 | source_path: str = "scientific-skills", 22 | branch: str = "main" 23 | ) -> None: 24 | """ 25 | Download all directories from the scientific-skills folder in the GitHub repository 26 | and place them in the target directory using git clone. 27 | 28 | Args: 29 | target_dir: Local directory to save the skills to 30 | github_repo: GitHub repository in format "owner/repo" 31 | source_path: Path within the repo to download from 32 | branch: Git branch to download from 33 | """ 34 | target_path = Path(target_dir) 35 | target_path.mkdir(parents=True, exist_ok=True) 36 | 37 | # Create a temporary directory 38 | with tempfile.TemporaryDirectory() as temp_dir: 39 | temp_path = Path(temp_dir) 40 | repo_url = f"https://github.com/{github_repo}.git" 41 | 42 | try: 43 | # Clone the repository with depth 1 for faster download 44 | print("Cloning Claude Scientific Skills repository (this may take a moment)...") 45 | subprocess.run( 46 | ["git", "clone", "--depth", "1", "--branch", branch, repo_url, str(temp_path)], 47 | check=True, 48 | capture_output=True, 49 | text=True 50 | ) 51 | 52 | # Path to the scientific-skills folder in the cloned repo 53 | source_dir = temp_path / source_path 54 | 55 | if not source_dir.exists(): 56 | raise FileNotFoundError(f"Source path '{source_path}' not found in repository") 57 | 58 | # Copy all skill directories from scientific-skills to target 59 | print(f"\nCopying skills to {target_path}...") 60 | skill_count = 0 61 | 62 | for skill_dir in source_dir.iterdir(): 63 | if skill_dir.is_dir(): 64 | dest_dir = target_path / skill_dir.name 65 | 66 | # Remove existing directory if it exists 67 | if dest_dir.exists(): 68 | shutil.rmtree(dest_dir) 69 | 70 | # Copy the skill directory 71 | shutil.copytree(skill_dir, dest_dir) 72 | print(f" [+] {skill_dir.name}") 73 | skill_count += 1 74 | 75 | print(f"\nSuccessfully downloaded {skill_count} scientific skills to {target_path.absolute()}") 76 | 77 | except subprocess.CalledProcessError as e: 78 | print(f"Error cloning repository: {e.stderr}") 79 | raise 80 | except Exception as e: 81 | print(f"Error: {e}") 82 | raise 83 | 84 | def setup_uv_environment( 85 | sandbox_path: Path, 86 | ml_packages: list[str] | None = None 87 | ) -> None: 88 | """ 89 | Create a uv virtual environment and install machine learning packages. 90 | 91 | Args: 92 | sandbox_path: Path to the sandbox directory 93 | ml_packages: List of packages to install. If None, installs default ML packages. 94 | """ 95 | if ml_packages is None: 96 | ml_packages = [ 97 | "numpy", 98 | "pandas", 99 | "scikit-learn", 100 | "matplotlib", 101 | "seaborn", 102 | "torch", 103 | "torchvision", 104 | "torchaudio", 105 | "transformers", 106 | "datasets", 107 | "scipy", 108 | "requests", 109 | "pytorch-lightning", 110 | "torch-geometric", 111 | ] 112 | 113 | print("\nCreating uv virtual environment...") 114 | venv_path = sandbox_path / ".venv" 115 | 116 | try: 117 | # Create uv environment 118 | subprocess.run( 119 | ["uv", "venv", str(venv_path)], 120 | check=True, 121 | capture_output=True, 122 | text=True 123 | ) 124 | print(f" [+] Virtual environment created at {venv_path}") 125 | 126 | # Install machine learning packages 127 | print("\nInstalling machine learning packages...") 128 | 129 | # Use uv pip to install packages 130 | install_cmd = ["uv", "pip", "install", "--python", str(venv_path / "bin" / "python")] + ml_packages 131 | 132 | print(f" Installing: {', '.join(ml_packages)}") 133 | print(" (This may take a few minutes...)") 134 | 135 | subprocess.run( 136 | install_cmd, 137 | check=True, 138 | capture_output=True, 139 | text=True 140 | ) 141 | 142 | print(" [+] All packages installed successfully") 143 | 144 | 145 | print(f"\nVirtual environment ready at {venv_path.absolute()}") 146 | 147 | except subprocess.CalledProcessError as e: 148 | print(f"Error setting up uv environment: {e.stderr}") 149 | print("Make sure uv is installed: https://github.com/astral-sh/uv") 150 | raise 151 | except FileNotFoundError: 152 | print("Error: 'uv' command not found") 153 | print("Please install uv: https://github.com/astral-sh/uv") 154 | print(" curl -LsSf https://astral.sh/uv/install.sh | sh") 155 | raise 156 | 157 | 158 | def copy_env_file() -> None: 159 | """ 160 | Copy the .env file from karpathy directory to sandbox directory. 161 | """ 162 | karpathy_env = Path("karpathy/.env") 163 | sandbox_env = Path("sandbox/.env") 164 | 165 | if not karpathy_env.exists(): 166 | print("\nWarning: .env file not found in karpathy directory") 167 | print(f" Looked for: {karpathy_env.absolute()}") 168 | return 169 | 170 | try: 171 | # Create sandbox directory if it doesn't exist 172 | sandbox_env.parent.mkdir(parents=True, exist_ok=True) 173 | 174 | # Copy the .env file 175 | shutil.copy2(karpathy_env, sandbox_env) 176 | print(f"\n[+] Copied .env file to {sandbox_env.absolute()}") 177 | 178 | except Exception as e: 179 | print(f"Error copying .env file: {e}") 180 | raise 181 | 182 | 183 | def setup_sandbox() -> None: 184 | """ 185 | Setup the sandbox directory with scientific skills and uv environment. 186 | """ 187 | sandbox_path = Path("sandbox") 188 | sandbox_path.mkdir(exist_ok=True) 189 | 190 | # Copy .env file from karpathy to sandbox 191 | copy_env_file() 192 | 193 | # Download scientific skills 194 | print("\nSetting up scientific skills...") 195 | download_scientific_skills(target_dir="sandbox/.claude/skills") 196 | 197 | # Create uv virtual environment and install ML packages 198 | setup_uv_environment(sandbox_path) 199 | 200 | print("\nSandbox setup complete!") 201 | return True 202 | 203 | 204 | if __name__ == "__main__": 205 | setup_sandbox() --------------------------------------------------------------------------------