Skip to content

Commit 475024c

Browse files
vertex-sdk-botcopybara-github
authored andcommitted
chore: Remove sandbox tool declarations from SDK AgentConfig display.
PiperOrigin-RevId: 954831634
1 parent dbcf815 commit 475024c

3 files changed

Lines changed: 41 additions & 64 deletions

File tree

agentplatform/_genai/_evals_builtin_tools.py

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
2727
**If the server catalog changes, this SDK-side copy must be updated to match.**
2828
29-
This module also provides sandbox-detection helpers
30-
(``SANDBOX_TOOL_NAMES``, ``is_sandbox_only_turn``) used by the display
31-
path (``_evals_common._interaction_dict_to_agent_data``).
29+
Sandbox orchestration tools (``provision_sandbox``, ``load_sandbox``) are
30+
intentionally excluded from the tool catalog. They are infrastructure
31+
initialization, not user-facing agent capabilities.
3232
"""
3333

3434
from typing import Any, Optional
@@ -76,25 +76,13 @@
7676
}
7777

7878

79-
# Sandbox-environment orchestration tool declarations.
80-
#
81-
# Source of truth: interaction_converter.py, _SANDBOX_FUNCTION_DECLARATIONS
82-
SANDBOX_DECLARATIONS: list[genai_types.FunctionDeclaration] = [
83-
genai_types.FunctionDeclaration(
84-
name="provision_sandbox",
85-
description="Provisions a sandbox environment.",
86-
),
87-
genai_types.FunctionDeclaration(
88-
name="load_sandbox",
89-
description="Loads a previously provisioned sandbox environment.",
90-
),
91-
]
92-
93-
94-
# Names of sandbox orchestration tools, derived from ``SANDBOX_DECLARATIONS``
95-
# so there is a single source of truth.
79+
# Sandbox-environment orchestration tools.
80+
# Source of truth: interaction_converter.py, _SANDBOX_TOOL_NAMES
9681
SANDBOX_TOOL_NAMES: frozenset[str] = frozenset(
97-
decl.name for decl in SANDBOX_DECLARATIONS if decl.name
82+
{
83+
"provision_sandbox",
84+
"load_sandbox",
85+
}
9886
)
9987

10088

@@ -146,7 +134,6 @@ def is_sandbox_only_turn(
146134

147135
def agent_tools_to_config_tools(
148136
agent_tools: Optional[list[Any]],
149-
has_environment: bool = False,
150137
) -> Optional[list[genai_types.Tool]]:
151138
"""Maps Gemini Agents API tools to ``genai_types.Tool`` for display.
152139
@@ -163,18 +150,19 @@ def agent_tools_to_config_tools(
163150
* ``mcp_server`` is represented as a named declaration with a
164151
human-readable label.
165152
* Tools carrying explicit ``function_declarations`` are passed through.
166-
* When ``has_environment`` is True, sandbox orchestration tools
167-
(``provision_sandbox``, ``load_sandbox``) are appended.
153+
154+
Sandbox orchestration tools (``provision_sandbox``, ``load_sandbox``)
155+
are intentionally excluded. They are infrastructure initialization,
156+
not user-facing capabilities.
168157
169158
Args:
170159
agent_tools: The ``tools`` list from a fetched Gemini agent dict.
171-
has_environment: Whether the agent has a sandbox environment configured.
172160
173161
Returns:
174162
A list of ``genai_types.Tool``, or ``None`` if there are no mappable
175163
tools.
176164
"""
177-
if not agent_tools and not has_environment:
165+
if not agent_tools:
178166
return None
179167
tools: list[genai_types.Tool] = []
180168
for tool in agent_tools or []:
@@ -218,7 +206,4 @@ def agent_tools_to_config_tools(
218206
elif remainder:
219207
tools.append(genai_types.Tool.model_validate(remainder))
220208

221-
if has_environment:
222-
tools.append(genai_types.Tool(function_declarations=list(SANDBOX_DECLARATIONS)))
223-
224209
return tools or None

agentplatform/_genai/_evals_common.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -903,13 +903,7 @@ def _fetch_agent_config_dict(
903903
instruction = agent_dict.get("system_instruction") or None
904904
description = agent_dict.get("description") or None
905905
agent_type = agent_dict.get("base_agent") or None
906-
has_environment = bool(
907-
agent_dict.get("environment_config")
908-
or agent_dict.get("base_environment")
909-
)
910-
tools = _agent_tools_to_config_tools(
911-
agent_dict.get("tools"), has_environment=has_environment
912-
)
906+
tools = _agent_tools_to_config_tools(agent_dict.get("tools"))
913907
except Exception as e: # pylint: disable=broad-exception-caught
914908
logger.warning(
915909
"Failed to fetch agent config for '%s' (continuing without it): %s",

tests/unit/agentplatform/genai/test_evals.py

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11553,9 +11553,7 @@ def test_load_sandbox_is_sandbox_only(self):
1155311553
self._make_event(
1155411554
author="agent",
1155511555
part=genai_types.Part(
11556-
function_call=genai_types.FunctionCall(
11557-
name="load_sandbox", args={}
11558-
)
11556+
function_call=genai_types.FunctionCall(name="load_sandbox", args={})
1155911557
),
1156011558
),
1156111559
]
@@ -11566,9 +11564,7 @@ def test_non_sandbox_tool_is_not_sandbox_only(self):
1156611564
self._make_event(
1156711565
author="agent",
1156811566
part=genai_types.Part(
11569-
function_call=genai_types.FunctionCall(
11570-
name="run_command", args={}
11571-
)
11567+
function_call=genai_types.FunctionCall(name="run_command", args={})
1157211568
),
1157311569
),
1157411570
]
@@ -11670,7 +11666,10 @@ def test_sandbox_prefix_with_multi_turn(self):
1167011666
}
1167111667
result = _evals_common._interaction_dict_to_agent_data(interaction_dict)
1167211668
assert len(result.turns) == 2
11673-
assert result.turns[0].events[0].content.parts[0].function_call.name == "provision_sandbox"
11669+
assert (
11670+
result.turns[0].events[0].content.parts[0].function_call.name
11671+
== "provision_sandbox"
11672+
)
1167411673
assert result.turns[0].events[-1].content.parts[0].text == "Reply 1"
1167511674
assert result.turns[1].events[0].content.parts[0].text == "Turn 2"
1167611675

@@ -12010,8 +12009,8 @@ def test_filesystem_expands_to_file_tools(self):
1201012009
"move_file",
1201112010
}
1201212011

12013-
def test_environment_adds_sandbox_tools(self):
12014-
"""When agent has environment_config, sandbox tools are appended."""
12012+
def test_environment_does_not_add_sandbox_tools(self):
12013+
"""Sandbox tools should NOT appear even when agent has environment."""
1201512014
agent_json = {
1201612015
"tools": [{"type": "code_execution"}],
1201712016
"environment_config": {"some_field": "value"},
@@ -12022,17 +12021,17 @@ def test_environment_adds_sandbox_tools(self):
1202212021
mock_api_client,
1202312022
"projects/p/locations/l/agents/a",
1202412023
)
12025-
# code_execution + sandbox tool
12026-
assert len(result.tools) == 2
12024+
# Only code_execution, no sandbox tools.
12025+
assert len(result.tools) == 1
1202712026
all_decl_names = {
1202812027
fd.name
1202912028
for t in result.tools
1203012029
if t.function_declarations
1203112030
for fd in t.function_declarations
1203212031
}
1203312032
assert "run_command" in all_decl_names
12034-
assert "provision_sandbox" in all_decl_names
12035-
assert "load_sandbox" in all_decl_names
12033+
assert "provision_sandbox" not in all_decl_names
12034+
assert "load_sandbox" not in all_decl_names
1203612035

1203712036
def test_mcp_server_kept_as_named_declaration(self):
1203812037
"""mcp_server entries are kept as named declarations, not dropped."""
@@ -12062,11 +12061,15 @@ def test_mcp_server_kept_as_named_declaration(self):
1206212061
def test_catalog_in_sync_with_server(self):
1206312062
"""SDK catalog keys and function names match the server-side catalog.
1206412063
12065-
The SDK-side BUILTIN_TOOL_DECLARATIONS and SANDBOX_DECLARATIONS in
12066-
_evals_builtin_tools are a display-only copy of the authoritative
12067-
server-side catalog in interaction_converter.py. This test imports
12068-
both and asserts that tool-type keys and declaration names stay in
12069-
sync. If this test fails, update _evals_builtin_tools.py to match.
12064+
The SDK-side BUILTIN_TOOL_DECLARATIONS in _evals_builtin_tools is a
12065+
display-only copy of the authoritative server-side catalog in
12066+
interaction_converter.py. This test imports both and asserts that
12067+
tool-type keys and declaration names stay in sync. If this test
12068+
fails, update _evals_builtin_tools.py to match.
12069+
12070+
Sandbox tool declarations (provision_sandbox, load_sandbox) are
12071+
intentionally excluded from both the SDK and server AgentConfig
12072+
tool catalogs, so no sync check is needed for them.
1207012073
"""
1207112074
# pylint: disable=g-import-not-at-top
1207212075
try:
@@ -12104,17 +12107,12 @@ def test_catalog_in_sync_with_server(self):
1210412107
f" SDK: {sorted(sdk_names)}"
1210512108
)
1210612109

12107-
# --- Sandbox declarations: names must match ---
12108-
server_sandbox_names = {
12109-
fd.name for fd in interaction_converter.sandbox_function_declarations()
12110-
}
12111-
sdk_sandbox_names = {
12112-
fd.name for fd in _evals_builtin_tools.SANDBOX_DECLARATIONS
12113-
}
12114-
assert sdk_sandbox_names == server_sandbox_names, (
12115-
f"SANDBOX_DECLARATIONS names out of sync.\n"
12110+
# --- Sandbox tool names: SDK names must match server names ---
12111+
server_sandbox_names = set(interaction_converter._SANDBOX_TOOL_NAMES)
12112+
assert _evals_builtin_tools.SANDBOX_TOOL_NAMES == server_sandbox_names, (
12113+
f"SANDBOX_TOOL_NAMES out of sync.\n"
1211612114
f" Server: {sorted(server_sandbox_names)}\n"
12117-
f" SDK: {sorted(sdk_sandbox_names)}"
12115+
f" SDK: {sorted(_evals_builtin_tools.SANDBOX_TOOL_NAMES)}"
1211812116
)
1211912117

1212012118

0 commit comments

Comments
 (0)