Skip to content

Bridle ​

Webchat relay for AI agents. Bridle connects browser users to an agent runtime through a stateless NestJS hub, with a ready-made Nuxt chat UI, an embeddable JS SDK for any site, and an agent-side Socket.IO client.

What it does ​

Bridle is the browser channel for an agent. Think Intercom, but the bot on the other side is your CleanSlice runtime.

Browser (Nuxt)               Bridle Hub (NestJS)           Agent Runtime
     |                             |                             |
     |--- /ws/client --------------->|                             |
     |   auth: { token, agentId }    |--- /ws/agent -------------->|
     |                             |   auth: { apiKey, agentId }   |
     |<--- stream/message ---------|<--- stream/message ---------|
     |   { text, parts[] }         |   { text, parts[] }         |

The hub is stateless — it holds no message history. It routes messages between browsers and agents in real time using Socket.IO. Multiple bots can connect simultaneously, each scoped by agentId.

Highlights ​

  • Stateless hub — horizontal scaling without sticky sessions.
  • Rich parts[] — text, images, files flow end-to-end.
  • Streaming — partial tokens delivered as they arrive.
  • Drop-in embed SDK — one <script> tag adds chat to any site.
  • Nuxt layer — for internal apps, get the full chat UI as a layer.
  • Agent client — Socket.IO repository plugs into the runtime as a channel.

Packages ​

DirectoryWhat it isStack
nestjs/Hub server — WebSocket relay + HTTP fallbackNestJS, Socket.IO, JWT
nuxt/Nuxt layer — chat UI for internal Nuxt appsNuxt 3, Vue 3, shadcn-vue
sdk/Embed SDK — Web Component for any websiteVue 3 (compiled), socket.io-client
runtime/Agent client — connects to the hub as a channelsocket.io-client

Embed in any site ​

html
<script
  src="https://bridle.cleanslice.org/sdk/latest.js"
  data-api-url="https://your-hub.example.com"
  data-agent-id="bot-abc-123"
  data-token="<jwt>"
></script>

Full embed guide: bridle.cleanslice.org/embed/script-tag.

Message parts ​

Every message carries parts: BridlePart[]. A text field is always present as a plain-text shorthand.

ts
{ type: "text",  text: "Hello" }
{ type: "image", base64: "...", mediaType: "image/jpeg" }
{ type: "file",  url: "https://...", name: "doc.pdf", mimeType: "application/pdf" }

Parts flow end-to-end (browser → hub → agent → hub → browser), including over stream and stream_end events.

Add to a CleanSlice project ​

The repo's README ships a Claude Code prompt that wires Bridle into an existing CleanSlice app — copies the slices into api/, app/, and the runtime, sets the env vars, and verifies the round-trip. See the README for the full snippet.

Built with CleanSlice