# Widgets

## Add Widget to Dashboard

`evaluation_dashboards.widgets.create(strdashboard_id, WidgetCreateParams**kwargs)  -> EvaluationDashboardWidgetWithResult`

**post** `/v5/evaluation-dashboards/{dashboard_id}/widgets`

Create a new widget, append it to the dashboard, and compute its result in one call.

The widget is persisted as its own entity, its ID is appended to the dashboard's
`widget_order`, and — unless it is a `markdown` or `heading` widget — its result is
computed synchronously against the dashboard's evaluation (or evaluation-group) data
before the response returns. Validation is type-specific: `markdown` requires
`config.content`, `bar`/`histogram`/`donut`/`scatter` require exactly one of
`config.x_column` or `config.x_column_group`, `table` configs with conditional
formatting are schema-validated, and all other chart types require a `query`. The
dashboard must exist and not be archived. A computation failure does not fail the
request: the widget is still created and returned with a result whose
`computation_status` is `failed` and an `error_message` set, while `markdown` and
`heading` widgets return a null result.

### Parameters

- `dashboard_id: str`

- `title: str`

  Widget title

- `type: EvaluationWidgetTypeEnum`

  Widget type

  - `"bar"`

  - `"histogram"`

  - `"donut"`

  - `"scatter"`

  - `"metric"`

  - `"table"`

  - `"markdown"`

  - `"heading"`

  - `"timeseries"`

- `config: Optional[Dict[str, object]]`

  Chart-specific display configuration

- `query: Optional[Query]`

  Structured query AST for metric computation (SeriesQuery or MetricQuery)

  - `class SeriesQuery: …`

    Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

    Used for widget types: table, bar, histogram, donut, scatter.
    Returns: {"type": "series", "data": [...]}

    Example SQL equivalent:
    SELECT category, AVG(score) as avg_score, COUNT(*) as count
    FROM evaluation_items
    WHERE score > 0.5 AND category = 'test'
    GROUP BY category
    ORDER BY avg_score DESC
    LIMIT 100

    - `select: List[SelectItem]`

      - `expression: Expression`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

        - `class ExpressionColumn: …`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `column: str`

            Column name from evaluation_items.data

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

          - `type: Optional[Literal["COLUMN"]]`

            - `"COLUMN"`

        - `class ExpressionAggregation: …`

          Aggregation function to apply

          Examples:
          {"type": "AGGREGATION", "function": "AVG", "column": "score"}
          {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
          {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

          - `column: str`

            Column to aggregate, or '*' for COUNT(*)

          - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

            Supported aggregation functions

            - `"COUNT"`

            - `"SUM"`

            - `"AVG"`

            - `"MIN"`

            - `"MAX"`

            - `"STDDEV"`

            - `"VARIANCE"`

            - `"PERCENTILE"`

            - `"COUNT_DISTINCT"`

            - `"PERCENTAGE"`

          - `evaluation_ids: Optional[List[str]]`

            Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

          - `params: Optional[Dict[str, object]]`

            Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

          - `type: Optional[Literal["AGGREGATION"]]`

            - `"AGGREGATION"`

      - `alias: Optional[str]`

        Optional alias for the selected item

    - `evaluation_ids: Optional[List[str]]`

      Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

    - `filter: Optional[Filter]`

      Filter conditions (WHERE clause)

      - `conditions: List[Condition]`

        - `column: str`

          Column name to filter on

        - `operator: Literal["=", "!=", ">", 9 more]`

          Comparison operator

          - `"="`

          - `"!="`

          - `">"`

          - `"<"`

          - `">="`

          - `"<="`

          - `"IN"`

          - `"NOT IN"`

          - `"LIKE"`

          - `"NOT LIKE"`

          - `"IS NULL"`

          - `"IS NOT NULL"`

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

        - `value: Optional[Union[str, float, bool, 2 more]]`

          Value to compare against. Not required for IS NULL / IS NOT NULL operators.

          - `str`

          - `float`

          - `bool`

          - `List[object]`

      - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

        Logical operators connecting conditions. Length must be len(conditions) - 1

        - `"AND"`

        - `"OR"`

    - `group_by: Optional[List[str]]`

      Columns to group by

    - `latest_only: Optional[bool]`

      When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

    - `limit: Optional[int]`

      Max rows to return

    - `order_by: Optional[List[OrderBy]]`

      Sort order

      - `column: str`

        Column name to sort by

      - `direction: Optional[Literal["ASC", "DESC"]]`

        Sort direction

        - `"ASC"`

        - `"DESC"`

      - `source: Optional[str]`

        Column source: 'data' or 'task_result_cache'

  - `class MetricQuery: …`

    Query that returns a single metric value (used for metric widgets).

    Used for widget type: metric.
    Enforces exactly 1 aggregation in select.
    Returns: {"type": "metric", "data": ...}

    Example SQL equivalent:
    SELECT AVG(score) as average_score
    FROM evaluation_items

    - `select: List[SelectItem]`

      - `expression: Expression`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

      - `alias: Optional[str]`

        Optional alias for the selected item

    - `evaluation_ids: Optional[List[str]]`

      Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

    - `filter: Optional[Filter]`

      Filter conditions (WHERE clause)

    - `latest_only: Optional[bool]`

      When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

### Returns

- `class EvaluationDashboardWidgetWithResult: …`

  Response model for widget creation - includes widget and computed result

  - `id: str`

    Unique identifier of the widget

  - `account_id: str`

    Account that owns this widget

  - `created_at: datetime`

    When the widget was created

  - `title: str`

    Widget title

  - `type: EvaluationWidgetTypeEnum`

    Widget type

    - `"bar"`

    - `"histogram"`

    - `"donut"`

    - `"scatter"`

    - `"metric"`

    - `"table"`

    - `"markdown"`

    - `"heading"`

    - `"timeseries"`

  - `config: Optional[Dict[str, object]]`

    Display configuration

  - `object: Optional[Literal["evaluation_widget"]]`

    - `"evaluation_widget"`

  - `query: Optional[Query]`

    Structured query AST for computation (SeriesQuery or MetricQuery)

    - `class SeriesQuery: …`

      Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

      Used for widget types: table, bar, histogram, donut, scatter.
      Returns: {"type": "series", "data": [...]}

      Example SQL equivalent:
      SELECT category, AVG(score) as avg_score, COUNT(*) as count
      FROM evaluation_items
      WHERE score > 0.5 AND category = 'test'
      GROUP BY category
      ORDER BY avg_score DESC
      LIMIT 100

      - `select: List[SelectItem]`

        - `expression: Expression`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `class ExpressionColumn: …`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

            - `column: str`

              Column name from evaluation_items.data

            - `source: Optional[str]`

              Column source: 'data' or 'task_result_cache'

            - `type: Optional[Literal["COLUMN"]]`

              - `"COLUMN"`

          - `class ExpressionAggregation: …`

            Aggregation function to apply

            Examples:
            {"type": "AGGREGATION", "function": "AVG", "column": "score"}
            {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
            {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

            - `column: str`

              Column to aggregate, or '*' for COUNT(*)

            - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

              Supported aggregation functions

              - `"COUNT"`

              - `"SUM"`

              - `"AVG"`

              - `"MIN"`

              - `"MAX"`

              - `"STDDEV"`

              - `"VARIANCE"`

              - `"PERCENTILE"`

              - `"COUNT_DISTINCT"`

              - `"PERCENTAGE"`

            - `evaluation_ids: Optional[List[str]]`

              Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

            - `params: Optional[Dict[str, object]]`

              Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

            - `source: Optional[str]`

              Column source: 'data' or 'task_result_cache'

            - `type: Optional[Literal["AGGREGATION"]]`

              - `"AGGREGATION"`

        - `alias: Optional[str]`

          Optional alias for the selected item

      - `evaluation_ids: Optional[List[str]]`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: Optional[Filter]`

        Filter conditions (WHERE clause)

        - `conditions: List[Condition]`

          - `column: str`

            Column name to filter on

          - `operator: Literal["=", "!=", ">", 9 more]`

            Comparison operator

            - `"="`

            - `"!="`

            - `">"`

            - `"<"`

            - `">="`

            - `"<="`

            - `"IN"`

            - `"NOT IN"`

            - `"LIKE"`

            - `"NOT LIKE"`

            - `"IS NULL"`

            - `"IS NOT NULL"`

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

          - `value: Optional[Union[str, float, bool, 2 more]]`

            Value to compare against. Not required for IS NULL / IS NOT NULL operators.

            - `str`

            - `float`

            - `bool`

            - `List[object]`

        - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

          Logical operators connecting conditions. Length must be len(conditions) - 1

          - `"AND"`

          - `"OR"`

      - `group_by: Optional[List[str]]`

        Columns to group by

      - `latest_only: Optional[bool]`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

      - `limit: Optional[int]`

        Max rows to return

      - `order_by: Optional[List[OrderBy]]`

        Sort order

        - `column: str`

          Column name to sort by

        - `direction: Optional[Literal["ASC", "DESC"]]`

          Sort direction

          - `"ASC"`

          - `"DESC"`

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

    - `class MetricQuery: …`

      Query that returns a single metric value (used for metric widgets).

      Used for widget type: metric.
      Enforces exactly 1 aggregation in select.
      Returns: {"type": "metric", "data": ...}

      Example SQL equivalent:
      SELECT AVG(score) as average_score
      FROM evaluation_items

      - `select: List[SelectItem]`

        - `expression: Expression`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

        - `alias: Optional[str]`

          Optional alias for the selected item

      - `evaluation_ids: Optional[List[str]]`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: Optional[Filter]`

        Filter conditions (WHERE clause)

      - `latest_only: Optional[bool]`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

  - `result: Optional[EvaluationDashboardWidgetResultResponse]`

    Computed result for this widget

    - `id: str`

      Unique identifier of the widget result

    - `computation_status: str`

      Status: pending, completed, or failed

    - `widget_id: str`

      Widget ID this result belongs to

    - `computed_at: Optional[datetime]`

      When computation completed

    - `computed_result: Optional[Dict[str, object]]`

      Computed result data. Metric: {type: 'metric', data: 42}, Series: {type: 'series', data: [{x: 'A', y: 10}, ...]}

    - `error_message: Optional[str]`

      Error message if computation failed

### Example

```python
import os
from scale_gp_beta import SGPClient

client = SGPClient(
    api_key=os.environ.get("SGP_API_KEY"),  # This is the default and can be omitted
)
evaluation_dashboard_widget_with_result = client.evaluation_dashboards.widgets.create(
    dashboard_id="dashboard_id",
    title="x",
    type="bar",
)
print(evaluation_dashboard_widget_with_result.id)
```

#### Response

```json
{
  "id": "id",
  "account_id": "account_id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "title": "title",
  "type": "bar",
  "config": {
    "foo": "bar"
  },
  "object": "evaluation_widget",
  "query": {
    "select": [
      {
        "expression": {
          "column": "column",
          "source": "source",
          "type": "COLUMN"
        },
        "alias": "alias"
      }
    ],
    "evaluation_ids": [
      "string"
    ],
    "filter": {
      "conditions": [
        {
          "column": "column",
          "operator": "=",
          "source": "source",
          "value": "string"
        }
      ],
      "logicalOperators": [
        "AND"
      ]
    },
    "groupBy": [
      "string"
    ],
    "latest_only": true,
    "limit": 1,
    "orderBy": [
      {
        "column": "column",
        "direction": "ASC",
        "source": "source"
      }
    ]
  },
  "result": {
    "id": "id",
    "computation_status": "computation_status",
    "widget_id": "widget_id",
    "computed_at": "2019-12-27T18:11:19.117Z",
    "computed_result": {
      "foo": "bar"
    },
    "error_message": "error_message"
  }
}
```

## Update Dashboard Widget

`evaluation_dashboards.widgets.update(strwidget_id, WidgetUpdateParams**kwargs)  -> EvaluationDashboardWidgetWithResult`

**patch** `/v5/evaluation-dashboards/{dashboard_id}/widgets/{widget_id}`

Update a widget's fields within this dashboard, using copy-on-write for shared widgets.

If the widget belongs only to this dashboard it is updated in place; if it is
referenced by more than one dashboard, a new widget is created with the updates
applied and swapped into this dashboard's `widget_order`, leaving the other
dashboards' copy untouched. The widget must already be in this dashboard's
`widget_order`, otherwise the call is rejected. The result is recomputed
synchronously when the `query` changes or when the widget was cloned; otherwise the
existing cached result is returned. For `table` widgets, conditional-formatting
column references are re-resolved against the (possibly updated) query on each save.
The dashboard must exist and not be archived.

### Parameters

- `dashboard_id: str`

- `widget_id: str`

- `config: Optional[Dict[str, object]]`

  Chart-specific display configuration

- `query: Optional[Query]`

  Structured query AST for metric computation (SeriesQuery or MetricQuery)

  - `class SeriesQuery: …`

    Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

    Used for widget types: table, bar, histogram, donut, scatter.
    Returns: {"type": "series", "data": [...]}

    Example SQL equivalent:
    SELECT category, AVG(score) as avg_score, COUNT(*) as count
    FROM evaluation_items
    WHERE score > 0.5 AND category = 'test'
    GROUP BY category
    ORDER BY avg_score DESC
    LIMIT 100

    - `select: List[SelectItem]`

      - `expression: Expression`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

        - `class ExpressionColumn: …`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `column: str`

            Column name from evaluation_items.data

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

          - `type: Optional[Literal["COLUMN"]]`

            - `"COLUMN"`

        - `class ExpressionAggregation: …`

          Aggregation function to apply

          Examples:
          {"type": "AGGREGATION", "function": "AVG", "column": "score"}
          {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
          {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

          - `column: str`

            Column to aggregate, or '*' for COUNT(*)

          - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

            Supported aggregation functions

            - `"COUNT"`

            - `"SUM"`

            - `"AVG"`

            - `"MIN"`

            - `"MAX"`

            - `"STDDEV"`

            - `"VARIANCE"`

            - `"PERCENTILE"`

            - `"COUNT_DISTINCT"`

            - `"PERCENTAGE"`

          - `evaluation_ids: Optional[List[str]]`

            Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

          - `params: Optional[Dict[str, object]]`

            Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

          - `type: Optional[Literal["AGGREGATION"]]`

            - `"AGGREGATION"`

      - `alias: Optional[str]`

        Optional alias for the selected item

    - `evaluation_ids: Optional[List[str]]`

      Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

    - `filter: Optional[Filter]`

      Filter conditions (WHERE clause)

      - `conditions: List[Condition]`

        - `column: str`

          Column name to filter on

        - `operator: Literal["=", "!=", ">", 9 more]`

          Comparison operator

          - `"="`

          - `"!="`

          - `">"`

          - `"<"`

          - `">="`

          - `"<="`

          - `"IN"`

          - `"NOT IN"`

          - `"LIKE"`

          - `"NOT LIKE"`

          - `"IS NULL"`

          - `"IS NOT NULL"`

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

        - `value: Optional[Union[str, float, bool, 2 more]]`

          Value to compare against. Not required for IS NULL / IS NOT NULL operators.

          - `str`

          - `float`

          - `bool`

          - `List[object]`

      - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

        Logical operators connecting conditions. Length must be len(conditions) - 1

        - `"AND"`

        - `"OR"`

    - `group_by: Optional[List[str]]`

      Columns to group by

    - `latest_only: Optional[bool]`

      When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

    - `limit: Optional[int]`

      Max rows to return

    - `order_by: Optional[List[OrderBy]]`

      Sort order

      - `column: str`

        Column name to sort by

      - `direction: Optional[Literal["ASC", "DESC"]]`

        Sort direction

        - `"ASC"`

        - `"DESC"`

      - `source: Optional[str]`

        Column source: 'data' or 'task_result_cache'

  - `class MetricQuery: …`

    Query that returns a single metric value (used for metric widgets).

    Used for widget type: metric.
    Enforces exactly 1 aggregation in select.
    Returns: {"type": "metric", "data": ...}

    Example SQL equivalent:
    SELECT AVG(score) as average_score
    FROM evaluation_items

    - `select: List[SelectItem]`

      - `expression: Expression`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

      - `alias: Optional[str]`

        Optional alias for the selected item

    - `evaluation_ids: Optional[List[str]]`

      Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

    - `filter: Optional[Filter]`

      Filter conditions (WHERE clause)

    - `latest_only: Optional[bool]`

      When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

- `title: Optional[str]`

  Widget title

### Returns

- `class EvaluationDashboardWidgetWithResult: …`

  Response model for widget creation - includes widget and computed result

  - `id: str`

    Unique identifier of the widget

  - `account_id: str`

    Account that owns this widget

  - `created_at: datetime`

    When the widget was created

  - `title: str`

    Widget title

  - `type: EvaluationWidgetTypeEnum`

    Widget type

    - `"bar"`

    - `"histogram"`

    - `"donut"`

    - `"scatter"`

    - `"metric"`

    - `"table"`

    - `"markdown"`

    - `"heading"`

    - `"timeseries"`

  - `config: Optional[Dict[str, object]]`

    Display configuration

  - `object: Optional[Literal["evaluation_widget"]]`

    - `"evaluation_widget"`

  - `query: Optional[Query]`

    Structured query AST for computation (SeriesQuery or MetricQuery)

    - `class SeriesQuery: …`

      Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

      Used for widget types: table, bar, histogram, donut, scatter.
      Returns: {"type": "series", "data": [...]}

      Example SQL equivalent:
      SELECT category, AVG(score) as avg_score, COUNT(*) as count
      FROM evaluation_items
      WHERE score > 0.5 AND category = 'test'
      GROUP BY category
      ORDER BY avg_score DESC
      LIMIT 100

      - `select: List[SelectItem]`

        - `expression: Expression`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `class ExpressionColumn: …`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

            - `column: str`

              Column name from evaluation_items.data

            - `source: Optional[str]`

              Column source: 'data' or 'task_result_cache'

            - `type: Optional[Literal["COLUMN"]]`

              - `"COLUMN"`

          - `class ExpressionAggregation: …`

            Aggregation function to apply

            Examples:
            {"type": "AGGREGATION", "function": "AVG", "column": "score"}
            {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
            {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

            - `column: str`

              Column to aggregate, or '*' for COUNT(*)

            - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

              Supported aggregation functions

              - `"COUNT"`

              - `"SUM"`

              - `"AVG"`

              - `"MIN"`

              - `"MAX"`

              - `"STDDEV"`

              - `"VARIANCE"`

              - `"PERCENTILE"`

              - `"COUNT_DISTINCT"`

              - `"PERCENTAGE"`

            - `evaluation_ids: Optional[List[str]]`

              Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

            - `params: Optional[Dict[str, object]]`

              Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

            - `source: Optional[str]`

              Column source: 'data' or 'task_result_cache'

            - `type: Optional[Literal["AGGREGATION"]]`

              - `"AGGREGATION"`

        - `alias: Optional[str]`

          Optional alias for the selected item

      - `evaluation_ids: Optional[List[str]]`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: Optional[Filter]`

        Filter conditions (WHERE clause)

        - `conditions: List[Condition]`

          - `column: str`

            Column name to filter on

          - `operator: Literal["=", "!=", ">", 9 more]`

            Comparison operator

            - `"="`

            - `"!="`

            - `">"`

            - `"<"`

            - `">="`

            - `"<="`

            - `"IN"`

            - `"NOT IN"`

            - `"LIKE"`

            - `"NOT LIKE"`

            - `"IS NULL"`

            - `"IS NOT NULL"`

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

          - `value: Optional[Union[str, float, bool, 2 more]]`

            Value to compare against. Not required for IS NULL / IS NOT NULL operators.

            - `str`

            - `float`

            - `bool`

            - `List[object]`

        - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

          Logical operators connecting conditions. Length must be len(conditions) - 1

          - `"AND"`

          - `"OR"`

      - `group_by: Optional[List[str]]`

        Columns to group by

      - `latest_only: Optional[bool]`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

      - `limit: Optional[int]`

        Max rows to return

      - `order_by: Optional[List[OrderBy]]`

        Sort order

        - `column: str`

          Column name to sort by

        - `direction: Optional[Literal["ASC", "DESC"]]`

          Sort direction

          - `"ASC"`

          - `"DESC"`

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

    - `class MetricQuery: …`

      Query that returns a single metric value (used for metric widgets).

      Used for widget type: metric.
      Enforces exactly 1 aggregation in select.
      Returns: {"type": "metric", "data": ...}

      Example SQL equivalent:
      SELECT AVG(score) as average_score
      FROM evaluation_items

      - `select: List[SelectItem]`

        - `expression: Expression`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

        - `alias: Optional[str]`

          Optional alias for the selected item

      - `evaluation_ids: Optional[List[str]]`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: Optional[Filter]`

        Filter conditions (WHERE clause)

      - `latest_only: Optional[bool]`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

  - `result: Optional[EvaluationDashboardWidgetResultResponse]`

    Computed result for this widget

    - `id: str`

      Unique identifier of the widget result

    - `computation_status: str`

      Status: pending, completed, or failed

    - `widget_id: str`

      Widget ID this result belongs to

    - `computed_at: Optional[datetime]`

      When computation completed

    - `computed_result: Optional[Dict[str, object]]`

      Computed result data. Metric: {type: 'metric', data: 42}, Series: {type: 'series', data: [{x: 'A', y: 10}, ...]}

    - `error_message: Optional[str]`

      Error message if computation failed

### Example

```python
import os
from scale_gp_beta import SGPClient

client = SGPClient(
    api_key=os.environ.get("SGP_API_KEY"),  # This is the default and can be omitted
)
evaluation_dashboard_widget_with_result = client.evaluation_dashboards.widgets.update(
    widget_id="widget_id",
    dashboard_id="dashboard_id",
)
print(evaluation_dashboard_widget_with_result.id)
```

#### Response

```json
{
  "id": "id",
  "account_id": "account_id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "title": "title",
  "type": "bar",
  "config": {
    "foo": "bar"
  },
  "object": "evaluation_widget",
  "query": {
    "select": [
      {
        "expression": {
          "column": "column",
          "source": "source",
          "type": "COLUMN"
        },
        "alias": "alias"
      }
    ],
    "evaluation_ids": [
      "string"
    ],
    "filter": {
      "conditions": [
        {
          "column": "column",
          "operator": "=",
          "source": "source",
          "value": "string"
        }
      ],
      "logicalOperators": [
        "AND"
      ]
    },
    "groupBy": [
      "string"
    ],
    "latest_only": true,
    "limit": 1,
    "orderBy": [
      {
        "column": "column",
        "direction": "ASC",
        "source": "source"
      }
    ]
  },
  "result": {
    "id": "id",
    "computation_status": "computation_status",
    "widget_id": "widget_id",
    "computed_at": "2019-12-27T18:11:19.117Z",
    "computed_result": {
      "foo": "bar"
    },
    "error_message": "error_message"
  }
}
```

## Remove Widget from Dashboard

`evaluation_dashboards.widgets.remove(strwidget_id, WidgetRemoveParams**kwargs)`

**delete** `/v5/evaluation-dashboards/{dashboard_id}/widgets/{widget_id}`

Detach a widget from this dashboard without deleting the widget itself.

This removes the widget's ID from the dashboard's `widget_order` only; the
underlying widget entity and any computed widget results are left intact, so a widget
shared with other dashboards continues to work there. The widget must currently be in
this dashboard's `widget_order`, otherwise a not-found error is returned. Responds
with 204 No Content on success.

### Parameters

- `dashboard_id: str`

- `widget_id: str`

### Example

```python
import os
from scale_gp_beta import SGPClient

client = SGPClient(
    api_key=os.environ.get("SGP_API_KEY"),  # This is the default and can be omitted
)
client.evaluation_dashboards.widgets.remove(
    widget_id="widget_id",
    dashboard_id="dashboard_id",
)
```

## Domain Types

### Evaluation Dashboard Widget

- `class EvaluationDashboardWidget: …`

  - `id: str`

    Unique identifier of the widget

  - `account_id: str`

    Account that owns this widget

  - `created_at: datetime`

    When the widget was created

  - `title: str`

    Widget title

  - `type: EvaluationWidgetTypeEnum`

    Widget type

    - `"bar"`

    - `"histogram"`

    - `"donut"`

    - `"scatter"`

    - `"metric"`

    - `"table"`

    - `"markdown"`

    - `"heading"`

    - `"timeseries"`

  - `archived_at: Optional[datetime]`

    When the widget was archived (soft-deleted)

  - `config: Optional[Dict[str, object]]`

    Chart-specific display configuration

  - `object: Optional[Literal["evaluation_dashboard_widget"]]`

    - `"evaluation_dashboard_widget"`

  - `query: Optional[Query]`

    Structured query AST for metric computation (SeriesQuery or MetricQuery)

    - `class SeriesQuery: …`

      Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

      Used for widget types: table, bar, histogram, donut, scatter.
      Returns: {"type": "series", "data": [...]}

      Example SQL equivalent:
      SELECT category, AVG(score) as avg_score, COUNT(*) as count
      FROM evaluation_items
      WHERE score > 0.5 AND category = 'test'
      GROUP BY category
      ORDER BY avg_score DESC
      LIMIT 100

      - `select: List[SelectItem]`

        - `expression: Expression`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `class ExpressionColumn: …`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

            - `column: str`

              Column name from evaluation_items.data

            - `source: Optional[str]`

              Column source: 'data' or 'task_result_cache'

            - `type: Optional[Literal["COLUMN"]]`

              - `"COLUMN"`

          - `class ExpressionAggregation: …`

            Aggregation function to apply

            Examples:
            {"type": "AGGREGATION", "function": "AVG", "column": "score"}
            {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
            {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

            - `column: str`

              Column to aggregate, or '*' for COUNT(*)

            - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

              Supported aggregation functions

              - `"COUNT"`

              - `"SUM"`

              - `"AVG"`

              - `"MIN"`

              - `"MAX"`

              - `"STDDEV"`

              - `"VARIANCE"`

              - `"PERCENTILE"`

              - `"COUNT_DISTINCT"`

              - `"PERCENTAGE"`

            - `evaluation_ids: Optional[List[str]]`

              Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

            - `params: Optional[Dict[str, object]]`

              Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

            - `source: Optional[str]`

              Column source: 'data' or 'task_result_cache'

            - `type: Optional[Literal["AGGREGATION"]]`

              - `"AGGREGATION"`

        - `alias: Optional[str]`

          Optional alias for the selected item

      - `evaluation_ids: Optional[List[str]]`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: Optional[Filter]`

        Filter conditions (WHERE clause)

        - `conditions: List[Condition]`

          - `column: str`

            Column name to filter on

          - `operator: Literal["=", "!=", ">", 9 more]`

            Comparison operator

            - `"="`

            - `"!="`

            - `">"`

            - `"<"`

            - `">="`

            - `"<="`

            - `"IN"`

            - `"NOT IN"`

            - `"LIKE"`

            - `"NOT LIKE"`

            - `"IS NULL"`

            - `"IS NOT NULL"`

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

          - `value: Optional[Union[str, float, bool, 2 more]]`

            Value to compare against. Not required for IS NULL / IS NOT NULL operators.

            - `str`

            - `float`

            - `bool`

            - `List[object]`

        - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

          Logical operators connecting conditions. Length must be len(conditions) - 1

          - `"AND"`

          - `"OR"`

      - `group_by: Optional[List[str]]`

        Columns to group by

      - `latest_only: Optional[bool]`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

      - `limit: Optional[int]`

        Max rows to return

      - `order_by: Optional[List[OrderBy]]`

        Sort order

        - `column: str`

          Column name to sort by

        - `direction: Optional[Literal["ASC", "DESC"]]`

          Sort direction

          - `"ASC"`

          - `"DESC"`

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

    - `class MetricQuery: …`

      Query that returns a single metric value (used for metric widgets).

      Used for widget type: metric.
      Enforces exactly 1 aggregation in select.
      Returns: {"type": "metric", "data": ...}

      Example SQL equivalent:
      SELECT AVG(score) as average_score
      FROM evaluation_items

      - `select: List[SelectItem]`

        - `expression: Expression`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

        - `alias: Optional[str]`

          Optional alias for the selected item

      - `evaluation_ids: Optional[List[str]]`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: Optional[Filter]`

        Filter conditions (WHERE clause)

      - `latest_only: Optional[bool]`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

### Evaluation Dashboard Widget Result

- `class EvaluationDashboardWidgetResult: …`

  - `id: str`

    Unique identifier of the widget result

  - `account_id: str`

    Account that owns this widget result

  - `computation_status: Literal["pending", "completed", "failed"]`

    Status of the computation

    - `"pending"`

    - `"completed"`

    - `"failed"`

  - `created_at: datetime`

    When the widget result was created

  - `widget_id: str`

    Unique identifier of the widget

  - `computation_job_id: Optional[str]`

    Temporal workflow ID or job ID for async computation tracking

  - `computed_at: Optional[datetime]`

    Timestamp when computation completed successfully

  - `computed_result: Optional[Dict[str, object]]`

    Cached computation results

  - `error_message: Optional[str]`

    Error message if computation failed

  - `evaluation_group_id: Optional[str]`

    FK to evaluation_groups. Null if result is for a single evaluation.

  - `evaluation_id: Optional[str]`

    FK to evaluations. Null if result is for an evaluation group.

  - `object: Optional[Literal["evaluation_dashboard_widget_result"]]`

    - `"evaluation_dashboard_widget_result"`

  - `widget: Optional[EvaluationDashboardWidget]`

    Widget that this result is for

    - `id: str`

      Unique identifier of the widget

    - `account_id: str`

      Account that owns this widget

    - `created_at: datetime`

      When the widget was created

    - `title: str`

      Widget title

    - `type: EvaluationWidgetTypeEnum`

      Widget type

      - `"bar"`

      - `"histogram"`

      - `"donut"`

      - `"scatter"`

      - `"metric"`

      - `"table"`

      - `"markdown"`

      - `"heading"`

      - `"timeseries"`

    - `archived_at: Optional[datetime]`

      When the widget was archived (soft-deleted)

    - `config: Optional[Dict[str, object]]`

      Chart-specific display configuration

    - `object: Optional[Literal["evaluation_dashboard_widget"]]`

      - `"evaluation_dashboard_widget"`

    - `query: Optional[Query]`

      Structured query AST for metric computation (SeriesQuery or MetricQuery)

      - `class SeriesQuery: …`

        Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

        Used for widget types: table, bar, histogram, donut, scatter.
        Returns: {"type": "series", "data": [...]}

        Example SQL equivalent:
        SELECT category, AVG(score) as avg_score, COUNT(*) as count
        FROM evaluation_items
        WHERE score > 0.5 AND category = 'test'
        GROUP BY category
        ORDER BY avg_score DESC
        LIMIT 100

        - `select: List[SelectItem]`

          - `expression: Expression`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

            - `class ExpressionColumn: …`

              Reference to a column from evaluation_items.data

              Example:
              {"type": "COLUMN", "column": "category"}

              - `column: str`

                Column name from evaluation_items.data

              - `source: Optional[str]`

                Column source: 'data' or 'task_result_cache'

              - `type: Optional[Literal["COLUMN"]]`

                - `"COLUMN"`

            - `class ExpressionAggregation: …`

              Aggregation function to apply

              Examples:
              {"type": "AGGREGATION", "function": "AVG", "column": "score"}
              {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
              {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

              - `column: str`

                Column to aggregate, or '*' for COUNT(*)

              - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

                Supported aggregation functions

                - `"COUNT"`

                - `"SUM"`

                - `"AVG"`

                - `"MIN"`

                - `"MAX"`

                - `"STDDEV"`

                - `"VARIANCE"`

                - `"PERCENTILE"`

                - `"COUNT_DISTINCT"`

                - `"PERCENTAGE"`

              - `evaluation_ids: Optional[List[str]]`

                Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

              - `params: Optional[Dict[str, object]]`

                Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

              - `source: Optional[str]`

                Column source: 'data' or 'task_result_cache'

              - `type: Optional[Literal["AGGREGATION"]]`

                - `"AGGREGATION"`

          - `alias: Optional[str]`

            Optional alias for the selected item

        - `evaluation_ids: Optional[List[str]]`

          Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

        - `filter: Optional[Filter]`

          Filter conditions (WHERE clause)

          - `conditions: List[Condition]`

            - `column: str`

              Column name to filter on

            - `operator: Literal["=", "!=", ">", 9 more]`

              Comparison operator

              - `"="`

              - `"!="`

              - `">"`

              - `"<"`

              - `">="`

              - `"<="`

              - `"IN"`

              - `"NOT IN"`

              - `"LIKE"`

              - `"NOT LIKE"`

              - `"IS NULL"`

              - `"IS NOT NULL"`

            - `source: Optional[str]`

              Column source: 'data' or 'task_result_cache'

            - `value: Optional[Union[str, float, bool, 2 more]]`

              Value to compare against. Not required for IS NULL / IS NOT NULL operators.

              - `str`

              - `float`

              - `bool`

              - `List[object]`

          - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

            Logical operators connecting conditions. Length must be len(conditions) - 1

            - `"AND"`

            - `"OR"`

        - `group_by: Optional[List[str]]`

          Columns to group by

        - `latest_only: Optional[bool]`

          When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

        - `limit: Optional[int]`

          Max rows to return

        - `order_by: Optional[List[OrderBy]]`

          Sort order

          - `column: str`

            Column name to sort by

          - `direction: Optional[Literal["ASC", "DESC"]]`

            Sort direction

            - `"ASC"`

            - `"DESC"`

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

      - `class MetricQuery: …`

        Query that returns a single metric value (used for metric widgets).

        Used for widget type: metric.
        Enforces exactly 1 aggregation in select.
        Returns: {"type": "metric", "data": ...}

        Example SQL equivalent:
        SELECT AVG(score) as average_score
        FROM evaluation_items

        - `select: List[SelectItem]`

          - `expression: Expression`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

          - `alias: Optional[str]`

            Optional alias for the selected item

        - `evaluation_ids: Optional[List[str]]`

          Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

        - `filter: Optional[Filter]`

          Filter conditions (WHERE clause)

        - `latest_only: Optional[bool]`

          When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

### Evaluation Dashboard Widget Result Response

- `class EvaluationDashboardWidgetResultResponse: …`

  Computed result for a widget - used in widget creation response

  - `id: str`

    Unique identifier of the widget result

  - `computation_status: str`

    Status: pending, completed, or failed

  - `widget_id: str`

    Widget ID this result belongs to

  - `computed_at: Optional[datetime]`

    When computation completed

  - `computed_result: Optional[Dict[str, object]]`

    Computed result data. Metric: {type: 'metric', data: 42}, Series: {type: 'series', data: [{x: 'A', y: 10}, ...]}

  - `error_message: Optional[str]`

    Error message if computation failed

### Evaluation Dashboard Widget With Result

- `class EvaluationDashboardWidgetWithResult: …`

  Response model for widget creation - includes widget and computed result

  - `id: str`

    Unique identifier of the widget

  - `account_id: str`

    Account that owns this widget

  - `created_at: datetime`

    When the widget was created

  - `title: str`

    Widget title

  - `type: EvaluationWidgetTypeEnum`

    Widget type

    - `"bar"`

    - `"histogram"`

    - `"donut"`

    - `"scatter"`

    - `"metric"`

    - `"table"`

    - `"markdown"`

    - `"heading"`

    - `"timeseries"`

  - `config: Optional[Dict[str, object]]`

    Display configuration

  - `object: Optional[Literal["evaluation_widget"]]`

    - `"evaluation_widget"`

  - `query: Optional[Query]`

    Structured query AST for computation (SeriesQuery or MetricQuery)

    - `class SeriesQuery: …`

      Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

      Used for widget types: table, bar, histogram, donut, scatter.
      Returns: {"type": "series", "data": [...]}

      Example SQL equivalent:
      SELECT category, AVG(score) as avg_score, COUNT(*) as count
      FROM evaluation_items
      WHERE score > 0.5 AND category = 'test'
      GROUP BY category
      ORDER BY avg_score DESC
      LIMIT 100

      - `select: List[SelectItem]`

        - `expression: Expression`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

          - `class ExpressionColumn: …`

            Reference to a column from evaluation_items.data

            Example:
            {"type": "COLUMN", "column": "category"}

            - `column: str`

              Column name from evaluation_items.data

            - `source: Optional[str]`

              Column source: 'data' or 'task_result_cache'

            - `type: Optional[Literal["COLUMN"]]`

              - `"COLUMN"`

          - `class ExpressionAggregation: …`

            Aggregation function to apply

            Examples:
            {"type": "AGGREGATION", "function": "AVG", "column": "score"}
            {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
            {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

            - `column: str`

              Column to aggregate, or '*' for COUNT(*)

            - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

              Supported aggregation functions

              - `"COUNT"`

              - `"SUM"`

              - `"AVG"`

              - `"MIN"`

              - `"MAX"`

              - `"STDDEV"`

              - `"VARIANCE"`

              - `"PERCENTILE"`

              - `"COUNT_DISTINCT"`

              - `"PERCENTAGE"`

            - `evaluation_ids: Optional[List[str]]`

              Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

            - `params: Optional[Dict[str, object]]`

              Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

            - `source: Optional[str]`

              Column source: 'data' or 'task_result_cache'

            - `type: Optional[Literal["AGGREGATION"]]`

              - `"AGGREGATION"`

        - `alias: Optional[str]`

          Optional alias for the selected item

      - `evaluation_ids: Optional[List[str]]`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: Optional[Filter]`

        Filter conditions (WHERE clause)

        - `conditions: List[Condition]`

          - `column: str`

            Column name to filter on

          - `operator: Literal["=", "!=", ">", 9 more]`

            Comparison operator

            - `"="`

            - `"!="`

            - `">"`

            - `"<"`

            - `">="`

            - `"<="`

            - `"IN"`

            - `"NOT IN"`

            - `"LIKE"`

            - `"NOT LIKE"`

            - `"IS NULL"`

            - `"IS NOT NULL"`

          - `source: Optional[str]`

            Column source: 'data' or 'task_result_cache'

          - `value: Optional[Union[str, float, bool, 2 more]]`

            Value to compare against. Not required for IS NULL / IS NOT NULL operators.

            - `str`

            - `float`

            - `bool`

            - `List[object]`

        - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

          Logical operators connecting conditions. Length must be len(conditions) - 1

          - `"AND"`

          - `"OR"`

      - `group_by: Optional[List[str]]`

        Columns to group by

      - `latest_only: Optional[bool]`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

      - `limit: Optional[int]`

        Max rows to return

      - `order_by: Optional[List[OrderBy]]`

        Sort order

        - `column: str`

          Column name to sort by

        - `direction: Optional[Literal["ASC", "DESC"]]`

          Sort direction

          - `"ASC"`

          - `"DESC"`

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

    - `class MetricQuery: …`

      Query that returns a single metric value (used for metric widgets).

      Used for widget type: metric.
      Enforces exactly 1 aggregation in select.
      Returns: {"type": "metric", "data": ...}

      Example SQL equivalent:
      SELECT AVG(score) as average_score
      FROM evaluation_items

      - `select: List[SelectItem]`

        - `expression: Expression`

          Reference to a column from evaluation_items.data

          Example:
          {"type": "COLUMN", "column": "category"}

        - `alias: Optional[str]`

          Optional alias for the selected item

      - `evaluation_ids: Optional[List[str]]`

        Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

      - `filter: Optional[Filter]`

        Filter conditions (WHERE clause)

      - `latest_only: Optional[bool]`

        When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

  - `result: Optional[EvaluationDashboardWidgetResultResponse]`

    Computed result for this widget

    - `id: str`

      Unique identifier of the widget result

    - `computation_status: str`

      Status: pending, completed, or failed

    - `widget_id: str`

      Widget ID this result belongs to

    - `computed_at: Optional[datetime]`

      When computation completed

    - `computed_result: Optional[Dict[str, object]]`

      Computed result data. Metric: {type: 'metric', data: 42}, Series: {type: 'series', data: [{x: 'A', y: 10}, ...]}

    - `error_message: Optional[str]`

      Error message if computation failed

### Evaluation Widget Type Enum

- `Literal["bar", "histogram", "donut", 6 more]`

  Widget types for dashboard visualizations

  - `"bar"`

  - `"histogram"`

  - `"donut"`

  - `"scatter"`

  - `"metric"`

  - `"table"`

  - `"markdown"`

  - `"heading"`

  - `"timeseries"`

### Filter

- `class Filter: …`

  Filter clause with conditions connected by logical operators.

  Conditions are evaluated left-to-right without precedence (no nesting/parentheses).
  Example: condition1 AND condition2 OR condition3 evaluates as ((condition1 AND condition2) OR condition3)

  Example:
  {
  "conditions": [
  {"column": "score", "operator": ">", "value": 0.5},
  {"column": "category", "operator": "=", "value": "test"}
  ],
  "logicalOperators": ["AND"]
  }

  - `conditions: List[Condition]`

    - `column: str`

      Column name to filter on

    - `operator: Literal["=", "!=", ">", 9 more]`

      Comparison operator

      - `"="`

      - `"!="`

      - `">"`

      - `"<"`

      - `">="`

      - `"<="`

      - `"IN"`

      - `"NOT IN"`

      - `"LIKE"`

      - `"NOT LIKE"`

      - `"IS NULL"`

      - `"IS NOT NULL"`

    - `source: Optional[str]`

      Column source: 'data' or 'task_result_cache'

    - `value: Optional[Union[str, float, bool, 2 more]]`

      Value to compare against. Not required for IS NULL / IS NOT NULL operators.

      - `str`

      - `float`

      - `bool`

      - `List[object]`

  - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

    Logical operators connecting conditions. Length must be len(conditions) - 1

    - `"AND"`

    - `"OR"`

### Metric Query

- `class MetricQuery: …`

  Query that returns a single metric value (used for metric widgets).

  Used for widget type: metric.
  Enforces exactly 1 aggregation in select.
  Returns: {"type": "metric", "data": ...}

  Example SQL equivalent:
  SELECT AVG(score) as average_score
  FROM evaluation_items

  - `select: List[SelectItem]`

    - `expression: Expression`

      Reference to a column from evaluation_items.data

      Example:
      {"type": "COLUMN", "column": "category"}

      - `class ExpressionColumn: …`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

        - `column: str`

          Column name from evaluation_items.data

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

        - `type: Optional[Literal["COLUMN"]]`

          - `"COLUMN"`

      - `class ExpressionAggregation: …`

        Aggregation function to apply

        Examples:
        {"type": "AGGREGATION", "function": "AVG", "column": "score"}
        {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
        {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

        - `column: str`

          Column to aggregate, or '*' for COUNT(*)

        - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

          Supported aggregation functions

          - `"COUNT"`

          - `"SUM"`

          - `"AVG"`

          - `"MIN"`

          - `"MAX"`

          - `"STDDEV"`

          - `"VARIANCE"`

          - `"PERCENTILE"`

          - `"COUNT_DISTINCT"`

          - `"PERCENTAGE"`

        - `evaluation_ids: Optional[List[str]]`

          Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

        - `params: Optional[Dict[str, object]]`

          Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

        - `type: Optional[Literal["AGGREGATION"]]`

          - `"AGGREGATION"`

    - `alias: Optional[str]`

      Optional alias for the selected item

  - `evaluation_ids: Optional[List[str]]`

    Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

  - `filter: Optional[Filter]`

    Filter conditions (WHERE clause)

    - `conditions: List[Condition]`

      - `column: str`

        Column name to filter on

      - `operator: Literal["=", "!=", ">", 9 more]`

        Comparison operator

        - `"="`

        - `"!="`

        - `">"`

        - `"<"`

        - `">="`

        - `"<="`

        - `"IN"`

        - `"NOT IN"`

        - `"LIKE"`

        - `"NOT LIKE"`

        - `"IS NULL"`

        - `"IS NOT NULL"`

      - `source: Optional[str]`

        Column source: 'data' or 'task_result_cache'

      - `value: Optional[Union[str, float, bool, 2 more]]`

        Value to compare against. Not required for IS NULL / IS NOT NULL operators.

        - `str`

        - `float`

        - `bool`

        - `List[object]`

    - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

      Logical operators connecting conditions. Length must be len(conditions) - 1

      - `"AND"`

      - `"OR"`

  - `latest_only: Optional[bool]`

    When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

### Select Item

- `class SelectItem: …`

  Column in SELECT clause

  - `expression: Expression`

    Reference to a column from evaluation_items.data

    Example:
    {"type": "COLUMN", "column": "category"}

    - `class ExpressionColumn: …`

      Reference to a column from evaluation_items.data

      Example:
      {"type": "COLUMN", "column": "category"}

      - `column: str`

        Column name from evaluation_items.data

      - `source: Optional[str]`

        Column source: 'data' or 'task_result_cache'

      - `type: Optional[Literal["COLUMN"]]`

        - `"COLUMN"`

    - `class ExpressionAggregation: …`

      Aggregation function to apply

      Examples:
      {"type": "AGGREGATION", "function": "AVG", "column": "score"}
      {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
      {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

      - `column: str`

        Column to aggregate, or '*' for COUNT(*)

      - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

        Supported aggregation functions

        - `"COUNT"`

        - `"SUM"`

        - `"AVG"`

        - `"MIN"`

        - `"MAX"`

        - `"STDDEV"`

        - `"VARIANCE"`

        - `"PERCENTILE"`

        - `"COUNT_DISTINCT"`

        - `"PERCENTAGE"`

      - `evaluation_ids: Optional[List[str]]`

        Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

      - `params: Optional[Dict[str, object]]`

        Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

      - `source: Optional[str]`

        Column source: 'data' or 'task_result_cache'

      - `type: Optional[Literal["AGGREGATION"]]`

        - `"AGGREGATION"`

  - `alias: Optional[str]`

    Optional alias for the selected item

### Series Query

- `class SeriesQuery: …`

  Query that returns a series of records (used for table/bar/histogram/donut/scatter widgets).

  Used for widget types: table, bar, histogram, donut, scatter.
  Returns: {"type": "series", "data": [...]}

  Example SQL equivalent:
  SELECT category, AVG(score) as avg_score, COUNT(*) as count
  FROM evaluation_items
  WHERE score > 0.5 AND category = 'test'
  GROUP BY category
  ORDER BY avg_score DESC
  LIMIT 100

  - `select: List[SelectItem]`

    - `expression: Expression`

      Reference to a column from evaluation_items.data

      Example:
      {"type": "COLUMN", "column": "category"}

      - `class ExpressionColumn: …`

        Reference to a column from evaluation_items.data

        Example:
        {"type": "COLUMN", "column": "category"}

        - `column: str`

          Column name from evaluation_items.data

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

        - `type: Optional[Literal["COLUMN"]]`

          - `"COLUMN"`

      - `class ExpressionAggregation: …`

        Aggregation function to apply

        Examples:
        {"type": "AGGREGATION", "function": "AVG", "column": "score"}
        {"type": "AGGREGATION", "function": "COUNT", "column": "*"}
        {"type": "AGGREGATION", "function": "PERCENTILE", "column": "score", "params": {"percentile": 95}}

        - `column: str`

          Column to aggregate, or '*' for COUNT(*)

        - `function: Literal["COUNT", "SUM", "AVG", 7 more]`

          Supported aggregation functions

          - `"COUNT"`

          - `"SUM"`

          - `"AVG"`

          - `"MIN"`

          - `"MAX"`

          - `"STDDEV"`

          - `"VARIANCE"`

          - `"PERCENTILE"`

          - `"COUNT_DISTINCT"`

          - `"PERCENTAGE"`

        - `evaluation_ids: Optional[List[str]]`

          Optional subset of evaluation IDs for per-aggregation filtering in evaluation group dashboards.

        - `params: Optional[Dict[str, object]]`

          Function parameters (e.g., {'percentile': 95} for PERCENTILE, {'percentage_filters': Filter} for PERCENTAGE)

        - `source: Optional[str]`

          Column source: 'data' or 'task_result_cache'

        - `type: Optional[Literal["AGGREGATION"]]`

          - `"AGGREGATION"`

    - `alias: Optional[str]`

      Optional alias for the selected item

  - `evaluation_ids: Optional[List[str]]`

    Optional subset of evaluation IDs to compute on. Only applicable for evaluation group dashboards. If omitted, computes on all evaluations in the group.

  - `filter: Optional[Filter]`

    Filter conditions (WHERE clause)

    - `conditions: List[Condition]`

      - `column: str`

        Column name to filter on

      - `operator: Literal["=", "!=", ">", 9 more]`

        Comparison operator

        - `"="`

        - `"!="`

        - `">"`

        - `"<"`

        - `">="`

        - `"<="`

        - `"IN"`

        - `"NOT IN"`

        - `"LIKE"`

        - `"NOT LIKE"`

        - `"IS NULL"`

        - `"IS NOT NULL"`

      - `source: Optional[str]`

        Column source: 'data' or 'task_result_cache'

      - `value: Optional[Union[str, float, bool, 2 more]]`

        Value to compare against. Not required for IS NULL / IS NOT NULL operators.

        - `str`

        - `float`

        - `bool`

        - `List[object]`

    - `logical_operators: Optional[List[Literal["AND", "OR"]]]`

      Logical operators connecting conditions. Length must be len(conditions) - 1

      - `"AND"`

      - `"OR"`

  - `group_by: Optional[List[str]]`

    Columns to group by

  - `latest_only: Optional[bool]`

    When True, the widget computes against rows from only the most recent active evaluation in the group (by EvaluationORM.created_at). Only applicable for evaluation group dashboards. Composes with evaluation_ids (latest within the subset). Cannot be combined with per-aggregation evaluation_ids; the use case enforces these rules.

  - `limit: Optional[int]`

    Max rows to return

  - `order_by: Optional[List[OrderBy]]`

    Sort order

    - `column: str`

      Column name to sort by

    - `direction: Optional[Literal["ASC", "DESC"]]`

      Sort direction

      - `"ASC"`

      - `"DESC"`

    - `source: Optional[str]`

      Column source: 'data' or 'task_result_cache'
