Skip to content

Commit 527e3c1

Browse files
haranrkcopybara-github
authored andcommitted
docs(samples): Add ManagedAgent code-execution sample
Add a runnable sample under contributing/samples/managed_agent/code_execution showing how to use ManagedAgent with the server-side code execution tool. Since ManagedAgent has no code_executor field, code execution is enabled by passing the raw types.Tool(code_execution=types.ToolCodeExecution()) config in tools. The sample exposes a root_agent in agent.py and ships a README plus a matching single-turn live integration test that verifies a code-executed prime-sum computation. Co-authored-by: Haran Rajkumar <haranrk@google.com> PiperOrigin-RevId: 943548907
1 parent 9a4f479 commit 527e3c1

4 files changed

Lines changed: 159 additions & 0 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Managed Agent - Code Execution
2+
3+
## Overview
4+
5+
This sample runs a `ManagedAgent` configured with the built-in **code execution**
6+
tool so it can write and run code server-side to compute answers.
7+
8+
Unlike a regular `LlmAgent` (which enables code execution via
9+
`code_executor=BuiltInCodeExecutor()`), `ManagedAgent` has no `code_executor`
10+
field. Instead you pass the raw built-in tool config
11+
`types.Tool(code_execution=types.ToolCodeExecution())` in `tools` -- the same
12+
config `BuiltInCodeExecutor` produces under the hood. This makes the sample a
13+
demonstration of the raw `types.Tool` server-side tool path.
14+
15+
## Sample Inputs
16+
17+
- `What is the sum of the first 50 prime numbers? Use code to compute it.`
18+
19+
The model writes and runs code server-side; the answer (5117) comes from the
20+
executed code rather than the model guessing.
21+
22+
- `Now do the same for the first 100 primes.`
23+
24+
A follow-up turn that reuses the recovered remote sandbox and the previous
25+
interaction (answer: 24133), demonstrating multi-turn chaining.
26+
27+
## Graph
28+
29+
```mermaid
30+
graph LR
31+
User -->|message| ManagedAgent
32+
ManagedAgent -->|interactions.create| ManagedAgentsAPI
33+
ManagedAgentsAPI -->|server-side code execution| ManagedAgentsAPI
34+
ManagedAgentsAPI -->|streamed events| ManagedAgent
35+
ManagedAgent -->|answer| User
36+
```
37+
38+
## How To
39+
40+
- **Create the agent**: instantiate `ManagedAgent` with an `agent_id`, an
41+
`environment` spec, and
42+
`tools=[types.Tool(code_execution=types.ToolCodeExecution())]`. No `model` is
43+
set -- the model is part of the managed agent on the server.
44+
- **Enable code execution**: `ManagedAgent` has no `code_executor` field, so the
45+
raw `types.Tool(code_execution=...)` config is passed in `tools`. The
46+
interactions converter turns it into the server-side `code_execution` tool.
47+
- **Provision a sandbox**: `environment={'type': 'remote'}` requests a fresh
48+
remote sandbox. The resulting environment id is stored on emitted events, so
49+
subsequent turns automatically recover and reuse it.
50+
- **Multi-turn chaining**: the agent recovers the `previous_interaction_id` from
51+
the session events, so follow-up turns continue the same interaction without
52+
any extra wiring.
53+
- **Drive it**: a `ManagedAgent` is a `BaseAgent`, so a standard `Runner` runs
54+
it just like any other agent.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from . import agent
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""A ManagedAgent that runs server-side code execution.
16+
17+
``ManagedAgent`` calls the Managed Agents API directly from its run loop instead
18+
of running a local model loop. It currently supports server-side tools only.
19+
20+
Unlike ``LlmAgent``, ``ManagedAgent`` has no ``code_executor`` field, so code
21+
execution is enabled by passing the raw built-in tool config
22+
``types.Tool(code_execution=types.ToolCodeExecution())`` in ``tools`` -- the
23+
same config ``BuiltInCodeExecutor`` produces under the hood. The model writes
24+
and runs code on the server to compute answers.
25+
26+
A fresh remote sandbox is provisioned via ``environment={'type': 'remote'}``;
27+
the environment id is recovered from prior events so multi-turn conversations
28+
reuse the same sandbox.
29+
30+
Run with ``adk web`` /
31+
``adk run contributing/samples/managed_agent/code_execution``. See the README
32+
for the required environment / auth setup.
33+
"""
34+
35+
import os
36+
37+
from google.adk.agents import ManagedAgent
38+
from google.genai import types
39+
40+
# The Managed Agent id served by the Managed Agents API. Override with the
41+
# MANAGED_AGENT_ID environment variable if your project has access to a
42+
# different agent.
43+
_DEFAULT_AGENT_ID = 'antigravity-preview-05-2026'
44+
45+
root_agent = ManagedAgent(
46+
name='managed_code_execution_agent',
47+
agent_id=os.environ.get('MANAGED_AGENT_ID', _DEFAULT_AGENT_ID),
48+
# Provision a remote sandbox for the agent. The environment id is recovered
49+
# from prior events, so follow-up turns reuse the same sandbox.
50+
environment={'type': 'remote'},
51+
# ManagedAgent has no `code_executor` field; enable server-side code
52+
# execution by passing the raw built-in tool config. This is the same config
53+
# BuiltInCodeExecutor appends for a regular LlmAgent.
54+
tools=[types.Tool(code_execution=types.ToolCodeExecution())],
55+
)

tests/integration/test_managed_agent.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,38 @@ async def test_google_search_project_hail_mary():
8686
assert (
8787
'james ortiz' in answer.lower()
8888
), f'expected the grounded answer to contain "James Ortiz"; got: {answer!r}'
89+
90+
91+
@pytest.mark.asyncio
92+
async def test_code_execution_prime_sum():
93+
agent = ManagedAgent(
94+
name='managed_code_execution_agent',
95+
agent_id=_AGENT_ID,
96+
environment={'type': 'remote'},
97+
tools=[types.Tool(code_execution=types.ToolCodeExecution())],
98+
)
99+
session_service = InMemorySessionService()
100+
runner = Runner(
101+
app_name='managed_agent_it',
102+
agent=agent,
103+
session_service=session_service,
104+
)
105+
session = await session_service.create_session(
106+
app_name='managed_agent_it', user_id='test_user'
107+
)
108+
109+
events = await _run_turn(
110+
runner,
111+
session,
112+
'What is the sum of the first 50 prime numbers? Use code to compute it.',
113+
)
114+
115+
answer = _joined_text(events)
116+
print('\n=== ManagedAgent code execution answer ===\n', answer)
117+
# The model may stream the number with thousands separators and/or stray
118+
# whitespace (e.g. "5,117" or "5, 117"), so remove all whitespace and commas
119+
# before matching the code-executed sum.
120+
normalized = ''.join(answer.split()).replace(',', '')
121+
assert (
122+
'5117' in normalized
123+
), f'expected the code-executed sum 5117; got: {answer!r}'

0 commit comments

Comments
 (0)