fix(retrieval): harden app_tools schema validation, method normalization, and config extraction

GH
8d ago
+221-14

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:

  1. Config & UID Extraction Resilience (_call_tool_endpoint):

    • Validates that config is a dictionary before accessing .get(), returning a structured error message (Error: Configuration not available for ...) instead of raising AttributeError.
    • Supports fallback extraction of user ID from top-level config['user_id'], alias configurable['uid'], or top-level config['uid'], ensuring seamless compatibility across different agent execution contexts.
  2. Schema & Parameters Validation (_create_pydantic_model_from_schema & create_app_tool):

    • Ensures parameters is a dict before attempting .get('properties'), generating an empty input model cleanly if omitted or malformed.
    • Guards properties and required parsing against non-dict or non-iterable values (raw_req is None).
    • Handles malformed individual parameter schemas gracefully without breaking tool model registration.
  3. HTTP Method & Request Payload Normalization (_call_tool_endpoint):

    • Normalizes app_tool.method with fallback to 'POST', stripping whitespace and handling lowercase method names safely.
    • For DELETE and non-POST/PUT/PATCH methods, passes request payload as query parameters (params=payload) rather than dropping them.
  4. MCP Tool Argument & Transport Safety (create_app_tool):

    • Validates mcp_oauth_tokens as a dictionary before calling .get('access_token').
    • Normalizes app_tool.transport with a default of "sse".
    • Hardens _supplied_arguments(kwargs) to return an empty dict when kwargs is non-dict.

Tests Added

  • Created backend/tests/unit/test_app_tools_resilience.py with 9 unit tests covering:
    • Non-dict / malformed parameters and properties in schema model creation.
    • Non-dict kwargs in _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.
    • DELETE method 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)