Skip to content

Cancellation ​

V1 uses different mechanisms for policy blocking, stream cancellation, approval rejection, and runtime failure. Keep them distinct so callers can handle each outcome correctly.

1. Block model input with a guardrail ​

Use an enforcing input guardrail when application policy should stop the request before a provider call:

ts
import {
  defineGuardrailPolicy,
  defineInputGuardrail,
} from '@anvia/core'

const environmentPolicy = defineGuardrailPolicy({
  id: 'environment-policy',
  input: [
    defineInputGuardrail({
      id: 'agent-runs-enabled',
      check(_context, actions) {
        if (deployment.agentRunsDisabled) {
          return actions.block({
            reason: 'agent_runs_disabled',
            message: 'Agent requests are temporarily unavailable.',
          })
        }

        return actions.allow()
      },
    }),
  ],
})

const agent = new Agent({
  id: 'support',
  model,
  guardrails: environmentPolicy,
})

An enforced input block completes with the safe block message and records guardrail decisions; it does not masquerade as a provider failure.

2. Stop a normal stream ​

When a browser aborts a normal createClientStreamResponse() response, the server closes the event iterator. Closing an active AgentStream cancels its run.

ts
const controller = new AbortController()

fetch('/api/chat', {
  method: 'POST',
  body: JSON.stringify(requestBody),
  signal: controller.signal,
})

controller.abort()

With useChat, call chat.stop(). See Streaming errors and cancellation.

3. Reject a pending tool approval ​

ts
const pending = await agent.generate({
    prompt: message
})

if (pending.type === 'interaction' && pending.interaction.type === 'tool-approval') {
  const result = await agent.resume(
    pending.continuation,
    {
      type: 'tool-approval',
      approved: false,
      reason: 'The reviewer rejected this operation.',
    },
  )
}

Rejection prevents that protected tool call from executing and lets the runtime continue with the rejection result.

4. Understand the limit ​

Observers receive cancellation as an explicit terminal error with status: 'cancelled', while other failures use status: 'failed'. On process shutdown, abort and await the active run before closing Lens, Langfuse, or OpenTelemetry. Closing the provider first can lose the still-open root observation.

Stopping a run prevents future model turns and tool calls. It cannot undo completed writes or external side effects. Write tools still need authorization, idempotency, transactions where appropriate, and audit records.

Use original error types for provider, tool, validation, and timeout failures. Do not relabel operational failures as policy cancellation.

Next, configure tool approval.

Built for Anvia.