35 Commits

Author SHA1 Message Date
George Weale c244a9c833 perf: run local code execution in a plain child interpreter
UnsafeLocalCodeExecutor ran each program as a multiprocessing spawn child,
which had to import this package before it could run a single line, costing
about 2.3 seconds per execution. It now runs the program in a plain child
interpreter, the shape ContainerCodeExecutor already uses, which brings a
trivial program down to about 35 milliseconds. The result now comes from the
child's exit status and pipes rather than a queue the child has to write to,
so a program that dies without reporting anything no longer leaves the agent
waiting forever, and the traceback the model is shown no longer opens with a
frame from inside this package.

One behavior change follows from taking the result from the exit status: a
program calling sys.exit(0) is now reported as having succeeded. It was
previously reported as a failure, because the spawn child raised SystemExit
before it could write to the result queue.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 967496975
2026-08-19 17:39:16 -07:00
Google Team Member 745de0ac13 feat: Stop using the obsolete Gemini 1.x / Gemini 2+ model-id check in ADK
Gemini 1.x is fully deprecated, so sorting Gemini model ids into "1.x"
and "or 2.0+" buckets no longer buys anything. Non-Gemini ids are unaffected: they still raise error.

PiperOrigin-RevId: 960655458
2026-08-06 20:15:47 -07:00
George Weale 456524d714 test: add unit tests for public symbols that had no coverage
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 960421043
2026-08-06 11:41:06 -07:00
George Weale 3eae315d36 fix: revert runtime behavior changed by the strict-typing pass
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 959884032
2026-08-05 14:53:52 -07:00
George Weale 0fcb7f1547 refactor(types): make the code executors, planners and runner pass strict mypy
Not annotations-only. This is one component's slice of a repo-wide typing
cleanup, and the wider change was found to contain behavior changes that have
not all been individually triaged, so please review it as a functional change.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 958458433
2026-08-03 10:44:09 -07:00
George Weale 27548e392f fix: kill runaway code on timeout in container and local executors
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 956773467
2026-07-30 15:41:07 -07:00
George Weale 8207880101 fix: do not mount a cluster credential into the GKE code sandbox
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 956005057
2026-07-29 11:48:21 -07:00
George Weale 46aaa313f5 test: make unit contracts platform neutral
Pre-emptive: every CI job is ubuntu-latest, so none of these tests fail today.
No assertion is weakened - each replacement is equivalent or stricter on Linux.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 954835278
2026-07-27 14:37:57 -07:00
Adil Burak Şen 0a9ce0f691 fix: harden ContainerCodeExecutor sandbox by default
Merge https://github.com/google/adk-python/pull/6074

## Summary

`ContainerCodeExecutor` runs model-generated code, which can be influenced by untrusted input (e.g. via prompt injection). It starts the container with default Docker networking and no capability restrictions, so the executed code can reach the cloud metadata endpoint (`169.254.169.254`) — which yields the host service-account token — reach internal services, or escalate privileges.

This is inconsistent with the isolation posture of every other ADK code executor:

- `GkeCodeExecutor` runs under gVisor with `cap_drop: ["ALL"]`, non-root, read-only root filesystem, and a strict security context.
- `BuiltInCodeExecutor` / `VertexAiCodeExecutor` / `AgentEngineSandboxCodeExecutor` run in managed server-side sandboxes.
- `UnsafeLocalCodeExecutor` is explicitly documented as unsafe.

`ContainerCodeExecutor` was the only executor running code with full network access and no isolation flags or warning.

## Change

- Start the container with networking disabled by default. This is exposed as a configurable `network_enabled` field — set it to `True` to re-enable networking when the executed code is trusted.
- Drop all Linux capabilities (`cap_drop=["ALL"]`) and forbid privilege escalation (`security_opt=["no-new-privileges"]`), matching `GkeCodeExecutor`.
- Document the security posture in the class docstring and point users to the sandboxed executors for untrusted code.
- Add unit tests covering the hardened defaults and the opt-in network path.

## Compatibility

Code that legitimately needs network access can opt back in with `ContainerCodeExecutor(..., network_enabled=True)`. Dropping capabilities and `no-new-privileges` do not affect normal Python code execution.

Co-authored-by: George Weale <gweale@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/6074 from adilburaksen:harden/container-code-executor-network f7eaec252d2369d710eb54ea6c51b2bc4e525e7a
PiperOrigin-RevId: 938260811
2026-06-25 16:41:40 -07:00
jordanchendev 2b7e08a5e1 fix: send correct field names for sandbox input files
Merge https://github.com/google/adk-python/pull/5958

## Problem

`AgentEngineSandboxCodeExecutor` was building the input-file payload with
incorrect JSON field names:

| Code sent  | API expects |
|------------|-------------|
| `contents` | `content`   |
| `mimeType` | `mime_type` |

This caused all input files to be silently unreadable inside the sandbox,
producing errors such as:

```
pandas.errors.EmptyDataError: No columns to parse from file
```

Fixes #3690

## Changes

- `src/google/adk/code_executors/agent_engine_sandbox_code_executor.py` — rename the two dict keys in the `input_data['files']` list comprehension.
- `tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py` — add regression test `test_execute_code_sends_correct_field_names_for_input_files` that verifies the correct keys are sent to the API.

## Testing plan

- [x] New regression test added that asserts `content` and `mime_type` are used (was failing before the fix, passes after).
- [x] All existing tests in the file still pass.

### pytest output

```
uv run --extra test python -m pytest tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py -v
======================== 11 passed, 5 warnings in 2.04s ========================
```

### pre-commit

```
pre-commit run --files src/google/adk/code_executors/agent_engine_sandbox_code_executor.py \
                       tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py
isort....................................................................Passed
pyink....................................................................Passed
addlicense...............................................................Passed
```

Co-authored-by: Kathy Wu <wukathy@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/5958 from jordanchendev:fix/3690-sandbox-input-file-field-names eefe91165fb5ea156b6e473adb329ce12d13616f
PiperOrigin-RevId: 933868136
2026-06-17 12:39:07 -07:00
Ashutosh0x 910e1c1321 fix: prevent ReDoS in code block extraction
Merge https://github.com/google/adk-python/pull/6118

## Summary
- Replace regular expression-based code block extraction with a simple and safe string-find based search. This avoids exponential backtracking (ReDoS) when processing long or repeating inputs with missing trailing delimiters.
- Add unit tests to verify standard behavior and test against ReDoS vulnerability.

Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 933834549
2026-06-17 11:30:32 -07:00
George Weale 6262f9415d fix: use correct 'content' key in sandbox code executor input files
Merge https://github.com/google/adk-python/pull/5505

Fixes #5500

### Root Cause

`AgentEngineSandboxCodeExecutor` builds the input file payload with key `'contents'` (plural), but the Vertex AI SDK (`vertexai/_genai/sandboxes.py`) reads `'content'` (singular). This causes `file.get("content", b"")` to always return the default empty bytes, so uploaded input files silently arrive as zero bytes in the sandbox.

### Fix

One-character change: `'contents'` → `'content'` at line 177.

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 930814004
2026-06-11 17:01:54 -07:00
Amaad Martin 69fa777881 fix: catch genai.ClientError when sandbox is missing
This fixes an issue where AgentEngineSandboxCodeExecutor catches the wrong exception class when attempting to recover from externally-deleted sandboxes.

Fixes #5480

Co-authored-by: Amaad Martin <amaadmartin@google.com>
PiperOrigin-RevId: 908965545
2026-05-01 16:49:52 -07:00
Google Team Member ed8b31ce5f chore: migrate from gemini-1.* and gemini-2.0* to gemini-2.5-*
`gemini-1.*` and `gemini-2.0*` models are respectively deprecated and scheduled for shutdown on June 1, 2026. `gemini-2.5*` models are their successors.
No regressions in unit tests:
```
========================================================================================== 5583 passed, 2237 warnings in 84.91s (0:01:24) ===========================================================================================
```

PiperOrigin-RevId: 907663315
2026-04-29 10:34:22 -07:00
Kathy Wu 71d26ef7b9 feat: Add support for timeout to UnsafeLocalCodeExecutor
Co-authored-by: Kathy Wu <wukathy@google.com>
PiperOrigin-RevId: 884557773
2026-03-16 11:39:31 -07:00
Google Team Member 6c34694da6 feat: Enhance AgentEngineSandboxCodeExecutor sample to automatically provision an Agent Engine if neither agent_engine_resource_name nor sandbox_resource_name is provided
The AgentEngineSandboxCodeExecutor now has three initialization modes:
1.  Create both an Agent Engine and sandbox if neither resource name is provided.
2.  Creating a new sandbox within a provided agent_engine_resource_name.
3.  Using a provided sandbox_resource_name.

PiperOrigin-RevId: 884088248
2026-03-15 13:48:07 -07:00
Shruti Nair 9c45166281 feat: execute-type param addition in GkeCodeExecutor
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/4111 from SHRUTI6991:execute-type/param-addition b1ec403e0927767d17c11cb9e894f6ccb4f08dd2
PiperOrigin-RevId: 877476098
2026-03-02 10:50:43 -08:00
Lusha Wang dff4c44040 fix: Update agent_engine_sandbox_code_executor in ADK
1. For prototyping and testing purposes, sandbox name can be provided, and it will be used for all requests across the lifecycle of an agent
2. If no sandbox name is provided, agent engine name will be provided, and we will automatically create one sandbox per session, and the sandbox has TTL set for a year.
If the sandbox stored in the session hits the TTL, it will not be in "STATE_RUNNING" so a new sandbox will be created.

Co-authored-by: Lusha Wang <lusha@google.com>
PiperOrigin-RevId: 876450610
2026-02-27 15:59:20 -08:00
Google Team Member ee8d956413 fix: Update agent_engine_sandbox_code_executor in ADK
1. For prototyping and testing purposes, sandbox name can be provided, and it will be used for all requests across the lifecycle of an agent
2. If no sandbox name is provided, agent engine name will be provided, and we will automatically create one sandbox per session, and the sandbox has TTL set for a year.
If the sandbox stored in the session hits the TTL, it will not be in "STATE_RUNNING" so a new sandbox will be created.

PiperOrigin-RevId: 874705260
2026-02-24 11:16:04 -08:00
Lusha Wang dab80e4a8f fix: Update agent_engine_sandbox_code_executor in ADK
1. For prototyping and testing purposes, sandbox name can be provided, and it will be used for all requests across the lifecycle of an agent
2. If no sandbox name is provided, agent engine name will be provided, and we will automatically create one sandbox per session, and the sandbox has TTL set for a year.
If the sandbox stored in the session hits the TTL, it will not be in "STATE_RUNNING" so a new sandbox will be created.

Co-authored-by: Lusha Wang <lusha@google.com>
PiperOrigin-RevId: 874415933
2026-02-23 23:52:09 -08:00
Google Team Member b1e33a90b4 fix: use correct msg_out/msg_err keys for Agent Engine sandbox output
PiperOrigin-RevId: 874126181
2026-02-23 09:56:49 -08:00
George Weale eaf50ce37e chore: provide a way to disable model check for builtin tools
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 872503435
2026-02-19 12:02:27 -08:00
George Weale 2367901ec5 chore: Upgrade to headers to 2026
Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 858763407
2026-01-20 14:50:09 -08:00
George Weale 31cfa3b82b feat: Capture thinking output, forward raw payloads, and fix exec locals
LlmResponse/Event now keep both provider reasoning output and the raw vendor payload so callbacks and loggers can inspect hidden “thoughts” or trace bugs without rewriting adapters.

LiteLLM’s adapter and streaming loop emit reasoning chunks alongside text and aggregate them into final events -> all responses now carry a JSON-safe copy of the source payload for debug. UnsafeLocalCodeExecutor uses the documented exec(code, globals, globals) form, letting helper functions defined inside snippets call each other.

Close #1749

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 834956847
2025-11-20 16:30:19 -08:00
Josh Soref d672349ddf chore: Fix spelling in tests
Merge https://github.com/google/adk-python/pull/3402

This PR corrects misspellings identified by the [check-spelling action](https://github.com/marketplace/actions/check-spelling)

Note: while I use tooling to identify errors, the tooling doesn't _actually_ provide the corrections, I'm picking them on my own. I'm a human, and I may make mistakes.

### Testing Plan

The misspellings have been reported at https://github.com/jsoref/adk-python/actions/runs/19056081305/attempts/1#summary-54426435973

The action reports that the changes in this PR would make it happy: https://github.com/jsoref/adk-python/actions/runs/19056081446/attempts/1#summary-54426436321

**Unit Tests:**

- [ ] I have added or updated unit tests for my change.
- [ ] All unit tests pass locally.

_Please include a summary of passed `pytest` results._

**Manual End-to-End (E2E) Tests:**

_Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix._

### Checklist

- [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document.
- [x] I have performed a self-review of my own code.
- [ ] I have commented my code, particularly in hard-to-understand areas.
- [ ] I have added tests that prove my fix is effective or that my feature works.
- [ ] New and existing unit tests pass locally with my changes.
- [ ] I have manually tested my changes end-to-end.
- [ ] Any dependent changes have been merged and published in downstream modules.

### Additional context

- https://github.com/google/adk-python/pull/3382#issuecomment-3488654110

Co-authored-by: Liang Wu <wuliang@google.com>
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/3402 from jsoref:spelling-tests 3cf0439d0584e4557179c25596aadf3b5b7c3fa8
PiperOrigin-RevId: 829035089
2025-11-06 11:21:59 -08:00
Liang Wu 44d45fe9cd chore: Lazy load Vertex AI dependencies in ADK modules
This is about 35% decrease. This change refactors several ADK modules to import `vertexai` and its submodules only when they are first used, rather than at the top of the file. This improves module load times by avoiding unnecessary imports of large dependencies. Imports are also placed within `if TYPE_CHECKING:` blocks where appropriate.

Co-authored-by: Liang Wu <wuliang@google.com>
PiperOrigin-RevId: 829017293
2025-11-06 10:40:54 -08:00
Josh Soref aa1233608a chore: Fix spelling
Merge https://github.com/google/adk-python/pull/2447

This PR corrects misspellings identified by the [check-spelling action](https://github.com/marketplace/actions/check-spelling)

The misspellings have been reported at https://github.com/jsoref/adk-python/actions/runs/16840838898/attempts/1#summary-47711379253

The action reports that the changes in this PR would make it happy: https://github.com/jsoref/adk-python/actions/runs/16840839269/attempts/1#summary-47711380479

Note: while I use tooling to identify errors, the tooling doesn't _actually_ provide the corrections, I'm picking them on my own. I'm a human, and I may make mistakes.

I've included a couple of changes to make CI happy. Personally, I object to CI being in a state of "random drive by person who adds a blank line in the middle of a file must fix all the preexisting bugs in the file", but that appears to be the state for this repository.

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/2447 from jsoref:spelling d85398e7fd154d124d477c6af6181481a01f34e0
PiperOrigin-RevId: 827629615
2025-11-03 13:33:53 -08:00
Google Team Member ee39a89110 feat: introduces a new AgentEngineSandboxCodeExecutor class that supports executes agent generated code
The AgentEngineSandboxCodeExecutor uses the Vertex AI Code Execution Sandbox API to execute code

PiperOrigin-RevId: 821699641
2025-10-20 10:14:34 -07:00
Google Team Member a5b742b360 feat: introduces a new AgentEngineSandboxCodeExecutor class that supports executes agent generated code
The AgentEngineSandboxCodeExecutor uses the Vertex AI Code Execution Sandbox API to execute code

PiperOrigin-RevId: 821197794
2025-10-18 20:24:04 -07:00
Google Team Member dbd818be0b feat: introduces a new AgentEngineSandboxCodeExecutor class that supports executes agent generated code
The AgentEngineSandboxCodeExecutor uses the Vertex AI Code Execution Sandbox API to execute code

PiperOrigin-RevId: 820854185
2025-10-17 15:42:24 -07:00
Google Team Member 72ff9c64a2 feat: Add GkeCodeExecutor for sandboxed code execution on GKE #non-breaking
Merge https://github.com/google/adk-python/pull/1629

close https://github.com/google/adk-python/issues/2170

### Summary

This PR introduces `GkeCodeExecutor`, a new code executor that provides a secure and scalable method for running LLM-generated code by leveraging GKE Sandbox. It serves as a robust alternative to local or standard containerized executors by leveraging the **GKE Sandbox** environment, which uses gVisor for workload isolation.

For each code execution request, it dynamically creates an ephemeral Kubernetes Job with a hardened Pod configuration, offering significant security benefits and ensuring that each code execution runs in a clean, isolated environment.

### Key Features of GkeCodeExecutor

* **Dynamic Job Creation**: Uses the Kubernetes `batch/v1` API to create a new Job for each code snippet.
* **Secure Code Mounting**: Injects code into the Pod via a temporary `ConfigMap`, which is mounted to a read-only file.
* **gVisor Sandboxing**: Enforces execution within a `gvisor` runtime for kernel-level isolation.
* **Hardened Security Context**: Pods run as non-root with all Linux capabilities dropped and a read-only root filesystem.
* **Resource Management**: Applies configurable CPU and memory limits to prevent abuse.
* **Automatic Cleanup**: Uses the `ttl_seconds_after_finished` feature on Jobs for robust, automatic garbage collection of completed Pods and Jobs.
* **Node Scheduling**: The executor uses Kubernetes `tolerations` in its Pod specification. This allows the k8s scheduler to place the execution Pod onto a **_pre-configured_** gVisor-enabled node.
* **Module Integration**: The `GkeCodeExecutor` is registered in the `code_executors/__init__.py`, making it available for use by agents. The `ImportError` handling is configured to check for the required `kubernetes` SDK.

### Execution Flow:

1.  Agent invokes `GkeCodeExecutor` with the LLM-generated code.
2.  The `GkeCodeExecutor` will `execute_code` – creates a temporary `ConfigMap`, and then create a k8s `Job` to run it.
3.  This Job runs a standard `python:3.11-slim` container. The image is pulled once to the node and cached. The Job will mount the ConfigMap as `/app/code.py`
4.  The GkeCodeExecutor will monitor the Job to completion, fetch `stdout/stderr` logs from the container, return `CodeExecutionResult` to the LlmAgent, and ensure all temp resources are deleted.
5.  The calling agent formats the result and provides a final response to the user. If the result contains error, it will retry up to `error_retry_attempts` times.

PiperOrigin-RevId: 804511467
2025-09-08 11:15:29 -07:00
Wei Sun (Jack) 4214c7eddd chore: auto-format files.
PiperOrigin-RevId: 764980009
2025-05-29 19:24:16 -07:00
Amulya Bhatia face2e8cf2 Copybara import of the project:
--
8baeb0b569eaedc638b20e46894178a3b878dbd6 by Amulya Bhatia <amulya.bhatia@t-online.de>:

test: unit tests for built_in_code_executor and unsafe_code_executor

--
cfac73b9271557ead96eb5fb419e05d88c6e8cd4 by Amulya Bhatia <amulya.bhatia@t-online.de>:

test: unit tests for built_in_code_executor and unsafe_code_executor
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/971 from iamulya:code-executor-tests 55290e27b5e58ef3835905aec88639e936318d01
PiperOrigin-RevId: 764976316
2025-05-29 19:08:55 -07:00
Xiang (Sean) Zhou ff8a3c9b43 chore: reformat the codes using autoformat.sh
PiperOrigin-RevId: 762004002
2025-05-22 09:43:54 -07:00
Amulya Bhatia 98727b4698 test: unit tests for code_executor_context.py
Copybara import of the project:

--
9e51865a6dd4de4d20088e8a7ac9f3a75501aa6b by Amulya Bhatia <amulya.bhatia@t-online.de>:

test: unit tests for code_executor_context.py
COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/780 from iamulya:test-code-executor-context 907b1712e43b8ce90cd8786780bef863adfcc167
PiperOrigin-RevId: 761294975
2025-05-20 17:40:33 -07:00