# AI Reply Composer

> A calm reply composer where an agent drafts in your voice. The draft is plain, editable text; Redraft changes what the reply does, its tone and length. A line the agent proposes waits as ghost text until you press Tab, and the sources it drew on sit one click away. Sends report who wrote how much; an agent at the controls can only request approval.

- Slug: `reply-composer`
- Category: [Email](https://www.assembli.design/category/email.md)
- Type: component
- Tags: email, mail, composer, reply, drafting, agents, ai, streaming
- npm dependencies: lucide-react, motion
- shadcn/ui dependencies: button, dropdown-menu, kbd, @assembli/avatar, @assembli/split-button, @assembli/tooltip
- Live preview: https://www.assembli.design/preview/reply-composer
- Page: https://www.assembli.design/components/reply-composer

![AI Reply Composer preview](https://www.assembli.design/thumbnails/reply-composer-light.png)

## Props

Other props pass through to the root element.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `threadId` (required) | `string` |  |  |
| `subject` (required) | `string` |  |  |
| `to` (required) | `Person[]` |  |  |
| `cc` | `Person[]` |  |  |
| `me` | `Person` | `ME` | The mailbox owner; signs the draft. |
| `intents` (required) | `ReplyIntent[]` |  |  |
| `defaultIntent` | `string` |  |  |
| `defaultTone` | `ReplyTone` | `"warm"` |  |
| `defaultLength` | `ReplyLength` | `"medium"` |  |
| `context` | `ContextSource[]` | `[]` |  |
| `voiceNote` | `string` |  | Shown above the sources, e.g. "Learned from 214 of your sent emails". |
| `draft` | `(request: DraftRequest) => AsyncIterable<string> \| Promise<string>` |  | Your model. Return the whole draft (it is revealed progressively) or stream chunks. Without it the draft is composed from the intent's `body` with `composeDraft`. |
| `actor` | `Actor` | `{ kind: "human", name: ME.name }` | Who is operating the composer. An agent can't send: its Send becomes a request for approval. |
| `agent` | `MailAgent` | `REPLIES` | The agent that writes drafts. |
| `sendLaterOptions` | `SendLaterOption[]` | `LATER` |  |
| `onAction` | `(action: MailAction) => void` |  |  |

## Install

One-time setup (needs a subscription):

1. Add the registry to the project's `components.json`: `{"@assembli":{"url":"https://www.assembli.design/r/{name}.json","headers":{"Authorization":"Bearer ${ASSEMBLI_API_KEY}"}}}` (merge into `"registries"`).
2. Put an API key from https://www.assembli.design/account in `.env.local` as `ASSEMBLI_API_KEY=asm_…`.

Then install with the shadcn CLI (writes `components/reply-composer/reply-composer.tsx` and installs dependencies):

```bash
npx shadcn@latest add @assembli/reply-composer
```

Registry item JSON: https://www.assembli.design/r/reply-composer.json (send `Authorization: Bearer <api key>`)

## Code

> Component source needs an Assembli subscription ($12/month or $96/year) and an API key sent as `Authorization: Bearer <key>`. To get one without copying anything, POST https://www.assembli.design/api/agent/login (or call the MCP tool connect_account), show the user the link it returns, and poll https://www.assembli.design/api/agent/token for the key. Or subscribe at https://www.assembli.design/pricing and create a key at https://www.assembli.design/account.
