aminghadersohi commented on code in PR #42244:
URL: https://github.com/apache/superset/pull/42244#discussion_r3623517956


##########
superset/mcp_service/middleware.py:
##########
@@ -1331,6 +1333,141 @@ def _try_truncate_info_response(
 
         return truncated
 
+    def _try_truncate_data_query_response(
+        self,
+        tool_name: str,
+        response: Any,
+        estimated_tokens: int,
+    ) -> Any | None:
+        """Attempt to truncate a data-query tool response by dropping tail 
rows.
+
+        Returns the truncated response if successful, None otherwise.
+        """
+        extracted = self._extract_payload_from_tool_result(response)
+        truncation_target = extracted if extracted is not None else response
+
+        try:
+            truncated, was_truncated, notes = truncate_query_result(
+                truncation_target, self.token_limit, tool_name=tool_name
+            )
+        except Exception as trunc_error:  # noqa: BLE001
+            logger.warning(
+                "Query result truncation failed for %s due to %s: %s",
+                tool_name,
+                type(trunc_error).__name__,
+                trunc_error,
+            )
+            return None
+
+        if not was_truncated:
+            return None
+
+        # Mirror the info-tool path: if truncation couldn't bring the
+        # response back under the limit (e.g. a single row/scalar field
+        # alone exceeds it), fall back to the hard size-limit error instead
+        # of shipping an over-budget response.
+        truncated_tokens = estimate_response_tokens(truncated)
+        if truncated_tokens > self.token_limit:
+            return None
+
+        logger.warning(
+            "Query result for %s truncated from ~%d to ~%d tokens (limit: %d). 
%s",
+            tool_name,
+            estimated_tokens,
+            truncated_tokens,
+            self.token_limit,
+            "; ".join(notes),
+        )
+
+        try:
+            user_id = get_user_id()
+            event_logger.log(
+                user_id=user_id,
+                action="mcp_response_truncated",
+                curated_payload={
+                    "tool": tool_name,
+                    "original_tokens": estimated_tokens,
+                    "truncated_tokens": truncated_tokens,
+                    "token_limit": self.token_limit,
+                    "truncation_notes": notes,
+                },
+            )
+        except Exception as log_error:  # noqa: BLE001
+            logger.warning("Failed to log truncation event: %s", log_error)
+
+        if extracted is not None and isinstance(truncated, dict):
+            return self._rewrap_as_tool_result(truncated, response)
+
+        return truncated

Review Comment:
   Confirmed, thanks — but not quite for the reason stated. 
`truncate_query_result`'s primary path (`_truncate_rows_field` / 
`_truncate_csv_data_field`) does already set 
`_response_truncated`/`_truncation_notes` on the dict as part of its 
size-reservation trick, so the common row/CSV-truncation case wasn't actually 
missing them.
   
   The real gap is the *fallback* path: when no recognised row/data field is 
found, `truncate_query_result` delegates to `truncate_oversized_response` (the 
info-tool truncation function), which returns `notes` as a separate list but 
never writes them onto the dict itself — that's why 
`_try_truncate_info_response` has to set them explicitly afterward. 
`_try_truncate_data_query_response` was missing that same explicit set for this 
fallback case, so those particular data-query responses would truncate silently.
   
   Fixed in 301b64e (`superset/mcp_service/middleware.py`): added the same 
`truncated["_response_truncated"] = True` / `truncated["_truncation_notes"] = 
notes` assignment that `_try_truncate_info_response` already does, right before 
the re-wrap step. It's idempotent for the row/CSV path (just re-sets the same 
values) and closes the gap for the fallback path.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to