Skip to content

Conversation

@DEVELOPER-DEEVEN
Copy link

Context

Issue #506 reported that default values defined in tools.yaml were not being parsed correctly by the Python SDK. Specifically, parameters with a default value were not reflecting this default in the tool's signature or execution logic. This caused tools to require arguments that should have been optional, or fail to use the configured defaults.

Solution

The root cause was identified in toolbox_core.protocol.ParameterSchema. The Pydantic model for parameter schema was missing the default field. Consequently, the default value from the API response was being ignored during parsing.

This PR:

  1. Adds default: Optional[Any] = None to the ParameterSchema model in packages/toolbox-core/src/toolbox_core/protocol.py.
  2. Updates ParameterSchema.to_param() to explicitly use self.default if it is not None, falling back to existing logic (None or Empty) otherwise.
  3. Adds regression tests in packages/toolbox-core/tests/test_protocol.py to verify that defaults are correctly parsed and applied to the generated inspect.Parameter objects.

Verification

  • Reproduction: Confirmed the issue with a reproduction script (failed before fix).
  • Fix Verification: Confirmed the reproduction script passes after fix.
  • Regression Testing: Ran existing tests in toolbox-core (tests/test_protocol.py, tests/test_tool.py) and verified they pass. Added new unit tests covering default value parsing.

Alternatives Considered

  • Modifying ToolboxTool: Considered handling defaults in ToolboxTool.__init__ by iterating over params, but the issue was fundamentally in the data model parsing (ParameterSchema). Fixing it at the schema level ensures correctness wherever ParameterSchema is used.

@DEVELOPER-DEEVEN
Copy link
Author

Hello @dishaprakash, I've pushed a fix for the syntax error (non-default argument follows default argument) that was causing the CI to fail. I also added the missing inspect.Parameter import and updated the Pydantic utility to ensure consistency across schema defaults.

Local verification confirms that all 114 unit tests across the Core, LangChain, and LlamaIndex packages are now passing. Ready for re-review.

@anubhav756
Copy link
Contributor

/gcbrun

@anubhav756
Copy link
Contributor

Hi @DEVELOPER-DEEVEN

Really appreciate the PR. Thanks!

Would it be possible for you to take a look at the failling lint and the tests as well?

@DEVELOPER-DEEVEN
Copy link
Author

DEVELOPER-DEEVEN commented Feb 10, 2026 via email

Copy link
Contributor

@anubhav756 anubhav756 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! Just a request to fix the presubmits.

@anubhav756 anubhav756 linked an issue Feb 10, 2026 that may be closed by this pull request
1 task
@DEVELOPER-DEEVEN
Copy link
Author

@anubhav756 take a look I think its resolved now

DEVELOPER-DEEVEN and others added 3 commits February 12, 2026 19:52
The ParameterSchema model was missing the default field, causing Pydantic to drop the default value provided in the tool schema. This resulted in the default value not being reflected in the tool's signature.

Fixes googleapis#506
@anubhav756 anubhav756 force-pushed the fix/506-parameter-defaults branch from 41bad81 to dbeb66d Compare February 12, 2026 14:22
@anubhav756
Copy link
Contributor

/gbrun

@anubhav756
Copy link
Contributor

/gcbrun

@DEVELOPER-DEEVEN
Copy link
Author

hi @anubhav756 can I take a look at logs. here is my mail id deevenseru11@gmail.com 😁

@anubhav756
Copy link
Contributor

hi @anubhav756 can I take a look at logs. here is my mail id deevenseru11@gmail.com 😁

@DEVELOPER-DEEVEN I retriggered the tests and they seem to be failling with the following logs:


Already have image (with digest): python:3.10
--
  | ============================= test session starts ==============================
  | platform linux -- Python 3.10.19, pytest-9.0.2, pluggy-1.6.0
  | rootdir: /workspace/packages/toolbox-core
  | configfile: pyproject.toml
  | plugins: asyncio-1.3.0, cov-7.0.0, aioresponses-0.3.0, mock-3.15.1
  | asyncio: mode=strict, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
  | collected 412 items
  |  
  | tests/mcp_transport/test_base.py ...........                             [  2%]
  | tests/mcp_transport/test_v20241105.py .................                  [  6%]
  | tests/mcp_transport/test_v20250326.py .................                  [ 10%]
  | tests/mcp_transport/test_v20250618.py ..................                 [ 15%]
  | tests/mcp_transport/test_v20251125.py ..................                 [ 19%]
  | tests/test_auth_methods.py .........                                     [ 21%]
  | tests/test_client.py .......................                             [ 27%]
  | tests/test_e2e.py ................F................                      [ 35%]
  | tests/test_e2e_mcp.py .................................................. [ 47%]
  | ........................................................................ [ 65%]
  | ..........                                                               [ 67%]
  | tests/test_protocol.py ....................                              [ 72%]
  | tests/test_sync_client.py ................                               [ 76%]
  | tests/test_sync_e2e.py ..............                                    [ 79%]
  | tests/test_sync_tool.py ...................                              [ 84%]
  | tests/test_tool.py ..........................                            [ 90%]
  | tests/test_toolbox_transport.py .............                            [ 93%]
  | tests/test_utils.py ..........................                           [100%]
  |  
  | =================================== FAILURES ===================================
  | ______________ TestOptionalParams.test_tool_signature_is_correct _______________
  |  
  | self = <test_e2e.TestOptionalParams object at 0x7fcc2898ed40>
  | toolbox = <toolbox_core.client.ToolboxClient object at 0x7fcc256907c0>
  |  
  | async def test_tool_signature_is_correct(self, toolbox: ToolboxClient):
  | """Verify the client correctly constructs the signature for a tool with optional params."""
  | tool = await toolbox.load_tool("search-rows")
  | sig = signature(tool)
  |  
  | assert "email" in sig.parameters
  | assert "data" in sig.parameters
  | assert "id" in sig.parameters
  |  
  | # The required parameter should have no default
  | assert sig.parameters["email"].default is Parameter.empty
  | assert sig.parameters["email"].annotation is str
  |  
  | # The optional parameter should have a default of None
  | >       assert sig.parameters["data"].default is None
  | E       assert 'row2' is None
  | E        +  where 'row2' = <Parameter "data: Optional[str] = 'row2'">.default
  |  
  | tests/test_e2e.py:250: AssertionError
  | ----------------------------- Captured stdout call -----------------------------
  | 2026-02-12T16:29:57.212834542Z INFO Response: 200 OK service: "httplog" httpRequest: {url: "http://localhost:5000/api/tool/search-rows" method: "GET" path: "/api/tool/search-rows" remoteIP: "127.0.0.1:40616" proto: "HTTP/1.1" requestID: "0685a09fd651/wRrJdkMAvI-000025"} httpResponse: {status: 200 bytes: 575 elapsed: 0.091264}
  | =============================== warnings summary ===============================
  | ../../venv/lib/python3.10/site-packages/google/api_core/_python_version_support.py:275
  | /workspace/venv/lib/python3.10/site-packages/google/api_core/_python_version_support.py:275: FutureWarning: You are using a Python version (3.10.19) which Google will stop supporting in new releases of google.api_core once it reaches its end of life (2026-10-04). Please upgrade to the latest Python version, or at least Python 3.11, to continue receiving updates for google.api_core past that date.
  | warnings.warn(message, FutureWarning)
  |  
  | ../../venv/lib/python3.10/site-packages/google/api_core/_python_version_support.py:275
  | /workspace/venv/lib/python3.10/site-packages/google/api_core/_python_version_support.py:275: FutureWarning: You are using a Python version (3.10.19) which Google will stop supporting in new releases of google.cloud.secretmanager_v1 once it reaches its end of life (2026-10-04). Please upgrade to the latest Python version, or at least Python 3.11, to continue receiving updates for google.cloud.secretmanager_v1 past that date.
  | warnings.warn(message, FutureWarning)
  |  
  | tests/test_tool.py:522
  | /workspace/packages/toolbox-core/tests/test_tool.py:522: DeprecationWarning: invalid escape sequence '\('
  | expected_error_message = "Authentication source\(s\) \`unused-auth-service\` unused by tool \`sample_tool\`."
  |  
  | tests/test_e2e.py::TestAuth::test_run_tool_wrong_auth
  | tests/test_e2e.py::TestAuth::test_run_tool_auth
  | tests/test_e2e.py::TestAuth::test_run_tool_async_auth
  | tests/test_e2e.py::TestAuth::test_run_tool_param_auth
  | tests/test_e2e.py::TestAuth::test_run_tool_param_auth_no_field
  | tests/test_toolbox_transport.py::test_tool_invoke_success
  | /workspace/packages/toolbox-core/src/toolbox_core/toolbox_transport.py:78: UserWarning: Sending data token over HTTP. User data may be exposed. Use HTTPS for secure communication.
  | warn(
  |  
  | tests/test_sync_client.py::TestSyncClientLifecycle::test_load_tool_raises_if_loop_or_thread_none
  | /workspace/packages/toolbox-core/tests/test_sync_client.py:333: RuntimeWarning: coroutine 'ToolboxClient.load_tool' was never awaited
  | with pytest.raises(
  | Enable tracemalloc to get traceback where the object was allocated.
  | See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.
  |  
  | tests/test_sync_client.py::TestSyncClientLifecycle::test_load_tool_raises_if_loop_or_thread_none
  | /workspace/packages/toolbox-core/tests/test_sync_client.py:342: RuntimeWarning: coroutine 'ToolboxClient.load_toolset' was never awaited
  | with pytest.raises(
  | Enable tracemalloc to get traceback where the object was allocated.
  | See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.
  |  
  | -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
  | ================================ tests coverage ================================
  | _______________ coverage: platform linux, python 3.10.19-final-0 _______________
  |  
  | Name                                                Stmts   Miss  Cover
  | -----------------------------------------------------------------------
  | src/toolbox_core/__init__.py                            3      0   100%
  | src/toolbox_core/auth_methods.py                       58      2    97%
  | src/toolbox_core/client.py                            111      2    98%
  | src/toolbox_core/itransport.py                         20      5    75%
  | src/toolbox_core/mcp_transport/__init__.py              5      0   100%
  | src/toolbox_core/mcp_transport/transport_base.py       70      3    96%
  | src/toolbox_core/mcp_transport/v20241105/mcp.py        68      9    87%
  | src/toolbox_core/mcp_transport/v20241105/types.py      87      1    99%
  | src/toolbox_core/mcp_transport/v20250326/mcp.py        81     13    84%
  | src/toolbox_core/mcp_transport/v20250326/types.py      87      1    99%
  | src/toolbox_core/mcp_transport/v20250618/mcp.py        71      9    87%
  | src/toolbox_core/mcp_transport/v20250618/types.py      87      1    99%
  | src/toolbox_core/mcp_transport/v20251125/mcp.py        71      9    87%
  | src/toolbox_core/mcp_transport/v20251125/types.py      87      1    99%
  | src/toolbox_core/protocol.py                           64      0   100%
  | src/toolbox_core/sync_client.py                        45      0   100%
  | src/toolbox_core/sync_tool.py                          64      0   100%
  | src/toolbox_core/tool.py                              112      7    94%
  | src/toolbox_core/toolbox_transport.py                  42      0   100%
  | src/toolbox_core/utils.py                              41      0   100%
  | src/toolbox_core/version.py                             1      0   100%
  | -----------------------------------------------------------------------
  | TOTAL                                                1275     63    95%
  | Required test coverage of 90% reached. Total coverage: 95.06%
  | =========================== short test summary info ============================
  | FAILED tests/test_e2e.py::TestOptionalParams::test_tool_signature_is_correct
  | ================= 1 failed, 411 passed, 11 warnings in 18.32s ==================
  | /usr/local/lib/python3.10/asyncio/base_events.py:688: ResourceWarning: unclosed event loop <_UnixSelectorEventLoop running=False closed=False debug=False>


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

add default value to the parameters

3 participants