# Web Transport

Canonical: https://auggy.dev/docs/augment-web-transport
Status: Published
Package: auggy 0.5.0

Serve AG-UI turns, the operator Console, health checks, and runtime discovery.

## Run one agent over HTTP

**What it enables:** Accept agent turns over AG-UI SSE and expose the per-agent Console, health endpoint, and runtime discovery on one port.

- **Status:** Core
- **Availability:** Installed by ``auggy create``.
- **Contributes:** `transport`, `built-in endpoints`, `health`, `Console`

A client posts messages to `/agent/run`; Web Transport authenticates the request, builds the peer identity, runs the kernel turn, and streams AG-UI events until `RUN_FINISHED`.

## Generated install

``auggy create <name>`` adds `webTransport` to `agent.yaml`, writes the metadata below, and generates `AUGGY_WEB_TOKEN`, `AUGGY_AGENT_ID`, and `AUGGY_PUBLIC_URL=http://localhost:8080` in the gitignored `.env`.

**augments/webTransport/augment.yaml**

```yaml
type: webTransport
config:
  port: 8080
  publicIntegration: false
  auth:
    type: bearer
    token: ${AUGGY_WEB_TOKEN}
  visitorTokens:
    agentBinding: ${AUGGY_AGENT_ID}
```

The current YAML resolver forwards `port`, `auth`, `cors`, `maxMessageLength`, `access.agents`, `concurrency`, `maxQueueDepth`, `rateLimitPerPeer`, `visitorTokens`, `allowAnonymous`, and `publicIntegration`. Do not put TypeScript-only Web Transport options in this YAML file; they are not forwarded by the current resolver.

## Stream one authenticated turn

**AG-UI request**

```bash
cd <agent>
set -a
source .env
set +a
auggy dev &

curl -N http://127.0.0.1:8080/agent/run \
  -H "Authorization: Bearer $AUGGY_WEB_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-smoke-1" \
  --data '{"threadId":"docs-smoke","messages":[{"role":"user","content":"Reply with: transport ready"}]}'
```

The response is `text/event-stream`. A valid generated bearer authenticates this request as the creator; the stable `threadId` keeps later turns in the same in-process conversation.

## Runtime surfaces

| Method | Path | Current behavior |
| --- | --- | --- |
| `POST` | `/agent/run` | AG-UI SSE turn endpoint. Body requires a non-empty `messages` array; last message content is used. |
| `GET`, `HEAD` | `/` | Public agent info page. A direct TypeScript caller may instead configure a redirect, but that option is not YAML-resolved. |
| `GET`, `POST` | ``/console``, ``/console`/*` | Operator SPA, chat, dashboard APIs, and Console actions. `HEAD` and other methods return 405. |
| `GET` | `/health` | Public JSON liveness response: `{"status":"healthy"}`. |
| `GET`, `HEAD` | `/agent` | Developer integration page only when `publicIntegration: true`; otherwise 404. `/agent/` redirects to it only in that posture. |
| `GET` | `/.well-known/agent-card.json` | Agent card; public with `publicIntegration: true`, otherwise returned only for the web bearer and hidden as 404 from other callers. |
| `OPTIONS` | Any path | `CORS` preflight; configured origins are emitted when `cors` is present. |

Transport defaults are `maxMessageLength: 4000`, `concurrency: 1`, and `maxQueueDepth: 50`. `visitorTokens` are not active merely because the generated config contains `agentBinding`; Visitor Auth enables recognition and supplies the signing key when installed.

> **Note: Advanced preview route hosting**
>
> Web Transport can also dispatch optional augment-defined HTTP routes. That app-integration surface is documented separately and is not required to run an agent.

## Boundaries

| Area | Boundary |
| --- | --- |
| Trust | A valid web bearer creates a creator turn; a present but invalid bearer always returns 401. Without a bearer, `allowAnonymous` defaults to true outside production and false in production unless YAML, environment, or a persisted Console override says otherwise. |
| Persistence | The transport does not provide durable conversation storage. Thread history is process memory; restart loses it. Console posture overrides can persist locally in `admin-overrides.json`. |
| Deployment | **Railway** requires the generated port `8080`. Secrets come from `.env` through deploy variables, `/health` is the liveness target, and non-loopback Console access requires HTTPS. |
| Limits | The current transport is HTTP plus SSE, not WebSocket. Closing the client stream does not cancel the running turn, and the AG-UI implementation is a focused subset rather than every protocol event. |

> **Warning: Protect the creator bearer**
>
> The generated bearer proves creator authority on `/agent/run`. Console uses HTTP Basic with a blank username and that token as the password; loopback skips the Console bearer check because local shell access already exposes `.env`. Do not expose plain HTTP Console traffic on a non-loopback interface.

## Verify

**Check liveness and discovery posture**

```bash
curl -s http://127.0.0.1:8080/health
curl -i http://127.0.0.1:8080/agent
curl -s -H "Authorization: Bearer $AUGGY_WEB_TOKEN" \
  http://127.0.0.1:8080/.well-known/agent-card.json
```

1. Confirm `/health` returns HTTP 200 and `{"status":"healthy"}`.
2. With the generated `publicIntegration: false`, confirm `/agent` returns 404.
3. Confirm the bearer-authenticated agent-card request returns JSON.
4. Run the AG-UI request above and confirm it emits `RUN_STARTED`, assistant text events, and one terminal `RUN_FINISHED`.
5. Open ``/console/capabilities`` and confirm the expected runtime capabilities are loaded.

## Related

- [Transports](https://auggy.dev/docs/transports/markdown)
- [Console](https://auggy.dev/docs/console/markdown)
- [Deploy and verify](https://auggy.dev/docs/deploy/markdown)
- [Security](https://auggy.dev/docs/security/markdown)