Skip to main content
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:

Switch the execution backend

Use runtime to select the inner-loop execution backend:

Use the Codex runtime

The Codex runtime requires the optional codex dependency group, which is not installed with VeADK by default. Install the required dependencies before using it:
The codex extra includes the OpenAI Codex SDK and the Codex CLI binary. The model name, API endpoint, and API key still come from the agent’s model configuration:
Tools and skills use the standard Agent configuration; the Codex runtime does not require a separate registration path:
  • function tools in tools are exposed as callable tools to the model;
  • an MCPToolset in tools supports tool discovery and invocation;
  • skills loaded through SkillToolset or VeADK’s legacy entry are made available through the Codex skill mechanism.

Codex security configuration

The Codex runtime defaults to least-privilege settings suited to a multi-tenant service: each invocation uses a session-isolated workspace, the workspace_write sandbox, no network access, and denial of escalated operations. Broader access must be enabled explicitly. Pass a CodexRuntimeConfig through the Agent codex_runtime_config parameter:
agent.py
The full set of CodexRuntimeConfig parameters: The following environment variables override the corresponding CodexRuntimeConfig field without changing code, and take precedence over codex_runtime_config:
sandbox="full_access" and reuse_workspace=True relax filesystem isolation between invocations and should only be enabled in trusted environments. In production, use a least-privilege isolated container and restrict the credentials, files, and network destinations it can access.

Codex observability

Codex-native lifecycle notifications and ADK Function/MCP tool calls are converted into standard ADK Events, so tool calls, results, state changes, confirmations, and authentication surface in Session, Trace, and the UI. Runtime logs use stable codex_* event names and attribution fields such as invocation_id, call_id, tool, status, and duration_ms. Tool arguments, tool results, API tokens, credentials, and backend addresses are not logged. Token usage is exposed through codex_event_type=token_usage events and the corresponding log entry.

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:

Use PiAgent

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.
Automatic installation requires access to the PiAgent release host. In offline or restricted networks, install the binary in advance and set PIAGENT_BINARY.

Output persistence

Agent inherits from Google ADK’s LlmAgent and supports persisting the agent’s final text response to session state through the output_key parameter. Other agents that run later in the same session can read that state, making it useful for passing results between agents in a multi-agent workflow.
output_key works across all runtimes, including the default ADK runtime and external runtimes such as codex and piagent. With an external runtime, the final response is still written to session state.
The following example uses SequentialAgent to chain two agents: the planner’s output is written to session state via output_key="plan", and the writer reads that state in the same session:
pipeline.py
After running, the session state keys plan and draft hold the final responses from the planner and the writer respectively.

Model callbacks

Agent inherits from Google ADK’s LlmAgent, so you can use before_model_callback, after_model_callback, and on_model_error_callback to inject custom logic before and after the model call and on errors. These callbacks, together with the same-named methods on ADK plugins (subclasses of BasePlugin), run in every runtime — the default ADK runtime and external runtimes such as codex and piagent. In external runtimes, callbacks run in ADK order: plugin callbacks first, then agent callbacks.
The LlmRequest built by an external runtime exposes only the stable fields callbacks need (conversation contents, system instruction, output schema, tools, and generation config); it does not run ADK’s full preprocessing pipeline. Callback behavior that depends on ADK-internal preprocessing stages may therefore differ in external runtimes.
Callbacks may be synchronous or asynchronous (async def). The following example uses before_model_callback in the Codex runtime to render PDF attachments into images so a vision-capable model can read the document:
agent.py
Use on_model_error_callback to return a fallback response when the model call fails, instead of letting the exception propagate to the caller:
agent.py

Choose where each tool runs

Whereas a runtime replaces an agent’s entire inner loop, a RuntimeProvider operates at a narrower layer: it decides where each individual tool call executes while the model reasoning loop remains unchanged. It works as an ADK plugin — by intercepting before_tool_callback, it takes over the call before Google ADK invokes the tool implementation, so the local implementation is not executed a second time. VeADK exposes the following public classes:

Usage example

The following example dispatches every non-MCP tool to a remote runtime; MCP tools retain their original ADK implementation:
agent.py
In the example above, every non-MCP tool only goes through dispatch_task and its local function is not invoked a second time. Pass a set of tool names to dispatch only those non-MCP tools. The dispatch function may be synchronous or asynchronous. To register directly on an Agent instead of through the Runner plugins parameter, pass the DispatchRuntimeProvider’s before_tool_callback to the Agent’s before_tool_callback parameter:
agent.py

DispatchRuntimeProvider parameters

ToolCall fields

MCP tools always retain their original ADK implementation and are not affected by the dispatchable_tools configuration, because MCP tool invocation must go through its own MCP session manager.

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:
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.
Last modified on September 19, 2026