> ## Documentation Index
> Fetch the complete documentation index at: https://dev.haico.gr/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Chart tool

> The chart_generator tool: produce a typed line, bar, or pie chart artifact that the frontend renders in the centre panel.

The `ChartTools` collection exposes a single tool, `chart_generator`, that produces a **typed chart artifact**. One instance is created per thread, bound to its `thread_id`, so the persisted artifact lands on the right conversation without the id being an LLM-facing parameter.

The tool does **not** render anything server-side. It validates and normalises the data into a small JSON payload, and the frontend's artifact registry dispatches on the `artifact_type` to a recharts component (`LineChartView`, `BarChartView`, or `PieChartView`). This is the typed-artifact pattern: the agent emits typed data, the frontend owns the rendering, which keeps the agent's surface area small (no SVG, no React) and avoids the XSS or sandboxing concerns of agent-emitted markup.

Shared conventions (the `@workspace_tool` contract, the injected `action_and_reasoning` argument, and the `(content, artifact)` return) are documented in [Tools](/docs/tools); the end-to-end artifact channel (persistence, the SSE `artifact` event, the frontend registry) is in [Agent core logic](/docs/agent-core-logic). The decorator injects the required `action_and_reasoning` argument, so it is omitted from the argument table below.

Source: [`backend/app/tools/charts.py`](https://github.com/petrosrapto/HAICO/blob/main/backend/app/tools/charts.py)

## `chart_generator`

Generate a line, bar, or pie chart that renders in the centre artifact panel.

**Description shown to the agent:**

> Generate a chart that will appear in the centre artifact panel. Pick the chart\_type that best matches the user's intent (line for trends, bar for comparisons, pie for proportions). Returns a confirmation message; the chart itself renders automatically in the frontend after this call. Suppose the chart is already displayed when you compose your reply.

**Arguments**

| Argument       | Type                              | Required | Description shown to the agent                                                                                                                                             |
| -------------- | --------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chart_type`   | `"line" \| "bar" \| "pie"`        | Yes      | Which kind of chart to render. 'line' for trends over time / ordered sequences, 'bar' for category comparisons or counts, 'pie' for parts of a whole (5-7 categories max). |
| `title`        | `string`                          | Yes      | Short title shown above the chart.                                                                                                                                         |
| `description`  | `string` (default `""`)           | No       | One-sentence subtitle shown below the chart title. Provide a concise summary of what the chart shows.                                                                      |
| `data`         | `array` of objects                | Yes      | List of data points. See [The `data` argument](#the-data-argument) for the verbatim shape rules.                                                                           |
| `x_axis_title` | `string` (default `""`)           | No       | Label for the x-axis (line/bar charts). Ignored for pie charts.                                                                                                            |
| `y_axis_title` | `string` (default `""`)           | No       | Label for the y-axis (line/bar charts). Ignored for pie charts.                                                                                                            |
| `style`        | `object \| null` (default `null`) | No       | Optional visual style object controlling palette and rendering details (grid, legend, line/bar/pie style knobs). See [Style options](#style-options).                      |

### The `data` argument

The `data` field carries strict, instructive guidance to the agent because the shape is enforced on the server. This is the verbatim `Field` description:

```text theme={null}
List of data points. Each point's label MUST use the literal key 'name' — even
when the label is a category, month, area, etc. Do NOT use 'category', 'label',
'x', or the axis title as the key; always 'name'. Every other key is a numeric
series.
Single series:   {'name': 'Jan', 'value': 30}
Multiple series: include the same keys on every point and fill missing values
                 with 0, never omit a key — e.g.
                 [{'name': 'Jan', 'Sales': 30, 'Profit': 10},
                  {'name': 'Feb', 'Sales': 45, 'Profit': 20}]
```

### Style options

The optional `style` object (`ChartStyleArgs`) is forwarded to the renderer as data, never code; the frontend applies safe defaults when a field is omitted.

| Field                  | Type                                       | Range       | Description shown to the agent                                                                                     |
| ---------------------- | ------------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------ |
| `palette`              | `array` of `string`                        | hex strings | Optional series color palette as hex strings (e.g. \['#4f46e5', '#0ea5e9']). If empty, frontend defaults are used. |
| `show_grid`            | `boolean \| null`                          | —           | Show chart grid lines.                                                                                             |
| `show_legend`          | `boolean \| null`                          | —           | Show chart legend.                                                                                                 |
| `stroke_width`         | `number \| null`                           | 1 to 6      | Line stroke width for line charts.                                                                                 |
| `bar_radius`           | `integer \| null`                          | 0 to 16     | Corner radius for bar charts.                                                                                      |
| `line_curve`           | `"monotone" \| "linear" \| "step" \| null` | —           | Curve interpolation for line charts.                                                                               |
| `tick_font_size`       | `integer \| null`                          | 10 to 18    | Font size for axis tick labels.                                                                                    |
| `label_font_size`      | `integer \| null`                          | 10 to 18    | Font size for axis titles and legend labels.                                                                       |
| `pie_inner_radius_pct` | `integer \| null`                          | 0 to 80     | Inner radius percent for pie charts (0 for full pie, greater than 0 for donut).                                    |
| `pie_outer_radius_pct` | `integer \| null`                          | 30 to 95    | Outer radius percent for pie charts.                                                                               |
| `show_value_labels`    | `boolean \| null`                          | —           | Show point/slice labels directly on chart marks.                                                                   |

**Returns:** a `(content, artifact)` tuple. The `content` is a confirmation for the agent, e.g. `Created a line chart titled 'Revenue' with 4 data points. It is now displayed in the artifact panel.`, which becomes the `summary` of the envelope. The `artifact` is persisted into the `artifacts` table (tagged with the per-turn index) by the decorator and emitted on the SSE stream as a dedicated `artifact` event, which updates the centre panel live. Its shape is:

```json theme={null}
{
  "artifact_type": "<line|bar|pie>_chart",
  "title": "<title>",
  "payload": {
    "title": "<title>",
    "description": "<subtitle>",
    "data": [ { "name": "Q1", "value": 30 } ],
    "x_axis_title": "<x label>",
    "y_axis_title": "<y label>",
    "style": { }
  }
}
```

**Validation and failure:** the tool validates the data shape strictly and fails loudly rather than guessing. It raises (which the decorator turns into a `{"success": false, "error": ...}` envelope so the agent can retry) when:

* `chart_type` is not one of `line`, `bar`, `pie`;
* `data` is empty;
* any point is not an object, or is missing the literal `name` key.

When `description` is empty, the tool synthesises a subtitle (e.g. `Line chart over 4 data points.`). The `style` object is coerced to a plain dict with `None` fields dropped before persistence.

**Implementation:** normalises every point (stringifying each `name`), builds the `artifact_type` as `f"{chart_type}_chart"`, and returns the tuple; persistence and streaming are handled by the decorator and the SSE layer, not the tool body. Source: [`backend/app/tools/charts.py`](https://github.com/petrosrapto/HAICO/blob/main/backend/app/tools/charts.py).
