Edit before run
Shows what the agent is about to do with every value editable, so you can fix one detail and approve instead of starting over.
Loading preview…
Install
- 1
Run this command in your Tailwind CSS project. It adds
components/ai/edit-before-run-action.tsxand installs its dependencies.$ npx shadcn@latest add https://gradientdeck.com/ai-components/r/edit-before-run-action.json
Usage & API
Example
import { EditableEmail } from "@/components/ai/edit-before-run-action"
<EditableEmail
draft={draft}
value={value}
onChange={() => {}}
status={status}
onSend={() => {}}
onCancel={() => {}}
from="…"
/>Props EditableEmail
| Prop | Type & description | Required |
|---|---|---|
draft | EmailFieldsWhat the agent wrote. Used for the edited markers, Reset and the diff. | Required |
value | EmailFields | Required |
onChange | (next: EmailFields) => void | Required |
status | DraftStatus | Required |
onSend | () => void | Required |
onCancel | () => void | Required |
onUndo | () => voidUndo a send or a discard while it's still possible. | Optional |
undoLeft | numberSeconds left to undo a send. Hidden at 0. | Optional |
from | string | Required |
sentAt | stringShown on the receipt, e.g. "10:42". | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
The email card is labeled Draft from the address you pass. Each row is To, Cc, Subject, Message or Files, with a reset on any row that differs from the proposal and a dot to show it changed. Add a recipient and Add someone are the placeholders. No files attached shows when the list is empty. Send stays disabled until there is a recipient and a subject. If anything changed, the button reads Send with changes. Ctrl Enter sends from the message. Sending shows a spinner. After it goes, Undo counts down. Discard is the cancel path, and it can be undone the same way.
Example
import { ToolArguments } from "@/components/ai/edit-before-run-arguments"
<ToolArguments
tool={tool}
fields={[]}
proposed={proposed}
value={value}
onChange={() => {}}
status={status}
onRun={() => {}}
onSkip={() => {}}
/>Props ToolArguments
| Prop | Type & description | Required |
|---|---|---|
tool | ToolInfo | Required |
fields | ArgField[] | Required |
proposed | Args | Required |
value | Args | Required |
onChange | (next: Args) => void | Required |
status | RunStatus | Required |
onRun | (mode: "edited" | "proposed") => void | Required |
onSkip | () => void | Required |
onReview | () => void | Optional |
result | ReactNodeWhat happened, shown once the call finishes. | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
The arguments card names the tool and can show an effect chip. A tab list, Edit as, switches Form and JSON, and the arrow keys move between them. Form rows show the key, the kind, the current value and a reset to the proposed value. A number out of range, an empty string, or an object that fails its check is marked, and the run button stays disabled while any error remains. JSON can be copied. Run as proposed is offered when nothing changed. Otherwise the run uses the edited values. Skip leaves the call not run, and Review again brings a skipped call back. A finished call says it ran with your changes or as proposed, and lists the keys that differed.
Choosing a layout
Use the email when the side effect is a message a person should read in full before it goes out. Use the arguments card when the side effect is a structured tool call and the person thinks in field names, or sometimes in the raw object. The form and JSON tabs are the same values, so a broken JSON blob cannot switch back to the form until it parses.
A yes-or-no on a proposal, without editing every field, is the decision inbox. A bundle of dates and amounts the agent still needs is the generative form. Edit before run starts from a complete draft. If the run already failed, run recovery is the place to change the input of the step that broke.
Can the person restore a single field without losing the other edits?
Yes. Reset on a row copies that field from the proposed draft and leaves the rest. The arguments form does the same per key. There is no control that reverts the whole card in one step other than running as proposed, which only exists when nothing has been edited.
Does the model see the secret or the email body from this card?
The card only edits the values you gave it and returns them through onSend or onRun. It does not talk to a model. What you do with the edited fields after that is outside the component.