“Stop” is ambiguous after a request crosses an external boundary. We can stop the model from planning more steps, prevent unsubmitted effects, and ask the provider to cancel a pending operation if it supports that. We cannot assume that cancelling a local coroutine or workflow erases a booking already accepted by the provider. AWS's Step Functions integration documentation notes that cancellation of an integrated task can be best effort. Its durable execution guidance says an external side effect may still take effect after an execution stops. The exact semantics depend on the tool and provider.

At message arrival, assign a new conversation intent revision. Fence future submissions from the old plan at the executor. A step that has not been sent checks the current intent revision, approval and action fingerprint before it runs. The old booking submission has a stable operation ID in an effect ledger, with states like prepared, submitted, confirmed, rejected and outcome unknown. Do not turn a timeout into “failed.” Retry a status lookup or reconcile using the provider reference and the same idempotency key if the API supports it. A new plan cannot make a second booking until the first outcome is known or the business has explicitly accepted the risk.

A new user intent fences future steps while the submitted booking is reconciled
New intent fences future steps while the old submission is reconciled.

I would respond to the user with what is known: “I stopped further booking steps. The first hotel request was already sent, and I am checking whether it completed.” That is less comforting than “cancelled,” but it is truthful. If it did complete, show the booking and its cancellation terms, then request a new authorized cancellation or change. Refundable does not mean instant reversal or no fee under every condition. The tool must return the actual provider status and terms.

The new instruction itself may be ambiguous. “Book next week instead” could mean change the existing reservation or make a second reservation after cancellation. Ask before an irreversible replacement if the user has not specified dates or consequences. Preserve the causal order of the two user messages, the proposed action, the submission receipt and the revised intent. If messages arrive through two clients, one durable intent revision should win. An old worker must not commit a new effect merely because it missed the latest chat event.

What if the provider has no idempotency lookup and the network response was lost? That is an explicitly unknown effect. Escalate for reconciliation through a provider dashboard or support path, with an SLA. Do not blindly resubmit a booking. What if the provider supports cancellation? Request it with its own operation ID, then confirm the outcome. A cancellation request can fail too.

The caller says stop while the voice agent is submitting a refund covers a spoken stop during a refund submission. This scenario adds a new user intent and a replacement plan while the earlier effect remains uncertain. Test the timing window before send, after send, after provider commit, and after a lost response. The invariant is that only the current intent can authorize new submissions, while every already submitted effect remains tracked to a terminal or explicitly unresolved state.