Skip to content

fix(tools): accept dict output_schema in SetModelResponseTool (#5469)#5516

Open
MukundaKatta wants to merge 1 commit intogoogle:mainfrom
MukundaKatta:fix/set-model-response-tool-dict-schema
Open

fix(tools): accept dict output_schema in SetModelResponseTool (#5469)#5516
MukundaKatta wants to merge 1 commit intogoogle:mainfrom
MukundaKatta:fix/set-model-response-tool-dict-schema

Conversation

@MukundaKatta
Copy link
Copy Markdown

Summary

Fixes #5469. When output_schema is a raw dict (e.g. {"type": "object", "properties": {...}}), SetModelResponseTool.__init__ previously fell through to the generic else branch and used the dict instance as the parameter annotation. Downstream, _function_parameter_parse_util._is_builtin_primitive_or_compound does annotation in _py_builtin_type_to_schema_type.keys(), which calls __hash__ on the annotation and raises TypeError: unhashable type: 'dict'.

This change adds an explicit elif isinstance(output_schema, dict) branch that uses the dict type (hashable) as the annotation, so the existing builtin lookup maps it to Type.OBJECT cleanly. run_async already handles this case via the existing args.get('response') pass-through.

Reproduction (before fix)

from google.adk.agents import Agent

agent = Agent(
    name="test",
    model="gemini-2.5-flash",
    instruction="You are a helpful agent.",
    output_schema={"type": "object", "properties": {"result": {"type": "string"}}},
)
# -> TypeError: unhashable type: 'dict'

Testing plan

  • Added regression unit tests in tests/unittests/tools/test_set_model_response_tool.py:
    • test_tool_initialization_raw_dict_schema__init__ with a raw dict does not crash and stores the schema.
    • test_function_signature_generation_raw_dict_schema — generated signature has a single response: dict parameter (annotation is the dict type, not the dict instance).
    • test_get_declaration_raw_dict_schema_get_declaration() returns a valid declaration without raising TypeError.
    • test_run_async_raw_dict_schemarun_async returns the response unchanged.
  • Run: pytest tests/unittests/tools/test_set_model_response_tool.py -q
  • Existing tests for BaseModel, list[BaseModel], list[str], dict[str, int] schemas remain unchanged and still pass.

Notes

  • Schema fidelity (propagating dict-schema constraints into the function declaration) is intentionally out of scope; this PR only fixes the crash, matching the issue's reported scope and the existing handling for list[str] / dict[str, int].

…#5469)

When `output_schema` is a raw dict (e.g. `{"type": "object", "properties":
{...}}`), `SetModelResponseTool` previously fell through to the generic else
branch and used the dict instance itself as the parameter annotation.
Downstream, `_function_parameter_parse_util._is_builtin_primitive_or_compound`
does `annotation in _py_builtin_type_to_schema_type.keys()`, which calls
`__hash__` on the annotation and raises `TypeError: unhashable type: 'dict'`.

Detect raw dict schemas explicitly and use the `dict` type as the
annotation, so the existing builtin lookup maps it to `Type.OBJECT` cleanly.
`run_async` already handles this case via the existing pass-through branch.

Fixes google#5469
@adk-bot adk-bot added the tools [Component] This issue is related to tools label Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tools [Component] This issue is related to tools

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SetModelResponseTool crashes with TypeError when output_schema is a raw dict

2 participants