@pluno/product-agent-web
v0.1.291
Published
Browser SDK and default widget for embedding Pluno Product Agent into customer web apps.
Readme
Pluno Product Agent Web SDK
Stack-agnostic browser SDK and default widget for embedding Product Agent into customer webapps.
Install
npm install @pluno/product-agent-webKeep your Product Agent secret_key on your server. Browser code should only receive a short-lived session token, or call your own authenticated token endpoint.
Host-rendered chat notices
The default widget handle exposes host. Hosts may append presentation-only elements with
slot="bottom-notices" (account, authentication, connection or device notices above the composer) or
slot="conversation-notices" (conversation-local notices inline). Remove these elements when their
existing owner clears the notice; the slots do not store state or decide eligibility. The main-web React
shell uses portals into these slots. Do not use them as a second transcript or interaction owner.
Headless SDK
import { PlunoProductAgent } from "@pluno/product-agent-web";
const agent = await PlunoProductAgent.init({
tokenProvider: async ({ signal } = {}) => {
const response = await fetch("/api/pluno-product-agent-token", {
method: "POST",
credentials: "include",
signal,
});
const payload = await response.json();
return payload.token;
},
});
agent.on("state", (state) => {
renderYourOwnChatUi(state);
});
agent.sendMessage("Update my settings");The SDK captures passive resource URL/timing metadata with PerformanceObserver and adds bounded method, header, status, and small textual body metadata through shared fetch/XMLHttpRequest instrumentation. Capture is best effort and detached from host requests: streaming, unknown-length, large, upload, token, Pluno, and internal bodies are not read, captured values are capped and redacted, and the instrumentation is removed after the final SDK instance is destroyed.
Drop-In Widget
<script
type="module"
src="https://app.pluno.ai/product-agent/product-agent-widget.js"
data-pluno-token-endpoint="/api/pluno-product-agent-token"
data-pluno-launcher-label="Ask for anything..."
data-pluno-accent-color="#7c3aed"
data-pluno-font-family='Inter, system-ui, sans-serif'
data-pluno-scribble-style="false"
></script>Scribble style is enabled by default. Set data-pluno-scribble-style="false" in the snippet, or scribbleStyle: false
for programmatic mounts, to use the standard widget appearance.
The floating widget launcher includes a minimize control by default. Its compact state survives reloads in the
current tab, while a new tab or browser session starts with the regular launcher. Programmatic mounts can set
showLauncherMinimizeButton: false to hide it.
This script-tag setup is the recommended integration. If your token endpoint needs custom browser-side authentication, import the same hosted widget module and provide the request logic programmatically:
const { mountPlunoProductAgentWidget } = await import(
"https://app.pluno.ai/product-agent/product-agent-widget.js"
);
const widget = await mountPlunoProductAgentWidget({
tokenProvider: async ({ signal } = {}) => {
const response = await fetch("/api/pluno-product-agent-token", {
method: "POST",
credentials: "include",
signal,
headers: {
Authorization: `Bearer ${customerAccessToken}`,
"X-CSRF-Token": csrfToken,
"X-Tenant-ID": tenantId,
},
});
if (!response.ok) throw new Error("Could not create Pluno session token");
return (await response.json()).token;
},
});
function removeProductAgentWidget() {
widget.destroy();
}The SDK keeps a valid JWT in memory, refreshes it shortly before expiry, and automatically retries transient provider
failures with capped backoff. Pass the supplied abort signal to your request so destroying the widget cancels it.
Generic provider failures are treated as transient; throw ProductAgentTokenProviderError with retryable: false for a
known permanent host-side validation or authorization failure, for example
new ProductAgentTokenProviderError("Not authorized", false, 403).
Importing the hosted module does not mount anything by itself. mountPlunoProductAgentWidget returns a handle containing
the underlying agent, openPanel(), appearance/auth update methods, and destroy().
The token endpoint must be implemented by the customer backend. It should authenticate the current user, then call Pluno's /api/product-agent/embed/token endpoint with:
public_keysecret_keyorigin- optional
metadata, includingmetadata.user_idwhen the customer has a stable user id - optional
context
