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
15 changes: 14 additions & 1 deletion google/genai/_extra_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,10 +530,23 @@ def raise_error_for_afc_incompatible_config(config: Optional[types.GenerateConte
return
afc_config = config.automatic_function_calling
disable_afc_config = afc_config.disable if afc_config else False
function_calling_config = config.tool_config.function_calling_config
stream_function_call = (
config.tool_config.function_calling_config.stream_function_call_arguments
function_calling_config.stream_function_call_arguments
)

if (
function_calling_config.mode == types.FunctionCallingConfigMode.ANY
and not disable_afc_config
):
logger.warning(
'tool_config.function_calling_config.mode is set to ANY while'
' automatic function calling (AFC) is enabled. AFC will continue'
' calling functions until max_remote_calls is reached, so the model'
' may not return a natural language response. Set mode to AUTO or'
' disable automatic function calling if this is intentional.'
)

if stream_function_call and not disable_afc_config:
raise ValueError(
'Running in streaming mode with stream_function_call_arguments'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

"""Tests for raise_error_for_afc_incompatible_config."""

import logging

import pytest
from ... import types
from ..._extra_utils import raise_error_for_afc_incompatible_config
Expand Down Expand Up @@ -157,3 +159,50 @@ def test_incompatible_config_stream_function_call_arguments_set_no_disable_afc()
),
)
)


@pytest.mark.parametrize(
('mode', 'disable_afc', 'should_warn'),
[
(types.FunctionCallingConfigMode.ANY, False, True),
(types.FunctionCallingConfigMode.ANY, True, False),
(types.FunctionCallingConfigMode.AUTO, False, False),
],
)
def test_function_calling_mode_warns_when_afc_is_enabled(
caplog, mode, disable_afc, should_warn
):
caplog.set_level(logging.WARNING, logger='google_genai.models')

raise_error_for_afc_incompatible_config(
types.GenerateContentConfig(
automatic_function_calling=types.AutomaticFunctionCallingConfig(
disable=disable_afc,
),
tool_config=types.ToolConfig(
function_calling_config=types.FunctionCallingConfig(mode=mode),
),
)
)

if should_warn:
assert 'mode is set to ANY' in caplog.text
assert 'automatic function calling' in caplog.text
else:
assert not caplog.records


def test_any_function_calling_mode_warns_when_afc_config_is_unset(caplog):
caplog.set_level(logging.WARNING, logger='google_genai.models')

raise_error_for_afc_incompatible_config(
types.GenerateContentConfig(
tool_config=types.ToolConfig(
function_calling_config=types.FunctionCallingConfig(
mode=types.FunctionCallingConfigMode.ANY,
),
),
)
)

assert 'mode is set to ANY' in caplog.text