> ## 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.

# Runtime

The runtime determines how an agent's inner loop runs — how each turn calls the
model, interprets intent, and invokes tools. The default runtime is built on
Google ADK's execution flow and works out of the box; you can also switch the
execution backend or inject shared processing logic into the flow, without
changing the agent itself.

## Default runtime

The ADK runtime is the default and needs no extra configuration:

```python lines theme={null}
from veadk import Agent

agent = Agent(name="assistant")  # uses the ADK runtime by default
```

## Switch the execution backend

Use `runtime` to select the inner-loop execution backend:

```python lines theme={null}
agent = Agent(name="assistant", runtime="codex")
```

| Value | Description |
| - | - |
| `adk` (default) | Google ADK's built-in execution flow; suitable for most cases. |
| `codex` | Runs the inner loop through the Codex SDK and bridges function tools, MCP tools, and skills. |
| `piagent` | Runs the inner loop through PiAgent RPC and bridges function tools, MCP tools, and skills. Added in 1.0.5. |

### Use the Codex runtime

The Codex runtime requires `openai-codex`, which is not installed with VeADK by
default. Install the required dependencies before using it:

```bash lines theme={null}
pip install openai-codex fastapi uvicorn
```

<Warning>
  By default, the Codex runtime does not request interactive approval and can execute commands, read and write files, and access the network from its host or container. Enable it only for trusted workloads. In production, use a least-privilege isolated container and restrict the credentials, files, and network destinations it can access.
</Warning>

The model name, API endpoint, and API key still come from the agent's model
configuration:

```python lines theme={null}
from veadk import Agent

agent = Agent(
    name="coding_assistant",
    runtime="codex",
    model_name="doubao-seed-2-1-pro-260628",
)
```

Tools and skills use the standard `Agent` configuration; the Codex runtime does
not require a separate registration path:

* [function tools](/productions/veadk/archives/1.0.5/en/components/tools/custom-function) in `tools` are exposed as callable tools to the model;
* an [MCPToolset](/productions/veadk/archives/1.0.5/en/components/tools/custom-mcp) in `tools` supports tool discovery and invocation;
* [skills](/productions/veadk/archives/1.0.5/en/components/agent/skills) loaded through `SkillToolset` or VeADK's legacy entry are made available through the Codex skill mechanism.

### Configure transient-error retries

When the Codex runtime calls the model backend, it retries transient failures
such as rate limits, server errors, overloads, and timeouts. It retries at most
twice by default. Use these environment variables to change the behavior:

| Environment variable | Type | Default | Description |
| - | - | - | - |
| `CODEX_SHIM_NUM_RETRIES` | `int` | `2` | Maximum retries for transient failures. Set to `0` to disable retries. |
| `CODEX_SHIM_TIMEOUT` | `float` | `0` | Timeout in seconds for one model-backend call. `0` uses the underlying client's default timeout. |

### Use PiAgent

```python lines theme={null}
from veadk import Agent

agent = Agent(
    name="coding_assistant",
    runtime="piagent",
    model_name="doubao-seed-2-1-pro-260628",
)
```

The VeADK Python package does not vendor the PiAgent binary. The runtime checks
the following locations in order:

1. the executable referenced by `PIAGENT_BINARY`;
2. the managed cache under `PIAGENT_INSTALL_DIR`, which defaults to `~/.cache/veadk/piagent`;
3. if the cache is missing, a downloaded and verified PiAgent release.

| Environment variable | Default | Description |
| - | - | - |
| `PIAGENT_BINARY` | — | Path to an installed PiAgent executable. Recommended for production. |
| `PIAGENT_INSTALL_DIR` | `~/.cache/veadk/piagent` | Managed download and cache directory. |
| `PIAGENT_AGENT_DIR` | A temporary directory per run | Isolated PiAgent configuration and session directory; it cannot point to the user's real `~/.pi/agent`. |
| `PIAGENT_WORKDIR` | Current directory | PiAgent working directory. |
| `PIAGENT_TIMEOUT_SECONDS` | `600` | Per-run timeout in seconds. |
| `PIAGENT_TOOL_ALLOWLIST` | Empty | Comma-separated built-in tools that may run. |
| `PIAGENT_EXCLUDE_TOOLS` | Empty | Comma-separated tools that may not run. |

<Note>
  Automatic installation requires access to the PiAgent release host. In offline or restricted networks, install the binary in advance and set `PIAGENT_BINARY`.
</Note>

## Request processing

Without touching business logic, you can inject shared cross-cutting processing
into each run. Pass a processor to `run_processor`, for example to enforce login
via identity authentication:

```python lines theme={null}
from veadk import Agent
from veadk.integrations.ve_identity import AuthRequestProcessor

agent = Agent(name="assistant", run_processor=AuthRequestProcessor())
```

When unset, the default processor is used and behavior is unchanged. VeADK ships
`AuthRequestProcessor` as a ready-made implementation for identity authentication.

### Custom processors

Every processor subclasses the abstract base `BaseRunProcessor` and implements
its `process_run(runner, message)` method. That method returns a decorator
wrapping the run's event stream, letting you:

* inject logic **before and after** the whole run (auth, logging, monitoring);
* **intercept, rewrite, or inject** events produced during the run;
* build control logic such as retries on top of that.

```python lines theme={null}
from veadk.processors.base_run_processor import BaseRunProcessor

class LoggingProcessor(BaseRunProcessor):
    def process_run(self, runner, message, **kwargs):
        def decorator(event_generator):
            async def wrapper():
                # Before: record start, validate, ...
                async for event in event_generator():
                    yield event  # intercept or rewrite events here
                # After: summarize, report, ...
            return wrapper
        return decorator
```
