> For the complete documentation index, see [llms.txt](https://ai.ortusbooks.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ai.ortusbooks.com/main-components/gateway-sessions.md).

# Gateway Sessions

Wire an AiAgent to one or more gateways for inbound message handling with aiGatewaySession() — dispatch policies, queueing, and lifecycle.

`GatewaySession` (via `aiGatewaySession()`) is the orchestrator that turns "a message arrived on a gateway" into "the agent responded, relayed back through that same gateway" — including deciding what happens when a second message arrives on a thread that already has a turn in flight.

## 🚀 Creating a Session

```javascript
session = aiGatewaySession(
    agent   : myAgent,
    gateways: [ "cli", "http" ],   // single gateway or an array — multiple gateways can share one agent
    policy  : "queue"              // "reject" | "queue" | "steer" | "interrupt"
)
session.start()
```

`gateways` entries can be a string name (resolved via `aiGateway( name )` — core names or anything registered in `aiGatewayRegistry()`) or an already-constructed `IGateway` instance (`aiGateway( "http", { secret: "..." } )` when you need to pass configuration options) — mix and match freely.

## 🧭 Dispatch Policies

A second message arriving on a busy thread is handled per a configurable `policy`:

| Policy            | A second message arrives on a busy thread…                                                                                                                                                                                                        |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `reject`          | …is refused immediately; the caller must resend.                                                                                                                                                                                                  |
| `queue` (default) | …is buffered and dispatched right after the current turn finishes.                                                                                                                                                                                |
| `steer`           | …is spliced into the *currently running* turn via `agent.steerRun()` — not a new turn, nothing already produced is lost. This is a non-destructive splice — **not** the same as some other agent frameworks' "steer," which cancels and restarts. |
| `interrupt`       | …asks the current turn to stop via `agent.cancelRun()` (takes effect at its next checkpoint, not instantly), then dispatches the new message next.                                                                                                |

`maxQueueDepth` (default `50`) bounds how many messages can buffer per thread under `queue`/`interrupt` before further messages fall back to an immediate rejection.

## 📡 Delivery

Gateways that declare the `"streaming"` capability get chunk-by-chunk delivery via `deliverChunk()`; others get one buffered `deliver()` call once the turn completes. A gateway that pushes inbound messages (rather than being driven by a request/response cycle) implements `IGateway.onMessage()` to register the session's dispatch callback, and `IGateway.onError()` to be notified if its connection drops unexpectedly rather than requiring a caller to poll.

## 🔎 Lifecycle & Observability

```javascript
session.isRunning()                 // has start() been called, and stop() not since?
session.getActiveThreadIds()        // threads with a turn currently in flight
session.getQueueDepth( threadId )   // how many messages are buffered for a thread
```

Every gateway fires interception points on connect/disconnect and inbound/outbound messages — independent of `GatewaySession`, since a gateway can be used directly (e.g. with `HumanInTheLoopMiddleware`) without one:

```javascript
BoxRegisterInterceptor( ( data ) => {
    log.info( "Message on thread #data.threadId# from user #data.userId#" )
}, "onGatewayMessageReceived" )
```

See [Gateways — Events](/main-components/gateways.md#-events) for the full table.

## Related Pages

* [Gateways](/main-components/gateways.md) — resolving gateways, core gateways, capabilities, building your own
* [Human-in-the-Loop](/main-components/human-in-the-loop.md) — approvals presented through a gateway
* [Agent Run Control](/main-components/agents/run-control.md) — `cancelRun()`/`steerRun()`, the mechanism behind `steer`/`interrupt`
* [aiGatewaySession()](/advanced/reference/built-in-functions/aigatewaysession.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ai.ortusbooks.com/main-components/gateway-sessions.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
