Skip to content

Commit 3daa791

Browse files
committed
fix: avoid mutating cached tools when applying exchanged auth
1 parent c19359b commit 3daa791

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

src/google/adk/tools/application_integration_tool/application_integration_toolset.py

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,25 @@ def _parse_spec_to_toolset(self, spec_dict, connection_details):
270270
)
271271
)
272272

273+
def _clone_connector_tool_with_auth_credential(
274+
self,
275+
tool: IntegrationConnectorTool,
276+
auth_credential: AuthCredential,
277+
) -> IntegrationConnectorTool:
278+
return IntegrationConnectorTool(
279+
name=tool.name,
280+
description=tool.description,
281+
connection_name=tool._connection_name,
282+
connection_host=tool._connection_host,
283+
connection_service_name=tool._connection_service_name,
284+
entity=tool._entity,
285+
action=tool._action,
286+
operation=tool._operation,
287+
rest_api_tool=tool._rest_api_tool,
288+
auth_scheme=tool._auth_scheme,
289+
auth_credential=auth_credential,
290+
)
291+
273292
@override
274293
async def get_tools(
275294
self,
@@ -278,17 +297,34 @@ async def get_tools(
278297
if self._openapi_toolset is not None:
279298
return await self._openapi_toolset.get_tools(readonly_context)
280299

281-
if self._auth_config and self._auth_config.exchanged_auth_credential:
282-
for tool in self._tools:
283-
if isinstance(tool, IntegrationConnectorTool) and tool._auth_scheme:
284-
tool._auth_credential = self._auth_config.exchanged_auth_credential
300+
exchanged_auth_credential = (
301+
self._auth_config.exchanged_auth_credential
302+
if self._auth_config
303+
else None
304+
)
285305

286-
return [
306+
selected_tools = [
287307
tool
288308
for tool in self._tools
289309
if self._is_tool_selected(tool, readonly_context)
290310
]
291311

312+
if not exchanged_auth_credential:
313+
return selected_tools
314+
315+
resolved_tools: List[RestApiTool] = []
316+
for tool in selected_tools:
317+
if isinstance(tool, IntegrationConnectorTool) and tool._auth_scheme:
318+
resolved_tools.append(
319+
self._clone_connector_tool_with_auth_credential(
320+
tool, exchanged_auth_credential
321+
)
322+
)
323+
else:
324+
resolved_tools.append(tool)
325+
326+
return resolved_tools
327+
292328
@override
293329
async def close(self) -> None:
294330
if self._openapi_toolset:

tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,10 @@ async def test_get_tools_uses_exchanged_auth_credential_when_available(
729729
)
730730
toolset._auth_config.exchanged_auth_credential = exchanged_auth_credential
731731

732+
original_tool = toolset._tools[0]
732733
tools = await toolset.get_tools()
733734

734735
assert len(tools) == 1
736+
assert tools[0] is not original_tool
735737
assert tools[0]._auth_credential == exchanged_auth_credential
738+
assert original_tool._auth_credential == raw_auth_credential

0 commit comments

Comments
 (0)