# Make an action consequential

> Have the assistant ring an action for the user to press, or ask in the panel before it presses.

A consequential action is one whose effect the user should own. Pick one of two shapes with the `consequential` prop.

## Ring it for the user to press

Pass `consequential`. When the assistant calls the action, the element is scrolled into view with a ring around it and the label above or below it. The user presses it, or dismisses the ring. From `examples/app/app/orders/[id]/page.tsx`:

```tsx
<AssistedAction name="refund_order" label="Refund this order" consequential>
  <Button
    variant="destructive"
    disabled={!refundable}
    onClick={() => shop.call("refundOrder", [order.id])}
  >
    Refund
  </Button>
</AssistedAction>
```

The model sees the action marked "(consequential)". Its call answers `Rang "<label>" for the user; pressing it is theirs.` A disabled or missing element answers so, and nothing rings.

## Ask in the panel, then press

Pass `consequential="confirm"`. When the assistant calls the action, the panel shows a card with the label and **Approve** and **Deny**. On approval the action is pressed. A denial is final for that call. From `examples/app/app/orders/page.tsx`:

<!-- prettier-ignore -->
```tsx
<AssistedAction
  name="cancel_order"
  id={order.id}
  label={`Cancel ${order.customer}'s order #${order.id}`}
  consequential="confirm"
>
  <Button
    size="sm"
    variant="outline"
    onClick={() => shop.call("cancelOrder", [order.id])}
  >
    Cancel
  </Button>
</AssistedAction>
```

The model sees the action marked "(asks first)". In a group, the card asks about the one row the assistant picked. The element is checked again after approval, in case it left or became disabled while the card waited.

The card is the package's [confirm card](https://superassist.app/components/cards/confirm-card.md). After the answer it stays in the conversation as a receipt: Finished or Denied. To render it your own way, see [Swap a card](https://superassist.app/how-to/swap-a-card.md).

## Ask before a tool runs

A tool has no element to ring. `consequential: true` on `useAssistedTool` asks in the panel and runs `execute` only on approval:

```tsx
export function Refund({ refund }: { refund: () => Promise<void> }) {
  useAssistedTool("refund_order", {
    description: "Refund this order.",
    parameters: { type: "object", properties: {} },
    consequential: true,
    execute: async () => {
      await refund();
      return "Refunded the order.";
    },
  });
  return null;
}
```

The card shows the tool's description.

## Ring an element from your own code

`useRing` returns a function that rings an element. The ring leaves when the component unmounts:

```tsx
export function WhereToSave() {
  const ringAt = useRing();
  const save = useRef<HTMLButtonElement>(null);
  return (
    <>
      <Button ref={save}>Save</Button>
      <Button
        variant="ghost"
        onClick={() => save.current && ringAt(save.current, { message: "Save is here" })}
      >
        Where do I save?
      </Button>
    </>
  );
}
```

`ring(element, { message })` does the same outside React and returns a function that dismisses it.
