Skip to content

Commit 7c9d5b0

Browse files
authored
Merge branch 'main' into sid/evaluate-full-response
2 parents 898da3d + b580891 commit 7c9d5b0

11 files changed

Lines changed: 1023 additions & 720 deletions

File tree

contributing/samples/adk_triaging_agent/agent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"models": "xuanyang15",
3838
"services": "DeanChensj",
3939
"tools": "xuanyang15",
40-
"tracing": "jawoszek",
40+
"tracing": "mhenc",
4141
"web": "wyf7107",
4242
"workflow": "DeanChensj",
4343
}

src/google/adk/cli/adk_web_server.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,6 +2075,7 @@ async def run_agent_live(
20752075
proactive_audio: bool | None = Query(default=None),
20762076
enable_affective_dialog: bool | None = Query(default=None),
20772077
enable_session_resumption: bool | None = Query(default=None),
2078+
save_live_blob: bool = Query(default=False),
20782079
) -> None:
20792080
ws_origin = websocket.headers.get("origin")
20802081
if ws_origin is not None and not _is_request_origin_allowed(
@@ -2117,6 +2118,7 @@ async def forward_events():
21172118
if enable_session_resumption is not None
21182119
else None
21192120
),
2121+
save_live_blob=save_live_blob,
21202122
)
21212123
async with Aclosing(
21222124
runner.run_live(

src/google/adk/integrations/agent_identity/gcp_auth_provider.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,17 @@
2929
from google.adk.auth.base_auth_provider import BaseAuthProvider
3030
from google.adk.flows.llm_flows.functions import REQUEST_EUC_FUNCTION_CALL_NAME
3131
from google.api_core.client_options import ClientOptions
32-
from google.cloud.iamconnectorcredentials_v1alpha import IAMConnectorCredentialsServiceClient as Client
33-
from google.cloud.iamconnectorcredentials_v1alpha import RetrieveCredentialsMetadata
34-
from google.cloud.iamconnectorcredentials_v1alpha import RetrieveCredentialsRequest
35-
from google.cloud.iamconnectorcredentials_v1alpha import RetrieveCredentialsResponse
32+
33+
try:
34+
from google.cloud.iamconnectorcredentials_v1alpha import IAMConnectorCredentialsServiceClient as Client
35+
from google.cloud.iamconnectorcredentials_v1alpha import RetrieveCredentialsMetadata
36+
from google.cloud.iamconnectorcredentials_v1alpha import RetrieveCredentialsRequest
37+
from google.cloud.iamconnectorcredentials_v1alpha import RetrieveCredentialsResponse
38+
except ImportError as e:
39+
raise ImportError(
40+
"Missing required dependencies for Agent Identity Auth Manager. "
41+
'Please install with: pip install "google-adk[agent-identity]"'
42+
) from e
3643
from google.longrunning.operations_pb2 import Operation
3744
from typing_extensions import override
3845

tests/unittests/cli/test_adk_web_server_run_live.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ async def _get_runner_async(_self, _app_name: str):
105105
"&proactive_audio=true"
106106
"&enable_affective_dialog=true"
107107
"&enable_session_resumption=true"
108+
"&save_live_blob=true"
108109
)
109110

110111
with client.websocket_connect(url) as ws:
@@ -118,28 +119,32 @@ async def _get_runner_async(_self, _app_name: str):
118119
assert run_config.proactivity.proactive_audio is True
119120
assert run_config.session_resumption is not None
120121
assert run_config.session_resumption.transparent is True
122+
assert run_config.save_live_blob is True
121123

122124

123125
@pytest.mark.parametrize(
124126
(
125127
"query,expected_enable_affective,expected_proactive_audio,"
126-
"expected_session_resumption_transparent"
128+
"expected_session_resumption_transparent,expected_save_live_blob"
127129
),
128130
[
129-
("", None, None, None),
130-
("&proactive_audio=true", None, True, None),
131-
("&proactive_audio=false", None, False, None),
132-
("&enable_affective_dialog=true", True, None, None),
133-
("&enable_affective_dialog=false", False, None, None),
134-
("&enable_session_resumption=true", None, None, True),
135-
("&enable_session_resumption=false", None, None, False),
131+
("", None, None, None, False),
132+
("&proactive_audio=true", None, True, None, False),
133+
("&proactive_audio=false", None, False, None, False),
134+
("&enable_affective_dialog=true", True, None, None, False),
135+
("&enable_affective_dialog=false", False, None, None, False),
136+
("&enable_session_resumption=true", None, None, True, False),
137+
("&enable_session_resumption=false", None, None, False, False),
138+
("&save_live_blob=true", None, None, None, True),
139+
("&save_live_blob=false", None, None, None, False),
136140
],
137141
)
138142
def test_run_live_defaults_and_individual_options(
139143
query: str,
140144
expected_enable_affective: bool | None,
141145
expected_proactive_audio: bool | None,
142146
expected_session_resumption_transparent: bool | None,
147+
expected_save_live_blob: bool,
143148
):
144149
session_service = InMemorySessionService()
145150
asyncio.run(
@@ -204,6 +209,7 @@ async def _get_runner_async(_self, _app_name: str):
204209
run_config.session_resumption.transparent
205210
is expected_session_resumption_transparent
206211
)
212+
assert run_config.save_live_blob is expected_save_live_blob
207213

208214

209215
_WS_BASE_URL = (

tests/unittests/cli/test_cli_feature_options.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from google.adk.features._feature_registry import _WARNED_FEATURES
2323
from google.adk.features._feature_registry import FeatureName
2424
from google.adk.features._feature_registry import is_feature_enabled
25+
from google.adk.features._feature_registry import temporary_feature_override
2526
import pytest
2627

2728

@@ -218,17 +219,21 @@ def test_no_enable_features_flag(self):
218219
"""Command works without --enable_features flag."""
219220
enabled_features = []
220221

221-
@click.command()
222-
@feature_options()
223-
def test_cmd():
224-
enabled_features.append(
225-
is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL)
226-
)
222+
with temporary_feature_override(
223+
FeatureName.JSON_SCHEMA_FOR_FUNC_DECL, False
224+
):
227225

228-
runner = CliRunner()
229-
result = runner.invoke(test_cmd, [], catch_exceptions=False)
230-
assert result.exit_code == 0
231-
assert enabled_features == [False]
226+
@click.command()
227+
@feature_options()
228+
def test_cmd():
229+
enabled_features.append(
230+
is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL)
231+
)
232+
233+
runner = CliRunner()
234+
result = runner.invoke(test_cmd, [], catch_exceptions=False)
235+
assert result.exit_code == 0
236+
assert enabled_features == [False]
232237

233238
def test_preserves_function_metadata(self):
234239
"""Decorator preserves the wrapped function's metadata."""

tests/unittests/tools/application_integration_tool/test_integration_connector_tool.py

Lines changed: 63 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -99,36 +99,46 @@ def integration_tool_with_auth(mock_rest_api_tool):
9999
)
100100

101101

102-
def test_get_declaration(integration_tool):
103-
"""Tests the generation of the function declaration."""
104-
declaration = integration_tool._get_declaration()
105-
106-
assert isinstance(declaration, FunctionDeclaration)
107-
assert declaration.name == "test_integration_tool"
108-
assert declaration.description == "Test integration tool description."
109-
110-
# Check parameters schema
111-
params = declaration.parameters
112-
assert isinstance(params, Schema)
113-
print(f"params: {params}")
114-
assert params.type == Type.OBJECT
115-
116-
# Check properties (excluded fields should not be present)
117-
assert "user_id" in params.properties
118-
assert "connection_name" not in params.properties
119-
assert "host" not in params.properties
120-
assert "service_name" not in params.properties
121-
assert "entity" not in params.properties
122-
assert "operation" not in params.properties
123-
assert "action" not in params.properties
124-
assert "page_size" in params.properties
125-
assert "filter" in params.properties
126-
127-
# Check required fields (optional and excluded fields should not be required)
128-
assert "user_id" in params.required
129-
assert "page_size" not in params.required
130-
assert "filter" not in params.required
131-
assert "connection_name" not in params.required
102+
class TestIntegrationConnectorToolLegacy:
103+
104+
@pytest.fixture(autouse=True)
105+
def disable_feature_flag(self):
106+
"""Disable the JSON_SCHEMA_FOR_FUNC_DECL feature flag for legacy tests."""
107+
with temporary_feature_override(
108+
FeatureName.JSON_SCHEMA_FOR_FUNC_DECL, False
109+
):
110+
yield
111+
112+
def test_get_declaration(self, integration_tool):
113+
"""Tests the generation of the function declaration."""
114+
declaration = integration_tool._get_declaration()
115+
116+
assert isinstance(declaration, FunctionDeclaration)
117+
assert declaration.name == "test_integration_tool"
118+
assert declaration.description == "Test integration tool description."
119+
120+
# Check parameters schema
121+
params = declaration.parameters
122+
assert isinstance(params, Schema)
123+
print(f"params: {params}")
124+
assert params.type == Type.OBJECT
125+
126+
# Check properties (excluded fields should not be present)
127+
assert "user_id" in params.properties
128+
assert "connection_name" not in params.properties
129+
assert "host" not in params.properties
130+
assert "service_name" not in params.properties
131+
assert "entity" not in params.properties
132+
assert "operation" not in params.properties
133+
assert "action" not in params.properties
134+
assert "page_size" in params.properties
135+
assert "filter" in params.properties
136+
137+
# Check required fields (optional and excluded fields should not be required)
138+
assert "user_id" in params.required
139+
assert "page_size" not in params.required
140+
assert "filter" not in params.required
141+
assert "connection_name" not in params.required
132142

133143

134144
@pytest.mark.asyncio
@@ -258,21 +268,27 @@ async def test_run_with_auth_async(
258268
assert result == {"status": "success", "data": "mock_data"}
259269

260270

261-
def test_get_declaration_with_json_schema_feature_enabled(integration_tool):
262-
"""Tests the generation of the function declaration with JSON schema feature enabled."""
263-
with temporary_feature_override(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL, True):
264-
declaration = integration_tool._get_declaration()
271+
class TestIntegrationConnectorToolWithJsonSchema:
265272

266-
assert isinstance(declaration, FunctionDeclaration)
267-
assert declaration.name == "test_integration_tool"
268-
assert declaration.description == "Test integration tool description."
269-
assert declaration.parameters is None
270-
assert declaration.parameters_json_schema == {
271-
"type": "object",
272-
"properties": {
273-
"user_id": {"type": "string", "description": "User ID"},
274-
"page_size": {"type": "integer"},
275-
"filter": {"type": "string"},
276-
},
277-
"required": ["user_id"],
278-
}
273+
def test_get_declaration_with_json_schema_feature_enabled(
274+
self, integration_tool
275+
):
276+
"""Tests the generation of the function declaration with JSON schema feature enabled."""
277+
with temporary_feature_override(
278+
FeatureName.JSON_SCHEMA_FOR_FUNC_DECL, True
279+
):
280+
declaration = integration_tool._get_declaration()
281+
282+
assert isinstance(declaration, FunctionDeclaration)
283+
assert declaration.name == "test_integration_tool"
284+
assert declaration.description == "Test integration tool description."
285+
assert declaration.parameters is None
286+
assert declaration.parameters_json_schema == {
287+
"type": "object",
288+
"properties": {
289+
"user_id": {"type": "string", "description": "User ID"},
290+
"page_size": {"type": "integer"},
291+
"filter": {"type": "string"},
292+
},
293+
"required": ["user_id"],
294+
}

0 commit comments

Comments
 (0)