codeant-ai-for-open-source[bot] commented on code in PR #41860:
URL: https://github.com/apache/superset/pull/41860#discussion_r3575644735


##########
superset/mcp_service/chart/chart_utils.py:
##########
@@ -891,6 +893,64 @@ def map_pie_config(config: PieChartConfig) -> Dict[str, 
Any]:
     return form_data
 
 
+def map_histogram_config(config: "HistogramChartConfig") -> Dict[str, Any]:
+    """Map histogram config to Superset form_data (viz_type histogram_v2).
+
+    Matches the frontend Histogram buildQuery contract: a single ``column``
+    string to bin, ``groupby`` name list for series, plus bins/normalize/
+    cumulative passed straight through to the histogram post-processing
+    operator.
+    """
+    form_data: Dict[str, Any] = {
+        "viz_type": "histogram_v2",
+        "column": config.column.name,
+        "groupby": [g.name for g in (config.groupby or [])],
+        "bins": config.bins,
+        "normalize": config.normalize,
+        "cumulative": config.cumulative,
+        "row_limit": config.row_limit,
+    }
+    _add_adhoc_filters(form_data, config.filters)
+    return form_data
+
+
+# The exact strings the frontend boxplotOperator understands; the percentile
+# variant must match its PERCENTILE_REGEX: "<low>/<high> percentiles".
+_WHISKER_TYPE_TO_OPTION = {
+    "tukey": "Tukey",
+    "min_max": "Min/max (no outliers)",
+}
+
+
+def map_box_plot_config(config: "BoxPlotChartConfig") -> Dict[str, Any]:
+    """Map box plot config to Superset form_data (viz_type box_plot).
+
+    Matches the frontend BoxPlot buildQuery contract: ``columns`` are the
+    distribute-across values (one box per value), ``groupby`` the series
+    dimensions, and ``whiskerOptions`` one of the strings the
+    boxplotOperator post-processor parses.
+    """
+    if config.whisker_type == "percentile":
+        whisker_options = (
+            f"{config.percentile_low}/{config.percentile_high} percentiles"
+        )
+    else:
+        whisker_options = _WHISKER_TYPE_TO_OPTION[config.whisker_type]
+
+    form_data: Dict[str, Any] = {
+        "viz_type": "box_plot",
+        "columns": [c.name for c in config.distribute_across],
+        "groupby": [d.name for d in (config.dimensions or [])],
+        "metrics": [create_metric_object(m) for m in config.metrics],

Review Comment:
   **Suggestion:** `map_box_plot_config` maps `distribute_across` to `columns` 
and leaves `groupby` driven only by optional `dimensions`, but the box-plot 
post-processing logic groups by `groupby` (not `columns`). This means a valid 
request with only required fields (`metrics` + `distribute_across`) produces an 
empty `groupby` and collapses into a single box, so the required split field 
does not actually control box separation. Map the split dimension into 
`groupby` (and combine additional dimensions intentionally) so box grouping 
matches the schema contract. [api mismatch]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Box plot MCP charts collapse into single global box.
   - ❌ Distribute_across column never controls box separation.
   - ⚠️ Agents misinterpret distributions when following schema examples.
   - ⚠️ get_chart_type_schema box_plot examples produce incorrect grouping.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Call the MCP generate_chart tool defined in
   superset/mcp_service/chart/tool/generate_chart.py:19-64 with a box plot 
config using only
   the required fields described in its docstring at lines 62-64, for example:
   
      - chart_type: "box_plot"
   
      - metrics: [{"name": "fare_amount", "aggregate": "AVG"}]
   
      - distribute_across: [{"name": "day_of_week"}]
   
      This matches the first box_plot example in
      superset/mcp_service/chart/tool/get_chart_type_schema.py:6-21 where only 
metrics and
      distribute_across are provided.
   
   
   
   2. The request config is validated against BoxPlotChartConfig in
   superset/mcp_service/chart/schemas.py:63-80, which requires metrics and 
distribute_across
   and makes dimensions optional. BoxPlotChartPlugin.pre_validate in
   superset/mcp_service/chart/plugins/box_plot.py:44-76 enforces the presence 
of "metrics"
   and "distribute_across" only, so the minimal config passes when dimensions 
is omitted.
   
   
   
   3. BoxPlotChartPlugin.to_form_data at 
superset/mcp_service/chart/plugins/box_plot.py:90-93
   calls map_box_plot_config(config) in 
superset/mcp_service/chart/chart_utils.py:76-102. For
   the minimal config, map_box_plot_config builds form_data with:
   
      - "columns": [c.name for c in config.distribute_across] (line 93)
   
      - "groupby": [d.name for d in (config.dimensions or [])] (line 94)
   
      Since config.dimensions is None, groupby becomes an empty list while 
columns contains
      ["day_of_week"].
   
   
   
   4. The Superset frontend Box Plot buildQuery in
   
superset-frontend/plugins/plugin-chart-echarts/src/BoxPlot/buildQuery.ts:13-37 
consumes
   this form_data. It constructs the query object with:
   
      - columns: distributed columns plus ensureIsArray(formData.groupby) 
(lines 13-35)
   
      - series_columns: formData.groupby (line 36)
   
      - post_processing: [boxplotOperator(formData, baseQueryObject)] (line 37)
   
      The boxplotOperator implementation in
      
superset-frontend/packages/superset-ui-chart-controls/src/operators/boxplotOperator.ts:11-44
      reads groupby from formData and passes 
ensureIsArray(groupby).map(getColumnLabel) into
      the backend boxplot post processor. Because groupby is empty, 
options.groupby is [], so
      superset/utils/pandas_postprocessing/boxplot.py:29-59 aggregates each 
metric over the
      entire dataset with groupby=[], producing a single box per metric instead 
of separate
      boxes per distribute_across value on the x axis. This contradicts the 
contract
      documented in BoxPlotChartConfig at 
superset/mcp_service/chart/schemas.py:75-79 and the
      generate_chart docstring at 62-64 that promise one box per 
distribute_across value.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=795717e795f24f50ba699fcb9694169f&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=795717e795f24f50ba699fcb9694169f&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/mcp_service/chart/chart_utils.py
   **Line:** 943:944
   **Comment:**
        *Api Mismatch: `map_box_plot_config` maps `distribute_across` to 
`columns` and leaves `groupby` driven only by optional `dimensions`, but the 
box-plot post-processing logic groups by `groupby` (not `columns`). This means 
a valid request with only required fields (`metrics` + `distribute_across`) 
produces an empty `groupby` and collapses into a single box, so the required 
split field does not actually control box separation. Map the split dimension 
into `groupby` (and combine additional dimensions intentionally) so box 
grouping matches the schema contract.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41860&comment_hash=81f874efce139e6b83fd4c1745611e75679d4304b626f5b0e7574c2ccf33d92d&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F41860&comment_hash=81f874efce139e6b83fd4c1745611e75679d4304b626f5b0e7574c2ccf33d92d&reaction=dislike'>👎</a>



-- 
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