# useAssistedTool

> Lends a tool that runs in the browser, scoped to its page under an AssistedPage and global elsewhere.

`useAssistedTool` lends a tool that runs in the browser: a page's tool under an `AssistedPage`, listed in its note and gone with it, or a global tool anywhere else.

![Orders beside the sheet panel, filtered to the three orders waiting to ship. The expanded filter_orders call answers Showing the orders that are to ship.](https://superassist.app/_astro/tool-light.D1lOcMrU.webp)

## Usage

Call it in a component under the page. From `examples/app/app/orders/page.tsx`:

```tsx
useAssistedTool("filter_orders", {
  description: "Show only the orders with one status, or all of them.",
  parameters: {
    type: "object",
    properties: { status: { type: "string", enum: filters } },
    required: ["status"],
  },
  execute: ({ status }: { status: Filter }) => {
    setFilter(status);
    return `Showing ${status === "all" ? "all orders" : `the orders that are ${status}`}.`;
  },
});
```

## What the model sees

The tool's `description` and its parameters' JSON Schema, here `status`, one of `all`, `to ship`, `shipped` and `cancelled`. As a page's tool it is named in the Orders note:

```md wrap
Its tools: filter_orders, get_page_content.
```

The call in the screenshot answered with what `execute` returned:

```txt wrap
Showing the orders that are to ship.
```

## States

### A global tool

![The sheet panel on Customers. The expanded get_shop_summary call answers with the shop's order and customer counts.](https://superassist.app/_astro/tool-global-light.DlQKNVhG.webp)

The example's shell lends `get_shop_summary` outside every `AssistedPage`, so it works from any page and no note names it. From `examples/app/app/shell.tsx`:

```tsx
useAssistedTool("get_shop_summary", {
  description: "How many orders and customers the shop has. Works from any page.",
  parameters: { type: "object", properties: {} },
  execute: () => ({ orders: shop.orders.length, customers: shop.customers.length }),
});
```

It answered on Customers with `{ "orders": 8, "customers": 4 }`.

## Signature

```ts
useAssistedTool<TArgs extends Record<string, unknown>, TResult>(
  name: string,
  tool: AssistedTool<TArgs, TResult>,
): void
```

| `AssistedTool` field | Type                                             | Required | Description                                                                                                     |
| -------------------- | ------------------------------------------------ | -------- | --------------------------------------------------------------------------------------------------------------- |
| `description`        | `string`                                         | Yes      | What the tool does, for the model.                                                                              |
| `parameters`         | JSON Schema object or Standard Schema            | Yes      | The arguments. A Standard Schema such as zod types `execute`'s arguments.                                       |
| `execute`            | `(args, context) => TResult \| Promise<TResult>` | Yes      | Runs the call. `context` is the call's execution context: `toolCallId`, `abortSignal` and `human`.              |
| `toModelOutput`      | `({ toolCallId, input, output }) => parts`       | No       | What the model sees in place of the result: `text` parts and `file` parts with base64 `data` and a `mediaType`. |
| `render`             | `ToolCallMessagePartComponent`                   | No       | Tool UI for the call in the thread. Pass a stable component.                                                    |
| `consequential`      | `boolean`                                        | No       | `true` asks in the panel before `execute` runs.                                                                 |
| `question`           | `(args) => string`                               | No       | With `consequential`, the card's question for this call.                                                        |

- Under an `AssistedPage`, the tool belongs to the page and the note lists it. Elsewhere it is global and no note lists it.
- The tool is lent on mount and leaves on unmount. It is lent again when `description` or the parameters' JSON Schema changes.
- `execute` always runs the latest closure.
- A throw answers `{ error: "<name> failed: <message>" }`.
- Arguments the schema rejects answer `{ error: "<name> got arguments its parameters reject: <issues>" }`.
- With `toModelOutput`, the result still shows in the thread, and its images show under it, while the model gets the parts. Over 4 files, or a file over 5 MB, answers `{ error }` instead. A model that takes no files gets the text parts and a line counting the files it missed.
- With `consequential`, the description gains ` (asks first)`. The panel's card shows `question(args)`, or the description without one. A denial answers with the decline text and `execute` does not run.
- With `consequential` and no `render`, the [Confirm card](https://superassist.app/components/cards/confirm-card.md), or `cards.confirm` on the provider, renders the call inline, outside the tool group. A `render` of your own replaces it and must answer the pause with `resume({ approved: boolean })`.

`AssistedToolFailure` is `{ error: string }`.

## See also

- [Lend a tool](https://superassist.app/how-to/lend-a-tool.md).
- [How model context composes](https://superassist.app/explanation/model-context.md).
