Skip to content

Commit 6a3340e

Browse files
Merge branch 'main' into docs/openapi-session-endpoint-docs-update
2 parents 16a5f62 + 6ee0362 commit 6a3340e

38 files changed

+2280
-221
lines changed
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: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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+
import os
16+
import random
17+
18+
from dotenv import load_dotenv
19+
from google.adk import Agent
20+
from google.adk.tools.agent_tool import AgentTool
21+
from google.adk.tools.tool_context import ToolContext
22+
from google.adk.tools.vertex_ai_search_tool import VertexAiSearchTool
23+
24+
load_dotenv(override=True)
25+
26+
VERTEXAI_DATASTORE_ID = os.getenv("VERTEXAI_DATASTORE_ID")
27+
if not VERTEXAI_DATASTORE_ID:
28+
raise ValueError("VERTEXAI_DATASTORE_ID environment variable not set")
29+
30+
31+
def roll_die(sides: int, tool_context: ToolContext) -> int:
32+
"""Roll a die and return the rolled result.
33+
34+
Args:
35+
sides: The integer number of sides the die has.
36+
37+
Returns:
38+
An integer of the result of rolling the die.
39+
"""
40+
result = random.randint(1, sides)
41+
if "rolls" not in tool_context.state:
42+
tool_context.state["rolls"] = []
43+
44+
tool_context.state["rolls"] = tool_context.state["rolls"] + [result]
45+
return result
46+
47+
48+
vertex_ai_search_agent = Agent(
49+
model="gemini-3-flash-preview",
50+
name="vertex_ai_search_agent",
51+
description="An agent for performing Vertex AI search.",
52+
tools=[
53+
VertexAiSearchTool(
54+
data_store_id=VERTEXAI_DATASTORE_ID,
55+
)
56+
],
57+
)
58+
59+
root_agent = Agent(
60+
model="gemini-3.1-pro-preview",
61+
name="hello_world_agent",
62+
description="A hello world agent with multiple tools.",
63+
instruction="""
64+
You are a helpful assistant which can help user to roll dice and search for information.
65+
- Use `roll_die` tool to roll dice.
66+
- Use `vertex_ai_search_agent` to search for Google Agent Development Kit (ADK) information in the datastore.
67+
""",
68+
tools=[
69+
roll_die,
70+
AgentTool(
71+
agent=vertex_ai_search_agent, propagate_grounding_metadata=True
72+
),
73+
],
74+
)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
"""Agent environments."""
16+
17+
from __future__ import annotations
18+
19+
from ._base_environment import BaseEnvironment
20+
from ._base_environment import ExecutionResult
21+
from ._local_environment import LocalEnvironment
22+
23+
__all__ = [
24+
'BaseEnvironment',
25+
'ExecutionResult',
26+
'LocalEnvironment',
27+
]
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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+
"""Base class for agent environments."""
16+
17+
from __future__ import annotations
18+
19+
from abc import ABC
20+
from abc import abstractmethod
21+
import dataclasses
22+
from pathlib import Path
23+
from typing import Optional
24+
25+
from ..utils.feature_decorator import experimental
26+
27+
28+
@dataclasses.dataclass
29+
class ExecutionResult:
30+
"""Result of a command execution."""
31+
32+
exit_code: int = 0
33+
"""The exit code of the process."""
34+
35+
stdout: str = ""
36+
"""Standard output captured from the process."""
37+
38+
stderr: str = ""
39+
"""Standard error captured from the process."""
40+
41+
timed_out: bool = False
42+
"""Whether the execution exceeded the timeout."""
43+
44+
45+
@experimental
46+
class BaseEnvironment(ABC):
47+
"""Abstract base class for code execution environments.
48+
49+
An environment provides the ability to execute shell commands,
50+
read files, and write files within a working directory. Concrete
51+
implementations include local subprocess execution, sandboxed
52+
execution, container environments, and cloud-hosted environments.
53+
54+
Lifecycle:
55+
1. Construct the environment (``__init__``).
56+
2. Call ``initialize()`` before first use.
57+
3. Use ``execute``, ``read_file``, ``write_file``.
58+
4. Call ``close()`` when done.
59+
"""
60+
61+
async def initialize(self) -> None:
62+
"""Initialize the environment (e.g. create working directory).
63+
64+
Called before first use. The default implementation is a
65+
no-op. Sub-classes should ensure this method is idempotent.
66+
"""
67+
68+
async def close(self) -> None:
69+
"""Release resources held by the environment.
70+
71+
Called when the environment is no longer needed. The default
72+
implementation is a no-op. Sub-classes should ensure this method is
73+
idempotent.
74+
"""
75+
76+
@property
77+
@abstractmethod
78+
def working_dir(self) -> Path:
79+
"""The absolute path to the environment's working directory."""
80+
81+
@abstractmethod
82+
async def execute(
83+
self,
84+
command: str,
85+
*,
86+
timeout: Optional[float] = None,
87+
) -> ExecutionResult:
88+
"""Execute a shell command in the working directory.
89+
90+
Args:
91+
command: The shell command string to execute.
92+
timeout: Maximum execution time in seconds. ``None`` means
93+
no limit.
94+
95+
Returns:
96+
An ``ExecutionResult`` with exit code, stdout, stderr, and
97+
timeout status.
98+
"""
99+
100+
@abstractmethod
101+
async def read_file(self, path: Path) -> bytes:
102+
"""Read a file from the environment filesystem.
103+
104+
Args:
105+
path: Absolute or working-dir-relative path to the file.
106+
107+
Returns:
108+
The raw file contents as bytes.
109+
110+
Raises:
111+
FileNotFoundError: If the file does not exist.
112+
"""
113+
114+
@abstractmethod
115+
async def write_file(self, path: Path, content: str | bytes) -> None:
116+
"""Write content to a file in the environment's filesystem.
117+
118+
Parent directories are created automatically if they do not
119+
exist.
120+
121+
Args:
122+
path: Absolute or working-dir-relative path to the file.
123+
content: The string or raw bytes to write.
124+
"""

0 commit comments

Comments
 (0)