For the complete documentation index, see llms.txt. This page is also available as Markdown.

Run Control

Cancel or steer an AiAgent run already in flight with cancelRun() and steerRun(), addressed purely by threadId — no token to construct or wire up.

Every AiAgent supports cancelling or steering a run already in flight — addressed purely by threadId, with nothing extra to construct or thread through your call sites.

🚀 Start a Conversation First

Run control is about an active run. A typical flow is:

  1. Pick or receive a threadId.

  2. Start the agent run with that threadId.

  3. Reuse the same threadId for follow-up turns.

  4. Call cancelRun() or steerRun() if that run needs intervention.

agent = aiAgent(
    name        : "Assistant",
    instructions: "Be concise and helpful"
)

// Pick a stable thread ID for this conversation
threadId = "support-42"

reply1 = agent.run( "Hi, I need help with my invoice", {}, {
    threadId      : threadId,
    userId        : "user-123",
    conversationId: "billing"
} )

// Same conversation thread: reuse the same IDs
reply2 = agent.run( "Can you summarize next steps?", {}, {
    threadId      : threadId,
    userId        : "user-123",
    conversationId: "billing"
} )

If you do not pass options.threadId, the agent auto-generates one per call. That is great for one-off calls, but you cannot target that run later unless you saved that generated ID.

🧵 What Is threadId?

threadId is the execution correlation key for a run.

  • It identifies which in-flight run cancelRun() and steerRun() should target.

  • It links checkpointed/suspended work to the correct thread for resume flows.

  • It can be reused across turns to keep a conversation lane consistent.

Think of it as a conversation lane ID, not a message ID.

🎯 Core Run-Control Calls

🎯 How It Works

Both take effect at the run's next checkpointbeforeLLMCall or beforeToolCall — not instantly. This is deliberate: a run is stopped or redirected between well-defined steps, never mid-flight through a provider call.

  • cancelRun( threadId, reason = "Cancelled by caller." ) stops the run with a terminal AiMiddlewareResult.cancel( reason ).

  • steerRun( threadId, input ) splices a new message into the live request without restarting anything already in progress — nothing already produced is lost.

Both return false as a safe no-op when the given thread has no run currently in flight — there's nothing to check before calling either one.

🛠️ Practical In-Flight Examples

Cancel a running task

Steer a running task without restarting

Steer with a full message struct

✅ Choosing Good Thread IDs

Use IDs that are stable and unique per active conversation.

  • Good: support-42, tenantA-user123-chat9, ticket-9981

  • Avoid: random new ID for every turn (unless intentionally one-shot)

If your app is multi-tenant, include tenant/user dimensions in the thread ID or pair it with userId and conversationId consistently.

📡 Events

onAIAgentRunCancel / onAIAgentRunSteer fire with { agent, threadId, reason, input } — but only when the call actually affects a run in flight, never on the no-op case:

🔌 Powering Gateway Sessions

aiGatewaySession()'s steer and interrupt dispatch policies are built directly on steerRun()/cancelRun() — a GatewaySession calls exactly the same API you can call yourself:

See Gateway Sessions for the full policy table.

Last updated