@promptjuggler/browser is the client for streaming: it opens the
SSE connection, speaks the whole protocol — segments, resets, resume, staleness — and
hands you one maintained text per run. Everything in the package is safe to ship to an
end user’s browser; it authenticates with a thread-scoped credential and never sees your
API key.
Installation
fetch + ReadableStream) and in Node.js 22+.
The credential flow
Your backend mints the credential with a server SDK and returns it verbatim; the browser hands it togetToken. That one function is the entire auth story:
Your backend (Node example)
Browser
Events
The one flag that matters is
gapped: when a terminal event carries gapped: true,
the streamed text is (or may be) incomplete — fetch the run through your backend for the
authoritative result. When it is false, the text you rendered is the full output and no
fetch is needed — with one edge for raw-event consumers: a gap arriving after a clean
done retroactively proves that text incomplete (as in the sample above). The React hook
folds all of this into runs[runId].gapped, which is why it is the recommended surface.
Reconnection is automatic — exponential backoff after failures, immediate when the
server hands the connection off during a deploy — and resumes exactly where it left off.
disconnect() stops everything.
React
runs[runId] is { text, channel, status: 'streaming' | 'done' | 'failed', gapped?, error? } — render text and you have a chatbot. The options object is read through a
ref, so inline literals never cause reconnects; only the deps array does.
Angular
The same surface as signals, for Angular 17+:stream.connected and stream.runs are signals holding the same shapes as the React
hook. Reactivity follows Angular’s grain: any signal read during the factory call —
here threadId, hoisted into a local — is tracked, and changing it drops the old
subscription (and its runs) and connects a fresh one. Reads deferred into getToken
happen after tracking ends, so hoist them as above. Call it in an injection context
(a field initializer or constructor); the subscription disconnects when the component is
destroyed. Signals-only, so it works in zoneless applications.
Workflows
Every prompt node of a workflow streams into the same connection, keyed byrunId and
tagged with its channel. Follow only the
user-facing lanes with channels: ['support'].
See the chatbot guide for the full end-to-end walkthrough.