---
title: Research tables
description: Optional. Tables whose rows agents find and whose cells they fill from sources. 6 tools.
group: tables
tools: [tables.list, tables.read, tables.build, tables.add_row, tables.research_rows, tables.accept_cell]
source: [packages/agents/src/tools/features.ts]
generated: true
---

> Roadstar docs for agents. Every page, as markdown: https://docs.roadstar.app/llms.txt

Optional research tools. A research table is built by agents that find its rows and fill each cell from a source. Building and researching rows cost money by the row, so both are always checked.

For the business's own lists, such as a month of hours, use a Google Sheet through [files](/tools/files/) or a spreadsheet in the [workspace](/tools/workspace/).

## How to use it

What `find_tools` sends with these tools, word for word:

> Research tables: agents find rows and fill each cell from a source. Builds cost money; Pro estimates the cost first.

## Tools

| Tool | What it does | Owner's yes |
| --- | --- | --- |
| [tables.list](#list) | Tables | No |
| [tables.read](#read) | A table's columns, rows and cell values | No |
| [tables.build](#build) | Plan and build a new table, in the project the owner names, else the one you file into. It costs money by the row | Checked |
| [tables.add_row](#add_row) | Add a row by the columns that identify it | No |
| [tables.research_rows](#research_rows) | Research some rows again. It costs money by the row | Checked |
| [tables.accept_cell](#accept_cell) | Accept a value waiting for review | Checked |

## list

`tables.list` · Tables.

**Owner's yes:** No. Nothing of the owner's changes.

| Input | Type | Required | Limits |
| --- | --- | --- | --- |
| `projectId` | id | no |  |

Returns:

```ts
{
  id: string;
  name: string;
  question: string;
  projects: {
    id: string;
    name: string;
  }[];
  row: string;
  columns: number;
  updatedAt: string;
  run: {
    id: string;
    kind: DatasetRunKind;
    status: DatasetRunStatus;
    estimateUsd: number;
    capUsd: number;
    spentUsd: number;
    rowsTotal: number;
    rowsDone: number;
    message: string | null;
    createdAt: string;
    completedAt: string | null;
  } | null;
}[]
```

## read

`tables.read` · A table's columns, rows and cell values.

**Owner's yes:** No. Nothing of the owner's changes.

| Input | Type | Required | Limits |
| --- | --- | --- | --- |
| `datasetId` | id | yes |  |

Returns:

```ts
{
  dataset: {
    id: string;
    projects: {
      id: string;
      name: string;
    }[];
    name: string;
    question: string;
    plan: {
      row: string;
      rule: string;
      queries: string[];
      columns: {
        name: string;
        label: string;
        type: "number" | "date" | "text" | "choice" | "rating" | "yes_no";
        unit: string | null;
        options: string[] | null;
        instructions: string;
        identifies: boolean;
      }[];
    };
    createdAt: string;
    agentId: string | null;
    spentUsd: number;
    run: {
      id: string;
      kind: DatasetRunKind;
      status: DatasetRunStatus;
      estimateUsd: number;
      capUsd: number;
      spentUsd: number;
      rowsTotal: number;
      rowsDone: number;
      message: string | null;
      createdAt: string;
      completedAt: string | null;
    } | null;
  };
  rows: StoredRow[];
}
```

## build

`tables.build` · Plan and build a new table, in the project the owner names, else the one you file into. It costs money by the row.

**Owner's yes:** Checked. It carries a note for the check to weigh, such as a cost.\
**Your work:** listed on Home.

| Input | Type | Required | Limits |
| --- | --- | --- | --- |
| `projectId` | id | no |  |
| `question` | text | yes | 1–2,000 characters |
| `maxRows` | whole number | no | 1–250, default 25 |

Returns:

```ts
{
  id: string;
  projects: {
    id: string;
    name: string;
  }[];
  name: string;
  question: string;
  plan: {
    row: string;
    rule: string;
    queries: string[];
    columns: {
      name: string;
      label: string;
      type: "number" | "date" | "text" | "choice" | "rating" | "yes_no";
      unit: string | null;
      options: string[] | null;
      instructions: string;
      identifies: boolean;
    }[];
  };
  createdAt: string;
  agentId: string | null;
  spentUsd: number;
  run: {
    id: string;
    kind: DatasetRunKind;
    status: DatasetRunStatus;
    estimateUsd: number;
    capUsd: number;
    spentUsd: number;
    rowsTotal: number;
    rowsDone: number;
    message: string | null;
    createdAt: string;
    completedAt: string | null;
  } | null;
}
```

## add_row

`tables.add_row` · Add a row by the columns that identify it.

**Owner's yes:** No. It makes something new.\
**Your work:** listed on Home.

| Input | Type | Required | Limits |
| --- | --- | --- | --- |
| `datasetId` | id | yes |  |
| `identity` | named values of text | yes |  |

Returns:

```ts
{
  key: string;
}
```

## research_rows

`tables.research_rows` · Research some rows again. It costs money by the row.

**Owner's yes:** Checked. It changes what's there. It can also carry a note for the check to weigh.\
**Your work:** listed on Home.

| Input | Type | Required | Limits |
| --- | --- | --- | --- |
| `datasetId` | id | yes |  |
| `rowKeys` | list of text | yes | 1–250 items |

Returns:

```ts
{
  id: string;
  projects: {
    id: string;
    name: string;
  }[];
  name: string;
  question: string;
  plan: {
    row: string;
    rule: string;
    queries: string[];
    columns: {
      name: string;
      label: string;
      type: "number" | "date" | "text" | "choice" | "rating" | "yes_no";
      unit: string | null;
      options: string[] | null;
      instructions: string;
      identifies: boolean;
    }[];
  };
  createdAt: string;
  agentId: string | null;
  spentUsd: number;
  run: {
    id: string;
    kind: DatasetRunKind;
    status: DatasetRunStatus;
    estimateUsd: number;
    capUsd: number;
    spentUsd: number;
    rowsTotal: number;
    rowsDone: number;
    message: string | null;
    createdAt: string;
    completedAt: string | null;
  } | null;
}
```

## accept_cell

`tables.accept_cell` · Accept a value waiting for review.

**Owner's yes:** Checked. It changes what's there.\
**Your work:** listed on Home.

| Input | Type | Required | Limits |
| --- | --- | --- | --- |
| `datasetId` | id | yes |  |
| `key` | text | yes |  |
| `column` | text | yes |  |

Returns:

```ts
{ done: true }
```

## Types

Named types in the results above.

```ts
type DatasetRunKind = "build" | "rerun"

type DatasetRunStatus = "stopped" | "done" | "queued" | "running" | "failed"

type StoredRow = {
  key: string;
  values: {
    [x: string]: CellValue;
  };
  sources: {
    [x: string]: CellSource;
  };
}

type CellValue = string | number | null

type CellSource = {
  status: "failed" | "filled" | "needs_review" | "not_disclosed" | "edited";
  quote?: QuoteRef;
  url?: string;
  agree?: number;
  from?: string;
  human?: true;
  was?: {
    value: CellValue;
    source: CellSource | null;
  };
}

type QuoteRef = {
  page: string;
  start: number;
  end: number;
}
```
