# piano-roll-tools

> AI-native tool surface for a piano roll, createPianoRollTools builds typed, agent-agnostic tools (setNotes/addNotes/removeNotes/transpose/clear/setTempo) an LLM calls to compose melodies and basslines from natural language, parameterized by the roll's pitch range and grid

```bash
npx shadcn@latest add @audio-ui/piano-roll-tools
```

```ts
import { clampNoteToDomain, createPianoRollTools } from "@/lib/piano-roll-tools";
```

- Files: `lib/piano-roll-tools.ts`
- Depends on: nothing; npm: `zod`
- Used by: nothing

| Export | Kind | What it is |
| --- | --- | --- |
| `PianoRollNote` | interface | A grid-snapped, pitched note. |
| `NoteInput` | interface | A note as the model supplies it, no id (the tools assign one), length/velocity optional. |
| `PianoRollState` | interface | What the tools read and write, the notes plus the tempo. |
| `clampNoteToDomain` | function | Normalizes a model-supplied note into the roll's domain, the same clamping the primitive does on its controlled value. |
| `PianoRollToolsConfig` | interface |  |
| `createPianoRollTools` | function | Builds the tool set for a specific roll. |
| `PianoRollTools` | type |  |

## Usage

Typed tools an AI model uses to edit a piano roll, through tool calls: adding, moving and deleting notes, each call checked against a schema (zod) and clamped into the roll's range, the notes coming in as values and going out as new ones.

```ts
import { createPianoRollTools } from "@/lib/piano-roll-tools";

const tools = createPianoRollTools({ maxPitch: 84, minPitch: 36 });
// Give tools to your model, then apply what it calls to the notes you hold.
```

The tools change the notes you hold, never the roll directly, so an undo, a playback and the roll follow them as they would a person's edit. See [Piano roll](/docs/components/base/piano-roll).
