@invergent/website-widget 2.7.4 → 2.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -18
- package/dist/agent-ia0JiKMG.d.cts +174 -0
- package/dist/agent-ia0JiKMG.d.ts +174 -0
- package/dist/chunk-MAUJDM7P.js +700 -0
- package/dist/chunk-MAUJDM7P.js.map +1 -0
- package/dist/index.cjs +22 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -173
- package/dist/index.d.ts +4 -173
- package/dist/index.js +1 -691
- package/dist/index.js.map +1 -1
- package/dist/surogates-widget.global.js +221 -9
- package/dist/surogates-widget.global.js.map +1 -1
- package/dist/ui.cjs +1254 -0
- package/dist/ui.cjs.map +1 -0
- package/dist/ui.d.cts +67 -0
- package/dist/ui.d.ts +67 -0
- package/dist/ui.js +556 -0
- package/dist/ui.js.map +1 -0
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -46,29 +46,57 @@ pnpm add @invergent/website-widget @ag-ui/client @ag-ui/core rxjs
|
|
|
46
46
|
|
|
47
47
|
`@ag-ui/client`, `@ag-ui/core`, and `rxjs` are **peer dependencies** -- they likely already exist in your app's bundle (especially if you're using CopilotKit or another AG-UI consumer), so we don't duplicate them.
|
|
48
48
|
|
|
49
|
-
###
|
|
49
|
+
### Drop-in widget (`<script>` tag)
|
|
50
50
|
|
|
51
|
-
For plain HTML sites without a bundler,
|
|
51
|
+
For plain HTML sites without a bundler, load the IIFE build from a CDN and
|
|
52
|
+
call `mount()`. One call renders a complete, self-contained chat widget — a
|
|
53
|
+
floating launcher button that opens a streaming chat panel, fully isolated in
|
|
54
|
+
a Shadow DOM so it can't collide with your site's CSS. The bundle includes
|
|
55
|
+
AG-UI, RxJS, and the UI:
|
|
52
56
|
|
|
53
57
|
```html
|
|
54
|
-
<script src="https://cdn.
|
|
58
|
+
<script src="https://cdn.jsdelivr.net/npm/@invergent/website-widget@2/dist/surogates-widget.global.js"></script>
|
|
55
59
|
<script>
|
|
56
|
-
|
|
60
|
+
SurogatesWidget.mount({
|
|
57
61
|
apiUrl: 'https://agent.acme.com',
|
|
58
62
|
publishableKey: 'surg_wk_...',
|
|
63
|
+
// Optional appearance:
|
|
64
|
+
// title: 'Acme Support',
|
|
65
|
+
// accentColor: '#4f46e5',
|
|
66
|
+
// welcomeMessage: 'Hi! How can I help?',
|
|
67
|
+
// position: 'bottom-right',
|
|
59
68
|
});
|
|
60
|
-
|
|
61
|
-
agent.subscribe({
|
|
62
|
-
onTextMessageContentEvent: ({ event }) => document.body.append(event.delta),
|
|
63
|
-
onRunFinishedEvent: () => console.log('done'),
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
agent.addMessage({ role: 'user', content: 'hello' });
|
|
67
|
-
agent.runAgent();
|
|
68
69
|
</script>
|
|
69
70
|
```
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
`mount(config)` returns a `WidgetHandle` — `{ open(), close(), toggle(),
|
|
73
|
+
destroy(), agent }` — for programmatic control.
|
|
74
|
+
|
|
75
|
+
| Option | Type | Notes |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| `apiUrl` | string, required | Base URL of the Surogates API. |
|
|
78
|
+
| `publishableKey` | string, required | `surg_wk_...` key. Safe to embed in browser JS. |
|
|
79
|
+
| `title` | string | Header label. Defaults to the deployed agent's name. |
|
|
80
|
+
| `accentColor` | string | Brand colour (hex) for the launcher/header/bubbles. |
|
|
81
|
+
| `welcomeMessage` | string | Greeting shown before the first turn (Markdown). |
|
|
82
|
+
| `position` | `'bottom-right'` \| `'bottom-left'` | Launcher corner. Default `bottom-right`. |
|
|
83
|
+
| `target` | `HTMLElement` | Host element. Defaults to `document.body`. |
|
|
84
|
+
| `inline` | boolean | Render the panel inline (no floating launcher). |
|
|
85
|
+
| `openByDefault` | boolean | Open the panel on load. |
|
|
86
|
+
|
|
87
|
+
The IIFE also exposes the headless `WebsiteAgent`, `EventType`,
|
|
88
|
+
`AbstractAgent`, the error classes, and the `Translator` on
|
|
89
|
+
`window.SurogatesWidget` for hosts that want to build their own UI.
|
|
90
|
+
|
|
91
|
+
#### Bundler consumers
|
|
92
|
+
|
|
93
|
+
If you build your own React/Vue app, import the headless client from the
|
|
94
|
+
package root, or the self-mounting UI from the `./ui` subpath:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { mount } from '@invergent/website-widget/ui';
|
|
98
|
+
mount({ apiUrl: 'https://agent.acme.com', publishableKey: 'surg_wk_...' });
|
|
99
|
+
```
|
|
72
100
|
|
|
73
101
|
## API
|
|
74
102
|
|
|
@@ -160,11 +188,15 @@ Measured on the current build:
|
|
|
160
188
|
|
|
161
189
|
| Target | Raw | Gzipped |
|
|
162
190
|
|---|---|---|
|
|
163
|
-
| ESM (`dist/index.js`) |
|
|
164
|
-
|
|
|
165
|
-
| IIFE (`dist/surogates-widget.global.js`) |
|
|
166
|
-
|
|
167
|
-
The npm
|
|
191
|
+
| ESM headless (`dist/index.js` + chunk) | ~23 KB | **~6 KB** |
|
|
192
|
+
| ESM widget UI (`dist/ui.js`) | 16 KB | **~5 KB** |
|
|
193
|
+
| IIFE (`dist/surogates-widget.global.js`) | 178 KB | **~49 KB** |
|
|
194
|
+
|
|
195
|
+
The npm headless numbers exclude AG-UI, RxJS, and zod (peer deps); the headless
|
|
196
|
+
entry stays Preact-free. The `./ui` build bundles Preact (peers still external).
|
|
197
|
+
The IIFE bundles everything (AG-UI + RxJS + Preact + UI) for script-tag users and
|
|
198
|
+
is built with `platform: 'browser'` so transitive deps resolve to their
|
|
199
|
+
Web-Crypto variants rather than Node's `require('crypto')`.
|
|
168
200
|
|
|
169
201
|
## Versioning
|
|
170
202
|
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { AbstractAgent, AgentConfig, RunAgentInput, BaseEvent } from '@ag-ui/client';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* HTTP + SSE wire layer.
|
|
6
|
+
*
|
|
7
|
+
* Pure functions that talk to the website channel's three endpoints,
|
|
8
|
+
* isolated here so :class:`WebsiteAgentClient` can stay focused on
|
|
9
|
+
* state-machine orchestration. All fetches use ``credentials:
|
|
10
|
+
* 'include'`` so the browser sends the HttpOnly session cookie that
|
|
11
|
+
* ``bootstrap`` set -- without it the message/SSE/end routes return
|
|
12
|
+
* 401 and the whole channel falls apart.
|
|
13
|
+
*
|
|
14
|
+
* SSE is handled by the native ``EventSource`` rather than a custom
|
|
15
|
+
* fetch-based parser because the native implementation is zero bytes,
|
|
16
|
+
* auto-reconnects on network drops, and respects browser-internal
|
|
17
|
+
* backoff heuristics. The one thing it can't do is resume with a
|
|
18
|
+
* server-side cursor, so we manage the ``?after=N`` reopen logic
|
|
19
|
+
* explicitly in :class:`WebsiteAgentClient`.
|
|
20
|
+
*/
|
|
21
|
+
interface BootstrapResult {
|
|
22
|
+
sessionId: string;
|
|
23
|
+
csrfToken: string;
|
|
24
|
+
expiresAt: number;
|
|
25
|
+
agentName: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* AG-UI ``AbstractAgent`` implementation for the Surogates public-website channel.
|
|
30
|
+
*
|
|
31
|
+
* A ``WebsiteAgent`` bridges the channel-specific HTTP protocol
|
|
32
|
+
* (publishable-key bootstrap, HttpOnly cookie, CSRF double-submit,
|
|
33
|
+
* ``/v1/website/sessions/{id}/events`` SSE) onto AG-UI's standard
|
|
34
|
+
* ``run()`` contract so any AG-UI-aware host app -- CopilotKit,
|
|
35
|
+
* custom chat UIs, LangGraph-style clients -- can talk to a Surogates
|
|
36
|
+
* backend with no custom glue beyond instantiation.
|
|
37
|
+
*
|
|
38
|
+
* Responsibilities
|
|
39
|
+
* ----------------
|
|
40
|
+
* * **Lazy bootstrap.** The first ``runAgent`` call POSTs to
|
|
41
|
+
* ``/v1/website/sessions`` to exchange the publishable key for a
|
|
42
|
+
* session cookie + CSRF token; subsequent calls reuse them. A cookie
|
|
43
|
+
* expiry (HTTP 401) triggers a transparent re-bootstrap so the host
|
|
44
|
+
* app never has to manage auth state.
|
|
45
|
+
*
|
|
46
|
+
* * **Message → POST.** On each ``runAgent`` call the agent finds the
|
|
47
|
+
* latest user message in ``input.messages`` and posts its content to
|
|
48
|
+
* ``/v1/website/sessions/{id}/messages`` with the CSRF header.
|
|
49
|
+
*
|
|
50
|
+
* * **SSE → AG-UI.** The channel's native event stream is converted
|
|
51
|
+
* to AG-UI events by :class:`Translator` frame-by-frame. The agent
|
|
52
|
+
* opens a fresh EventSource per run (with ``?after=<cursor>`` to
|
|
53
|
+
* skip already-processed frames) and closes it after a short grace
|
|
54
|
+
* drain on turn completion so trailing server frames (late
|
|
55
|
+
* ``memory.update``, ``session.done``) advance the cursor rather
|
|
56
|
+
* than replaying on the next run.
|
|
57
|
+
*
|
|
58
|
+
* * **RUN lifecycle.** AG-UI requires every run to be bracketed by
|
|
59
|
+
* ``RUN_STARTED`` and exactly one of ``RUN_FINISHED`` / ``RUN_ERROR``.
|
|
60
|
+
* Surogates has no such sentinel on the wire, so the agent emits
|
|
61
|
+
* them itself; a per-run ``terminated`` flag guarantees at most one
|
|
62
|
+
* terminal event even under concurrent SSE ``onerror`` + translator
|
|
63
|
+
* end-of-turn detection.
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Constructor config for :class:`WebsiteAgent`. Extends AG-UI's
|
|
68
|
+
* base ``AgentConfig`` with the two Surogates-specific fields the
|
|
69
|
+
* bootstrap needs; everything else (``agentId``, ``threadId``,
|
|
70
|
+
* ``initialMessages``, ``initialState``, ``debug``) is inherited
|
|
71
|
+
* unchanged so consumers reuse the AG-UI patterns they already know.
|
|
72
|
+
*/
|
|
73
|
+
interface WebsiteAgentConfig extends AgentConfig {
|
|
74
|
+
/** Base URL of the Surogates API, e.g. ``https://agent.acme.com``. */
|
|
75
|
+
apiUrl: string;
|
|
76
|
+
/** Publishable key issued by ops (``surg_wk_...``). */
|
|
77
|
+
publishableKey: string;
|
|
78
|
+
}
|
|
79
|
+
declare class WebsiteAgent extends AbstractAgent {
|
|
80
|
+
readonly apiUrl: string;
|
|
81
|
+
readonly publishableKey: string;
|
|
82
|
+
/** Cached bootstrap result. ``undefined`` until the first ``run()``. */
|
|
83
|
+
private bootstrapResult;
|
|
84
|
+
/** Monotonic cursor across runs. Passed to the SSE ``?after=`` param. */
|
|
85
|
+
private cursor;
|
|
86
|
+
constructor(config: WebsiteAgentConfig);
|
|
87
|
+
/**
|
|
88
|
+
* Ensure we have a live session cookie + CSRF token.
|
|
89
|
+
*
|
|
90
|
+
* Idempotent; returns the cached result when one already exists.
|
|
91
|
+
* ``bootstrap()`` is the only call that requires the publishable
|
|
92
|
+
* key to travel in an Authorization header, so callers that want
|
|
93
|
+
* to eagerly validate their configuration (e.g. to surface a
|
|
94
|
+
* setup error at widget-load time) can invoke this directly.
|
|
95
|
+
*/
|
|
96
|
+
ensureBootstrapped(): Promise<BootstrapResult>;
|
|
97
|
+
/**
|
|
98
|
+
* Close the current session on the server side and drop local state.
|
|
99
|
+
*
|
|
100
|
+
* Callers should invoke this when the visitor closes the chat UI
|
|
101
|
+
* so the server can mark the session complete instead of waiting
|
|
102
|
+
* for the idle-reset timer. Safe to call when no session has been
|
|
103
|
+
* bootstrapped yet.
|
|
104
|
+
*/
|
|
105
|
+
end(): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Implementation of the AG-UI ``run()`` contract.
|
|
108
|
+
*
|
|
109
|
+
* Returns a cold observable: one subscription per run. AG-UI's
|
|
110
|
+
* ``runAgent`` pipeline pipes this through chunk transformation,
|
|
111
|
+
* verification, and subscriber notifications before updating
|
|
112
|
+
* ``this.messages``.
|
|
113
|
+
*/
|
|
114
|
+
run(input: RunAgentInput): Observable<BaseEvent>;
|
|
115
|
+
/**
|
|
116
|
+
* Async body of the observable factory.
|
|
117
|
+
*
|
|
118
|
+
* Emits ``RUN_STARTED`` up front so every downstream failure is
|
|
119
|
+
* well-bracketed by the AG-UI lifecycle. ``RUN_FINISHED`` is
|
|
120
|
+
* emitted by the SSE listeners when the translator detects end-of-
|
|
121
|
+
* turn; ``RUN_ERROR`` is emitted from the catch below when bootstrap
|
|
122
|
+
* or message-send fails before the SSE has any chance to close out.
|
|
123
|
+
*
|
|
124
|
+
* The ``ctx.terminated`` guard is the single enforcement point for
|
|
125
|
+
* AG-UI's "exactly one terminal event" invariant. Every emission
|
|
126
|
+
* site checks it before calling ``subscriber.next`` with RUN_FINISHED
|
|
127
|
+
* or RUN_ERROR, and every terminal call sets it to true first.
|
|
128
|
+
*/
|
|
129
|
+
private driveRun;
|
|
130
|
+
/**
|
|
131
|
+
* Tear down whatever EventSource is currently live on ``ctx`` and
|
|
132
|
+
* open a fresh one against *sessionId* starting at *after*. Called
|
|
133
|
+
* both for the initial stream and after cookie recovery. Always
|
|
134
|
+
* clears the stale ``onerror`` first so the old source can't race
|
|
135
|
+
* a ``RUN_ERROR`` into the subscriber after it's been replaced.
|
|
136
|
+
*/
|
|
137
|
+
private replaceStreamSource;
|
|
138
|
+
/**
|
|
139
|
+
* Try ``sendMessage``; on auth failure re-bootstrap once and retry.
|
|
140
|
+
*
|
|
141
|
+
* The re-bootstrap mints a new session id, so the caller passes an
|
|
142
|
+
* ``onRebootstrap`` callback that reopens the SSE stream against the
|
|
143
|
+
* fresh session before the retry. Visitor continuity across
|
|
144
|
+
* bootstraps is a deliberate non-feature for v1; the new session
|
|
145
|
+
* starts empty. Only frames emitted on the OLD session between
|
|
146
|
+
* SSE-open and send-failure are lost -- and those are always
|
|
147
|
+
* previous-turn events, since the current turn's ``sendMessage`` is
|
|
148
|
+
* what 401-ed.
|
|
149
|
+
*/
|
|
150
|
+
private sendWithCookieRecovery;
|
|
151
|
+
/**
|
|
152
|
+
* Wire up the EventSource to translate and forward every frame,
|
|
153
|
+
* and terminate the observable when the translator flags
|
|
154
|
+
* end-of-turn or a transport failure occurs.
|
|
155
|
+
*
|
|
156
|
+
* After the translator flips end-of-turn we emit ``RUN_FINISHED``
|
|
157
|
+
* immediately, then keep the stream open for ``DRAIN_WINDOW_MS``
|
|
158
|
+
* so trailing frames (late ``memory.update``, the sentinel
|
|
159
|
+
* ``session.done``) advance ``this.cursor`` rather than arriving
|
|
160
|
+
* on the next run. The ``ctx.terminated`` gate stops additional
|
|
161
|
+
* subscriber emissions during the drain.
|
|
162
|
+
*/
|
|
163
|
+
private attachStreamListeners;
|
|
164
|
+
/**
|
|
165
|
+
* Find the last user-authored message body to post. AG-UI supports
|
|
166
|
+
* multimodal content arrays; this v1 only handles string content
|
|
167
|
+
* (the website channel's ``POST /messages`` endpoint accepts plain
|
|
168
|
+
* text). Multimodal support lands once the server grows a media
|
|
169
|
+
* upload path.
|
|
170
|
+
*/
|
|
171
|
+
private extractUserText;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export { WebsiteAgent as W, type WebsiteAgentConfig as a };
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { AbstractAgent, AgentConfig, RunAgentInput, BaseEvent } from '@ag-ui/client';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* HTTP + SSE wire layer.
|
|
6
|
+
*
|
|
7
|
+
* Pure functions that talk to the website channel's three endpoints,
|
|
8
|
+
* isolated here so :class:`WebsiteAgentClient` can stay focused on
|
|
9
|
+
* state-machine orchestration. All fetches use ``credentials:
|
|
10
|
+
* 'include'`` so the browser sends the HttpOnly session cookie that
|
|
11
|
+
* ``bootstrap`` set -- without it the message/SSE/end routes return
|
|
12
|
+
* 401 and the whole channel falls apart.
|
|
13
|
+
*
|
|
14
|
+
* SSE is handled by the native ``EventSource`` rather than a custom
|
|
15
|
+
* fetch-based parser because the native implementation is zero bytes,
|
|
16
|
+
* auto-reconnects on network drops, and respects browser-internal
|
|
17
|
+
* backoff heuristics. The one thing it can't do is resume with a
|
|
18
|
+
* server-side cursor, so we manage the ``?after=N`` reopen logic
|
|
19
|
+
* explicitly in :class:`WebsiteAgentClient`.
|
|
20
|
+
*/
|
|
21
|
+
interface BootstrapResult {
|
|
22
|
+
sessionId: string;
|
|
23
|
+
csrfToken: string;
|
|
24
|
+
expiresAt: number;
|
|
25
|
+
agentName: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* AG-UI ``AbstractAgent`` implementation for the Surogates public-website channel.
|
|
30
|
+
*
|
|
31
|
+
* A ``WebsiteAgent`` bridges the channel-specific HTTP protocol
|
|
32
|
+
* (publishable-key bootstrap, HttpOnly cookie, CSRF double-submit,
|
|
33
|
+
* ``/v1/website/sessions/{id}/events`` SSE) onto AG-UI's standard
|
|
34
|
+
* ``run()`` contract so any AG-UI-aware host app -- CopilotKit,
|
|
35
|
+
* custom chat UIs, LangGraph-style clients -- can talk to a Surogates
|
|
36
|
+
* backend with no custom glue beyond instantiation.
|
|
37
|
+
*
|
|
38
|
+
* Responsibilities
|
|
39
|
+
* ----------------
|
|
40
|
+
* * **Lazy bootstrap.** The first ``runAgent`` call POSTs to
|
|
41
|
+
* ``/v1/website/sessions`` to exchange the publishable key for a
|
|
42
|
+
* session cookie + CSRF token; subsequent calls reuse them. A cookie
|
|
43
|
+
* expiry (HTTP 401) triggers a transparent re-bootstrap so the host
|
|
44
|
+
* app never has to manage auth state.
|
|
45
|
+
*
|
|
46
|
+
* * **Message → POST.** On each ``runAgent`` call the agent finds the
|
|
47
|
+
* latest user message in ``input.messages`` and posts its content to
|
|
48
|
+
* ``/v1/website/sessions/{id}/messages`` with the CSRF header.
|
|
49
|
+
*
|
|
50
|
+
* * **SSE → AG-UI.** The channel's native event stream is converted
|
|
51
|
+
* to AG-UI events by :class:`Translator` frame-by-frame. The agent
|
|
52
|
+
* opens a fresh EventSource per run (with ``?after=<cursor>`` to
|
|
53
|
+
* skip already-processed frames) and closes it after a short grace
|
|
54
|
+
* drain on turn completion so trailing server frames (late
|
|
55
|
+
* ``memory.update``, ``session.done``) advance the cursor rather
|
|
56
|
+
* than replaying on the next run.
|
|
57
|
+
*
|
|
58
|
+
* * **RUN lifecycle.** AG-UI requires every run to be bracketed by
|
|
59
|
+
* ``RUN_STARTED`` and exactly one of ``RUN_FINISHED`` / ``RUN_ERROR``.
|
|
60
|
+
* Surogates has no such sentinel on the wire, so the agent emits
|
|
61
|
+
* them itself; a per-run ``terminated`` flag guarantees at most one
|
|
62
|
+
* terminal event even under concurrent SSE ``onerror`` + translator
|
|
63
|
+
* end-of-turn detection.
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Constructor config for :class:`WebsiteAgent`. Extends AG-UI's
|
|
68
|
+
* base ``AgentConfig`` with the two Surogates-specific fields the
|
|
69
|
+
* bootstrap needs; everything else (``agentId``, ``threadId``,
|
|
70
|
+
* ``initialMessages``, ``initialState``, ``debug``) is inherited
|
|
71
|
+
* unchanged so consumers reuse the AG-UI patterns they already know.
|
|
72
|
+
*/
|
|
73
|
+
interface WebsiteAgentConfig extends AgentConfig {
|
|
74
|
+
/** Base URL of the Surogates API, e.g. ``https://agent.acme.com``. */
|
|
75
|
+
apiUrl: string;
|
|
76
|
+
/** Publishable key issued by ops (``surg_wk_...``). */
|
|
77
|
+
publishableKey: string;
|
|
78
|
+
}
|
|
79
|
+
declare class WebsiteAgent extends AbstractAgent {
|
|
80
|
+
readonly apiUrl: string;
|
|
81
|
+
readonly publishableKey: string;
|
|
82
|
+
/** Cached bootstrap result. ``undefined`` until the first ``run()``. */
|
|
83
|
+
private bootstrapResult;
|
|
84
|
+
/** Monotonic cursor across runs. Passed to the SSE ``?after=`` param. */
|
|
85
|
+
private cursor;
|
|
86
|
+
constructor(config: WebsiteAgentConfig);
|
|
87
|
+
/**
|
|
88
|
+
* Ensure we have a live session cookie + CSRF token.
|
|
89
|
+
*
|
|
90
|
+
* Idempotent; returns the cached result when one already exists.
|
|
91
|
+
* ``bootstrap()`` is the only call that requires the publishable
|
|
92
|
+
* key to travel in an Authorization header, so callers that want
|
|
93
|
+
* to eagerly validate their configuration (e.g. to surface a
|
|
94
|
+
* setup error at widget-load time) can invoke this directly.
|
|
95
|
+
*/
|
|
96
|
+
ensureBootstrapped(): Promise<BootstrapResult>;
|
|
97
|
+
/**
|
|
98
|
+
* Close the current session on the server side and drop local state.
|
|
99
|
+
*
|
|
100
|
+
* Callers should invoke this when the visitor closes the chat UI
|
|
101
|
+
* so the server can mark the session complete instead of waiting
|
|
102
|
+
* for the idle-reset timer. Safe to call when no session has been
|
|
103
|
+
* bootstrapped yet.
|
|
104
|
+
*/
|
|
105
|
+
end(): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Implementation of the AG-UI ``run()`` contract.
|
|
108
|
+
*
|
|
109
|
+
* Returns a cold observable: one subscription per run. AG-UI's
|
|
110
|
+
* ``runAgent`` pipeline pipes this through chunk transformation,
|
|
111
|
+
* verification, and subscriber notifications before updating
|
|
112
|
+
* ``this.messages``.
|
|
113
|
+
*/
|
|
114
|
+
run(input: RunAgentInput): Observable<BaseEvent>;
|
|
115
|
+
/**
|
|
116
|
+
* Async body of the observable factory.
|
|
117
|
+
*
|
|
118
|
+
* Emits ``RUN_STARTED`` up front so every downstream failure is
|
|
119
|
+
* well-bracketed by the AG-UI lifecycle. ``RUN_FINISHED`` is
|
|
120
|
+
* emitted by the SSE listeners when the translator detects end-of-
|
|
121
|
+
* turn; ``RUN_ERROR`` is emitted from the catch below when bootstrap
|
|
122
|
+
* or message-send fails before the SSE has any chance to close out.
|
|
123
|
+
*
|
|
124
|
+
* The ``ctx.terminated`` guard is the single enforcement point for
|
|
125
|
+
* AG-UI's "exactly one terminal event" invariant. Every emission
|
|
126
|
+
* site checks it before calling ``subscriber.next`` with RUN_FINISHED
|
|
127
|
+
* or RUN_ERROR, and every terminal call sets it to true first.
|
|
128
|
+
*/
|
|
129
|
+
private driveRun;
|
|
130
|
+
/**
|
|
131
|
+
* Tear down whatever EventSource is currently live on ``ctx`` and
|
|
132
|
+
* open a fresh one against *sessionId* starting at *after*. Called
|
|
133
|
+
* both for the initial stream and after cookie recovery. Always
|
|
134
|
+
* clears the stale ``onerror`` first so the old source can't race
|
|
135
|
+
* a ``RUN_ERROR`` into the subscriber after it's been replaced.
|
|
136
|
+
*/
|
|
137
|
+
private replaceStreamSource;
|
|
138
|
+
/**
|
|
139
|
+
* Try ``sendMessage``; on auth failure re-bootstrap once and retry.
|
|
140
|
+
*
|
|
141
|
+
* The re-bootstrap mints a new session id, so the caller passes an
|
|
142
|
+
* ``onRebootstrap`` callback that reopens the SSE stream against the
|
|
143
|
+
* fresh session before the retry. Visitor continuity across
|
|
144
|
+
* bootstraps is a deliberate non-feature for v1; the new session
|
|
145
|
+
* starts empty. Only frames emitted on the OLD session between
|
|
146
|
+
* SSE-open and send-failure are lost -- and those are always
|
|
147
|
+
* previous-turn events, since the current turn's ``sendMessage`` is
|
|
148
|
+
* what 401-ed.
|
|
149
|
+
*/
|
|
150
|
+
private sendWithCookieRecovery;
|
|
151
|
+
/**
|
|
152
|
+
* Wire up the EventSource to translate and forward every frame,
|
|
153
|
+
* and terminate the observable when the translator flags
|
|
154
|
+
* end-of-turn or a transport failure occurs.
|
|
155
|
+
*
|
|
156
|
+
* After the translator flips end-of-turn we emit ``RUN_FINISHED``
|
|
157
|
+
* immediately, then keep the stream open for ``DRAIN_WINDOW_MS``
|
|
158
|
+
* so trailing frames (late ``memory.update``, the sentinel
|
|
159
|
+
* ``session.done``) advance ``this.cursor`` rather than arriving
|
|
160
|
+
* on the next run. The ``ctx.terminated`` gate stops additional
|
|
161
|
+
* subscriber emissions during the drain.
|
|
162
|
+
*/
|
|
163
|
+
private attachStreamListeners;
|
|
164
|
+
/**
|
|
165
|
+
* Find the last user-authored message body to post. AG-UI supports
|
|
166
|
+
* multimodal content arrays; this v1 only handles string content
|
|
167
|
+
* (the website channel's ``POST /messages`` endpoint accepts plain
|
|
168
|
+
* text). Multimodal support lands once the server grows a media
|
|
169
|
+
* upload path.
|
|
170
|
+
*/
|
|
171
|
+
private extractUserText;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export { WebsiteAgent as W, type WebsiteAgentConfig as a };
|