> ## Documentation Index
> Fetch the complete documentation index at: https://docs.veadk.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Code sandboxes

## Overview

VeADK provides a set of tools that run tasks remotely in an [AgentKit sandbox](https://console.volcengine.com/agentkit):

| Tool | Description |
| :- | :- |
| `run_code` | Execute arbitrary code or shell commands — good for computation, data processing, dependency installation, and so on |
| `execute_skills` | Run an `agent.py` workflow in a prebuilt skills sandbox |
| `coding` | Run a code-generation workflow in an OpenCode sandbox |
| `run_sandbox_agent` | Run `agent.py` in a remote sandbox under any `tool_id` |

Import paths:

* `from veadk.tools.builtin_tools.run_code import run_code`
* `from veadk.tools.builtin_tools.execute_skills import execute_skills`
* `from veadk.tools.builtin_tools.coding import coding`
* `from veadk.tools.builtin_tools.run_sandbox_agent import run_sandbox_agent`

## Environment & prerequisites

<Warning>
  Requirements:

  1. Configure Volcengine AK / SK.
  2. Configure the API key for the agent's reasoning model.
  3. Configure the AgentKit Tool ID (see below).
</Warning>

Environment variables:

* `MODEL_AGENT_API_KEY`: API key for the agent's reasoning model
* `VOLCENGINE_ACCESS_KEY` / `VOLCENGINE_SECRET_KEY`: Volcengine AK / SK
* `AGENTKIT_TOOL_ID`: default AgentKit sandbox ID, used as the fallback for all sandbox tools
* `AGENTKIT_TOOL_ID_SCRIPT`: sandbox ID dedicated to `run_code`; falls back to `AGENTKIT_TOOL_ID`
* `AGENTKIT_TOOL_ID_SKILLS`: sandbox ID dedicated to `execute_skills`; falls back to `AGENTKIT_TOOL_ID`
* `AGENTKIT_TOOL_ID_OPENCODE`: sandbox ID dedicated to `coding`; falls back to `AGENTKIT_TOOL_ID`
* `AGENTKIT_TOOL_HOST`: endpoint for calling AgentKit Tools
* `AGENTKIT_TOOL_SERVICE_CODE`: service code for calling AgentKit Tools
* `AGENTKIT_TOOL_REGION`: region for calling AgentKit Tools; defaults to `cn-beijing`

`config.yaml` keys:

```yaml title="config.yaml" lines theme={null}
agentkit:
  tool_id: your-default-tool-id
  tool_id_script: your-script-tool-id
  tool_id_skills: your-skills-tool-id
  tool_id_opencode: your-opencode-tool-id
```

Creating a sandbox:

<Steps>
  <Step title="Create a sandbox tool">
    Create a sandbox tool in the console: give it a name (e.g. `AIO_Sandbox_xxxx`) and choose the "all-in-one tool set" type, which includes Browser, Terminal, and Code runtimes.
  </Step>

  <Step title="Obtain the sandbox ID">
    After creation, obtain the sandbox ID from the console (looks like `t-ye8dj82xxxxx`) and fill it into the environment variables or `config.yaml` above.
  </Step>
</Steps>

## Usage

```python title="examples/tools/run_code/agent.py" lines theme={null}
import asyncio

from veadk import Agent, Runner
from veadk.memory.short_term_memory import ShortTermMemory
from veadk.tools.builtin_tools.run_code import run_code
from veadk.tools.builtin_tools.web_search import web_search

agent = Agent(
    name="data_analysis_agent",
    model_name="doubao-seed-2-1-pro-260628",
    description="A data analysis agent for the stock market.",
    instruction=(
        "You are a senior engineer running code in a sandbox. Use web_search to find "
        "company operating data, use libraries such as akshare to download stock data, "
        "and install missing dependencies from within the sandbox via code."
    ),
    tools=[run_code, web_search],
)

runner = Runner(agent=agent, short_term_memory=ShortTermMemory())


async def main():
    response = await runner.run("Analyze the recent stock price trend of Sungrow Power")
    print(response)


if __name__ == "__main__":
    asyncio.run(main())
```

## Running shell commands

In addition to running code such as Python, `run_code` can run shell commands in the sandbox. When `language` is set to `bash` or `shell`, the `code` is executed as a shell command in the remote sandbox — useful for file operations, installing dependencies, or invoking command-line tools.

Shell execution reuses the sandbox ID and credential configuration of `run_code`. The `code` is submitted as a command, so multiple commands can be chained within a single execution.

<Warning>
  Shell can execute arbitrary commands, install dependencies, read and write files, and reach services available from the remote sandbox network. Run only trusted commands and restrict the data, network, and permissions available to the sandbox. Do not put long-lived credentials in commands or `env`; use the sandbox's supported credential-hosting mechanism when credentials are required.
</Warning>

### Parameters

The full signature of `run_code`:

```python lines theme={null}
def run_code(
    code: str,
    language: str,
    tool_context: ToolContext,
    timeout: int = 30,
    exec_dir: str = "/tmp",
    env: dict[str, str] | None = None,
    hard_timeout: int = 300,
    max_output_length: int = 30000,
) -> str:
    ...
```

| Parameter | Type | Default | Description |
| :- | :- | :- | :- |
| `code` | `str` | — | The code or shell command to run. |
| `language` | `str` | — | Execution language. Use `python3` for code, or `bash` / `shell` for shell commands. |
| `tool_context` | `ToolContext` | — | Tool runtime context, injected automatically by VeADK. |
| `timeout` | `int` | `30` | Execution timeout in seconds. |
| `exec_dir` | `str` | `/tmp` | Working directory for shell execution. |
| `env` | `dict[str, str] \| None` | `None` | Environment variables for shell execution. |
| `hard_timeout` | `int` | `300` | Hard timeout for shell execution, in seconds. |
| `max_output_length` | `int` | `30000` | Maximum length of shell output. |

`exec_dir`, `env`, `hard_timeout`, and `max_output_length` apply only when running shell commands (`language` set to `bash` or `shell`); they are managed by the sandbox runtime and do not apply when running code.

### Example

```python title="run_code_bash.py" lines theme={null}
import asyncio

from google.adk.tools import ToolContext
from veadk import Agent, Runner
from veadk.memory.short_term_memory import ShortTermMemory
from veadk.tools.builtin_tools.run_code import run_code


def check_python(tool_context: ToolContext) -> str:
    """Show the Python version in the remote sandbox."""
    return run_code(
        code="pwd && python --version",
        language="bash",
        tool_context=tool_context,
        timeout=60,
        exec_dir="/tmp",
        env={"APP_ENV": "test"},
        hard_timeout=120,
        max_output_length=5000,
    )


agent = Agent(
    name="shell_agent",
    instruction="Call the tool to show the sandbox working directory and Python version.",
    tools=[check_python],
)
runner = Runner(agent=agent, short_term_memory=ShortTermMemory())


async def main():
    response = await runner.run("Check the sandbox environment")
    print(response)


if __name__ == "__main__":
    asyncio.run(main())
```

## Injecting environment variables into sandbox executions

`execute_skills` and `run_sandbox_agent` accept custom environment variables that are injected into a single sandbox execution. Use them to pass runtime parameters (configuration values, credential references, feature flags, and so on) to a skill or an in-sandbox workflow. Injected variables are scoped to the current execution only and are not persisted to the sandbox base environment.

`execute_skills` injects variables through the `env_vars` parameter; `run_sandbox_agent` injects them through `extra_env_vars`. Both share the same validation and merge rules.

### Parameters

| Parameter | Type | Default | Description |
| :- | :- | :- | :- |
| `env_vars` | `Optional[dict[str, str]]` | `None` | Environment variables injected by `execute_skills`; keys and values are strings, scoped to the current execution. |
| `extra_env_vars` | `Optional[dict[str, str]]` | `None` | Environment variables injected by `run_sandbox_agent`; keys and values are strings, scoped to the current execution. |

### Validation rules

Injected variables are merged with the framework-managed variables that VeADK sets itself, then passed to the sandbox process under these rules:

* Names must match `^[A-Za-z_][A-Za-z0-9_]*$`; otherwise initialization raises an error.
* `TOOL_USER_SESSION_ID` and `USER_SESSION_ID` are managed by VeADK and cannot be overridden; initialization raises an error if they are set.
* Values must be strings; non-string values raise an error.
* Values must not contain null bytes (`\x00`); otherwise initialization raises an error.
* Custom variables override any same-named variable in the sandbox process environment (including VeADK defaults such as `TOS_SKILLS_DIR` and `SKILL_SPACE_ID`), so resource paths for a single execution can be adjusted on demand.

### Examples

The following example wraps both calls as function tools. `Runner` injects `tool_context` when it invokes a function tool, while the application sets the environment variables for each execution in the wrapper:

```python title="sandbox_env.py" lines theme={null}
import asyncio

from google.adk.tools import ToolContext
from veadk import Agent, Runner
from veadk.memory.short_term_memory import ShortTermMemory
from veadk.tools.builtin_tools.execute_skills import execute_skills
from veadk.tools.builtin_tools.run_sandbox_agent import run_sandbox_agent


def run_skill_workflow(workflow_prompt: str, tool_context: ToolContext) -> str:
    """Run a workflow in the skills sandbox."""
    return execute_skills(
        workflow_prompt=workflow_prompt,
        tool_context=tool_context,
        env_vars={
            "SKILL_CONFIG_PATH": "/tmp/skill_config.yaml",
            "MAX_RESULTS": "20",
        },
    )


def run_custom_workflow(workflow_prompt: str, tool_context: ToolContext) -> str:
    """Run a workflow in a specified AgentKit sandbox."""
    return run_sandbox_agent(
        workflow_prompt=workflow_prompt,
        tool_id="t-your-sandbox-tool-id",
        tool_context=tool_context,
        extra_env_vars={"DATA_SOURCE_URL": "https://example.com/data.csv"},
    )


agent = Agent(
    name="sandbox_agent",
    instruction="Call the appropriate sandbox workflow for the user's request.",
    skills=["space:your-skill-space-id"],
    skills_mode="skills_sandbox",
    tools=[run_skill_workflow, run_custom_workflow],
)
runner = Runner(agent=agent, short_term_memory=ShortTermMemory())


async def main():
    response = await runner.run("Use the skills workflow to summarize the knowledge base")
    print(response)


if __name__ == "__main__":
    asyncio.run(main())
```

<Warning>
  Values in `env_vars` and `extra_env_vars` are passed to the remote sandbox process. Do not put long-lived credentials in source code; use the sandbox's supported credential-hosting mechanism when credentials are required.
</Warning>
