Skip to content

Embedding: an agent on your own site ​

Put a chat with an Agentfy agent on a page you own. The visitor needs no account here, installs nothing, and never leaves your site.

This section is written for the person doing the installing — someone with a website and an agent, not someone with this repository.

What embedding actually is ​

Three participants, and only the middle one is new:

visitor's browser  ──►  the hub  ──►  the agent
   your page            one port      runs a turn
   one <script>         WebSocket     answers back
  • The visitor's browser loads a small widget from a script tag on your page.
  • The hub is the one address that browser talks to. By default the hub is the Agentfy api itself, on a port of its own — so a normal installation needs no second service. See What you need on the server.
  • The agent is yours: the same agent you talk to in the cabinet, with the same instructions and the same knowledge.

The connection is a WebSocket, and the answer arrives token by token — the visitor watches the reply appear rather than waiting for it.

Three ways in ​

All three talk to the same hub and the same agent. They differ only in how much of the interface is yours.

1. A script tag, and a floating bubble ​

One block pasted into your page template. A button appears in the bottom-right corner; pressing it opens the chat. Nothing to build, nothing to install — this works on a WordPress theme and on hand-written HTML alike.

html
<script>
  (function () {
    var sdk = document.createElement('script')
    sdk.src = 'https://bridle.cleanslice.org/sdk/latest.js'
    sdk.onload = function () {
      window.Bridle.init({
        apiUrl: 'https://hub.example.com',
        agentId: 'agent-…',
        token: '<the ticket from the cabinet>',
        mode: 'floating',
        title: 'Support',
      })
    }
    document.head.appendChild(sdk)
  })()
</script>

Copy it from the cabinet, not from here

The cabinet assembles this block for you — the agent's screen «Сайт», the Copy button. What it gives you is slightly longer: it adds the function that exchanges the page's ticket for a per-visitor one, so that two people who open your site do not end up in one conversation. That difference matters and is explained under Two kinds of ticket.

2. A package in your build ​

If your site has a build — Vite, Next, Nuxt, Webpack — the widget installs as a package and is called from code. That buys you two things the script tag cannot give: the chat can be mounted into a specific place on the page instead of hanging in a corner, and the token can be a function, which is asked again on every reconnect.

bash
npm i @cleanslice/bridle
ts
import { init } from '@cleanslice/bridle'

init({
  apiUrl: import.meta.env.VITE_HUB_URL,
  agentId: 'agent-…',
  token: () => fetch('/api/agent-token').then((r) => r.json()).then((t) => t.token),
  mount: '#chat',
  mode: 'inline',
  title: 'Support',
})

3. Your own interface, over the client ​

You can skip the shipped widget entirely. The client gives you a connection and events — typing, a piece of the answer arrived, the answer is finished — and what it all looks like is your markup. This is how a chat goes into an interface that is already designed: a support panel, a product card, a mobile app.

ts
import { BridleClient } from '@cleanslice/bridle'

const client = new BridleClient({ apiUrl, agentId, token })

client.on('typing', () => showTypingIndicator())
client.on('stream', (m) => renderPartial(m.text))
client.on('stream_end', (m) => commit(m.text))
client.on('message', (m) => commit(m.text))
client.on('error', (e) => showError(e.code))

await client.connect()
client.send('Hello')

All three run side by side on one page in the demo.

What the visitor sees ​

A chat window with your agent's name on it. They type; a typing indicator appears; the answer streams in. Nothing identifies them to us, and nothing about them is asked for.

What they do not see is as deliberate as what they do:

  • not the reasoning, and not the steps the agent took;
  • not the tools it called, nor what those tools returned;
  • not the agent's other conversations — theirs is a thread of its own.

The widget renders inside a shadow root, so your site's CSS cannot leak into it and its CSS cannot leak into your site.

What it will not do, and why ​

An external conversation is deliberately narrower than the owner's own. By default the agent answering your visitors has no hands, writes nothing to its long-term memory, and cannot re-time its own scheduled work. Every one of those can be lifted, one at a time, by the agent's owner — and each is worth understanding before it is.

That is Boundaries and rights, and it is the page to read before you open anything.

Partner identity and payer specification ​

The proposed v1 design supports both organization-paid and team-paid teams. Read identity and user journeys, provisioning and payer contracts, and migration and self-audit. Partner customer access uses organization-scoped actors; it is separate from the existing guest embed, and linking never grants a partner access to direct accounts.