fix: build function declaration when a param uses a TYPE_CHECKING-only annotation - #6488
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
Hi @NishchayMahor , Thank you for your contribution! It appears you haven't yet signed the Contributor License Agreement (CLA). Please visit https://cla.developers.google.com/ to complete the signing process. Once the CLA is signed, we'll be able to proceed with the review of your PR. Thank you! |
|
Thanks @rohityan — I've signed the CLA at https://cla.developers.google.com/ under nishchaymahor@gmail.com, which is the same email the commit is authored with. The |
…y annotation When a tool is defined in a module using `from __future__ import annotations` and its context parameter is typed with an import guarded by `if TYPE_CHECKING:`, `get_type_hints()` raises NameError while resolving that (excluded) parameter, aborting declaration building on the default JSON-schema path. Only TypeError was caught. Catch the unresolvable-forward-reference errors too and fall back to the raw per-parameter annotation, which already handles this case. The same guard is applied to return-type resolution. This is distinct from google#4754 (which fixed find_context_parameter): the context parameter is now correctly identified and excluded, but schema/return resolution still resolves its annotation and crashes.
4adbf26 to
bc467b9
Compare
|
Rebased onto latest |
Summary
A
FunctionToolfails to build its declaration when the tool is defined in a module usingfrom __future__ import annotationsand its context parameter is typed with an import guarded byif TYPE_CHECKING:— the pattern ADK's own docs recommend for context params:Building the declaration raises
NameError: name 'ToolContext' is not definedat the first LLM request — even thoughtool_contextis excluded from the schema anyway.Root cause
_get_function_fields(and the return-type path in_build_response_json_schema) callget_type_hints(func), which resolves all annotations at once, including the excluded context parameter. When that annotation is aTYPE_CHECKING-only forward reference, resolution raisesNameError— but onlyTypeErrorwas caught, so it aborts declaration building on the default JSON-schema path.Not a duplicate of #4754
#4754 / commit 22fc332 fixed
find_context_parameterso the context param is correctly identified and excluded. This is a separate crash further down: schema and return-type resolution still resolve the excluded param's annotation. Verified the repro still fails on current main (which already contains 22fc332).Fix
Catch
NameError/AttributeErroralongsideTypeErrorin both spots and fall back to the raw per-parameter annotation — logic that already exists directly below but was unreachable. Whenget_type_hintssucceeds (the common case), behavior is unchanged.Testing
Added
test_type_checking_only_context_annotation_builds_declarationtotests/unittests/tools/test_function_tool_with_import_annotations.py, asserting the declaration builds with the real param described and the context param excluded. Fails on main (NameError), passes with the fix.(Async suites in
test_function_tool.pyfail identically with and without this change — they need pytest-asyncio in my env — so no regression from this diff.)pyink+isortclean.This fix was developed with AI assistance; I found the bug, verified the root cause and the fix end-to-end, and reviewed every line.