Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/google/adk/flows/llm_flows/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ def build_auth_request_event(
args=AuthToolArguments(
function_call_id=function_call_id,
auth_config=auth_config,
).model_dump(exclude_none=True, by_alias=True),
).model_dump(mode='json', exclude_none=True, by_alias=True),
)
long_running_tool_ids.add(request_euc_function_call.id)
parts.append(types.Part(function_call=request_euc_function_call))
Expand Down
63 changes: 63 additions & 0 deletions tests/unittests/flows/llm_flows/test_functions_request_euc.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import json
from typing import Any
from typing import Optional

Expand Down Expand Up @@ -153,6 +154,68 @@ def call_external_api2(tool_context: ToolContext) -> Optional[int]:
)


def test_function_request_euc_args_are_json_serializable():
responses = [
[
types.Part.from_function_call(name='call_external_api', args={}),
],
[
types.Part.from_text(text='response1'),
],
]

auth_config = AuthConfig(
auth_scheme=OAuth2(
flows=OAuthFlows(
authorizationCode=OAuthFlowAuthorizationCode(
authorizationUrl='https://accounts.google.com/o/oauth2/auth',
tokenUrl='https://oauth2.googleapis.com/token',
scopes={
'https://www.googleapis.com/auth/calendar': (
'See, edit, share, and permanently delete all the'
' calendars you can access using Google Calendar'
)
},
)
)
),
raw_auth_credential=AuthCredential(
auth_type=AuthCredentialTypes.OAUTH2,
oauth2=OAuth2Auth(
client_id='oauth_client_id',
client_secret='oauth_client_secret',
),
),
)

mock_model = testing_utils.MockModel.create(responses=responses)

def call_external_api(tool_context: ToolContext) -> Optional[int]:
tool_context.request_credential(auth_config)

agent = Agent(
name='root_agent',
model=mock_model,
tools=[call_external_api],
)
runner = testing_utils.InMemoryRunner(agent)
events = runner.run('test')

request_euc_function_call = events[1].content.parts[0].function_call
assert (
request_euc_function_call.name == functions.REQUEST_EUC_FUNCTION_CALL_NAME
)

# The in-memory event args must be JSON-serializable. A python-mode dump
# leaves auth_scheme.type as a live SecuritySchemeType enum, which breaks any
# consumer that json.dumps the event before it round-trips the session DB.
json.dumps(request_euc_function_call.args)
assert (
request_euc_function_call.args['authConfig']['authScheme']['type']
== 'oauth2'
)


def test_function_get_auth_response():
id_1 = 'id_1'
id_2 = 'id_2'
Expand Down