// cancel_order.js
export async function handle(input, ctx) {
const token = `cancel_order_${input.order_id}`;
// Turn 2: try the gate first. If the user has already confirmed, proceed.
const approval = await ctx.tools.commit_action({
commit_token: token,
side_effect: `cancel order #${input.order_id}, refund $${input.amount}`,
});
if (approval.ok) {
// Gate passed — the user clicked Confirm. Do the real work.
const res = await fetch(
`https://api.example.com/orders/${input.order_id}/cancel`,
{ method: 'POST' }
);
const data = await res.json();
return { cancelled: true, refund_id: data.refund_id, amount: input.amount };
}
// Turn 1: no prior approval exists yet — show the confirmation card.
await ctx.tools.confirm_action({
title: 'Cancel order?',
description: `This will cancel order #${input.order_id} and issue a $${input.amount} refund. This cannot be undone.`,
action_label: 'Cancel order',
cancel_label: 'Keep order',
destructive: true,
commit_token: token,
});
// Returns immediately. The UI shows the card; the LLM waits.
// When the user clicks, the server persists the choice.
// The LLM then calls this tool again — and hits the approval.ok branch above.
return { asked: true };
}