Skip to main content
A runtime organizes model calls, tool execution, and results. VeADK uses Google ADK by default, with codex and piagent available for coding-oriented execution. Check model settings, tools, and callbacks before switching Complete model configuration first. Volcengine and BytePlus each require their own model endpoint and API Key

Default runtime

Omitting runtime is equivalent to runtime="adk", suitable for standard model calls, structured output, and tool workflows
main.py
Run python main.py to print the final response. Use Runner.run_async for event and streaming handling

Parallel synchronous tool execution

Synchronous functions in the ADK runtime can block other async tasks. Set tool_thread_pool_config to run synchronous tools in worker threads, allowing concurrent execution when the model issues multiple calls in one turn
parallel_tools.py
Run python parallel_tools.py to query both products. The model decides whether to issue calls together; the thread pool does not split tasks itself. Tools sharing mutable data or connections must support concurrent access RunConfig.tool_thread_pool_config takes precedence over the agent setting. It affects ADK synchronous tools, not Codex or PiAgent execution. See code sandbox for parallel run_code session isolation and VEADK_RUN_CODE_ISOLATE_PARALLEL_CALLS

Switch the execution backend

Use the Codex runtime

Install the optional SDK and CLI binary dependencies:
Model settings remain model_name, model_api_base, and model_api_key. Defaults use an isolated workspace, workspace_write, disabled network, and denied escalation. This example keeps those settings explicit
codex_runtime.py
Run python codex_runtime.py. Register function and MCP tools through Agent.tools. Local skills in ADK SkillToolset can be passed to the runtime; see the compatibility table for legacy skills_mode restrictions

Codex security configuration

Agent.codex_runtime_config accepts CodexRuntimeConfig or a matching dictionary
auto_review automatically approves escalation and file changes; it is not model-based review. full_access broadens host access, and reuse_workspace=True can share files across invocations. Use them only when explicitly needed in trusted environments. network_access=False cannot restrict full_access, so that combination is rejected. read_only also ignores this network switch
These environment variables override constructor settings:

Codex observability

Lifecycle notifications, function calls, and MCP calls become ADK events for sessions, traces, and frontends. Log fields such as invocation_id, call_id, tool, status, and duration_ms correlate operations. Token usage is exposed through codex_event_type=token_usage events Runtime logs are not complete traces of every model call. Events, sessions, and configured exporters may contain task and tool content; control access and retention when exporting them

Configure transient-error retries

Use PiAgent

PiAgent executes in a local working directory. Built-in tools may modify files or run commands. An isolated configuration directory is not an operating-system sandbox. Use trusted projects, a restricted environment, and appropriate tool limits
piagent_runtime.py
Run python piagent_runtime.py. VeADK checks PIAGENT_BINARY, then its managed cache, and downloads a Pi Release if neither is available. Download checksums are verified only when PIAGENT_BINARY_SHA256 is set. Preinstall the binary and specify its path for offline and production environments

Runtime compatibility

Check these settings when switching to codex or piagent:

Agent transfer

transfer_to_agent lets the model delegate to another agent in the tree, which continues execution and returns results. ADK, Codex, and PiAgent support transfers
transfer.py
Run python transfer.py to obtain an announcement. Transfers require Runner; the target executes in the same invocation context, including its output_key behavior. Use the sequential workflow below when execution order must be fixed

Output persistence

output_key stores the final response in session state under ADK, Codex, and PiAgent. It does not independently persist data to disk; survival across processes depends on session storage
pipeline.py
Run python pipeline.py. The planner writes plan, the writer reads it through {plan}, and the article is stored in draft. The script prints the response and both state values for verification

Model callbacks

Callbacks may be synchronous or asynchronous. ADK runs them around model calls; external runtimes run before/after callbacks around the whole turn, with plugin callbacks before agent callbacks. Returning None continues normal handling Mutating a request does not add support for every ADK setting. The compatibility table still applies, including restrictions on output_schema
model_callback.py
Run python model_callback.py. A successful model call returns its normal answer; a model failure returns the configured message. The callback does not handle every initialization, tool, or business error

Convert PDF attachments to images

pdf_to_images_before_model_callback converts inline PDF bytes into images for models that support images but cannot read raw PDFs. PDF rendering dependencies are included in the default VeADK installation Save a document suitable for sending to the model service as example.pdf in the current directory, select a vision-capable model, and run this script:
pdf_callback.py
The default callback renders at most the first 10 pages of each PDF at scale 2.0. To change these values, import make_pdf_to_images_callback from the same module and set max_pages and scale. More pages or a larger scale increase image volume, memory use, and model input usage

Choose where each tool runs

RuntimeProvider controls individual tool calls, typically keeping the ADK flow while sending selected work to an application service. DispatchRuntimeProvider invokes your dispatch function, while LocalRuntimeProvider uses the original tool. To customize the full policy, subclass RuntimeProvider and implement execute(tool_call)

Usage example

This runnable example simulates a service adapter locally. Dispatched stock is 12; the original tool returning 0 is not executed again. It does not connect to a real remote service
dispatch.py
For a real service, replace dispatch_task with a client configured with authentication and timeouts, correlating requests with tool_call.id. Dispatch functions may be sync or async and should return a tool-compatible result. The application defines the service contract Alternatively, pass runtime_provider.before_tool_callback to Agent.before_tool_callback. Do not register both entry points, which would intercept twice. MCP tools retain their own connections regardless of dispatch selection

DispatchRuntimeProvider parameters

ToolCall fields

Request processing

run_processor wraps the event stream of Runner.run for authentication, timing, cleanup, or event transformation. Precedence is the current Runner.run(run_processor=...), the Runner constructor, the root agent, then the default pass-through processor. Calling run_async directly does not apply this wrapper For authentication, pass veadk.integrations.ve_identity.AuthRequestProcessor to Agent(run_processor=...). See inbound authentication for identity setup

Custom processors

Subclass BaseRunProcessor and implement process_run(runner, message, **kwargs). This processor forwards events, records elapsed time, and closes the event stream on success, failure, or cancellation
run_processor.py
Run python run_processor.py to see the response and elapsed time. Before adding retries to a processor, determine whether a task has already produced external side effects to avoid repeating them
Last modified on September 19, 2026