/** * Hello UIAgent — vanilla JS client. * * Wires three pieces of the SDK end to end: * 1. PipecatClient + SmallWebRTCTransport for the voice session. * 2. PipecatClient-managed accessibility snapshot streaming on * every meaningful change (DOM mutations, focus, scroll-end, * resize, visibility, selection). * * The agent has no tools — the snapshot is the entire input. The * server's ``UIAgent`` auto-injects the latest ```` block * into the LLM context at the start of every turn, so the agent * always answers grounded in what's currently on screen. */ import { PipecatClient, RTVIEvent } from "@pipecat-ai/client-js"; import { SmallWebRTCTransport } from "@pipecat-ai/small-webrtc-transport"; const BOT_URL = "http://localhost:7860/api/offer"; const connectButton = document.getElementById("connect"); const status = document.getElementById("status"); const botAudio = document.getElementById("bot-audio"); let client; function setStatus(text, autoHideMs = 0) { status.textContent = text; status.dataset.show = text ? "1" : "0"; if (text && autoHideMs > 0) { setTimeout(() => { if (status.textContent === text) status.dataset.show = "0"; }, autoHideMs); } } async function connect() { connectButton.disabled = true; setStatus("Connecting…"); // 1. Construct the Pipecat client with the WebRTC transport. client = new PipecatClient({ transport: new SmallWebRTCTransport(), enableMic: true, enableCam: false, }); client.on(RTVIEvent.BotConnected, () => setStatus("Bot connected", 1500)); client.on(RTVIEvent.Disconnected, () => { setStatus("Disconnected", 2000); connectButton.dataset.state = ""; connectButton.textContent = "Connect"; connectButton.disabled = false; teardownUI(); }); // Pipe the bot's audio track into the