---
title: "Tools"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Tools}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  eval = FALSE
)
```

querychat combines [tool calling](https://ellmer.tidyverse.org/articles/tool-calling.html) with [reactivity](https://shiny.posit.co/r/articles/build/reactivity-overview.html) to not only execute SQL, but also reactively update dependent data views. Understanding how these tools work will help you better understand what querychat is capable of and how to customize/extend its behavior.

One important thing to understand generally about querychat's tools is they are R functions, and that execution happens on _your machine_, not on the LLM provider's side. In other words, the SQL queries generated by the LLM are executed locally in the R process running the app.

querychat provides the LLM access to three tool groups:

1. **Data updating** - Filter and sort data (without sending results to the LLM).
2. **Data analysis** - Calculate summaries and return results for interpretation by the LLM.
3. **Data visualization** - Create charts inline in the chat.

```{r}
library(querychat)
library(palmerpenguins)
```

## Data updating {#data-updating}

When a user asks to "Show me..." or "Filter to..." or "Sort by...", the LLM requests a call to the `update_dashboard` tool with an appropriate SQL query as input. An important constraint is that the query must return all original schema columns (typically using `SELECT *`). When called, querychat will both set a reactive value holding [the current SQL query](build.html#sql-query) and execute the query to get the result. The result of query then used to set a reactive value holding the [filtered/sorted data frame](build.html#filtered-data). Thanks to reactivity, this will automatically update any views depending on this data frame, such as the data table displayed in the UI.

This tool also takes a `title` parameter, which is a short description of the filter/sort operation (e.g., "Adelie penguins"). This, also, is made available through [a reactive value](build.html#title) for display somewhere in your app.

Here's a basic example of this tool in action with the `$app()` method. Notice how this pre-built app not only shows the data table, but also the SQL query and title generated by the LLM (for transparency):

```{r}
querychat_app(penguins)
```

![](../reference/figures/quickstart-filter.png){alt="Screenshot of the querychat's app with the penguins dataset filtered." class="shadow rounded"}

The other data updating tool is `reset_dashboard`, which clears any active filters and returns the data table to its original unfiltered state. The LLM typically uses this when users say "reset", "start over", or "clear filters".

## Data analysis

When a user asks analytical questions like "What is the average...?", "How many...?", or "Which item has the highest...?", the LLM generates a SQL query and requests a call to the `query` tool. Unlike the data updating tools, this tool will not update any reactive values. Instead, it will:

1. Execute the SQL query
2. Display both the SQL query and results in the UI
3. Return the results back to the LLM for interpretation

Here's an example of it in action:

```{r}
querychat_app(penguins)
```

![](../reference/figures/quickstart-summary.png){alt="Screenshot of the querychat's app with a summary statistic inlined in the chat." class="shadow rounded"}

## Data visualization

When a user asks for a chart or visualization, the LLM generates a [ggsql](https://ggsql.org/) query — standard SQL extended with a `VISUALISE` clause — and requests a call to the `visualize` tool.
This tool:

1. Executes the SQL portion of the query
2. Renders the `VISUALISE` clause as an interactive chart
3. Displays the chart inline in the chat

Unlike the data updating tools, visualization queries don't affect the dashboard filter.
They query the full dataset independently, and each call produces a new inline chart message in the chat.

The inline chart includes controls for fullscreen viewing, saving as PNG/SVG, and a "Show Query" toggle that reveals the underlying ggsql code.

To use the visualization tool, first install the ggsql package:

```r
install.packages("ggsql")
```

Then include `"visualize"` in the `tools` parameter (it is not enabled by default):

```{r}
library(palmerpenguins)

qc <- QueryChat$new(
  penguins,
  tools = c("query", "update", "visualize")
)
qc$app()
```

See [Visualizations](visualize.html) for more details.

## View the source

If you'd like to better understand how the tools work and how the LLM is prompted to use them, check out the following resources:

**Source code:**

- [`querychat_tools.R`](https://github.com/posit-dev/querychat/blob/main/pkg-r/R/querychat_tools.R)
- [`querychat_viz.R`](https://github.com/posit-dev/querychat/blob/main/pkg-r/R/querychat_viz.R)

**Prompts:**

- [`prompts/tool-update-dashboard.md`](https://github.com/posit-dev/querychat/blob/main/pkg-r/inst/prompts/tool-update-dashboard.md)
- [`prompts/tool-reset-dashboard.md`](https://github.com/posit-dev/querychat/blob/main/pkg-r/inst/prompts/tool-reset-dashboard.md)
- [`prompts/tool-query.md`](https://github.com/posit-dev/querychat/blob/main/pkg-r/inst/prompts/tool-query.md)
- [`prompts/tool-visualize.md`](https://github.com/posit-dev/querychat/blob/main/pkg-r/inst/prompts/tool-visualize.md)
