fix(retrieval): harden app_tools schema validation, method normalization, and config extraction
GH
8d ago+221+221+012345678901234567890123456789-14-14-01234567890123456789
Summary of Changes
This PR hardens backend/utils/retrieval/tools/app_tools.py against edge-case crashes when handling dynamically configured app tools and manifest schemas:
-
Config & UID Extraction Resilience (
_call_tool_endpoint):- Validates that
configis a dictionary before accessing.get(), returning a structured error message (Error: Configuration not available for ...) instead of raisingAttributeError. - Supports fallback extraction of user ID from top-level
config['user_id'], aliasconfigurable['uid'], or top-levelconfig['uid'], ensuring seamless compatibility across different agent execution contexts.
- Validates that
-
Schema & Parameters Validation (
_create_pydantic_model_from_schema&create_app_tool):- Ensures
parametersis a dict before attempting.get('properties'), generating an empty input model cleanly if omitted or malformed. - Guards
propertiesandrequiredparsing against non-dict or non-iterable values (raw_req is None). - Handles malformed individual parameter schemas gracefully without breaking tool model registration.
- Ensures
-
HTTP Method & Request Payload Normalization (
_call_tool_endpoint):- Normalizes
app_tool.methodwith fallback to'POST', stripping whitespace and handling lowercase method names safely. - For
DELETEand non-POST/PUT/PATCH methods, passes request payload as query parameters (params=payload) rather than dropping them.
- Normalizes
-
MCP Tool Argument & Transport Safety (
create_app_tool):- Validates
mcp_oauth_tokensas a dictionary before calling.get('access_token'). - Normalizes
app_tool.transportwith a default of"sse". - Hardens
_supplied_arguments(kwargs)to return an empty dict whenkwargsis non-dict.
- Validates
Tests Added
- Created
backend/tests/unit/test_app_tools_resilience.pywith 9 unit tests covering:- Non-dict / malformed parameters and properties in schema model creation.
- Non-dict
kwargsin_supplied_arguments. - Non-dict parameters and transport defaults in
create_app_tool. - Non-dict config, top-level user ID fallback, and alias fallbacks in
_call_tool_endpoint. DELETEmethod payload routing and method normalization.
- Verified all 16 app_tools tests pass hermetically:
test_app_tools_resilience.py(9 passed)test_app_tools_omitted_arguments.py(5 passed)test_app_tools_status_cap.py(2 passed)