@syntrologie/adapt-chatbot 2.8.0-canary.285 → 2.8.0-canary.287
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/dist/AdaptiveChatBarMountable.d.ts.map +1 -1
- package/dist/ChatSession.d.ts +15 -1
- package/dist/ChatSession.d.ts.map +1 -1
- package/dist/ChatTransport.d.ts +18 -0
- package/dist/ChatTransport.d.ts.map +1 -1
- package/dist/runtime.js +29 -5
- package/dist/runtime.js.map +2 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdaptiveChatBarMountable.d.ts","sourceRoot":"","sources":["../src/AdaptiveChatBarMountable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"AdaptiveChatBarMountable.d.ts","sourceRoot":"","sources":["../src/AdaptiveChatBarMountable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,mBAAmB,CAAC;AAyY3B,eAAO,MAAM,wBAAwB;qBAClB,WAAW,gBAAgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI;sBAyC9D,WAAW,gBAAgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAQ5E,CAAC"}
|
package/dist/ChatSession.d.ts
CHANGED
|
@@ -40,9 +40,23 @@ export interface ToolResultEvent {
|
|
|
40
40
|
export type ChatSessionSubscriber = (state: ChatSessionState) => void;
|
|
41
41
|
export type SendListener = (event: {
|
|
42
42
|
text: string;
|
|
43
|
+
activeLidSlot?: string;
|
|
43
44
|
}) => void;
|
|
44
45
|
export type InterruptListener = () => void;
|
|
45
46
|
export type ToolResultListener = (event: ToolResultEvent) => void;
|
|
47
|
+
/** Optional per-send envelope. */
|
|
48
|
+
export interface SendOptions {
|
|
49
|
+
/**
|
|
50
|
+
* The slot the calling chat-bar lives in (e.g. ``"drawer"``,
|
|
51
|
+
* ``"adaptive-chat"``). Forwarded to transport listeners so the
|
|
52
|
+
* outbound request can tag the correct ``X-Active-Lid-Slot`` regardless
|
|
53
|
+
* of which bar most recently configured the singleton transport.
|
|
54
|
+
* Without per-send threading, two coexisting chat-bars race over the
|
|
55
|
+
* transport's cached ``activeLidSlot`` and the user-facing routing
|
|
56
|
+
* silently follows whichever bar configured last.
|
|
57
|
+
*/
|
|
58
|
+
activeLidSlot?: string;
|
|
59
|
+
}
|
|
46
60
|
export type Unsubscribe = () => void;
|
|
47
61
|
export declare const CHAT_SESSION_STORAGE_KEY = "syntro:chat:v1";
|
|
48
62
|
export declare class ChatSession {
|
|
@@ -67,7 +81,7 @@ export declare class ChatSession {
|
|
|
67
81
|
* event so transports can pick it up. Empty/whitespace text is a
|
|
68
82
|
* no-op (matches the chat bar's local guard).
|
|
69
83
|
*/
|
|
70
|
-
send(text: string): void;
|
|
84
|
+
send(text: string, opts?: SendOptions): void;
|
|
71
85
|
/**
|
|
72
86
|
* Single-shot assistant reply (no streaming). Equivalent to
|
|
73
87
|
* receiveStart + receiveDelta + receiveEnd in one call. Useful for
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatSession.d.ts","sourceRoot":"","sources":["../src/ChatSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;AACtE,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatSession.d.ts","sourceRoot":"","sources":["../src/ChatSession.ts"],"names":[],"mappings":"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"}
|
package/dist/ChatTransport.d.ts
CHANGED
|
@@ -151,6 +151,17 @@ export declare class ChatTransport {
|
|
|
151
151
|
private _hasSucceeded;
|
|
152
152
|
/** True once fallback has fired (one-shot). */
|
|
153
153
|
private _fallbackRendered;
|
|
154
|
+
/**
|
|
155
|
+
* Per-send override for ``X-Active-Lid-Slot``. Set in the
|
|
156
|
+
* ``chatSession.onSend`` listener immediately before each
|
|
157
|
+
* ``_forwardUserMessage`` and consumed by ``buildHeaders`` on the
|
|
158
|
+
* outbound request. The singleton transport is shared by every
|
|
159
|
+
* mounted chat-bar (drawer + inline) so cached ``_config.activeLidSlot``
|
|
160
|
+
* follows whichever bar last reconfigured — using that for routing
|
|
161
|
+
* silently misroutes tiles when both bars coexist. Per-send threading
|
|
162
|
+
* pins the header to the bar that actually sent the message.
|
|
163
|
+
*/
|
|
164
|
+
private _pendingLidSlot;
|
|
154
165
|
/** Active debounce timer; null when no debounce pending. */
|
|
155
166
|
private _errorDebounceTimer;
|
|
156
167
|
/** Most recent error payload, captured so debounced fallback can attach it. */
|
|
@@ -200,6 +211,13 @@ export declare class ChatTransport {
|
|
|
200
211
|
* the hasSucceeded gate flips without a real AgUi round-trip.
|
|
201
212
|
*/
|
|
202
213
|
simulateSuccessfulMessage(): void;
|
|
214
|
+
/**
|
|
215
|
+
* Test seam — return the lid slot that the next outbound request
|
|
216
|
+
* WOULD tag ``X-Active-Lid-Slot`` with, given current state. Mirrors
|
|
217
|
+
* the exact resolution buildHeaders uses (per-send slot wins over
|
|
218
|
+
* cached config). Not part of the documented API.
|
|
219
|
+
*/
|
|
220
|
+
getActiveLidSlotForTest(): string | null;
|
|
203
221
|
/**
|
|
204
222
|
* Tear connection-level state down. Used internally by configure()
|
|
205
223
|
* to swap backends; preserves host-registered fallback listeners
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatTransport.d.ts","sourceRoot":"","sources":["../src/ChatTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AASH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,mFAAmF;IACnF,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;IACvF;;;;;;;;;;;;;;OAcG;IACH,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAC3D;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,OAAQ,CAAC;AAE1C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;IAC7C,QAAQ,EAAE,qBAAqB,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;AAwClE,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,sBAAsB,CAA6B;IAC3D,OAAO,CAAC,uBAAuB,CAA6B;IAC5D,OAAO,CAAC,gBAAgB,CAAiC;IACzD,iFAAiF;IACjF,OAAO,CAAC,0BAA0B,CAAuB;IACzD,yCAAyC;IACzC,OAAO,CAAC,kBAAkB,CAAwB;IAClD,8DAA8D;IAC9D,OAAO,CAAC,kBAAkB,CAAK;IAC/B,4EAA4E;IAC5E,OAAO,CAAC,aAAa,CAAS;IAC9B,+CAA+C;IAC/C,OAAO,CAAC,iBAAiB,CAAS;IAClC,4DAA4D;IAC5D,OAAO,CAAC,mBAAmB,CAA8C;IACzE,+EAA+E;IAC/E,OAAO,CAAC,iBAAiB,CAKT;IAChB,OAAO,CAAC,kBAAkB,CAA+B;IACzD;;;;;OAKG;IACH,OAAO,CAAC,YAAY,CAAkD;IACtE,OAAO,CAAC,aAAa,CAAK;IAE1B;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAwB5C,yEAAyE;IACzE,OAAO,CAAC,MAAM;IAId,qFAAqF;IACrF,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,qCAAqC;IACrC,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;;;OAKG;IACH,UAAU,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAOlD;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,GAAG,IAAI;IAIR;;;OAGG;IACH,yBAAyB,IAAI,IAAI;IAMjC;;;;;OAKG;IACH,OAAO,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"ChatTransport.d.ts","sourceRoot":"","sources":["../src/ChatTransport.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime.js
CHANGED
|
@@ -73,13 +73,15 @@ var ChatSession = class {
|
|
|
73
73
|
* event so transports can pick it up. Empty/whitespace text is a
|
|
74
74
|
* no-op (matches the chat bar's local guard).
|
|
75
75
|
*/
|
|
76
|
-
send(text) {
|
|
76
|
+
send(text, opts) {
|
|
77
77
|
const trimmed = text.trim();
|
|
78
78
|
if (!trimmed) return;
|
|
79
79
|
this._messages.push({ id: this._nextId++, role: "user", text: trimmed });
|
|
80
80
|
this._inFlight = true;
|
|
81
81
|
this.notify();
|
|
82
|
-
|
|
82
|
+
const event = { text: trimmed };
|
|
83
|
+
if (opts?.activeLidSlot) event.activeLidSlot = opts.activeLidSlot;
|
|
84
|
+
for (const listener of this.sendListeners) listener(event);
|
|
83
85
|
}
|
|
84
86
|
/**
|
|
85
87
|
* Single-shot assistant reply (no streaming). Equivalent to
|
|
@@ -311,6 +313,17 @@ var ChatTransport = class {
|
|
|
311
313
|
this._hasSucceeded = false;
|
|
312
314
|
/** True once fallback has fired (one-shot). */
|
|
313
315
|
this._fallbackRendered = false;
|
|
316
|
+
/**
|
|
317
|
+
* Per-send override for ``X-Active-Lid-Slot``. Set in the
|
|
318
|
+
* ``chatSession.onSend`` listener immediately before each
|
|
319
|
+
* ``_forwardUserMessage`` and consumed by ``buildHeaders`` on the
|
|
320
|
+
* outbound request. The singleton transport is shared by every
|
|
321
|
+
* mounted chat-bar (drawer + inline) so cached ``_config.activeLidSlot``
|
|
322
|
+
* follows whichever bar last reconfigured — using that for routing
|
|
323
|
+
* silently misroutes tiles when both bars coexist. Per-send threading
|
|
324
|
+
* pins the header to the bar that actually sent the message.
|
|
325
|
+
*/
|
|
326
|
+
this._pendingLidSlot = null;
|
|
314
327
|
/** Active debounce timer; null when no debounce pending. */
|
|
315
328
|
this._errorDebounceTimer = null;
|
|
316
329
|
/** Most recent error payload, captured so debounced fallback can attach it. */
|
|
@@ -390,6 +403,15 @@ var ChatTransport = class {
|
|
|
390
403
|
this._messagesSucceeded += 1;
|
|
391
404
|
this._clearDebounceTimer();
|
|
392
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* Test seam — return the lid slot that the next outbound request
|
|
408
|
+
* WOULD tag ``X-Active-Lid-Slot`` with, given current state. Mirrors
|
|
409
|
+
* the exact resolution buildHeaders uses (per-send slot wins over
|
|
410
|
+
* cached config). Not part of the documented API.
|
|
411
|
+
*/
|
|
412
|
+
getActiveLidSlotForTest() {
|
|
413
|
+
return this._pendingLidSlot ?? this._config?.activeLidSlot ?? null;
|
|
414
|
+
}
|
|
393
415
|
/**
|
|
394
416
|
* Tear connection-level state down. Used internally by configure()
|
|
395
417
|
* to swap backends; preserves host-registered fallback listeners
|
|
@@ -427,6 +449,7 @@ var ChatTransport = class {
|
|
|
427
449
|
this._hasSucceeded = false;
|
|
428
450
|
this._fallbackRendered = false;
|
|
429
451
|
this._lastErrorPayload = null;
|
|
452
|
+
this._pendingLidSlot = null;
|
|
430
453
|
}
|
|
431
454
|
/**
|
|
432
455
|
* Tear everything down — connection state PLUS host listeners.
|
|
@@ -512,7 +535,8 @@ var ChatTransport = class {
|
|
|
512
535
|
// Internal: chatSession wiring
|
|
513
536
|
// -------------------------------------------------------------------------
|
|
514
537
|
_wireSession() {
|
|
515
|
-
this._sessionUnsubSend = chatSession.onSend(({ text }) => {
|
|
538
|
+
this._sessionUnsubSend = chatSession.onSend(({ text, activeLidSlot }) => {
|
|
539
|
+
this._pendingLidSlot = typeof activeLidSlot === "string" && activeLidSlot.length > 0 ? activeLidSlot : null;
|
|
516
540
|
void this._forwardUserMessage(text);
|
|
517
541
|
});
|
|
518
542
|
this._sessionUnsubInterrupt = chatSession.onInterrupt(() => {
|
|
@@ -554,7 +578,7 @@ var ChatTransport = class {
|
|
|
554
578
|
const h = {};
|
|
555
579
|
if (token) h.Authorization = `Bearer ${token}`;
|
|
556
580
|
if (cft) h["CF-Turnstile-Token"] = cft;
|
|
557
|
-
const lidSlot = this._config?.activeLidSlot;
|
|
581
|
+
const lidSlot = this._pendingLidSlot ?? this._config?.activeLidSlot;
|
|
558
582
|
if (typeof lidSlot === "string" && lidSlot.length > 0) {
|
|
559
583
|
h["X-Active-Lid-Slot"] = lidSlot;
|
|
560
584
|
}
|
|
@@ -1296,7 +1320,7 @@ function startObserverIfPossible(cfg) {
|
|
|
1296
1320
|
function wireListeners(bar, state) {
|
|
1297
1321
|
const onMessageSent = (e) => {
|
|
1298
1322
|
const text = e.detail.text;
|
|
1299
|
-
chatSession.send(text);
|
|
1323
|
+
chatSession.send(text, { activeLidSlot: state.cfg._syntroSlotName });
|
|
1300
1324
|
if (!chatSession.hasTransport()) {
|
|
1301
1325
|
chatSession.error("Chat backend not configured \u2014 set backendUrl in the canvas config.");
|
|
1302
1326
|
}
|
package/dist/runtime.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/ChatSession.ts", "../src/ChatTransport.ts", "../src/observer/allowlist.ts", "../src/observer/queue.ts", "../src/observer/transport.ts", "../src/observer/index.ts", "../src/AdaptiveChatBarMountable.ts", "../src/AdaptiveChipsStripMountable.ts", "../src/NavLinkMountable.ts", "../src/TextAnswerMountable.ts", "../src/runtime.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * ChatSession \u2014 singleton holder of the chat conversation state.\n *\n * The chat is conceptually one thing. Whether it's rendered in the\n * mini-canvas's lid, the drawer's lid, or as a tile inside any slot,\n * they're all VIEWS of the same conversation. This module owns that\n * shared state.\n *\n * Why a module-level singleton (not on `runtime`):\n * - Per-page scope is the right granularity for a chat (one user,\n * one conversation, however many canvas instances on the page).\n * - Avoids a new SmartCanvasRuntime API surface for now. Easy to\n * promote to `runtime.chat` later without breaking the widget API.\n * - Module identity is stable per page; multiple imports return the\n * same instance.\n *\n * Separation of concerns:\n * - `ChatSession` owns state: messages, inFlight.\n * - Views (AdaptiveChatBar via AdaptiveChatBarMountable) subscribe\n * to state changes and dispatch user actions back via send() /\n * interrupt().\n * - Transports (the LLM call, SSE pipeline, stub timers) listen\n * for \"send\" / \"interrupt\" events and eventually call receive()\n * with the assistant's reply. Transports are NOT owned by this\n * module \u2014 adapters live separately.\n *\n * No persistence in this slice. Future: snapshot to runtime.state\n * for cross-session continuity.\n */\n\nimport type { TrailMessage, TrailToolCall } from './AdaptiveChatTrail';\n\nexport interface ChatSessionState {\n readonly messages: readonly TrailMessage[];\n readonly inFlight: boolean;\n}\n\nexport interface ToolResultEvent {\n toolCallId: string;\n result: unknown;\n approved: boolean;\n}\n\nexport type ChatSessionSubscriber = (state: ChatSessionState) => void;\nexport type SendListener = (event: { text: string }) => void;\nexport type InterruptListener = () => void;\nexport type ToolResultListener = (event: ToolResultEvent) => void;\nexport type Unsubscribe = () => void;\n\nexport const CHAT_SESSION_STORAGE_KEY = 'syntro:chat:v1';\n\ninterface PersistedShape {\n messages: TrailMessage[];\n nextId: number;\n}\n\nfunction isValidMessage(value: unknown): value is TrailMessage {\n if (typeof value !== 'object' || value === null) return false;\n const m = value as Record<string, unknown>;\n return (\n (typeof m.id === 'number' || typeof m.id === 'string') &&\n (m.role === 'user' || m.role === 'assistant' || m.role === 'system') &&\n typeof m.text === 'string'\n );\n}\n\nfunction loadFromStorage(): PersistedShape | null {\n try {\n const raw = globalThis.localStorage?.getItem(CHAT_SESSION_STORAGE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (!parsed || !Array.isArray(parsed.messages)) return null;\n const messages = parsed.messages.filter(isValidMessage);\n const nextId = typeof parsed.nextId === 'number' ? parsed.nextId : messages.length + 1;\n return { messages, nextId };\n } catch {\n return null;\n }\n}\n\nexport class ChatSession {\n private _messages: TrailMessage[] = [];\n private _inFlight = false;\n private _nextId = 1;\n\n private subscribers = new Set<ChatSessionSubscriber>();\n private sendListeners = new Set<SendListener>();\n private interruptListeners = new Set<InterruptListener>();\n private toolResultListeners = new Set<ToolResultListener>();\n\n constructor() {\n const restored = loadFromStorage();\n if (restored) {\n this._messages = restored.messages;\n this._nextId = restored.nextId;\n }\n }\n\n /** Snapshot the current state. Always returns a fresh immutable view. */\n getState(): ChatSessionState {\n return { messages: [...this._messages], inFlight: this._inFlight };\n }\n\n /**\n * Subscribe to state changes. Called immediately with the current\n * state, then again on every change. Returns an unsubscribe function.\n */\n subscribe(cb: ChatSessionSubscriber): Unsubscribe {\n this.subscribers.add(cb);\n cb(this.getState());\n return () => {\n this.subscribers.delete(cb);\n };\n }\n\n /**\n * User submitted a message. Appends a user-role message, sets\n * inFlight=true, notifies state subscribers, and fires a \"send\"\n * event so transports can pick it up. Empty/whitespace text is a\n * no-op (matches the chat bar's local guard).\n */\n send(text: string): void {\n const trimmed = text.trim();\n if (!trimmed) return;\n this._messages.push({ id: this._nextId++, role: 'user', text: trimmed });\n this._inFlight = true;\n this.notify();\n for (const listener of this.sendListeners) listener({ text: trimmed });\n }\n\n /**\n * Single-shot assistant reply (no streaming). Equivalent to\n * receiveStart + receiveDelta + receiveEnd in one call. Useful for\n * stub transports and tests that don't model streaming.\n */\n receive(text: string): void {\n const id = `m-${this._nextId++}`;\n this._messages.push({ id, role: 'assistant', text, status: 'complete' });\n this._inFlight = false;\n this.notify();\n }\n\n /**\n * Begin a streaming assistant message. Appends an empty assistant\n * message with status='streaming'. Caller (transport adapter) feeds\n * deltas via receiveDelta(id, text) and signals completion via\n * receiveEnd(id). `inFlight` stays true through the stream.\n */\n receiveStart(id: string): void {\n this._messages.push({ id, role: 'assistant', text: '', status: 'streaming' });\n this._inFlight = true;\n this.notify();\n }\n\n /**\n * Append a delta to a streaming message. No-op when the id is\n * unknown (race between transport events and reset, etc.) \u2014 never\n * throws so transports can fire-and-forget.\n */\n receiveDelta(id: string, delta: string): void {\n const msg = this._messages.find((m) => m.id === id);\n if (!msg || msg.status !== 'streaming') return;\n msg.text += delta;\n this.notify();\n }\n\n /**\n * Mark a streaming message complete and clear inFlight. No-op when\n * the id is unknown (defensive against transport double-fires).\n */\n receiveEnd(id: string): void {\n const msg = this._messages.find((m) => m.id === id);\n if (msg && msg.status === 'streaming') {\n msg.status = 'complete';\n }\n this._inFlight = false;\n this.notify();\n }\n\n /**\n * Transport reports a fatal error. Marks any in-flight streaming\n * message as 'error' (so the trail can render a styled error chip\n * instead of pretending the partial text was a complete answer),\n * appends a system-role message with the error text for visibility,\n * and clears inFlight.\n */\n error(message: string): void {\n for (const m of this._messages) {\n if (m.status === 'streaming') m.status = 'error';\n }\n this._messages.push({\n id: `err-${this._nextId++}`,\n role: 'system',\n text: message,\n status: 'error',\n });\n this._inFlight = false;\n this.notify();\n }\n\n /**\n * User clicked the in-flight stop button. Clears inFlight and\n * fires an \"interrupt\" event so transports can cancel their\n * in-flight request. No-op if not in-flight (idempotent).\n */\n interrupt(): void {\n if (!this._inFlight) return;\n this._inFlight = false;\n this.notify();\n for (const listener of this.interruptListeners) listener();\n }\n\n /**\n * Wipe state. Used by the canvas-close path (start a fresh\n * conversation next time) and by tests.\n */\n reset(): void {\n this._messages = [];\n this._inFlight = false;\n this._nextId = 1;\n this.notify();\n }\n\n /** Register a transport's send listener. Returns unsubscribe. */\n onSend(listener: SendListener): Unsubscribe {\n this.sendListeners.add(listener);\n return () => {\n this.sendListeners.delete(listener);\n };\n }\n\n /**\n * True when at least one transport has wired itself to the session's\n * send pipeline. Views can use this to surface \"no chat backend\n * connected\" affordances instead of hanging in `inFlight` after a\n * send fires into the void.\n */\n hasTransport(): boolean {\n return this.sendListeners.size > 0;\n }\n\n /** Register a transport's interrupt listener. Returns unsubscribe. */\n onInterrupt(listener: InterruptListener): Unsubscribe {\n this.interruptListeners.add(listener);\n return () => {\n this.interruptListeners.delete(listener);\n };\n }\n\n /**\n * Register a transport's tool-result listener. The transport\n * forwards `tool-result` actions back to the agent after the user\n * approves or rejects a client-tool call. Returns unsubscribe.\n */\n onToolResult(listener: ToolResultListener): Unsubscribe {\n this.toolResultListeners.add(listener);\n return () => {\n this.toolResultListeners.delete(listener);\n };\n }\n\n // -------------------------------------------------------------------------\n // Tool calls\n // -------------------------------------------------------------------------\n\n /**\n * Attach a tool call to a streaming assistant message. No-op when\n * the message id is unknown (race between transport events and\n * reset / late mount).\n */\n addToolCall(messageId: string | number, toolCall: TrailToolCall): void {\n const msg = this._messages.find((m) => m.id === messageId);\n if (!msg) return;\n msg.toolCalls = [...(msg.toolCalls ?? []), { ...toolCall }];\n this.notify();\n }\n\n /**\n * Partially update a tool call by id. Used by the transport to\n * advance status (args-streaming \u2192 running \u2192 done) as AG-UI events\n * arrive. No-op when the id is unknown.\n */\n updateToolCall(toolCallId: string, patch: Partial<TrailToolCall>): void {\n for (const msg of this._messages) {\n const tcs = msg.toolCalls;\n if (!tcs) continue;\n const idx = tcs.findIndex((tc) => tc.id === toolCallId);\n if (idx === -1) continue;\n const next = [...tcs];\n next[idx] = { ...next[idx], ...patch } as TrailToolCall;\n msg.toolCalls = next;\n this.notify();\n return;\n }\n }\n\n /**\n * Resolve a (client-) tool call. Marks the call done, persists, and\n * fires onToolResult so the transport can forward the result + the\n * user's approve/reject decision back to the agent. No-op when the\n * id is unknown.\n */\n resolveToolCall(toolCallId: string, result: unknown, approved: boolean): void {\n let found = false;\n for (const msg of this._messages) {\n const tcs = msg.toolCalls;\n if (!tcs) continue;\n const idx = tcs.findIndex((tc) => tc.id === toolCallId);\n if (idx === -1) continue;\n const next = [...tcs];\n next[idx] = { ...next[idx], status: 'done' } as TrailToolCall;\n msg.toolCalls = next;\n found = true;\n break;\n }\n if (!found) return;\n this.notify();\n for (const listener of this.toolResultListeners) {\n listener({ toolCallId, result, approved });\n }\n }\n\n private notify(): void {\n const state = this.getState();\n this.persist();\n for (const sub of this.subscribers) sub(state);\n }\n\n private persist(): void {\n try {\n if (this._messages.length === 0) {\n globalThis.localStorage?.removeItem(CHAT_SESSION_STORAGE_KEY);\n return;\n }\n const payload: PersistedShape = { messages: this._messages, nextId: this._nextId };\n globalThis.localStorage?.setItem(CHAT_SESSION_STORAGE_KEY, JSON.stringify(payload));\n } catch {\n // private mode / quota / SSR \u2014 swallow; in-memory state is still valid\n }\n }\n}\n\n/**\n * The module-level singleton. Every `<adaptive-chat-bar>` (regardless\n * of which slot it lives in) reads from and writes to this instance.\n * Multiple imports of this module return the same object.\n *\n * Scope: per-page. Correct for the canonical case (one user, one\n * conversation, however many canvas views surface it). Multiple\n * `<smart-canvas>` instances on the same page will share state \u2014\n * tracked in project_future_work.md for per-runtime scoping.\n */\nexport const chatSession = new ChatSession();\n", "/**\n * ChatTransport \u2014 singleton transport adapter that bridges chatSession\n * (the view-side state holder) to the real backend chat pipeline\n * (AG-UI SSE at `/api/adaptive/stream`).\n *\n * This is the unification of two formerly separate paths:\n * - `ChatAssistantLit` (old) owns the transport plumbing \u2014\n * AgUiTransport, Cloudflare Turnstile, headers, A2UI passthrough,\n * telemetry, fallback card.\n * - `AdaptiveChatBar` + `chatSession` (new) owns the canvas-lid UX \u2014\n * glassmorphism bar, bubble-up trail, per-page persistence.\n *\n * This module ports every transport-side concern from ChatAssistantLit\n * into a session-shaped adapter so the new bar gets full backend\n * parity. The bar stays a pure view; the transport stays a pure pipe.\n *\n * Lifecycle:\n * - `configure({ backendUrl, runtime, ... })` \u2014 called once by the\n * SDK runtime at bootstrap from chat config. Idempotent; second\n * call with the same backendUrl is a no-op.\n * - Connection is LAZY. The transport doesn't acquire Turnstile or\n * open the SSE until the first chatSession.send() \u2014 saves cost\n * on pages where the user never opens chat.\n * - On chatSession.send \u2192 transport ensures connected (acquires\n * Turnstile token, builds AgUiTransport) then forwards\n * `{type:'user-message', text}` to the agent.\n * - On chatSession.onInterrupt \u2192 transport sends stop-generation.\n * - AgUi events stream into chatSession via receiveStart / Delta /\n * End / error.\n * - A2UI custom events forward to runtime.actions.applyBatch so the\n * agent can drive canvas updates.\n *\n * Telemetry parity with ChatAssistantLit:\n * - chatbot.transport_error (every error, with status/body/name)\n * - chatbot.a2ui_applied\n * - chatbot.fallback_rendered \u2014 emitted when the transport gives up\n * (Turnstile failed AND backend rejected) so existing PostHog\n * queries keep working.\n *\n * Threading model: single-flight per page. Multiple concurrent sends\n * are queued by AgUiTransport itself. Multiple bar mounts share this\n * one transport via chatSession.\n */\n\nimport type { ServerEvent } from '@syntrologie/chat';\n// AgUiTransport / Turnstile helpers live in the existing packages \u2014\n// we reuse them instead of re-implementing.\nimport { AgUiTransport } from '@syntrologie/chat/transport/agui';\n\nimport type { TrailToolCall } from './AdaptiveChatTrail';\nimport { chatSession } from './ChatSession';\nimport type { ElementMutation } from './elements';\nimport { decodeMutationEnvelope } from './elements';\nimport { acquireTokenWithChallenge } from './Turnstile';\nimport type { ChatbotWidgetRuntime } from './types';\n\n/**\n * Per-customer \"chat unavailable\" card config. Surfaced via onFallback\n * when the transport gives up after repeated failures. Mirrors\n * ChatbotFallback in types.ts so consumers can pass the same config.\n */\nexport interface ChatbotFallbackConfig {\n title?: string;\n message?: string;\n ctaLabel?: string;\n ctaHref?: string;\n}\n\nexport interface ChatTransportConfig {\n /** Backend host, e.g. \"https://demo-api.syntrologie.com\" or \"\" for same-origin. */\n backendUrl: string;\n /** Runtime hooks for A2UI apply + telemetry. */\n runtime: ChatbotWidgetRuntime;\n /** Optional thread id for conversation continuity across reloads. */\n threadId?: string;\n /**\n * Optional set of client-tool names the transport should treat as\n * \"needs user approval\" (surfaced via chatSession.toolCalls instead\n * of auto-executed server-side). Empty by default \u2014 all tool calls\n * are server-driven and the transport just emits the \"tool call\n * happened\" event.\n */\n clientTools?: Set<string>;\n /**\n * Per-customer \"chat unavailable\" card. Rendered by the host\n * (typically AdaptiveChatBarMountable) after repeated connect\n * failures wipe the chat surface \u2014 exactly the same UX\n * ChatAssistantLit's fallback path provides.\n */\n fallback?: ChatbotFallbackConfig;\n /**\n * Arbitrary JSON object attached to every AG-UI request as\n * `forwardedProps`. Used by the adaptive chat surface to ship the\n * LLM-authored UI element config (`uiTemplates`, `elementsEnabled`)\n * per request \u2014 the backend reads these to enable the\n * `mount_element` / `patch_element` / `unmount_element` tools.\n * Callable form is re-evaluated on every turn so a config edit can\n * land mid-conversation.\n */\n forwardedProps?: Record<string, unknown> | (() => Record<string, unknown> | undefined);\n /**\n * Optional callback for `syntro.element.mutation` AG-UI custom events.\n * The transport decodes the envelope on receipt; if it matches the\n * element-mutation schema, mutations are routed here instead of the\n * generic `runtime.actions.applyBatch` legacy path. Consumers are\n * expected to forward to `ElementInstanceStore.apply(mutations)` \u2014\n * we don't take a store reference directly so the transport stays\n * agnostic of which surface owns the store (the chat-bar widget\n * may own one; ChatAssistantLit owns its own; both share this\n * singleton transport).\n *\n * When unset, element-mutation envelopes fall back to applyBatch,\n * matching legacy behaviour (which would no-op since applyBatch\n * doesn't know about MutationEnvelope).\n */\n onElementMutation?: (mutations: ElementMutation[]) => void;\n /**\n * Slot the chat-bar widget is mounted into (e.g. ``\"drawer\"``,\n * ``\"adaptive-chat\"``). Forwarded as ``X-Active-Lid-Slot`` on every\n * ``/api/adaptive/stream`` request so the backend can route mounts to\n * the canvas next to whichever lid the visitor sent from. Optional \u2014\n * omitting it falls back to the template's static ``default_slot``\n * server-side, which is the pre-change behaviour.\n */\n activeLidSlot?: string;\n}\n\n/**\n * Debounce window for connect errors. Single transient errors\n * (cold-start 502, brief CORS preflight failure) should NOT swap the\n * chat to the fallback card; only sustained failure should. Matches\n * ChatAssistantLit's ERROR_DEBOUNCE_MS.\n */\nexport const FALLBACK_DEBOUNCE_MS = 1_500;\n\nexport interface FallbackPayload {\n reason: 'connect_failed' | 'connect_timeout';\n fallback: ChatbotFallbackConfig;\n transportId: string;\n transportAgeMs: number;\n messagesSucceeded: number;\n hadTurnstileToken: boolean | null;\n errorStatus: number | null;\n errorBody: string | null;\n errorMessage: string | null;\n errorName: string | null;\n}\n\nexport type FallbackListener = (payload: FallbackPayload) => void;\n\ntype ChatTransportStatus =\n | 'idle' // configure() not called yet\n | 'configured' // ready but not connected\n | 'acquiring' // Turnstile token acquisition in flight\n | 'connected' // AgUiTransport up and ready\n | 'error'; // last attempt failed; will retry on next send\n\ninterface SyntroGlobalConfig {\n token?: string;\n}\n\n/**\n * Read the workspace's syn_* token from runtime-config.js. The SDK\n * sets this global at bootstrap; for non-CDN test environments the\n * test page sets it directly. Returns undefined when the global is\n * missing \u2014 the connect will then fall through to the unauthenticated\n * path and the backend will 401 (caught by error handling below).\n */\nfunction readSyntroToken(): string | undefined {\n if (typeof window === 'undefined') return undefined;\n const cfg = (window as unknown as { __SYNTRO_CONFIG__?: SyntroGlobalConfig }).__SYNTRO_CONFIG__;\n const token = cfg?.token;\n return typeof token === 'string' && token.length > 0 ? token : undefined;\n}\n\n/**\n * Debug logger gated on `window.__SYNTRO_CHAT_DEBUG__`. Mirrors\n * ChatAssistantLit so flipping that flag in the customer's DevTools\n * enables verbose tracing across the whole chat pipeline (the bar\n * AND the legacy assistant) without rebuilding the SDK.\n */\nfunction debug(...args: unknown[]): void {\n if (typeof window === 'undefined') return;\n if ((window as unknown as { __SYNTRO_CHAT_DEBUG__?: boolean }).__SYNTRO_CHAT_DEBUG__) {\n console.debug('[chat-transport]', ...args);\n }\n}\n\nexport class ChatTransport {\n private _config: ChatTransportConfig | null = null;\n private _status: ChatTransportStatus = 'idle';\n private _agui: AgUiTransport | null = null;\n private _transportUnsub: (() => void) | null = null;\n private _sessionUnsubSend: (() => void) | null = null;\n private _sessionUnsubInterrupt: (() => void) | null = null;\n private _sessionUnsubToolResult: (() => void) | null = null;\n private _connectInFlight: Promise<boolean> | null = null;\n /** Bounded streaming-message id for the currently-being-typed assistant turn. */\n private _currentAssistantMessageId: string | null = null;\n /** Outcome bookkeeping for telemetry. */\n private _hadTurnstileToken: boolean | null = null;\n /** Count of successful round-trips for telemetry payloads. */\n private _messagesSucceeded = 0;\n /** True once a successful assistant message has landed \u2014 gates fallback. */\n private _hasSucceeded = false;\n /** True once fallback has fired (one-shot). */\n private _fallbackRendered = false;\n /** Active debounce timer; null when no debounce pending. */\n private _errorDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n /** Most recent error payload, captured so debounced fallback can attach it. */\n private _lastErrorPayload: {\n message?: string;\n status?: number | null;\n body?: string | null;\n errorName?: string | null;\n } | null = null;\n private _fallbackListeners = new Set<FallbackListener>();\n /**\n * Per-configure-cycle id for correlating telemetry events from a\n * single transport lifetime. Mirrors ChatAssistantLit's mountId\n * but scoped to configure cycles since the transport is a\n * singleton across mounts.\n */\n private _transportId = `tx_${Math.random().toString(36).slice(2, 8)}`;\n private _configuredAt = 0;\n\n /**\n * Configure the transport. Idempotent \u2014 calling again with the same\n * backendUrl is a no-op; calling with a different backendUrl tears\n * the connection down and re-arms.\n */\n configure(config: ChatTransportConfig): void {\n const same =\n this._config &&\n this._config.backendUrl === config.backendUrl &&\n this._config.threadId === config.threadId;\n if (same) {\n // Allow runtime + clientTools to be replaced without reconnect \u2014\n // the bar may remount with a fresh runtime closure.\n this._config = { ...this._config, ...config };\n return;\n }\n this._disconnect();\n this._config = config;\n this._status = 'configured';\n this._transportId = `tx_${Math.random().toString(36).slice(2, 8)}`;\n this._configuredAt = Date.now();\n this._wireSession();\n debug('configured', {\n transportId: this._transportId,\n backendUrl: config.backendUrl,\n threadId: config.threadId,\n });\n }\n\n /** ms since the most recent configure() call. 0 before any configure. */\n private _ageMs(): number {\n return this._configuredAt === 0 ? 0 : Date.now() - this._configuredAt;\n }\n\n /** True when configure() has been called and we're ready to lazy-connect on send. */\n get isConfigured(): boolean {\n return this._status !== 'idle';\n }\n\n /** True when AgUiTransport is up. */\n get isConnected(): boolean {\n return this._status === 'connected';\n }\n\n /**\n * Subscribe to fallback events \u2014 fires once per configure cycle\n * when the transport gives up after sustained failure. Hosts\n * (typically AdaptiveChatBarMountable) use this to swap the chat\n * bar for a static \"contact support\" card.\n */\n onFallback(listener: FallbackListener): () => void {\n this._fallbackListeners.add(listener);\n return () => {\n this._fallbackListeners.delete(listener);\n };\n }\n\n /**\n * Test seam \u2014 drive a synthetic error event through the transport's\n * error handling without standing up a real AgUi transport. Production\n * code path uses _onTransportEvent. Exported as a public method to\n * keep the test isolation simple; not part of the documented API.\n */\n simulateError(payload: {\n message?: string;\n status?: number | null;\n body?: string | null;\n errorName?: string | null;\n }): void {\n this._handleErrorEvent(payload);\n }\n\n /**\n * Test seam \u2014 register a synthetic successful message-complete so\n * the hasSucceeded gate flips without a real AgUi round-trip.\n */\n simulateSuccessfulMessage(): void {\n this._hasSucceeded = true;\n this._messagesSucceeded += 1;\n this._clearDebounceTimer();\n }\n\n /**\n * Tear connection-level state down. Used internally by configure()\n * to swap backends; preserves host-registered fallback listeners\n * because the host UI handler (e.g. AdaptiveChatBarMountable's\n * \"swap to fallback card\" callback) is configuration-independent.\n */\n private _disconnect(): void {\n if (this._transportUnsub) {\n this._transportUnsub();\n this._transportUnsub = null;\n }\n if (this._sessionUnsubSend) {\n this._sessionUnsubSend();\n this._sessionUnsubSend = null;\n }\n if (this._sessionUnsubInterrupt) {\n this._sessionUnsubInterrupt();\n this._sessionUnsubInterrupt = null;\n }\n if (this._sessionUnsubToolResult) {\n this._sessionUnsubToolResult();\n this._sessionUnsubToolResult = null;\n }\n if (this._agui) {\n this._agui.disconnect();\n this._agui = null;\n }\n this._clearDebounceTimer();\n this._config = null;\n this._status = 'idle';\n this._connectInFlight = null;\n this._currentAssistantMessageId = null;\n this._hadTurnstileToken = null;\n this._messagesSucceeded = 0;\n this._hasSucceeded = false;\n this._fallbackRendered = false;\n this._lastErrorPayload = null;\n }\n\n /**\n * Tear everything down \u2014 connection state PLUS host listeners.\n * Use this in test teardown or when fully shutting the transport\n * (page unload, integration test reset). The mountable calls\n * _disconnect indirectly via reconfigure.\n */\n reset(): void {\n this._disconnect();\n this._fallbackListeners.clear();\n }\n\n private _clearDebounceTimer(): void {\n if (this._errorDebounceTimer) {\n clearTimeout(this._errorDebounceTimer);\n this._errorDebounceTimer = null;\n }\n }\n\n /**\n * Shared error-handling kernel \u2014 called by the AG-UI subscriber and\n * by the simulateError test seam. Publishes transport_error\n * telemetry, captures lastErrorPayload, and starts the debounce\n * timer that will fire fallback if no successful message arrives\n * before it expires. Gated by hasSucceeded (post-success errors\n * never fallback) and _fallbackRendered (one-shot).\n */\n private _handleErrorEvent(payload: {\n message?: string;\n status?: number | null;\n body?: string | null;\n errorName?: string | null;\n }): void {\n const status = payload.status ?? null;\n const body = payload.body ? String(payload.body).slice(0, 200) : null;\n this._lastErrorPayload = {\n message: payload.message,\n status,\n body,\n errorName: payload.errorName ?? null,\n };\n\n this._config?.runtime.events.publish('chatbot.transport_error', {\n source: 'chat-transport',\n transportId: this._transportId,\n transportAgeMs: this._ageMs(),\n messagesSucceeded: this._messagesSucceeded,\n hadTurnstileToken: this._hadTurnstileToken,\n hasSucceeded: this._hasSucceeded,\n errorMessage: payload.message ?? null,\n errorStatus: status,\n errorBody: body,\n errorName: payload.errorName ?? null,\n });\n\n if (this._hasSucceeded || this._fallbackRendered || this._errorDebounceTimer) return;\n this._errorDebounceTimer = setTimeout(() => {\n this._errorDebounceTimer = null;\n if (this._hasSucceeded || this._fallbackRendered) return;\n this._renderFallback('connect_failed');\n }, FALLBACK_DEBOUNCE_MS);\n }\n\n /**\n * Fire the fallback. One-shot per configure cycle. Notifies all\n * fallback listeners with the per-customer card config and the\n * diagnostic snapshot for telemetry/debug.\n */\n private _renderFallback(reason: FallbackPayload['reason']): void {\n if (this._fallbackRendered) return;\n this._fallbackRendered = true;\n debug('fallback', { reason, transportId: this._transportId, ageMs: this._ageMs() });\n const fallback = this._config?.fallback ?? {};\n const payload: FallbackPayload = {\n reason,\n fallback,\n transportId: this._transportId,\n transportAgeMs: this._ageMs(),\n messagesSucceeded: this._messagesSucceeded,\n hadTurnstileToken: this._hadTurnstileToken,\n errorStatus: this._lastErrorPayload?.status ?? null,\n errorBody: this._lastErrorPayload?.body ?? null,\n errorMessage: this._lastErrorPayload?.message ?? null,\n errorName: this._lastErrorPayload?.errorName ?? null,\n };\n this._config?.runtime.events.publish(\n 'chatbot.fallback_rendered',\n payload as unknown as Record<string, unknown>\n );\n for (const listener of this._fallbackListeners) listener(payload);\n }\n\n // -------------------------------------------------------------------------\n // Internal: chatSession wiring\n // -------------------------------------------------------------------------\n\n private _wireSession(): void {\n this._sessionUnsubSend = chatSession.onSend(({ text }) => {\n void this._forwardUserMessage(text);\n });\n this._sessionUnsubInterrupt = chatSession.onInterrupt(() => {\n this._agui?.send({ type: 'stop-generation' });\n });\n this._sessionUnsubToolResult = chatSession.onToolResult(({ toolCallId, result, approved }) => {\n this._agui?.send({ type: 'tool-result', toolCallId, result, approved });\n });\n }\n\n private async _forwardUserMessage(text: string): Promise<void> {\n const ok = await this._ensureConnected();\n if (!ok || !this._agui) {\n // Connect failed; surface to the session so the bar shows an error\n // chip and clears inFlight (otherwise the user is stuck on the\n // \u23F9 stop button forever).\n chatSession.error(\"Couldn't connect to chat. Please try again.\");\n return;\n }\n this._agui.send({ type: 'user-message', text });\n }\n\n // -------------------------------------------------------------------------\n // Internal: connect (lazy, Turnstile-gated)\n // -------------------------------------------------------------------------\n\n /**\n * Ensure AgUiTransport is up. Idempotent \u2014 multiple concurrent calls\n * dedupe to a single Turnstile acquisition + transport setup.\n * Returns true on success, false on terminal failure.\n */\n private async _ensureConnected(): Promise<boolean> {\n if (this._status === 'connected' && this._agui) return true;\n if (!this._config) return false;\n if (this._connectInFlight) return this._connectInFlight;\n\n this._connectInFlight = (async () => {\n this._status = 'acquiring';\n const cft = await this._acquireTurnstileWithChallenge();\n this._hadTurnstileToken = cft !== null;\n\n if (this._config === null) return false; // raced with reset()\n\n const baseUrl = this._config.backendUrl.replace(/\\/$/, '');\n const streamUrl = `${baseUrl}/api/adaptive/stream`;\n const token = readSyntroToken();\n const buildHeaders = (): Record<string, string> => {\n const h: Record<string, string> = {};\n if (token) h.Authorization = `Bearer ${token}`;\n if (cft) h['CF-Turnstile-Token'] = cft;\n // Forward the slot this chat-bar lives in so the backend can\n // route mount_element results to the canvas next to it. Read\n // from `this._config` on EVERY header build, not a captured\n // const \u2014 a reconfigure (e.g. user closes the drawer and opens\n // the inline chat anchor) updates `_config` in place and the\n // next turn must reflect the new slot. Capturing as a const\n // here closes over the value at connect-time and silently\n // tags every subsequent turn with the original slot.\n const lidSlot = this._config?.activeLidSlot;\n if (typeof lidSlot === 'string' && lidSlot.length > 0) {\n h['X-Active-Lid-Slot'] = lidSlot;\n }\n // Forward PostHog distinct_id so the backend can resolve historical\n // context (KNOWN ABOUT VISITOR block, persona summaries). Two\n // sources, in order:\n // 1. runtime.telemetry.getDistinctId() \u2014 preferred, mirrors what\n // the rest of the SDK uses for capture identity.\n // 2. window.posthog.get_distinct_id() \u2014 fallback for embeds where\n // the host page initialises PostHog directly.\n // Defensive: missing/blocked PostHog \u2192 header omitted \u2192 backend\n // falls back to cold-start.\n try {\n const rt = this._config?.runtime as\n | { telemetry?: { getDistinctId?: () => string | null | undefined } }\n | undefined;\n const fromRuntime = rt?.telemetry?.getDistinctId?.();\n const fromWindow = (\n window as unknown as { posthog?: { get_distinct_id?: () => string } }\n ).posthog?.get_distinct_id?.();\n const did = fromRuntime || fromWindow;\n if (typeof did === 'string' && did.length > 0) {\n h['X-Distinct-Id'] = did;\n }\n } catch {\n // PostHog throw on get_distinct_id is extremely rare but cheap to guard.\n }\n return h;\n };\n\n const runtime = this._config.runtime;\n // Resolve forwardedProps at run-time (each AG-UI request), not at\n // transport construction. The config can be updated via\n // `configure()` with the same backendUrl (no reconnect), so the\n // late-bound closure keeps the transport in sync with the most\n // recent uiTemplates / elementsEnabled declarations.\n const resolveForwardedProps = (): Record<string, unknown> | undefined => {\n const raw = this._config?.forwardedProps;\n return typeof raw === 'function' ? raw() : raw;\n };\n this._agui = new AgUiTransport({\n url: streamUrl,\n headers: buildHeaders,\n threadId: this._config.threadId,\n clientTools: this._config.clientTools,\n // Adaptive runtime SDK needs the `syntro_chat_session` cookie to\n // round-trip cross-origin so subsequent boot fetches can rehydrate\n // LLM-authored UI elements. Editor / action-plan chat surfaces\n // auth via `?token=` and intentionally leave this unset (see\n // AgUiTransportOptions.credentials docstring).\n credentials: 'include',\n forwardedProps: resolveForwardedProps,\n onA2UIEvent: (payload) => {\n // Discriminate `syntro.element.mutation` envelopes (LLM-\n // authored UI element mounts/patches/unmounts) from legacy\n // A2UI / raw ActionStep payloads. Mirrors ChatAssistantLit's\n // routing \u2014 the chat-bar lid surface needs the same wiring so\n // mount_element / patch_element / unmount_element results\n // actually land on the host page.\n const mutations = decodeMutationEnvelope(payload);\n if (mutations !== null) {\n const handler = this._config?.onElementMutation;\n if (handler) {\n try {\n handler(mutations);\n runtime.events.publish('chatbot.element_mutation_applied', {\n source: 'chat-transport',\n count: mutations.length,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[chat-transport] element mutation apply failed:', msg);\n }\n return;\n }\n // No handler registered \u2014 the surface using this transport\n // didn't opt into element mutations. Drop silently rather\n // than feeding a MutationEnvelope into applyBatch (which\n // would no-op or warn).\n return;\n }\n runtime.actions\n .applyBatch([payload as unknown as Record<string, unknown>])\n .then(() => {\n runtime.events.publish('chatbot.a2ui_applied', { source: 'chat-transport' });\n })\n .catch((err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[chat-transport] A2UI apply failed:', msg);\n });\n },\n });\n this._agui.connect();\n this._transportUnsub = this._agui.subscribe((event) => this._onTransportEvent(event));\n this._status = 'connected';\n return true;\n })();\n\n try {\n return await this._connectInFlight;\n } finally {\n this._connectInFlight = null;\n }\n }\n\n /**\n * Acquire a Turnstile token via the managed-challenge flow.\n * Delegates to the shared Turnstile helper that owns the verify\n * panel lifecycle. Returns null when Turnstile is disabled at\n * build time or acquisition fails.\n */\n private async _acquireTurnstileWithChallenge(): Promise<string | null> {\n const { token } = await acquireTokenWithChallenge();\n return token;\n }\n\n // -------------------------------------------------------------------------\n // Internal: AgUi event \u2192 chatSession\n // -------------------------------------------------------------------------\n\n /**\n * Look up a tool call's current chatSession-side status by id.\n * Used to decide between addToolCall (first sighting) and\n * updateToolCall (subsequent updates) when AG-UI re-emits\n * `tool-call` events for client tools transitioning to 'pending'.\n */\n private _findToolCallStatus(toolCallId: string): TrailToolCall['status'] | null {\n const state = chatSession.getState();\n for (const msg of state.messages) {\n const tc = msg.toolCalls?.find((t) => t.id === toolCallId);\n if (tc) return tc.status;\n }\n return null;\n }\n\n /** Map AG-UI ToolCallStatus to TrailToolCall status. */\n private _mapToolCallStatus(status: string): TrailToolCall['status'] {\n switch (status) {\n case 'args-streaming':\n return 'args-streaming';\n case 'pending':\n return 'pending';\n case 'running':\n return 'running';\n case 'done':\n return 'done';\n case 'error':\n return 'error';\n default:\n return 'running';\n }\n }\n\n private _onTransportEvent(event: ServerEvent): void {\n const runtime = this._config?.runtime;\n\n switch (event.type) {\n case 'session-ready':\n case 'messages-snapshot':\n case 'typing':\n // Local-only events from AgUiTransport.connect() \u2014 no UI impact.\n return;\n\n case 'message-append': {\n // Start of a new streaming assistant message.\n this._currentAssistantMessageId = event.message.id;\n chatSession.receiveStart(event.message.id);\n if (event.message.content && event.message.content.length > 0) {\n chatSession.receiveDelta(event.message.id, event.message.content);\n }\n return;\n }\n\n case 'message-delta': {\n const id = event.messageId ?? this._currentAssistantMessageId;\n if (!id || !event.delta) return;\n chatSession.receiveDelta(id, event.delta);\n return;\n }\n\n case 'message-complete': {\n const id = event.messageId ?? this._currentAssistantMessageId;\n if (!id) return;\n chatSession.receiveEnd(id);\n this._currentAssistantMessageId = null;\n this._messagesSucceeded += 1;\n // Flip the hasSucceeded gate: errors after this point will no\n // longer trigger a fallback swap (matches ChatAssistantLit).\n this._hasSucceeded = true;\n this._clearDebounceTimer();\n return;\n }\n\n case 'tool-call': {\n // tool-call arrives twice in the AG-UI flow: once at start\n // (status='args-streaming') and once at end for client tools\n // with status='pending' awaiting user approval. Add on the\n // first sighting, update on the second.\n const targetMessageId = event.messageId ?? this._currentAssistantMessageId;\n if (!targetMessageId) return;\n const existing = this._findToolCallStatus(event.toolCall.id);\n if (!existing) {\n chatSession.addToolCall(targetMessageId, {\n id: event.toolCall.id,\n name: event.toolCall.name,\n status: this._mapToolCallStatus(event.toolCall.status),\n });\n } else {\n chatSession.updateToolCall(event.toolCall.id, {\n name: event.toolCall.name,\n status: this._mapToolCallStatus(event.toolCall.status),\n });\n }\n return;\n }\n\n case 'tool-call-args-delta':\n // We don't currently surface streaming args in the trail chip\n // (too noisy for the compact UI), but a future expanded view\n // could subscribe and render them. Logged under debug.\n debug('tool-call-args-delta', event);\n return;\n\n case 'tool-call-done':\n // Server-side tool finished. Mark complete in the trail so the\n // chip transitions from \"running\" to \"done\". Client-tool\n // resolution goes through chatSession.resolveToolCall instead.\n chatSession.updateToolCall(event.toolCallId, { status: 'done' });\n return;\n\n case 'a2ui':\n // A2UI events also flow via onA2UIEvent in the transport\n // constructor \u2014 that path is what applies the batch. This\n // duplicate event is the public mirror; ignore here.\n return;\n\n case 'error': {\n const status = event.status ?? null;\n const body = event.body ? String(event.body).slice(0, 200) : null;\n console.warn(\n `[chat-transport] error status=${status ?? 'no-status'} succeeded=${this._messagesSucceeded}`,\n event\n );\n // Route through the shared error-handling kernel so the\n // debounce / hasSucceeded gate / fallback path apply uniformly\n // regardless of whether the error came from AG-UI or a test seam.\n this._handleErrorEvent({\n message: event.message,\n status,\n body,\n errorName: event.errorName ?? null,\n });\n // The chip-level error chip (shown immediately, no debounce)\n // gives the user feedback even when we're still waiting to see\n // if the failure is sustained enough to swap to the fallback.\n chatSession.error(event.message ?? 'Chat connection failed');\n this._currentAssistantMessageId = null;\n // Tear AgUiTransport down so the next send re-acquires Turnstile\n // and re-opens. Avoids reusing a broken HttpAgent under us.\n if (this._agui) {\n this._agui.disconnect();\n this._agui = null;\n }\n if (this._transportUnsub) {\n this._transportUnsub();\n this._transportUnsub = null;\n }\n this._status = 'error';\n return;\n }\n }\n }\n}\n\n/**\n * The module-level singleton. Imported by both the SDK runtime\n * bootstrap (to call configure) and any code that needs to read\n * transport state. Mirrors the chatSession singleton shape.\n */\nexport const chatTransport = new ChatTransport();\n", "/**\n * Pure mapping from raw PostHog events to ObservationEvents.\n *\n * One function: matchEvent(raw, opts) \u2192 ObservationEvent | null. Null means\n * \"drop, not significant.\" This module is the single source of truth for what\n * the chat agent sees on the in-session timeline; the SDK observer never\n * forwards anything matchEvent returns null for.\n *\n * Kept dependency-free (no DOM access, no PostHog SDK imports) so the\n * Vitest unit tests run without any browser shim.\n */\n\nexport type ObservationKind =\n | 'nav'\n | 'click'\n | 'form'\n | 'rage'\n | 'dead'\n | 'scroll'\n | 'view'\n | 'idle'\n | 'hover'\n | 'hesitation'\n | 'custom';\n\nexport interface ObservationEvent {\n ts: number;\n kind: ObservationKind;\n text: string;\n ref?: string;\n}\n\n/** Shape of a raw event reaching matchEvent. Loose by design \u2014 PostHog's\n * event shape evolves, and we want matchEvent to be resilient to extra\n * properties. */\nexport interface RawEvent {\n event: string;\n timestamp: number;\n properties: Record<string, unknown>;\n}\n\nexport interface MatchOptions {\n /** Workspace-configured custom event names to forward as kind=\"custom\". */\n observableEvents?: readonly string[];\n}\n\nconst MAX_TEXT_LEN = 200;\nconst SIGNIFICANT_CLICK_TAGS = new Set(['button', 'a']);\n\nfunction truncate(s: string): string {\n return s.length <= MAX_TEXT_LEN ? s : `${s.slice(0, MAX_TEXT_LEN - 1)}\u2026`;\n}\n\nfunction firstElement(props: Record<string, unknown>): Record<string, unknown> | null {\n const els = props.$elements;\n if (Array.isArray(els) && els.length > 0 && typeof els[0] === 'object' && els[0] !== null) {\n return els[0] as Record<string, unknown>;\n }\n return null;\n}\n\nfunction elementText(props: Record<string, unknown>): string {\n const el = firstElement(props);\n if (!el) return '';\n const t = el.text;\n return typeof t === 'string' ? t.trim() : '';\n}\n\nfunction elementTag(props: Record<string, unknown>): string {\n const explicit = props.$element_tag_name;\n if (typeof explicit === 'string') return explicit.toLowerCase();\n const el = firstElement(props);\n if (el && typeof el.tag_name === 'string') return (el.tag_name as string).toLowerCase();\n return '';\n}\n\nfunction elementRole(props: Record<string, unknown>): string {\n const el = firstElement(props);\n if (!el) return '';\n const role = el.attr__role;\n return typeof role === 'string' ? role.toLowerCase() : '';\n}\n\nfunction formName(props: Record<string, unknown>): string {\n const el = firstElement(props);\n if (!el) return 'unnamed';\n const name = el.attr__name;\n if (typeof name === 'string' && name) return name;\n const id = el.attr__id;\n if (typeof id === 'string' && id) return id;\n return 'unnamed';\n}\n\nfunction isSignificantClickTarget(props: Record<string, unknown>): boolean {\n const tag = elementTag(props);\n if (SIGNIFICANT_CLICK_TAGS.has(tag)) return true;\n if (elementRole(props) === 'button') return true;\n return false;\n}\n\nfunction pathname(props: Record<string, unknown>): string {\n const pn = props.$pathname;\n return typeof pn === 'string' ? pn : '/';\n}\n\nfunction renderCustomEvent(raw: RawEvent): string {\n // Stable summary: event name + up to two scalar props.\n const fields: string[] = [];\n for (const [k, v] of Object.entries(raw.properties)) {\n if (k.startsWith('$')) continue;\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n fields.push(`${k}=${v}`);\n if (fields.length >= 2) break;\n }\n }\n return fields.length > 0 ? `${raw.event} (${fields.join(', ')})` : raw.event;\n}\n\nexport function matchEvent(raw: RawEvent, opts: MatchOptions = {}): ObservationEvent | null {\n const props = raw.properties;\n\n switch (raw.event) {\n case '$pageview': {\n const path = pathname(props);\n return {\n ts: raw.timestamp,\n kind: 'nav',\n text: truncate(`navigated to ${path}`),\n ref: path,\n };\n }\n\n case '$autocapture': {\n const eventType = props.$event_type;\n\n if (eventType === 'click') {\n if (!isSignificantClickTarget(props)) return null;\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'click',\n text: truncate(`clicked '${text}'`),\n };\n }\n\n if (eventType === 'submit' && elementTag(props) === 'form') {\n return {\n ts: raw.timestamp,\n kind: 'form',\n text: truncate(`submitted form '${formName(props)}'`),\n };\n }\n\n return null;\n }\n\n case '$rageclick': {\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'rage',\n text: truncate(`rage-clicked '${text}'`),\n };\n }\n\n case '$dead_click': {\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'dead',\n text: truncate(`clicked '${text}' (no response)`),\n };\n }\n\n // \u2500\u2500 Canonical runtime-bus events (sources: `'canvas'` instrumentation\n // or the event-processor's rrweb detectors). These don't go through\n // PostHog; the chat-bar's bus translator forwards them as-is with\n // the canonical event name, and matchEvent picks the right slot\n // here. Keeps a single allowlist as the source of truth for what\n // the agent's observation tail can carry.\n case 'nav.section_viewed': {\n const section = typeof props.section === 'string' ? props.section : '';\n if (!section) return null;\n return {\n ts: raw.timestamp,\n kind: 'view',\n text: truncate(`viewed the '${section}' section`),\n ref: section,\n };\n }\n\n case 'nav.scroll_depth': {\n const pct = typeof props.percent === 'number' ? props.percent : null;\n if (pct === null) return null;\n return {\n ts: raw.timestamp,\n kind: 'scroll',\n text: truncate(`scrolled to ${pct}% of the page`),\n };\n }\n\n case 'ui.scroll_thrash': {\n return {\n ts: raw.timestamp,\n kind: 'scroll',\n text: 'scrolled up and down repeatedly (looking for something)',\n };\n }\n\n case 'ui.idle': {\n const ms = typeof props.durationMs === 'number' ? props.durationMs : null;\n const secs = ms !== null ? Math.round(ms / 1000) : null;\n return {\n ts: raw.timestamp,\n kind: 'idle',\n text: secs !== null ? `idle for ${secs}s` : 'idle',\n };\n }\n\n case 'ui.hover': {\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'hover',\n text: truncate(`hovered on '${text}'`),\n };\n }\n\n case 'ui.hesitation': {\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'hesitation',\n text: truncate(`hesitated near '${text}'`),\n };\n }\n\n case 'ui.focus_bounce': {\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'form',\n text: truncate(`focused '${text}' but didn't fill it`),\n };\n }\n\n default: {\n const allow = opts.observableEvents ?? [];\n if (allow.includes(raw.event)) {\n return {\n ts: raw.timestamp,\n kind: 'custom',\n text: truncate(renderCustomEvent(raw)),\n };\n }\n return null;\n }\n }\n}\n", "/**\n * In-memory batching queue for ObservationEvents.\n *\n * Holds events until either a size threshold or a time interval triggers\n * a flush. The flush function is injected so transport choice (fetch vs.\n * sendBeacon) and auth wiring stay out of this module.\n *\n * Backoff strategy: pure exponential, starting at 1s and capping at 30s\n * (1s \u2192 2s \u2192 4s \u2192 8s \u2192 16s \u2192 30s). Reset on first successful flush.\n * Jitter is intentionally omitted \u2014 the observer queue is per-client, so\n * thundering-herd at recovery is not a meaningful risk, and deterministic\n * timing keeps unit tests fast and stable. A \"permanent\" failure (4xx\n * marked by the caller) disables the queue entirely \u2014 no further flushes\n * are attempted; lastError is exposed via stats().\n */\n\nimport type { ObservationEvent } from './allowlist';\n\nexport interface FlushError extends Error {\n /** When true, the queue stops trying forever. Set by transport for 4xx. */\n permanent?: boolean;\n}\n\nexport interface ObserverQueueOptions {\n batchSize: number;\n flushIntervalMs: number;\n queueCap: number;\n flush: (batch: ObservationEvent[]) => Promise<void>;\n backoffStartMs?: number;\n backoffCapMs?: number;\n}\n\nexport interface ObserverStats {\n queued: number;\n sent: number;\n dropped: number;\n lastError: string | null;\n disabled: boolean;\n}\n\nexport class ObserverQueue {\n private readonly _opts: Required<ObserverQueueOptions>;\n private readonly _buffer: ObservationEvent[] = [];\n private _sent = 0;\n private _dropped = 0;\n private _lastError: string | null = null;\n private _disabled = false;\n private _intervalTimer: ReturnType<typeof setTimeout> | null = null;\n private _backoffTimer: ReturnType<typeof setTimeout> | null = null;\n private _currentBackoffMs = 0;\n private _inFlight = false;\n\n constructor(opts: ObserverQueueOptions) {\n this._opts = {\n backoffStartMs: 1000,\n backoffCapMs: 30_000,\n ...opts,\n };\n }\n\n push(event: ObservationEvent): void {\n if (this._disabled) return;\n if (this._buffer.length >= this._opts.queueCap) {\n this._buffer.shift();\n this._dropped += 1;\n }\n this._buffer.push(event);\n\n if (this._buffer.length >= this._opts.batchSize) {\n this._scheduleImmediate();\n } else {\n this._scheduleInterval();\n }\n }\n\n async flushNow(): Promise<void> {\n this._clearInterval();\n await this._flush();\n }\n\n stats(): ObserverStats {\n return {\n queued: this._buffer.length,\n sent: this._sent,\n dropped: this._dropped,\n lastError: this._lastError,\n disabled: this._disabled,\n };\n }\n\n private _scheduleImmediate(): void {\n queueMicrotask(() => {\n void this._flush();\n });\n }\n\n private _scheduleInterval(): void {\n if (this._intervalTimer != null) return;\n this._intervalTimer = setTimeout(() => {\n this._intervalTimer = null;\n void this._flush();\n }, this._opts.flushIntervalMs);\n }\n\n private _clearInterval(): void {\n if (this._intervalTimer != null) {\n clearTimeout(this._intervalTimer);\n this._intervalTimer = null;\n }\n }\n\n private async _flush(): Promise<void> {\n if (this._disabled || this._inFlight || this._buffer.length === 0) return;\n this._clearInterval();\n\n const batch = this._buffer.splice(0, this._opts.batchSize);\n this._inFlight = true;\n try {\n await this._opts.flush(batch);\n this._sent += batch.length;\n this._currentBackoffMs = 0;\n this._lastError = null;\n } catch (err) {\n this._buffer.unshift(...batch);\n const perm = (err as FlushError)?.permanent === true;\n this._lastError =\n err instanceof Error ? err.message : String((err as { message?: unknown })?.message ?? err);\n if (perm) {\n this._disabled = true;\n } else {\n this._scheduleBackoff();\n }\n } finally {\n this._inFlight = false;\n }\n }\n\n private _scheduleBackoff(): void {\n const next =\n this._currentBackoffMs === 0\n ? this._opts.backoffStartMs\n : Math.min(this._currentBackoffMs * 2, this._opts.backoffCapMs);\n this._currentBackoffMs = next;\n\n if (this._backoffTimer != null) clearTimeout(this._backoffTimer);\n this._backoffTimer = setTimeout(() => {\n this._backoffTimer = null;\n void this._flush();\n }, next);\n }\n}\n", "/**\n * HTTP transport for the observer queue.\n *\n * Two send paths:\n * - send(batch) \u2014 async fetch. Used for normal flushes. Throws on\n * non-2xx; sets the FlushError.permanent flag for 4xx so the queue\n * stops trying.\n * - sendBeacon(batch) \u2014 fire-and-forget via navigator.sendBeacon.\n * Used on `pagehide` so the last batch survives navigation. No\n * error path \u2014 beacon failure is invisible by design.\n *\n * Auth: same syn_ Bearer token mechanism as /stream. The token is read\n * via a getter so SDK tokens that rotate live get refreshed naturally.\n */\n\nimport type { ObservationEvent } from './allowlist';\n\nexport interface TransportOptions {\n url: string;\n token: () => string;\n getDistinctId: () => string | null;\n}\n\nexport interface Transport {\n send(batch: ObservationEvent[]): Promise<void>;\n sendBeacon(batch: ObservationEvent[]): boolean;\n}\n\ninterface RequestBody {\n distinct_id: string | null;\n batch: ObservationEvent[];\n}\n\nfunction buildBody(distinctId: string | null, batch: ObservationEvent[]): string {\n const body: RequestBody = { distinct_id: distinctId, batch };\n return JSON.stringify(body);\n}\n\nexport function createTransport(opts: TransportOptions): Transport {\n return {\n async send(batch: ObservationEvent[]): Promise<void> {\n const body = buildBody(opts.getDistinctId(), batch);\n const resp = await fetch(opts.url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${opts.token()}`,\n 'Content-Type': 'application/json',\n },\n body,\n keepalive: true,\n credentials: 'include',\n });\n if (!resp.ok) {\n const err = new Error(`observation POST ${resp.status}`) as Error & {\n permanent?: boolean;\n };\n // 4xx is permanent (bad token, malformed payload, etc.) EXCEPT 429:\n // the rate-limit middleware buckets /api/adaptive by workspace token,\n // so a busy site hitting 200/min should back off, not give up forever.\n if (resp.status >= 400 && resp.status < 500 && resp.status !== 429) {\n err.permanent = true;\n }\n throw err;\n }\n },\n\n sendBeacon(batch: ObservationEvent[]): boolean {\n const body = buildBody(opts.getDistinctId(), batch);\n const blob = new Blob([body], { type: 'application/json' });\n const beacon = navigator?.sendBeacon;\n if (typeof beacon !== 'function') return false;\n return beacon.call(navigator, opts.url, blob);\n },\n };\n}\n", "/**\n * Observer entry point.\n *\n * startObserver wires the four pieces \u2014 allowlist filter + queue +\n * transport + PostHog subscription \u2014 into a single lifecycle controlled\n * via the returned handle. The handle is reference-counted: multiple\n * call sites (e.g. multiple chatbot widgets on the same page) share\n * one observer.\n *\n * Idempotent: calling startObserver twice with equivalent options\n * returns the same instance. Calling stop() decrements the ref count;\n * the observer tears down only when the count reaches zero.\n */\n\nimport { matchEvent, type RawEvent } from './allowlist';\nimport { ObserverQueue, type ObserverStats } from './queue';\nimport { createTransport, type Transport } from './transport';\n\nexport interface StartObserverOptions {\n url: string;\n token: () => string;\n getDistinctId: () => string | null;\n observableEvents?: readonly string[];\n /** Test seam: override fetch/timer behavior by injecting a custom transport. */\n transport?: Transport;\n}\n\nexport interface ObserverHandle {\n stop(): void;\n stats(): ObserverStats;\n /** Test seam: ingest a raw event directly without depending on PostHog being loaded. */\n ingest(raw: RawEvent): void;\n flushNow(): Promise<void>;\n}\n\ninterface ActiveObserver {\n refCount: number;\n queue: ObserverQueue;\n unsubscribe: () => void;\n options: StartObserverOptions;\n}\n\nlet _active: ActiveObserver | null = null;\n\nfunction _attachPostHog(\n ingest: (raw: RawEvent) => void,\n _observableEvents: readonly string[]\n): () => void {\n const ph = (globalThis as { posthog?: unknown }).posthog;\n if (!ph) return () => {};\n\n // PostHog's internal hook for \"an event was just captured\". The hook\n // fires for $pageview, $autocapture, $rageclick, $dead_click, and any\n // custom posthog.capture(name, props) call \u2014 exactly what the observer\n // wants. Used by the runtime SDK's bundled dist (smart-canvas.*.js).\n const addHook = (ph as { _addCaptureHook?: unknown })._addCaptureHook;\n if (typeof addHook !== 'function') return () => {};\n\n const handler = (eventName: string, properties: Record<string, unknown> | undefined) => {\n if (typeof eventName !== 'string') return;\n ingest({\n event: eventName,\n timestamp: Date.now(),\n properties: properties ?? {},\n });\n };\n\n // _addCaptureHook returns void in current PostHog SDK versions (no\n // unsubscribe). We accept that the listener leaks for the page lifetime \u2014\n // disabling it lives on the queue's `_disabled` flag instead.\n (addHook as (cb: typeof handler) => void).call(ph, handler);\n return () => {};\n}\n\nfunction _attachPageHide(_transport: Transport, queue: ObserverQueue): () => void {\n const handler = () => {\n const stats = queue.stats();\n if (stats.queued > 0) {\n void queue.flushNow();\n }\n };\n window.addEventListener('pagehide', handler, { capture: true });\n return () => window.removeEventListener('pagehide', handler, { capture: true });\n}\n\nexport function startObserver(opts: StartObserverOptions): ObserverHandle {\n if (_active) {\n _active.refCount += 1;\n return _makeHandle();\n }\n\n const transport = opts.transport ?? createTransport(opts);\n\n const queue = new ObserverQueue({\n batchSize: 10,\n flushIntervalMs: 2000,\n queueCap: 200,\n flush: (batch) => transport.send(batch),\n });\n\n const ingest = (raw: RawEvent) => {\n const ev = matchEvent(raw, { observableEvents: opts.observableEvents });\n if (ev !== null) {\n queue.push(ev);\n }\n };\n\n const unsubscribePh = _attachPostHog(ingest, opts.observableEvents ?? []);\n const unsubscribePageHide = _attachPageHide(transport, queue);\n\n _active = {\n refCount: 1,\n queue,\n unsubscribe: () => {\n unsubscribePh();\n unsubscribePageHide();\n },\n options: opts,\n };\n\n return _makeHandle();\n}\n\nfunction _makeHandle(): ObserverHandle {\n return {\n stop(): void {\n if (!_active) return;\n _active.refCount -= 1;\n if (_active.refCount <= 0) {\n _active.unsubscribe();\n _active = null;\n }\n },\n stats(): ObserverStats {\n return (\n _active?.queue.stats() ?? {\n queued: 0,\n sent: 0,\n dropped: 0,\n lastError: null,\n disabled: true,\n }\n );\n },\n ingest(raw: RawEvent): void {\n if (!_active) return;\n const ev = matchEvent(raw, {\n observableEvents: _active.options.observableEvents,\n });\n if (ev !== null) _active.queue.push(ev);\n },\n flushNow(): Promise<void> {\n return _active?.queue.flushNow() ?? Promise.resolve();\n },\n };\n}\n\n/** Test-only: reset module singleton state. */\nexport function _resetObserverForTests(): void {\n if (_active) {\n _active.unsubscribe();\n _active = null;\n }\n}\n", "/**\n * AdaptiveChatBarMountable \u2014 `MountableWidget` adapter that turns the\n * standalone `<adaptive-chat-bar>` Lit element into something the\n * runtime widget registry can mount.\n *\n * Registered as widget id `adaptive-chatbot:chat-bar`. Customers\n * reference it from canvas config \u2014 either as a slot's `lid` widget\n * (replaces the launcher when referenced from `slots.drawer.lid`) or\n * as a regular tile widget.\n *\n * The bar is a VIEW. State lives in the singleton `chatSession` \u2014\n * whether the bar mounts in the mini-canvas lid, the drawer lid, or\n * both, they're all views of the same conversation. The mountable:\n * - subscribes to chatSession.subscribe() and pushes state into\n * the bar's `messages` + `inFlight` props on every change\n * - routes the bar's `chat-message-sent` event \u2192 chatSession.send()\n * - routes the bar's `chat-interrupt` event \u2192 chatSession.interrupt()\n * - bubbles the bar's `canvas-close` event \u2192 optional onClose\n * callback (canvas-level concern, not session-level)\n *\n * Props (passed via mountConfig):\n * - `placeholder?: string` \u2014 input placeholder copy\n * - `onClose?: () => void` \u2014 fires on \u2715 click (canvas-level)\n *\n * Note: messages and inFlight are NOT props. They flow from chatSession.\n * A canvas-config author who wants to pre-seed messages should do so\n * via the session directly (e.g. via a startup action) \u2014 but typical\n * use is to let the conversation start empty.\n */\n\nimport './AdaptiveChatBar';\nimport type { AdaptiveChatBar } from './AdaptiveChatBar';\nimport { renderFallbackHtml } from './ChatAssistantLit';\nimport type { Unsubscribe } from './ChatSession';\nimport { chatSession } from './ChatSession';\nimport type { ChatTransportConfig } from './ChatTransport';\nimport { chatTransport } from './ChatTransport';\nimport {\n ActionHandler,\n ElementInstanceStore,\n type ElementMutation,\n fetchMountedElements,\n ItemHandler,\n TileHandler,\n} from './elements';\nimport { startObserver } from './observer';\nimport type { ChatbotFallback, ChatbotWidgetRuntime } from './types.js';\n\ninterface ChatBarMountConfig {\n placeholder?: string;\n /** Initial assistant greeting shown before any real conversation. */\n greeting?: string;\n onClose?: () => void;\n /**\n * Backend host for the live chat transport. Same shape as\n * ChatbotConfig.backendUrl. When provided alongside `runtime`, the\n * bar configures the singleton ChatTransport on first mount so\n * sends hit the real `/api/adaptive/stream` SSE pipeline. Omitting\n * either disables the transport \u2014 the bar stays a pure view and\n * nothing replies. Useful for storybook / config-preview surfaces.\n */\n backendUrl?: string;\n /** Runtime injected by WidgetRegistry \u2014 required for backendUrl wiring. */\n runtime?: ChatbotWidgetRuntime;\n /** Optional thread id for conversation continuity across reloads. */\n threadId?: string;\n /**\n * Per-customer \"chat unavailable\" card. Rendered in place of the\n * chat bar when the transport gives up after sustained failure.\n * Mirrors ChatAssistantLit's fallback behaviour.\n */\n fallback?: ChatbotFallback;\n /**\n * Declarations for the LLM-authored UI element pipeline (Phase 5+).\n * When `elementsEnabled === true` AND `uiTemplates` is non-null, the\n * backend exposes `mount_element` / `patch_element` / `unmount_element`\n * tools to the chat agent, scoped to the templates declared here.\n *\n * Shape mirrors `UiTemplatesBlock` from `syntrologie_common.sdk.templates`\n * \u2014 typed loosely on the SDK side because the SDK never introspects\n * templates (it only receives mount/patch/unmount mutations); the\n * backend Pydantic models are the validation gate.\n *\n * Passed verbatim as `forwardedProps.uiTemplates` to the AG-UI\n * transport so the backend's `/api/adaptive/stream` reads them off\n * the inbound request body.\n */\n uiTemplates?: Record<string, unknown>;\n elementsEnabled?: boolean;\n /**\n * Slot name the runtime mounted this chat-bar into (e.g. ``\"drawer\"``,\n * ``\"adaptive-chat\"``). Injected by the host SDK slot components\n * (SyntroCanvasOverlay for the drawer, SyntroInlineSlot for inline\n * slots) so the chat-bar can forward it to the backend as\n * ``X-Active-Lid-Slot``. The backend uses it to mount tiles into the\n * canvas spatially nearest to the lid the visitor is engaging with.\n * Optional \u2014 older host bundles that don't inject this still work;\n * the backend falls back to the template's static default_slot.\n */\n _syntroSlotName?: string;\n}\n\ninterface MountState {\n bar: AdaptiveChatBar;\n cleanup: () => void;\n cfg: ChatBarMountConfig;\n}\n\nconst STATE_KEY = '__syntroChatBarMount';\n\nfunction getState(container: HTMLElement): MountState | null {\n return (container as unknown as Record<string, MountState | undefined>)[STATE_KEY] ?? null;\n}\nfunction setState(container: HTMLElement, state: MountState | null): void {\n (container as unknown as Record<string, MountState | null>)[STATE_KEY] = state;\n}\n\nfunction applyPlaceholder(bar: AdaptiveChatBar, cfg: ChatBarMountConfig): void {\n if (cfg.placeholder !== undefined) bar.placeholder = cfg.placeholder;\n if (cfg.greeting !== undefined) bar.greeting = cfg.greeting;\n}\n\n/**\n * Configure the singleton transport if the caller supplied a backend\n * URL + runtime. Idempotent \u2014 second mount with same args is a no-op.\n * Missing backendUrl OR runtime leaves the transport untouched (the\n * bar is then a pure local view; useful for previews / storybook).\n *\n * Spread (not cherry-pick) so the bar-only fields (placeholder,\n * onClose) flow through silently; ChatTransport ignores them. Cast\n * narrows after the guard.\n */\n/**\n * Lazily-constructed ElementInstanceStore singleton for the chat-bar\n * surface. Mounted on first configure with `elementsEnabled` so the\n * `runtime` closure is captured; subsequent reconfigures with the same\n * runtime reuse it. ChatAssistantLit owns its own store separately \u2014\n * each surface keeps independent state to avoid cross-surface\n * double-mounts on the same instance_id.\n */\nlet _elementStore: ElementInstanceStore | null = null;\n/**\n * Live ``template_id \u2192 widget`` map. Re-derived on each ``configure()``\n * from the chat-bar's ``uiTemplates`` prop (which mirrors what the admin\n * declared in canvas-config). Both the TileHandler (live mount path) and\n * the ElementInstanceStore (rehydrate replay path) read through this map\n * so the widget id stays consistent regardless of mount provenance.\n *\n * Without this, an LLM-authored mount with ``template_id: \"product-card\"``\n * emits ``widget: \"product-card\"`` to the runtime, which then renders the\n * tile chrome with a \"Widget not available: product-card\" body because\n * the actual widget is registered as ``adaptive-product:card``.\n */\nconst _templateWidgetMap = new Map<string, string>();\n\nfunction resolveTileWidget(templateId: string): string | undefined {\n return _templateWidgetMap.get(templateId);\n}\n\nfunction refreshTemplateWidgetMap(uiTemplates: Record<string, unknown> | undefined): void {\n _templateWidgetMap.clear();\n if (!uiTemplates) return;\n const tiles = (uiTemplates as { tiles?: Array<{ id?: unknown; widget?: unknown }> }).tiles;\n if (!Array.isArray(tiles)) return;\n for (const t of tiles) {\n const id = typeof t?.id === 'string' ? t.id : null;\n const widget = typeof t?.widget === 'string' ? t.widget : null;\n if (id && widget) _templateWidgetMap.set(id, widget);\n }\n}\n\nfunction getOrCreateElementStore(runtime: ChatbotWidgetRuntime): ElementInstanceStore {\n if (_elementStore) return _elementStore;\n _elementStore = new ElementInstanceStore({\n actions: runtime.actions,\n // Pass the runtime's event bus so ItemHandler can broadcast\n // `element.compositional_append` / `_patch` / `_remove` events\n // to container widgets (chips strip, FAQ accordion, nav tips).\n events: {\n publish: runtime.events.publish.bind(runtime.events),\n subscribe: runtime.events.subscribe?.bind(runtime.events),\n },\n handlers: [new TileHandler(resolveTileWidget), new ActionHandler(), new ItemHandler()],\n resolveTileWidget,\n });\n return _elementStore;\n}\n\n/**\n * Track whether we've already hydrated this store's snapshot. The store\n * itself is a singleton across mounts in the same page session, so we\n * want to hydrate exactly ONCE \u2014 repeated mounts (e.g. after an SPA\n * navigation that unmounts + remounts the chat-bar) reuse the warm\n * store without re-firing handler.mount() for every persisted item.\n *\n * The store's own version-dedup also prevents double-application, but\n * we still don't want to issue redundant HTTP requests on every mount.\n */\nlet _hydrationStarted = false;\n\nfunction hydrateOnce(runtime: ChatbotWidgetRuntime, backendUrl: string): void {\n if (_hydrationStarted) return;\n _hydrationStarted = true;\n const store = getOrCreateElementStore(runtime);\n // The fetcher reads `window.__SYNTRO_CONFIG__.token` by default; the\n // boot path already populated that. Empty/missing backendUrl falls\n // back to a same-origin relative endpoint so dev-server proxies\n // (Vite, Webpack) and host pages serving the SDK from their own\n // domain work without extra config. Same-origin is also the only\n // path that lets the `syntro_chat_session` cookie ride along \u2014 Lax\n // cookies don't follow cross-origin fetches.\n const trimmed = backendUrl.replace(/\\/$/, '');\n const endpoint = trimmed\n ? `${trimmed}/api/adaptive/mounted_elements`\n : '/api/adaptive/mounted_elements';\n fetchMountedElements({ endpoint }).then((response) => {\n if (!response) return; // 404 / network error / feature off \u2014 silent no-op\n // Hydrate replays each instance through its handler.mount(); for\n // ItemHandler that publishes `element.compositional_append` events,\n // which the chips strip subscribes to and re-inserts. Effects are\n // NOT replayed \u2014 they were never persisted in mounted_elements\n // (`_emit_effect_envelope` in the agent skips persistence).\n void store.hydrate(response.mounted_elements);\n });\n}\n\nfunction configureTransportIfPossible(cfg: ChatBarMountConfig): void {\n // backendUrl === \"\" is a valid configuration \u2014 the chat-bar makes\n // relative-URL fetches and the host page's dev-server proxy (or\n // production reverse proxy) forwards `/api/...` to the backend.\n // This keeps the chat on the page's own origin, which lets cookies\n // ride along even when the backend container is on a different host.\n if (cfg.backendUrl === undefined || !cfg.runtime) return;\n // Translate the element-instantiation declarations into the opaque\n // `forwardedProps` bag the transport ships on every AG-UI request.\n // Only attach when the feature is on AND templates are declared \u2014\n // otherwise the backend stays in its safe-default (feature_disabled)\n // path and the tools are never exposed.\n const elementsActive = cfg.elementsEnabled === true && cfg.uiTemplates != null;\n // Refresh the template\u2192widget map on every configure (and clear it\n // when elements are off) so live mounts and replays resolve the same\n // widget id. Done before getOrCreateElementStore below since the\n // store reads through ``resolveTileWidget`` at construction.\n refreshTemplateWidgetMap(elementsActive ? cfg.uiTemplates : undefined);\n const forwardedProps: Record<string, unknown> | undefined = elementsActive\n ? { elementsEnabled: true, uiTemplates: cfg.uiTemplates }\n : undefined;\n\n // Wire the `syntro.element.mutation` envelope route to a per-surface\n // ElementInstanceStore. The store applies mounts/patches/unmounts to\n // the host page via the runtime's ActionEngine. ChatAssistantLit has\n // its own equivalent wiring (it instantiates AgUiTransport directly,\n // not via this singleton); the lid surface needs the same routing\n // here so mount_element results actually land.\n const runtime = cfg.runtime;\n const onElementMutation = elementsActive\n ? (mutations: ElementMutation[]) => {\n void getOrCreateElementStore(runtime).apply(mutations);\n }\n : undefined;\n\n // Hydrate the element store from the backend session on first chat-bar\n // mount. Async \u2014 by the time the response arrives, container widgets\n // (chips strip, FAQ accordion) have already subscribed to the event\n // bus, so the replay events land in their subscribers. Items mounted\n // by the LLM in previous turns survive SPA navigation + page reload\n // for the lifetime of the AdaptiveSession (~24h default).\n if (elementsActive) {\n hydrateOnce(runtime, cfg.backendUrl);\n }\n\n chatTransport.configure({\n ...cfg,\n forwardedProps,\n onElementMutation,\n activeLidSlot: cfg._syntroSlotName,\n } as ChatTransportConfig);\n\n // Wire the visitor-activity observer once the transport is configured.\n // The observer subscribes to PostHog's capture hook and POSTs batched\n // `nav` / `click` / `form` / `rage` / `dead` events to\n // `/api/adaptive/observation` so the next ``/stream`` turn arrives\n // with `recent_observations` populated \u2014 that's what answers\n // \"what did the visitor just do?\" from the agent's perspective.\n // Without this the observer module is dead code: events sit in\n // PostHog with no path into the agent prompt.\n //\n // Idempotent + ref-counted in `startObserver`, so multiple chat-bar\n // mounts (drawer lid + page anchor) share one observer.\n startObserverIfPossible(cfg);\n}\n\nlet _observerStarted = false;\n\nfunction startObserverIfPossible(cfg: ChatBarMountConfig): void {\n if (_observerStarted) return;\n if (typeof window === 'undefined') return;\n const runtime = cfg.runtime as\n | undefined\n | { events?: { subscribe?: (filter: unknown, cb: (e: unknown) => void) => () => void } };\n if (!runtime?.events?.subscribe) return;\n // Same-origin or backend-relative URL \u2014 mirror the transport's path\n // building so the observer hits the same backend instance the chat\n // is talking to.\n const trimmed = (cfg.backendUrl ?? '').replace(/\\/$/, '');\n const url = trimmed ? `${trimmed}/api/adaptive/observation` : '/api/adaptive/observation';\n // Distinct id from PostHog when available; falls back to null and\n // the backend keys observations purely by session id in that case.\n const getDistinctId = (): string | null => {\n const ph = (window as { posthog?: { get_distinct_id?: () => string } }).posthog;\n try {\n const v = ph?.get_distinct_id?.();\n return typeof v === 'string' && v.length > 0 ? v : null;\n } catch {\n return null;\n }\n };\n const token = (): string => {\n const c = (window as { __SYNTRO_CONFIG__?: { token?: string } }).__SYNTRO_CONFIG__;\n return typeof c?.token === 'string' ? c.token : '';\n };\n // startObserver's PostHog auto-attach is a no-op in environments where\n // `window.posthog` isn't directly exposed (most production builds \u2014\n // PostHog is wrapped by the SDK telemetry layer and surfaced through\n // `SynOS.runtime.events`, not via the global). We always start it for\n // the queue + transport plumbing, then subscribe to the runtime event\n // bus and translate normalized events back into the `RawEvent` shape\n // the observer's allowlist expects.\n const handle = startObserver({ url, token, getDistinctId });\n // Expose queue stats on the window for in-page diagnostics. Lets a\n // tester verify events are queueing / flushing via the devtools\n // console without bouncing into source. Cheap; harmless in prod.\n (window as { __syntroObserverStats?: () => unknown }).__syntroObserverStats = () =>\n handle.stats();\n runtime.events.subscribe({}, (evt: unknown) => {\n const e = evt as {\n ts?: number;\n name?: string;\n source?: string;\n props?: Record<string, unknown> & { originalEvent?: string };\n };\n if (!e?.name) return;\n const ts = typeof e.ts === 'number' ? e.ts : Date.now();\n // Two-path translation. The allowlist's `matchEvent` switches on\n // `event` name, so we just hand it the right name in either case:\n //\n // 1. PostHog-originated events arrive with `source: 'posthog'`\n // and `props.originalEvent` carrying the raw `$pageview` /\n // `$autocapture` name. Re-prefix `pathname`/`url` to their\n // `$`-prefixed forms so the PostHog matchers find them.\n // 2. Canonical runtime-bus events (`nav.section_viewed`,\n // `nav.scroll_depth`, `ui.scroll_thrash`, `ui.hover`, \u2026)\n // come straight from runtime-sdk instrumentation. Forward the\n // canonical name as-is \u2014 the allowlist has explicit cases for\n // each one.\n if (e.source === 'posthog') {\n const original = e.props?.originalEvent;\n if (typeof original !== 'string' || original.length === 0) return;\n const properties: Record<string, unknown> = { ...(e.props ?? {}) };\n if (typeof e.props?.pathname === 'string') properties.$pathname = e.props.pathname;\n if (typeof e.props?.url === 'string') properties.$current_url = e.props.url;\n handle.ingest({ event: original, timestamp: ts, properties });\n return;\n }\n // Forward canonical names directly. The allowlist drops any name\n // it doesn't know, so listing everything here is safe \u2014 match\n // decides what reaches the agent's observation tail.\n handle.ingest({\n event: e.name,\n timestamp: ts,\n properties: { ...(e.props ?? {}) },\n });\n });\n _observerStarted = true;\n}\n\nfunction wireListeners(bar: AdaptiveChatBar, state: MountState): Unsubscribe {\n const onMessageSent = (e: Event) => {\n const text = (e as CustomEvent<{ text: string }>).detail.text;\n chatSession.send(text);\n // If no transport is listening for sends (no backendUrl in\n // mountConfig, the runtime injection didn't happen, or a test\n // didn't wire one up) the session would sit in `inFlight: true`\n // forever. Surface a clear, actionable error so the user sees\n // *something* rather than an indefinitely-spinning stop button.\n if (!chatSession.hasTransport()) {\n chatSession.error('Chat backend not configured \u2014 set backendUrl in the canvas config.');\n }\n };\n const onInterrupt = () => {\n chatSession.interrupt();\n };\n const onToolCallApproved = (e: Event) => {\n const detail = (e as CustomEvent<{ toolCallId: string; approved: boolean }>).detail;\n // Default to an empty-object result \u2014 the agent re-runs with the\n // approval signal. Hosts that want richer results (e.g. a form\n // result payload) can listen for `trail-toolcall-approved` higher\n // up and call chatSession.resolveToolCall themselves.\n chatSession.resolveToolCall(detail.toolCallId, {}, detail.approved);\n };\n // onClose reads state.cfg fresh on each invocation so update() can\n // swap the callback without re-wiring listeners.\n const onClose = () => {\n state.cfg.onClose?.();\n };\n bar.addEventListener('chat-message-sent', onMessageSent);\n bar.addEventListener('chat-interrupt', onInterrupt);\n bar.addEventListener('canvas-close', onClose);\n bar.addEventListener('trail-toolcall-approved', onToolCallApproved);\n return () => {\n bar.removeEventListener('chat-message-sent', onMessageSent);\n bar.removeEventListener('chat-interrupt', onInterrupt);\n bar.removeEventListener('canvas-close', onClose);\n bar.removeEventListener('trail-toolcall-approved', onToolCallApproved);\n };\n}\n\nexport const AdaptiveChatBarMountable = {\n mount(container: HTMLElement, mountConfig?: Record<string, unknown>): () => void {\n const cfg = (mountConfig ?? {}) as ChatBarMountConfig;\n configureTransportIfPossible(cfg);\n const bar = document.createElement('adaptive-chat-bar') as AdaptiveChatBar;\n applyPlaceholder(bar, cfg);\n\n // Subscribe to the shared session. Fires immediately with the\n // current state so the bar reflects any pre-existing conversation.\n const unsubSession = chatSession.subscribe((s) => {\n bar.messages = [...s.messages];\n bar.inFlight = s.inFlight;\n });\n\n // state holds the mutable cfg so update() can swap callbacks\n // without forcing a listener re-wire.\n const state = { bar, cleanup: () => {}, cfg };\n const unwireListeners = wireListeners(bar, state);\n\n container.appendChild(bar);\n\n // Subscribe to the transport's fallback signal. When the transport\n // gives up after sustained failure, replace the bar with the\n // per-customer \"chat unavailable\" card. One-shot \u2014 fallback fires\n // once per configure cycle, so we don't need to track re-mounts.\n const unsubFallback = chatTransport.onFallback(() => {\n bar.remove();\n container.innerHTML = renderFallbackHtml(state.cfg.fallback);\n });\n\n state.cleanup = () => {\n unsubSession();\n unsubFallback();\n unwireListeners();\n bar.remove();\n setState(container, null);\n };\n\n setState(container, state);\n return state.cleanup;\n },\n\n update(container: HTMLElement, mountConfig?: Record<string, unknown>): void {\n const state = getState(container);\n if (!state) return;\n const cfg = (mountConfig ?? {}) as ChatBarMountConfig;\n configureTransportIfPossible(cfg);\n applyPlaceholder(state.bar, cfg);\n state.cfg = cfg;\n },\n};\n", "/**\n * AdaptiveChipsStripMountable \u2014 `MountableWidget` adapter for\n * `<adaptive-chips-strip>`. Registered as widget id\n * `adaptive-chatbot:chips-strip`.\n *\n * Mirrors `AdaptiveChatBarMountable`: creates the Lit element, forwards\n * props, bridges DOM events \u2192 prop callbacks, cleans up on unmount.\n *\n * Props (passed via mountConfig):\n * - `chips: SuggestionChip[]` \u2014 the strip's contents (required)\n * - `onChipRevealed?: ({id, payload}) => void` \u2014 fires when a chip\n * is opened\n * - `onChipDismissed?: ({id}) => void` \u2014 fires when \u00D7 is clicked\n *\n * The runtime registry injects `runtime` into mountConfig (see\n * `WidgetRegistry.mount`). We forward it as `runtimeRef` on the strip\n * so it can mount chip payload widgets through the same registry.\n */\n\nimport './AdaptiveChipsStrip';\nimport type { AdaptiveChipsStrip, SuggestionChip } from './AdaptiveChipsStrip';\n\ninterface ChipsStripMountConfig {\n chips?: SuggestionChip[];\n onChipRevealed?: (detail: { id: string; payload: SuggestionChip['config']['payload'] }) => void;\n onChipDismissed?: (detail: { id: string }) => void;\n // Injected by WidgetRegistry \u2014 see runtime-sdk/src/widgets/WidgetRegistry.ts.\n runtime?: unknown;\n // Injected by SyntroTileCard from the tile's resolved chromeless\n // state (which itself comes from `slot.theme.chromeless` with\n // `tile.chromeless` as the per-tile override).\n chromeless?: boolean;\n}\n\ninterface MountState {\n strip: AdaptiveChipsStrip;\n listeners: {\n revealed: (e: Event) => void;\n dismissed: (e: Event) => void;\n };\n}\n\nconst STATE_KEY = '__syntroChipsStripMount';\n\nfunction getState(container: HTMLElement): MountState | null {\n return (container as unknown as Record<string, MountState | undefined>)[STATE_KEY] ?? null;\n}\nfunction setState(container: HTMLElement, state: MountState | null): void {\n (container as unknown as Record<string, MountState | null>)[STATE_KEY] = state;\n}\n\nfunction applyProps(strip: AdaptiveChipsStrip, cfg: ChipsStripMountConfig): void {\n if (cfg.chips !== undefined) strip.chips = cfg.chips;\n // `runtime` arrives in every mountConfig from the WidgetRegistry \u2014\n // forward it so the strip can resolve + mount payload widgets.\n if (cfg.runtime !== undefined) {\n strip.runtimeRef = cfg.runtime as AdaptiveChipsStrip['runtimeRef'];\n }\n if (cfg.chromeless !== undefined) strip.chromeless = cfg.chromeless;\n}\n\nexport const AdaptiveChipsStripMountable = {\n mount(container: HTMLElement, mountConfig?: Record<string, unknown>): () => void {\n const cfg = (mountConfig ?? {}) as ChipsStripMountConfig;\n const strip = document.createElement('adaptive-chips-strip') as AdaptiveChipsStrip;\n applyProps(strip, cfg);\n\n const state: MountState = {\n strip,\n listeners: {\n revealed: (e) => {\n const cb = cfg.onChipRevealed;\n if (cb) {\n cb(\n (e as CustomEvent<{ id: string; payload: SuggestionChip['config']['payload'] }>)\n .detail\n );\n }\n },\n dismissed: (e) => {\n const cb = cfg.onChipDismissed;\n if (cb) cb((e as CustomEvent<{ id: string }>).detail);\n },\n },\n };\n strip.addEventListener('chip-revealed', state.listeners.revealed);\n strip.addEventListener('chip-dismissed', state.listeners.dismissed);\n\n container.appendChild(strip);\n setState(container, state);\n\n return () => {\n strip.removeEventListener('chip-revealed', state.listeners.revealed);\n strip.removeEventListener('chip-dismissed', state.listeners.dismissed);\n strip.remove();\n setState(container, null);\n };\n },\n\n update(container: HTMLElement, mountConfig?: Record<string, unknown>): void {\n const state = getState(container);\n if (!state) return;\n const cfg = (mountConfig ?? {}) as ChipsStripMountConfig;\n applyProps(state.strip, cfg);\n // Re-wire callback listeners so the new cfg's handlers fire.\n state.strip.removeEventListener('chip-revealed', state.listeners.revealed);\n state.strip.removeEventListener('chip-dismissed', state.listeners.dismissed);\n state.listeners.revealed = (e) => {\n const cb = cfg.onChipRevealed;\n if (cb) {\n cb((e as CustomEvent<{ id: string; payload: SuggestionChip['config']['payload'] }>).detail);\n }\n };\n state.listeners.dismissed = (e) => {\n const cb = cfg.onChipDismissed;\n if (cb) cb((e as CustomEvent<{ id: string }>).detail);\n };\n state.strip.addEventListener('chip-revealed', state.listeners.revealed);\n state.strip.addEventListener('chip-dismissed', state.listeners.dismissed);\n },\n};\n", "/**\n * NavLinkMountable \u2014 `MountableWidget` used as the payload of an\n * LLM-authored navigation chip.\n *\n * Flow:\n * LLM mounts `suggest-navigation` ItemTemplate with `{title, url}`\n * \u2192 backend builds chip with payload `{widget: 'adaptive-chatbot:nav-link', props: {url}}`\n * \u2192 user clicks the chip \u2192 chips-strip mounts THIS widget into the\n * chip's drawer\n * \u2192 user clicks the \"Go to <url>\" button this widget renders\n * \u2192 same-origin SPA navigation via pushState + popstate (matches\n * `adaptive-nav`'s `executeNavigate` path for SPA-router compatibility)\n *\n * Registered as widget id `adaptive-chatbot:nav-link`.\n *\n * Security note: only http(s), same-origin destinations are honored.\n * `javascript:`, `data:`, and cross-origin URLs are silently dropped at\n * URL construction. The ItemTemplate's EnumField allowlist is the\n * primary constraint; this is defense-in-depth.\n */\n\ninterface NavLinkProps {\n url?: string;\n /** Optional override for the button label. Defaults to \"Go to <url>\".\n * The chip's title already advertises the destination; this is just\n * the call-to-action verb. */\n label?: string;\n}\n\ninterface MountState {\n button: HTMLButtonElement;\n cfg: NavLinkProps;\n onClick: (e: Event) => void;\n}\n\nconst STATE_KEY = '__syntroNavLinkMount';\n\nfunction getState(container: HTMLElement): MountState | null {\n return (container as unknown as Record<string, MountState | undefined>)[STATE_KEY] ?? null;\n}\nfunction setState(container: HTMLElement, state: MountState | null): void {\n (container as unknown as Record<string, MountState | null>)[STATE_KEY] = state;\n}\n\nfunction navigateTo(rawUrl: string): void {\n if (!rawUrl) return;\n let resolved: URL;\n try {\n resolved = new URL(rawUrl, window.location.origin);\n } catch {\n return;\n }\n if (resolved.origin !== window.location.origin) return;\n if (resolved.protocol !== 'http:' && resolved.protocol !== 'https:') return;\n window.history.pushState(null, '', resolved.toString());\n window.dispatchEvent(new PopStateEvent('popstate'));\n}\n\nfunction buildButton(cfg: NavLinkProps): HTMLButtonElement {\n const button = document.createElement('button');\n button.type = 'button';\n button.dataset.syntroNavLink = '';\n button.style.display = 'inline-flex';\n button.style.alignItems = 'center';\n button.style.gap = '6px';\n button.style.padding = '6px 12px';\n button.style.borderRadius = '8px';\n button.style.fontFamily = \"var(--sc-font-family, 'system-ui')\";\n button.style.fontSize = '12px';\n button.style.fontWeight = '600';\n button.style.cursor = 'pointer';\n button.style.color = 'var(--sc-accent-foreground, currentColor)';\n button.style.background = 'hsl(var(--sc-accent-color) / 0.85)';\n button.style.border = '1px solid hsl(var(--sc-accent-color) / 0.30)';\n applyLabel(button, cfg);\n return button;\n}\n\nfunction applyLabel(button: HTMLButtonElement, cfg: NavLinkProps): void {\n const url = String(cfg.url ?? '');\n const label = cfg.label ?? (url ? `Go to ${url}` : 'Go');\n // textContent (not innerHTML) \u2014 LLM-authored URLs are an enum on the\n // backend so injection isn't realistic, but defense-in-depth is cheap.\n button.textContent = label;\n}\n\nexport const NavLinkMountable = {\n mount(container: HTMLElement, mountConfig?: Record<string, unknown>): () => void {\n const cfg = (mountConfig ?? {}) as NavLinkProps;\n const button = buildButton(cfg);\n const onClick = (_e: Event): void => {\n const current = getState(container);\n const url = current?.cfg.url ?? cfg.url;\n navigateTo(String(url ?? ''));\n };\n button.addEventListener('click', onClick);\n container.appendChild(button);\n setState(container, { button, cfg, onClick });\n return () => {\n button.removeEventListener('click', onClick);\n button.remove();\n setState(container, null);\n };\n },\n\n update(container: HTMLElement, mountConfig?: Record<string, unknown>): void {\n const state = getState(container);\n if (!state) return;\n const cfg = (mountConfig ?? {}) as NavLinkProps;\n applyLabel(state.button, cfg);\n state.cfg = cfg;\n },\n};\n", "/**\n * TextAnswerMountable \u2014 `MountableWidget` for the simplest chip payload\n * kind: a single paragraph of body text.\n *\n * Registered as widget id `adaptive-chatbot:text-answer`. Used by\n * `AdaptiveChipsStrip` when a chip's payload references it.\n *\n * Replaces the old hand-rolled resolver path. Customers wanting richer\n * payloads (markdown, mini-product cards, embedded charts, etc.) ship\n * their own mountable through the same registry \u2014 no special\n * resolver-map seam.\n */\n\ninterface TextAnswerProps {\n text?: string;\n}\n\ninterface MountState {\n paragraph: HTMLParagraphElement;\n cfg: TextAnswerProps;\n}\n\nconst STATE_KEY = '__syntroTextAnswerMount';\n\nfunction getState(container: HTMLElement): MountState | null {\n return (container as unknown as Record<string, MountState | undefined>)[STATE_KEY] ?? null;\n}\nfunction setState(container: HTMLElement, state: MountState | null): void {\n (container as unknown as Record<string, MountState | null>)[STATE_KEY] = state;\n}\n\nfunction applyText(p: HTMLParagraphElement, text: string): void {\n p.textContent = text;\n}\n\nexport const TextAnswerMountable = {\n mount(container: HTMLElement, mountConfig?: Record<string, unknown>): () => void {\n const cfg = (mountConfig ?? {}) as TextAnswerProps;\n const paragraph = document.createElement('p');\n paragraph.dataset.syntroTextAnswer = '';\n // Keep the styling minimal \u2014 paragraph inherits the slot's\n // `--sc-tile-text-color` (set by the chips strip's drawer chrome)\n // so the text reads consistently against the host's surface.\n paragraph.style.margin = '0';\n paragraph.style.fontSize = '12px';\n paragraph.style.lineHeight = '1.55';\n paragraph.style.color = 'var(--sc-tile-text-color, currentColor)';\n applyText(paragraph, String(cfg.text ?? ''));\n container.appendChild(paragraph);\n\n setState(container, { paragraph, cfg });\n return () => {\n paragraph.remove();\n setState(container, null);\n };\n },\n\n update(container: HTMLElement, mountConfig?: Record<string, unknown>): void {\n const state = getState(container);\n if (!state) return;\n const cfg = (mountConfig ?? {}) as TextAnswerProps;\n applyText(state.paragraph, String(cfg.text ?? ''));\n state.cfg = cfg;\n },\n};\n", "/**\n * Adaptive Chatbot - Runtime Module\n *\n * Runtime manifest for the AI chat assistant adaptive.\n * Uses @syntrologie/chat for the UI \u2014 no React dependency.\n *\n * Chat surfaces are config-driven: customers reference the chat-bar\n * widget id (`adaptive-chatbot:chat-bar`) from `slots.drawer.lid` (to\n * replace the launcher FAB) or any other slot's `lid` / tile slot. The\n * adaptive no longer auto-registers a canvas lid renderer.\n */\n\n// Side-effect imports so the custom elements register with the global\n// registry as soon as the adaptive is loaded.\nimport './AdaptiveChatBar';\nimport './AdaptiveChatTrail';\nimport { AdaptiveChatBarMountable } from './AdaptiveChatBarMountable';\nimport { AdaptiveChipsStripMountable } from './AdaptiveChipsStripMountable';\nimport { ChatAssistantLitMountable } from './ChatAssistantLit';\nimport { NavLinkMountable } from './NavLinkMountable';\nimport { TextAnswerMountable } from './TextAnswerMountable';\n\nexport const runtime = {\n id: 'adaptive-chatbot',\n version: '2.0.0',\n name: 'Chat Assistant',\n description: 'AI chat assistant powered by @syntrologie/chat with SSE transport',\n\n executors: [],\n\n widgets: [\n {\n id: 'adaptive-chatbot:assistant',\n component: ChatAssistantLitMountable,\n metadata: {\n name: 'Chat Assistant',\n description: 'AI-powered chat assistant with SSE streaming and A2UI support',\n icon: '\uD83D\uDCAC',\n },\n },\n // PRD \u00A73 chat lid: the standalone chat bar UI shell. Used as a slot\n // `lid` widget (where it replaces the launcher) or as a regular\n // tile widget (renders inside the drawer). Headless of any chat\n // transport \u2014 emits chat-message-sent / chat-interrupt / canvas-close\n // for the parent to wire to whatever pipeline it owns.\n {\n id: 'adaptive-chatbot:chat-bar',\n component: AdaptiveChatBarMountable,\n metadata: {\n name: 'Chat Bar',\n description:\n 'Always-visible chat input row with bubble-up trail. Headless \u2014 wire to your own transport.',\n icon: '\u2726',\n },\n },\n // PRD \u00A74.5 suggested-chips tile: horizontally-wrapping chip strip\n // with click-to-reveal payload drawer. Each chip is a\n // `suggestions:chip` action.\n {\n id: 'adaptive-chatbot:chips-strip',\n component: AdaptiveChipsStripMountable,\n metadata: {\n name: 'Suggested Chips',\n description: 'Wrapping chip strip with click-to-reveal payloads.',\n icon: '\u2728',\n },\n },\n // Built-in chip payload \u2014 a single paragraph of body text. Chip\n // payloads are widget references (same {widget,props} shape as\n // tile/lid configs); this is the simplest one shipped out of the\n // box so the chip pattern works without requiring a downstream\n // adaptive for a \"just answer with text\" case.\n {\n id: 'adaptive-chatbot:text-answer',\n component: TextAnswerMountable,\n metadata: {\n name: 'Text Answer',\n description: 'Single paragraph payload \u2014 the default chip-drawer content.',\n icon: '\u00B6',\n },\n },\n // Chip payload for LLM-authored navigation suggestions. Backed by\n // the `suggest-navigation` ItemTemplate: the backend wraps a curated\n // URL into props.url, the chip's payload-drawer mounts this widget,\n // user clicks \"Go to <url>\" \u2192 same-origin SPA navigation. Kept here\n // (not in adaptive-nav) so chip payloads ship with the chatbot\n // bundle that already provides chips-strip + text-answer.\n {\n id: 'adaptive-chatbot:nav-link',\n component: NavLinkMountable,\n metadata: {\n name: 'Nav Link',\n description:\n 'Same-origin navigation button \u2014 used as a chip payload for LLM-authored nav suggestions.',\n icon: '\u2192',\n },\n },\n ],\n};\n\nexport default runtime;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAiDO,IAAM,2BAA2B;AAOxC,SAAS,eAAe,OAAuC;AAC7D,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,IAAI;AACV,UACG,OAAO,EAAE,OAAO,YAAY,OAAO,EAAE,OAAO,cAC5C,EAAE,SAAS,UAAU,EAAE,SAAS,eAAe,EAAE,SAAS,aAC3D,OAAO,EAAE,SAAS;AAEtB;AAEA,SAAS,kBAAyC;AAChD,MAAI;AACF,UAAM,MAAM,WAAW,cAAc,QAAQ,wBAAwB;AACrE,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,CAAC,UAAU,CAAC,MAAM,QAAQ,OAAO,QAAQ,EAAG,QAAO;AACvD,UAAM,WAAW,OAAO,SAAS,OAAO,cAAc;AACtD,UAAM,SAAS,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS,SAAS,SAAS;AACrF,WAAO,EAAE,UAAU,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,cAAN,MAAkB;AAAA,EAUvB,cAAc;AATd,SAAQ,YAA4B,CAAC;AACrC,SAAQ,YAAY;AACpB,SAAQ,UAAU;AAElB,SAAQ,cAAc,oBAAI,IAA2B;AACrD,SAAQ,gBAAgB,oBAAI,IAAkB;AAC9C,SAAQ,qBAAqB,oBAAI,IAAuB;AACxD,SAAQ,sBAAsB,oBAAI,IAAwB;AAGxD,UAAM,WAAW,gBAAgB;AACjC,QAAI,UAAU;AACZ,WAAK,YAAY,SAAS;AAC1B,WAAK,UAAU,SAAS;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA,EAGA,WAA6B;AAC3B,WAAO,EAAE,UAAU,CAAC,GAAG,KAAK,SAAS,GAAG,UAAU,KAAK,UAAU;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,IAAwC;AAChD,SAAK,YAAY,IAAI,EAAE;AACvB,OAAG,KAAK,SAAS,CAAC;AAClB,WAAO,MAAM;AACX,WAAK,YAAY,OAAO,EAAE;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAK,MAAoB;AACvB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,QAAS;AACd,SAAK,UAAU,KAAK,EAAE,IAAI,KAAK,WAAW,MAAM,QAAQ,MAAM,QAAQ,CAAC;AACvE,SAAK,YAAY;AACjB,SAAK,OAAO;AACZ,eAAW,YAAY,KAAK,cAAe,UAAS,EAAE,MAAM,QAAQ,CAAC;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,MAAoB;AAC1B,UAAM,KAAK,KAAK,KAAK,SAAS;AAC9B,SAAK,UAAU,KAAK,EAAE,IAAI,MAAM,aAAa,MAAM,QAAQ,WAAW,CAAC;AACvE,SAAK,YAAY;AACjB,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,IAAkB;AAC7B,SAAK,UAAU,KAAK,EAAE,IAAI,MAAM,aAAa,MAAM,IAAI,QAAQ,YAAY,CAAC;AAC5E,SAAK,YAAY;AACjB,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,IAAY,OAAqB;AAC5C,UAAM,MAAM,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAClD,QAAI,CAAC,OAAO,IAAI,WAAW,YAAa;AACxC,QAAI,QAAQ;AACZ,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,IAAkB;AAC3B,UAAM,MAAM,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAClD,QAAI,OAAO,IAAI,WAAW,aAAa;AACrC,UAAI,SAAS;AAAA,IACf;AACA,SAAK,YAAY;AACjB,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SAAuB;AAC3B,eAAW,KAAK,KAAK,WAAW;AAC9B,UAAI,EAAE,WAAW,YAAa,GAAE,SAAS;AAAA,IAC3C;AACA,SAAK,UAAU,KAAK;AAAA,MAClB,IAAI,OAAO,KAAK,SAAS;AAAA,MACzB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,QAAQ;AAAA,IACV,CAAC;AACD,SAAK,YAAY;AACjB,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAkB;AAChB,QAAI,CAAC,KAAK,UAAW;AACrB,SAAK,YAAY;AACjB,SAAK,OAAO;AACZ,eAAW,YAAY,KAAK,mBAAoB,UAAS;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAc;AACZ,SAAK,YAAY,CAAC;AAClB,SAAK,YAAY;AACjB,SAAK,UAAU;AACf,SAAK,OAAO;AAAA,EACd;AAAA;AAAA,EAGA,OAAO,UAAqC;AAC1C,SAAK,cAAc,IAAI,QAAQ;AAC/B,WAAO,MAAM;AACX,WAAK,cAAc,OAAO,QAAQ;AAAA,IACpC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAwB;AACtB,WAAO,KAAK,cAAc,OAAO;AAAA,EACnC;AAAA;AAAA,EAGA,YAAY,UAA0C;AACpD,SAAK,mBAAmB,IAAI,QAAQ;AACpC,WAAO,MAAM;AACX,WAAK,mBAAmB,OAAO,QAAQ;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,UAA2C;AACtD,SAAK,oBAAoB,IAAI,QAAQ;AACrC,WAAO,MAAM;AACX,WAAK,oBAAoB,OAAO,QAAQ;AAAA,IAC1C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,YAAY,WAA4B,UAA+B;AACrE,UAAM,MAAM,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,SAAS;AACzD,QAAI,CAAC,IAAK;AACV,QAAI,YAAY,CAAC,GAAI,IAAI,aAAa,CAAC,GAAI,EAAE,GAAG,SAAS,CAAC;AAC1D,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,YAAoB,OAAqC;AACtE,eAAW,OAAO,KAAK,WAAW;AAChC,YAAM,MAAM,IAAI;AAChB,UAAI,CAAC,IAAK;AACV,YAAM,MAAM,IAAI,UAAU,CAAC,OAAO,GAAG,OAAO,UAAU;AACtD,UAAI,QAAQ,GAAI;AAChB,YAAM,OAAO,CAAC,GAAG,GAAG;AACpB,WAAK,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,GAAG,GAAG,MAAM;AACrC,UAAI,YAAY;AAChB,WAAK,OAAO;AACZ;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,gBAAgB,YAAoB,QAAiB,UAAyB;AAC5E,QAAI,QAAQ;AACZ,eAAW,OAAO,KAAK,WAAW;AAChC,YAAM,MAAM,IAAI;AAChB,UAAI,CAAC,IAAK;AACV,YAAM,MAAM,IAAI,UAAU,CAAC,OAAO,GAAG,OAAO,UAAU;AACtD,UAAI,QAAQ,GAAI;AAChB,YAAM,OAAO,CAAC,GAAG,GAAG;AACpB,WAAK,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,GAAG,QAAQ,OAAO;AAC3C,UAAI,YAAY;AAChB,cAAQ;AACR;AAAA,IACF;AACA,QAAI,CAAC,MAAO;AACZ,SAAK,OAAO;AACZ,eAAW,YAAY,KAAK,qBAAqB;AAC/C,eAAS,EAAE,YAAY,QAAQ,SAAS,CAAC;AAAA,IAC3C;AAAA,EACF;AAAA,EAEQ,SAAe;AACrB,UAAM,QAAQ,KAAK,SAAS;AAC5B,SAAK,QAAQ;AACb,eAAW,OAAO,KAAK,YAAa,KAAI,KAAK;AAAA,EAC/C;AAAA,EAEQ,UAAgB;AACtB,QAAI;AACF,UAAI,KAAK,UAAU,WAAW,GAAG;AAC/B,mBAAW,cAAc,WAAW,wBAAwB;AAC5D;AAAA,MACF;AACA,YAAM,UAA0B,EAAE,UAAU,KAAK,WAAW,QAAQ,KAAK,QAAQ;AACjF,iBAAW,cAAc,QAAQ,0BAA0B,KAAK,UAAU,OAAO,CAAC;AAAA,IACpF,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAYO,IAAM,cAAc,IAAI,YAAY;;;AC3NpC,IAAM,uBAAuB;AAmCpC,SAAS,kBAAsC;AAC7C,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,MAAO,OAAiE;AAC9E,QAAM,QAAQ,KAAK;AACnB,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AACjE;AAQA,SAAS,SAAS,MAAuB;AACvC,MAAI,OAAO,WAAW,YAAa;AACnC,MAAK,OAA0D,uBAAuB;AACpF,YAAQ,MAAM,oBAAoB,GAAG,IAAI;AAAA,EAC3C;AACF;AAEO,IAAM,gBAAN,MAAoB;AAAA,EAApB;AACL,SAAQ,UAAsC;AAC9C,SAAQ,UAA+B;AACvC,SAAQ,QAA8B;AACtC,SAAQ,kBAAuC;AAC/C,SAAQ,oBAAyC;AACjD,SAAQ,yBAA8C;AACtD,SAAQ,0BAA+C;AACvD,SAAQ,mBAA4C;AAEpD;AAAA,SAAQ,6BAA4C;AAEpD;AAAA,SAAQ,qBAAqC;AAE7C;AAAA,SAAQ,qBAAqB;AAE7B;AAAA,SAAQ,gBAAgB;AAExB;AAAA,SAAQ,oBAAoB;AAE5B;AAAA,SAAQ,sBAA4D;AAEpE;AAAA,SAAQ,oBAKG;AACX,SAAQ,qBAAqB,oBAAI,IAAsB;AAOvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAQ,eAAe,MAAM,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AACnE,SAAQ,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOxB,UAAU,QAAmC;AAC3C,UAAM,OACJ,KAAK,WACL,KAAK,QAAQ,eAAe,OAAO,cACnC,KAAK,QAAQ,aAAa,OAAO;AACnC,QAAI,MAAM;AAGR,WAAK,UAAU,EAAE,GAAG,KAAK,SAAS,GAAG,OAAO;AAC5C;AAAA,IACF;AACA,SAAK,YAAY;AACjB,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,eAAe,MAAM,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAChE,SAAK,gBAAgB,KAAK,IAAI;AAC9B,SAAK,aAAa;AAClB,UAAM,cAAc;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,YAAY,OAAO;AAAA,MACnB,UAAU,OAAO;AAAA,IACnB,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,SAAiB;AACvB,WAAO,KAAK,kBAAkB,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK;AAAA,EAC1D;AAAA;AAAA,EAGA,IAAI,eAAwB;AAC1B,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA;AAAA,EAGA,IAAI,cAAuB;AACzB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,UAAwC;AACjD,SAAK,mBAAmB,IAAI,QAAQ;AACpC,WAAO,MAAM;AACX,WAAK,mBAAmB,OAAO,QAAQ;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,SAKL;AACP,SAAK,kBAAkB,OAAO;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,4BAAkC;AAChC,SAAK,gBAAgB;AACrB,SAAK,sBAAsB;AAC3B,SAAK,oBAAoB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,cAAoB;AAC1B,QAAI,KAAK,iBAAiB;AACxB,WAAK,gBAAgB;AACrB,WAAK,kBAAkB;AAAA,IACzB;AACA,QAAI,KAAK,mBAAmB;AAC1B,WAAK,kBAAkB;AACvB,WAAK,oBAAoB;AAAA,IAC3B;AACA,QAAI,KAAK,wBAAwB;AAC/B,WAAK,uBAAuB;AAC5B,WAAK,yBAAyB;AAAA,IAChC;AACA,QAAI,KAAK,yBAAyB;AAChC,WAAK,wBAAwB;AAC7B,WAAK,0BAA0B;AAAA,IACjC;AACA,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,WAAW;AACtB,WAAK,QAAQ;AAAA,IACf;AACA,SAAK,oBAAoB;AACzB,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,mBAAmB;AACxB,SAAK,6BAA6B;AAClC,SAAK,qBAAqB;AAC1B,SAAK,qBAAqB;AAC1B,SAAK,gBAAgB;AACrB,SAAK,oBAAoB;AACzB,SAAK,oBAAoB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAc;AACZ,SAAK,YAAY;AACjB,SAAK,mBAAmB,MAAM;AAAA,EAChC;AAAA,EAEQ,sBAA4B;AAClC,QAAI,KAAK,qBAAqB;AAC5B,mBAAa,KAAK,mBAAmB;AACrC,WAAK,sBAAsB;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,kBAAkB,SAKjB;AACP,UAAM,SAAS,QAAQ,UAAU;AACjC,UAAM,OAAO,QAAQ,OAAO,OAAO,QAAQ,IAAI,EAAE,MAAM,GAAG,GAAG,IAAI;AACjE,SAAK,oBAAoB;AAAA,MACvB,SAAS,QAAQ;AAAA,MACjB;AAAA,MACA;AAAA,MACA,WAAW,QAAQ,aAAa;AAAA,IAClC;AAEA,SAAK,SAAS,QAAQ,OAAO,QAAQ,2BAA2B;AAAA,MAC9D,QAAQ;AAAA,MACR,aAAa,KAAK;AAAA,MAClB,gBAAgB,KAAK,OAAO;AAAA,MAC5B,mBAAmB,KAAK;AAAA,MACxB,mBAAmB,KAAK;AAAA,MACxB,cAAc,KAAK;AAAA,MACnB,cAAc,QAAQ,WAAW;AAAA,MACjC,aAAa;AAAA,MACb,WAAW;AAAA,MACX,WAAW,QAAQ,aAAa;AAAA,IAClC,CAAC;AAED,QAAI,KAAK,iBAAiB,KAAK,qBAAqB,KAAK,oBAAqB;AAC9E,SAAK,sBAAsB,WAAW,MAAM;AAC1C,WAAK,sBAAsB;AAC3B,UAAI,KAAK,iBAAiB,KAAK,kBAAmB;AAClD,WAAK,gBAAgB,gBAAgB;AAAA,IACvC,GAAG,oBAAoB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,gBAAgB,QAAyC;AAC/D,QAAI,KAAK,kBAAmB;AAC5B,SAAK,oBAAoB;AACzB,UAAM,YAAY,EAAE,QAAQ,aAAa,KAAK,cAAc,OAAO,KAAK,OAAO,EAAE,CAAC;AAClF,UAAM,WAAW,KAAK,SAAS,YAAY,CAAC;AAC5C,UAAM,UAA2B;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,gBAAgB,KAAK,OAAO;AAAA,MAC5B,mBAAmB,KAAK;AAAA,MACxB,mBAAmB,KAAK;AAAA,MACxB,aAAa,KAAK,mBAAmB,UAAU;AAAA,MAC/C,WAAW,KAAK,mBAAmB,QAAQ;AAAA,MAC3C,cAAc,KAAK,mBAAmB,WAAW;AAAA,MACjD,WAAW,KAAK,mBAAmB,aAAa;AAAA,IAClD;AACA,SAAK,SAAS,QAAQ,OAAO;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AACA,eAAW,YAAY,KAAK,mBAAoB,UAAS,OAAO;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAqB;AAC3B,SAAK,oBAAoB,YAAY,OAAO,CAAC,EAAE,KAAK,MAAM;AACxD,WAAK,KAAK,oBAAoB,IAAI;AAAA,IACpC,CAAC;AACD,SAAK,yBAAyB,YAAY,YAAY,MAAM;AAC1D,WAAK,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAAA,IAC9C,CAAC;AACD,SAAK,0BAA0B,YAAY,aAAa,CAAC,EAAE,YAAY,QAAQ,SAAS,MAAM;AAC5F,WAAK,OAAO,KAAK,EAAE,MAAM,eAAe,YAAY,QAAQ,SAAS,CAAC;AAAA,IACxE,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,oBAAoB,MAA6B;AAC7D,UAAM,KAAK,MAAM,KAAK,iBAAiB;AACvC,QAAI,CAAC,MAAM,CAAC,KAAK,OAAO;AAItB,kBAAY,MAAM,6CAA6C;AAC/D;AAAA,IACF;AACA,SAAK,MAAM,KAAK,EAAE,MAAM,gBAAgB,KAAK,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,mBAAqC;AACjD,QAAI,KAAK,YAAY,eAAe,KAAK,MAAO,QAAO;AACvD,QAAI,CAAC,KAAK,QAAS,QAAO;AAC1B,QAAI,KAAK,iBAAkB,QAAO,KAAK;AAEvC,SAAK,oBAAoB,YAAY;AACnC,WAAK,UAAU;AACf,YAAM,MAAM,MAAM,KAAK,+BAA+B;AACtD,WAAK,qBAAqB,QAAQ;AAElC,UAAI,KAAK,YAAY,KAAM,QAAO;AAElC,YAAM,UAAU,KAAK,QAAQ,WAAW,QAAQ,OAAO,EAAE;AACzD,YAAM,YAAY,GAAG,OAAO;AAC5B,YAAM,QAAQ,gBAAgB;AAC9B,YAAM,eAAe,MAA8B;AACjD,cAAM,IAA4B,CAAC;AACnC,YAAI,MAAO,GAAE,gBAAgB,UAAU,KAAK;AAC5C,YAAI,IAAK,GAAE,oBAAoB,IAAI;AASnC,cAAM,UAAU,KAAK,SAAS;AAC9B,YAAI,OAAO,YAAY,YAAY,QAAQ,SAAS,GAAG;AACrD,YAAE,mBAAmB,IAAI;AAAA,QAC3B;AAUA,YAAI;AACF,gBAAM,KAAK,KAAK,SAAS;AAGzB,gBAAM,cAAc,IAAI,WAAW,gBAAgB;AACnD,gBAAM,aACJ,OACA,SAAS,kBAAkB;AAC7B,gBAAM,MAAM,eAAe;AAC3B,cAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,GAAG;AAC7C,cAAE,eAAe,IAAI;AAAA,UACvB;AAAA,QACF,QAAQ;AAAA,QAER;AACA,eAAO;AAAA,MACT;AAEA,YAAMA,WAAU,KAAK,QAAQ;AAM7B,YAAM,wBAAwB,MAA2C;AACvE,cAAM,MAAM,KAAK,SAAS;AAC1B,eAAO,OAAO,QAAQ,aAAa,IAAI,IAAI;AAAA,MAC7C;AACA,WAAK,QAAQ,IAAI,cAAc;AAAA,QAC7B,KAAK;AAAA,QACL,SAAS;AAAA,QACT,UAAU,KAAK,QAAQ;AAAA,QACvB,aAAa,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAM1B,aAAa;AAAA,QACb,gBAAgB;AAAA,QAChB,aAAa,CAAC,YAAY;AAOxB,gBAAM,YAAY,uBAAuB,OAAO;AAChD,cAAI,cAAc,MAAM;AACtB,kBAAM,UAAU,KAAK,SAAS;AAC9B,gBAAI,SAAS;AACX,kBAAI;AACF,wBAAQ,SAAS;AACjB,gBAAAA,SAAQ,OAAO,QAAQ,oCAAoC;AAAA,kBACzD,QAAQ;AAAA,kBACR,OAAO,UAAU;AAAA,gBACnB,CAAC;AAAA,cACH,SAAS,KAAK;AACZ,sBAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,wBAAQ,MAAM,mDAAmD,GAAG;AAAA,cACtE;AACA;AAAA,YACF;AAKA;AAAA,UACF;AACA,UAAAA,SAAQ,QACL,WAAW,CAAC,OAA6C,CAAC,EAC1D,KAAK,MAAM;AACV,YAAAA,SAAQ,OAAO,QAAQ,wBAAwB,EAAE,QAAQ,iBAAiB,CAAC;AAAA,UAC7E,CAAC,EACA,MAAM,CAAC,QAAiB;AACvB,kBAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,oBAAQ,MAAM,uCAAuC,GAAG;AAAA,UAC1D,CAAC;AAAA,QACL;AAAA,MACF,CAAC;AACD,WAAK,MAAM,QAAQ;AACnB,WAAK,kBAAkB,KAAK,MAAM,UAAU,CAAC,UAAU,KAAK,kBAAkB,KAAK,CAAC;AACpF,WAAK,UAAU;AACf,aAAO;AAAA,IACT,GAAG;AAEH,QAAI;AACF,aAAO,MAAM,KAAK;AAAA,IACpB,UAAE;AACA,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,iCAAyD;AACrE,UAAM,EAAE,MAAM,IAAI,MAAM,0BAA0B;AAClD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,oBAAoB,YAAoD;AAC9E,UAAM,QAAQ,YAAY,SAAS;AACnC,eAAW,OAAO,MAAM,UAAU;AAChC,YAAM,KAAK,IAAI,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU;AACzD,UAAI,GAAI,QAAO,GAAG;AAAA,IACpB;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,mBAAmB,QAAyC;AAClE,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA,EAEQ,kBAAkB,OAA0B;AAClD,UAAMA,WAAU,KAAK,SAAS;AAE9B,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAEH;AAAA,MAEF,KAAK,kBAAkB;AAErB,aAAK,6BAA6B,MAAM,QAAQ;AAChD,oBAAY,aAAa,MAAM,QAAQ,EAAE;AACzC,YAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,QAAQ,SAAS,GAAG;AAC7D,sBAAY,aAAa,MAAM,QAAQ,IAAI,MAAM,QAAQ,OAAO;AAAA,QAClE;AACA;AAAA,MACF;AAAA,MAEA,KAAK,iBAAiB;AACpB,cAAM,KAAK,MAAM,aAAa,KAAK;AACnC,YAAI,CAAC,MAAM,CAAC,MAAM,MAAO;AACzB,oBAAY,aAAa,IAAI,MAAM,KAAK;AACxC;AAAA,MACF;AAAA,MAEA,KAAK,oBAAoB;AACvB,cAAM,KAAK,MAAM,aAAa,KAAK;AACnC,YAAI,CAAC,GAAI;AACT,oBAAY,WAAW,EAAE;AACzB,aAAK,6BAA6B;AAClC,aAAK,sBAAsB;AAG3B,aAAK,gBAAgB;AACrB,aAAK,oBAAoB;AACzB;AAAA,MACF;AAAA,MAEA,KAAK,aAAa;AAKhB,cAAM,kBAAkB,MAAM,aAAa,KAAK;AAChD,YAAI,CAAC,gBAAiB;AACtB,cAAM,WAAW,KAAK,oBAAoB,MAAM,SAAS,EAAE;AAC3D,YAAI,CAAC,UAAU;AACb,sBAAY,YAAY,iBAAiB;AAAA,YACvC,IAAI,MAAM,SAAS;AAAA,YACnB,MAAM,MAAM,SAAS;AAAA,YACrB,QAAQ,KAAK,mBAAmB,MAAM,SAAS,MAAM;AAAA,UACvD,CAAC;AAAA,QACH,OAAO;AACL,sBAAY,eAAe,MAAM,SAAS,IAAI;AAAA,YAC5C,MAAM,MAAM,SAAS;AAAA,YACrB,QAAQ,KAAK,mBAAmB,MAAM,SAAS,MAAM;AAAA,UACvD,CAAC;AAAA,QACH;AACA;AAAA,MACF;AAAA,MAEA,KAAK;AAIH,cAAM,wBAAwB,KAAK;AACnC;AAAA,MAEF,KAAK;AAIH,oBAAY,eAAe,MAAM,YAAY,EAAE,QAAQ,OAAO,CAAC;AAC/D;AAAA,MAEF,KAAK;AAIH;AAAA,MAEF,KAAK,SAAS;AACZ,cAAM,SAAS,MAAM,UAAU;AAC/B,cAAM,OAAO,MAAM,OAAO,OAAO,MAAM,IAAI,EAAE,MAAM,GAAG,GAAG,IAAI;AAC7D,gBAAQ;AAAA,UACN,iCAAiC,UAAU,WAAW,cAAc,KAAK,kBAAkB;AAAA,UAC3F;AAAA,QACF;AAIA,aAAK,kBAAkB;AAAA,UACrB,SAAS,MAAM;AAAA,UACf;AAAA,UACA;AAAA,UACA,WAAW,MAAM,aAAa;AAAA,QAChC,CAAC;AAID,oBAAY,MAAM,MAAM,WAAW,wBAAwB;AAC3D,aAAK,6BAA6B;AAGlC,YAAI,KAAK,OAAO;AACd,eAAK,MAAM,WAAW;AACtB,eAAK,QAAQ;AAAA,QACf;AACA,YAAI,KAAK,iBAAiB;AACxB,eAAK,gBAAgB;AACrB,eAAK,kBAAkB;AAAA,QACzB;AACA,aAAK,UAAU;AACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAOO,IAAM,gBAAgB,IAAI,cAAc;;;AChuB/C,IAAM,eAAe;AACrB,IAAM,yBAAyB,oBAAI,IAAI,CAAC,UAAU,GAAG,CAAC;AAEtD,SAAS,SAAS,GAAmB;AACnC,SAAO,EAAE,UAAU,eAAe,IAAI,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC,CAAC;AACvE;AAEA,SAAS,aAAa,OAAgE;AACpF,QAAM,MAAM,MAAM;AAClB,MAAI,MAAM,QAAQ,GAAG,KAAK,IAAI,SAAS,KAAK,OAAO,IAAI,CAAC,MAAM,YAAY,IAAI,CAAC,MAAM,MAAM;AACzF,WAAO,IAAI,CAAC;AAAA,EACd;AACA,SAAO;AACT;AAEA,SAAS,YAAY,OAAwC;AAC3D,QAAM,KAAK,aAAa,KAAK;AAC7B,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,IAAI,GAAG;AACb,SAAO,OAAO,MAAM,WAAW,EAAE,KAAK,IAAI;AAC5C;AAEA,SAAS,WAAW,OAAwC;AAC1D,QAAM,WAAW,MAAM;AACvB,MAAI,OAAO,aAAa,SAAU,QAAO,SAAS,YAAY;AAC9D,QAAM,KAAK,aAAa,KAAK;AAC7B,MAAI,MAAM,OAAO,GAAG,aAAa,SAAU,QAAQ,GAAG,SAAoB,YAAY;AACtF,SAAO;AACT;AAEA,SAAS,YAAY,OAAwC;AAC3D,QAAM,KAAK,aAAa,KAAK;AAC7B,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,OAAO,GAAG;AAChB,SAAO,OAAO,SAAS,WAAW,KAAK,YAAY,IAAI;AACzD;AAEA,SAAS,SAAS,OAAwC;AACxD,QAAM,KAAK,aAAa,KAAK;AAC7B,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,OAAO,GAAG;AAChB,MAAI,OAAO,SAAS,YAAY,KAAM,QAAO;AAC7C,QAAM,KAAK,GAAG;AACd,MAAI,OAAO,OAAO,YAAY,GAAI,QAAO;AACzC,SAAO;AACT;AAEA,SAAS,yBAAyB,OAAyC;AACzE,QAAM,MAAM,WAAW,KAAK;AAC5B,MAAI,uBAAuB,IAAI,GAAG,EAAG,QAAO;AAC5C,MAAI,YAAY,KAAK,MAAM,SAAU,QAAO;AAC5C,SAAO;AACT;AAEA,SAAS,SAAS,OAAwC;AACxD,QAAM,KAAK,MAAM;AACjB,SAAO,OAAO,OAAO,WAAW,KAAK;AACvC;AAEA,SAAS,kBAAkB,KAAuB;AAEhD,QAAM,SAAmB,CAAC;AAC1B,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,IAAI,UAAU,GAAG;AACnD,QAAI,EAAE,WAAW,GAAG,EAAG;AACvB,QAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,OAAO,MAAM,WAAW;AAC5E,aAAO,KAAK,GAAG,CAAC,IAAI,CAAC,EAAE;AACvB,UAAI,OAAO,UAAU,EAAG;AAAA,IAC1B;AAAA,EACF;AACA,SAAO,OAAO,SAAS,IAAI,GAAG,IAAI,KAAK,KAAK,OAAO,KAAK,IAAI,CAAC,MAAM,IAAI;AACzE;AAEO,SAAS,WAAW,KAAe,OAAqB,CAAC,GAA4B;AAC1F,QAAM,QAAQ,IAAI;AAElB,UAAQ,IAAI,OAAO;AAAA,IACjB,KAAK,aAAa;AAChB,YAAM,OAAO,SAAS,KAAK;AAC3B,aAAO;AAAA,QACL,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,MAAM,SAAS,gBAAgB,IAAI,EAAE;AAAA,QACrC,KAAK;AAAA,MACP;AAAA,IACF;AAAA,IAEA,KAAK,gBAAgB;AACnB,YAAM,YAAY,MAAM;AAExB,UAAI,cAAc,SAAS;AACzB,YAAI,CAAC,yBAAyB,KAAK,EAAG,QAAO;AAC7C,cAAM,OAAO,YAAY,KAAK,KAAK,WAAW,KAAK;AACnD,eAAO;AAAA,UACL,IAAI,IAAI;AAAA,UACR,MAAM;AAAA,UACN,MAAM,SAAS,YAAY,IAAI,GAAG;AAAA,QACpC;AAAA,MACF;AAEA,UAAI,cAAc,YAAY,WAAW,KAAK,MAAM,QAAQ;AAC1D,eAAO;AAAA,UACL,IAAI,IAAI;AAAA,UACR,MAAM;AAAA,UACN,MAAM,SAAS,mBAAmB,SAAS,KAAK,CAAC,GAAG;AAAA,QACtD;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK,cAAc;AACjB,YAAM,OAAO,YAAY,KAAK,KAAK,WAAW,KAAK;AACnD,aAAO;AAAA,QACL,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,MAAM,SAAS,iBAAiB,IAAI,GAAG;AAAA,MACzC;AAAA,IACF;AAAA,IAEA,KAAK,eAAe;AAClB,YAAM,OAAO,YAAY,KAAK,KAAK,WAAW,KAAK;AACnD,aAAO;AAAA,QACL,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,MAAM,SAAS,YAAY,IAAI,iBAAiB;AAAA,MAClD;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,KAAK,sBAAsB;AACzB,YAAM,UAAU,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU;AACpE,UAAI,CAAC,QAAS,QAAO;AACrB,aAAO;AAAA,QACL,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,MAAM,SAAS,eAAe,OAAO,WAAW;AAAA,QAChD,KAAK;AAAA,MACP;AAAA,IACF;AAAA,IAEA,KAAK,oBAAoB;AACvB,YAAM,MAAM,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU;AAChE,UAAI,QAAQ,KAAM,QAAO;AACzB,aAAO;AAAA,QACL,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,MAAM,SAAS,eAAe,GAAG,eAAe;AAAA,MAClD;AAAA,IACF;AAAA,IAEA,KAAK,oBAAoB;AACvB,aAAO;AAAA,QACL,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,KAAK,WAAW;AACd,YAAM,KAAK,OAAO,MAAM,eAAe,WAAW,MAAM,aAAa;AACrE,YAAM,OAAO,OAAO,OAAO,KAAK,MAAM,KAAK,GAAI,IAAI;AACnD,aAAO;AAAA,QACL,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,MAAM,SAAS,OAAO,YAAY,IAAI,MAAM;AAAA,MAC9C;AAAA,IACF;AAAA,IAEA,KAAK,YAAY;AACf,YAAM,OAAO,YAAY,KAAK,KAAK,WAAW,KAAK;AACnD,aAAO;AAAA,QACL,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,MAAM,SAAS,eAAe,IAAI,GAAG;AAAA,MACvC;AAAA,IACF;AAAA,IAEA,KAAK,iBAAiB;AACpB,YAAM,OAAO,YAAY,KAAK,KAAK,WAAW,KAAK;AACnD,aAAO;AAAA,QACL,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,MAAM,SAAS,mBAAmB,IAAI,GAAG;AAAA,MAC3C;AAAA,IACF;AAAA,IAEA,KAAK,mBAAmB;AACtB,YAAM,OAAO,YAAY,KAAK,KAAK,WAAW,KAAK;AACnD,aAAO;AAAA,QACL,IAAI,IAAI;AAAA,QACR,MAAM;AAAA,QACN,MAAM,SAAS,YAAY,IAAI,sBAAsB;AAAA,MACvD;AAAA,IACF;AAAA,IAEA,SAAS;AACP,YAAM,QAAQ,KAAK,oBAAoB,CAAC;AACxC,UAAI,MAAM,SAAS,IAAI,KAAK,GAAG;AAC7B,eAAO;AAAA,UACL,IAAI,IAAI;AAAA,UACR,MAAM;AAAA,UACN,MAAM,SAAS,kBAAkB,GAAG,CAAC;AAAA,QACvC;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AC1NO,IAAM,gBAAN,MAAoB;AAAA,EAYzB,YAAY,MAA4B;AAVxC,SAAiB,UAA8B,CAAC;AAChD,SAAQ,QAAQ;AAChB,SAAQ,WAAW;AACnB,SAAQ,aAA4B;AACpC,SAAQ,YAAY;AACpB,SAAQ,iBAAuD;AAC/D,SAAQ,gBAAsD;AAC9D,SAAQ,oBAAoB;AAC5B,SAAQ,YAAY;AAGlB,SAAK,QAAQ;AAAA,MACX,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EAEA,KAAK,OAA+B;AAClC,QAAI,KAAK,UAAW;AACpB,QAAI,KAAK,QAAQ,UAAU,KAAK,MAAM,UAAU;AAC9C,WAAK,QAAQ,MAAM;AACnB,WAAK,YAAY;AAAA,IACnB;AACA,SAAK,QAAQ,KAAK,KAAK;AAEvB,QAAI,KAAK,QAAQ,UAAU,KAAK,MAAM,WAAW;AAC/C,WAAK,mBAAmB;AAAA,IAC1B,OAAO;AACL,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,MAAM,WAA0B;AAC9B,SAAK,eAAe;AACpB,UAAM,KAAK,OAAO;AAAA,EACpB;AAAA,EAEA,QAAuB;AACrB,WAAO;AAAA,MACL,QAAQ,KAAK,QAAQ;AAAA,MACrB,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,WAAW,KAAK;AAAA,MAChB,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAAA,EAEQ,qBAA2B;AACjC,mBAAe,MAAM;AACnB,WAAK,KAAK,OAAO;AAAA,IACnB,CAAC;AAAA,EACH;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAK,kBAAkB,KAAM;AACjC,SAAK,iBAAiB,WAAW,MAAM;AACrC,WAAK,iBAAiB;AACtB,WAAK,KAAK,OAAO;AAAA,IACnB,GAAG,KAAK,MAAM,eAAe;AAAA,EAC/B;AAAA,EAEQ,iBAAuB;AAC7B,QAAI,KAAK,kBAAkB,MAAM;AAC/B,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,SAAwB;AACpC,QAAI,KAAK,aAAa,KAAK,aAAa,KAAK,QAAQ,WAAW,EAAG;AACnE,SAAK,eAAe;AAEpB,UAAM,QAAQ,KAAK,QAAQ,OAAO,GAAG,KAAK,MAAM,SAAS;AACzD,SAAK,YAAY;AACjB,QAAI;AACF,YAAM,KAAK,MAAM,MAAM,KAAK;AAC5B,WAAK,SAAS,MAAM;AACpB,WAAK,oBAAoB;AACzB,WAAK,aAAa;AAAA,IACpB,SAAS,KAAK;AACZ,WAAK,QAAQ,QAAQ,GAAG,KAAK;AAC7B,YAAM,OAAQ,KAAoB,cAAc;AAChD,WAAK,aACH,eAAe,QAAQ,IAAI,UAAU,OAAQ,KAA+B,WAAW,GAAG;AAC5F,UAAI,MAAM;AACR,aAAK,YAAY;AAAA,MACnB,OAAO;AACL,aAAK,iBAAiB;AAAA,MACxB;AAAA,IACF,UAAE;AACA,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,mBAAyB;AAC/B,UAAM,OACJ,KAAK,sBAAsB,IACvB,KAAK,MAAM,iBACX,KAAK,IAAI,KAAK,oBAAoB,GAAG,KAAK,MAAM,YAAY;AAClE,SAAK,oBAAoB;AAEzB,QAAI,KAAK,iBAAiB,KAAM,cAAa,KAAK,aAAa;AAC/D,SAAK,gBAAgB,WAAW,MAAM;AACpC,WAAK,gBAAgB;AACrB,WAAK,KAAK,OAAO;AAAA,IACnB,GAAG,IAAI;AAAA,EACT;AACF;;;ACrHA,SAAS,UAAU,YAA2B,OAAmC;AAC/E,QAAM,OAAoB,EAAE,aAAa,YAAY,MAAM;AAC3D,SAAO,KAAK,UAAU,IAAI;AAC5B;AAEO,SAAS,gBAAgB,MAAmC;AACjE,SAAO;AAAA,IACL,MAAM,KAAK,OAA0C;AACnD,YAAM,OAAO,UAAU,KAAK,cAAc,GAAG,KAAK;AAClD,YAAM,OAAO,MAAM,MAAM,KAAK,KAAK;AAAA,QACjC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,eAAe,UAAU,KAAK,MAAM,CAAC;AAAA,UACrC,gBAAgB;AAAA,QAClB;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,aAAa;AAAA,MACf,CAAC;AACD,UAAI,CAAC,KAAK,IAAI;AACZ,cAAM,MAAM,IAAI,MAAM,oBAAoB,KAAK,MAAM,EAAE;AAMvD,YAAI,KAAK,UAAU,OAAO,KAAK,SAAS,OAAO,KAAK,WAAW,KAAK;AAClE,cAAI,YAAY;AAAA,QAClB;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,WAAW,OAAoC;AAC7C,YAAM,OAAO,UAAU,KAAK,cAAc,GAAG,KAAK;AAClD,YAAM,OAAO,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAM,SAAS,WAAW;AAC1B,UAAI,OAAO,WAAW,WAAY,QAAO;AACzC,aAAO,OAAO,KAAK,WAAW,KAAK,KAAK,IAAI;AAAA,IAC9C;AAAA,EACF;AACF;;;AChCA,IAAI,UAAiC;AAErC,SAAS,eACP,QACA,mBACY;AACZ,QAAM,KAAM,WAAqC;AACjD,MAAI,CAAC,GAAI,QAAO,MAAM;AAAA,EAAC;AAMvB,QAAM,UAAW,GAAqC;AACtD,MAAI,OAAO,YAAY,WAAY,QAAO,MAAM;AAAA,EAAC;AAEjD,QAAM,UAAU,CAAC,WAAmB,eAAoD;AACtF,QAAI,OAAO,cAAc,SAAU;AACnC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,WAAW,KAAK,IAAI;AAAA,MACpB,YAAY,cAAc,CAAC;AAAA,IAC7B,CAAC;AAAA,EACH;AAKA,EAAC,QAAyC,KAAK,IAAI,OAAO;AAC1D,SAAO,MAAM;AAAA,EAAC;AAChB;AAEA,SAAS,gBAAgB,YAAuB,OAAkC;AAChF,QAAM,UAAU,MAAM;AACpB,UAAM,QAAQ,MAAM,MAAM;AAC1B,QAAI,MAAM,SAAS,GAAG;AACpB,WAAK,MAAM,SAAS;AAAA,IACtB;AAAA,EACF;AACA,SAAO,iBAAiB,YAAY,SAAS,EAAE,SAAS,KAAK,CAAC;AAC9D,SAAO,MAAM,OAAO,oBAAoB,YAAY,SAAS,EAAE,SAAS,KAAK,CAAC;AAChF;AAEO,SAAS,cAAc,MAA4C;AACxE,MAAI,SAAS;AACX,YAAQ,YAAY;AACpB,WAAO,YAAY;AAAA,EACrB;AAEA,QAAM,YAAY,KAAK,aAAa,gBAAgB,IAAI;AAExD,QAAM,QAAQ,IAAI,cAAc;AAAA,IAC9B,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,UAAU;AAAA,IACV,OAAO,CAAC,UAAU,UAAU,KAAK,KAAK;AAAA,EACxC,CAAC;AAED,QAAM,SAAS,CAAC,QAAkB;AAChC,UAAM,KAAK,WAAW,KAAK,EAAE,kBAAkB,KAAK,iBAAiB,CAAC;AACtE,QAAI,OAAO,MAAM;AACf,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,QAAM,gBAAgB,eAAe,QAAQ,KAAK,oBAAoB,CAAC,CAAC;AACxE,QAAM,sBAAsB,gBAAgB,WAAW,KAAK;AAE5D,YAAU;AAAA,IACR,UAAU;AAAA,IACV;AAAA,IACA,aAAa,MAAM;AACjB,oBAAc;AACd,0BAAoB;AAAA,IACtB;AAAA,IACA,SAAS;AAAA,EACX;AAEA,SAAO,YAAY;AACrB;AAEA,SAAS,cAA8B;AACrC,SAAO;AAAA,IACL,OAAa;AACX,UAAI,CAAC,QAAS;AACd,cAAQ,YAAY;AACpB,UAAI,QAAQ,YAAY,GAAG;AACzB,gBAAQ,YAAY;AACpB,kBAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA,QAAuB;AACrB,aACE,SAAS,MAAM,MAAM,KAAK;AAAA,QACxB,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,MACZ;AAAA,IAEJ;AAAA,IACA,OAAO,KAAqB;AAC1B,UAAI,CAAC,QAAS;AACd,YAAM,KAAK,WAAW,KAAK;AAAA,QACzB,kBAAkB,QAAQ,QAAQ;AAAA,MACpC,CAAC;AACD,UAAI,OAAO,KAAM,SAAQ,MAAM,KAAK,EAAE;AAAA,IACxC;AAAA,IACA,WAA0B;AACxB,aAAO,SAAS,MAAM,SAAS,KAAK,QAAQ,QAAQ;AAAA,IACtD;AAAA,EACF;AACF;;;AC/CA,IAAM,YAAY;AAElB,SAAS,SAAS,WAA2C;AAC3D,SAAQ,UAAgE,SAAS,KAAK;AACxF;AACA,SAAS,SAAS,WAAwB,OAAgC;AACxE,EAAC,UAA2D,SAAS,IAAI;AAC3E;AAEA,SAAS,iBAAiB,KAAsB,KAA+B;AAC7E,MAAI,IAAI,gBAAgB,OAAW,KAAI,cAAc,IAAI;AACzD,MAAI,IAAI,aAAa,OAAW,KAAI,WAAW,IAAI;AACrD;AAoBA,IAAI,gBAA6C;AAajD,IAAM,qBAAqB,oBAAI,IAAoB;AAEnD,SAAS,kBAAkB,YAAwC;AACjE,SAAO,mBAAmB,IAAI,UAAU;AAC1C;AAEA,SAAS,yBAAyB,aAAwD;AACxF,qBAAmB,MAAM;AACzB,MAAI,CAAC,YAAa;AAClB,QAAM,QAAS,YAAsE;AACrF,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG;AAC3B,aAAW,KAAK,OAAO;AACrB,UAAM,KAAK,OAAO,GAAG,OAAO,WAAW,EAAE,KAAK;AAC9C,UAAM,SAAS,OAAO,GAAG,WAAW,WAAW,EAAE,SAAS;AAC1D,QAAI,MAAM,OAAQ,oBAAmB,IAAI,IAAI,MAAM;AAAA,EACrD;AACF;AAEA,SAAS,wBAAwBC,UAAqD;AACpF,MAAI,cAAe,QAAO;AAC1B,kBAAgB,IAAI,qBAAqB;AAAA,IACvC,SAASA,SAAQ;AAAA;AAAA;AAAA;AAAA,IAIjB,QAAQ;AAAA,MACN,SAASA,SAAQ,OAAO,QAAQ,KAAKA,SAAQ,MAAM;AAAA,MACnD,WAAWA,SAAQ,OAAO,WAAW,KAAKA,SAAQ,MAAM;AAAA,IAC1D;AAAA,IACA,UAAU,CAAC,IAAI,YAAY,iBAAiB,GAAG,IAAI,cAAc,GAAG,IAAI,YAAY,CAAC;AAAA,IACrF;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAYA,IAAI,oBAAoB;AAExB,SAAS,YAAYA,UAA+B,YAA0B;AAC5E,MAAI,kBAAmB;AACvB,sBAAoB;AACpB,QAAM,QAAQ,wBAAwBA,QAAO;AAQ7C,QAAM,UAAU,WAAW,QAAQ,OAAO,EAAE;AAC5C,QAAM,WAAW,UACb,GAAG,OAAO,mCACV;AACJ,uBAAqB,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,aAAa;AACpD,QAAI,CAAC,SAAU;AAMf,SAAK,MAAM,QAAQ,SAAS,gBAAgB;AAAA,EAC9C,CAAC;AACH;AAEA,SAAS,6BAA6B,KAA+B;AAMnE,MAAI,IAAI,eAAe,UAAa,CAAC,IAAI,QAAS;AAMlD,QAAM,iBAAiB,IAAI,oBAAoB,QAAQ,IAAI,eAAe;AAK1E,2BAAyB,iBAAiB,IAAI,cAAc,MAAS;AACrE,QAAM,iBAAsD,iBACxD,EAAE,iBAAiB,MAAM,aAAa,IAAI,YAAY,IACtD;AAQJ,QAAMA,WAAU,IAAI;AACpB,QAAM,oBAAoB,iBACtB,CAAC,cAAiC;AAChC,SAAK,wBAAwBA,QAAO,EAAE,MAAM,SAAS;AAAA,EACvD,IACA;AAQJ,MAAI,gBAAgB;AAClB,gBAAYA,UAAS,IAAI,UAAU;AAAA,EACrC;AAEA,gBAAc,UAAU;AAAA,IACtB,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA,eAAe,IAAI;AAAA,EACrB,CAAwB;AAaxB,0BAAwB,GAAG;AAC7B;AAEA,IAAI,mBAAmB;AAEvB,SAAS,wBAAwB,KAA+B;AAC9D,MAAI,iBAAkB;AACtB,MAAI,OAAO,WAAW,YAAa;AACnC,QAAMA,WAAU,IAAI;AAGpB,MAAI,CAACA,UAAS,QAAQ,UAAW;AAIjC,QAAM,WAAW,IAAI,cAAc,IAAI,QAAQ,OAAO,EAAE;AACxD,QAAM,MAAM,UAAU,GAAG,OAAO,8BAA8B;AAG9D,QAAM,gBAAgB,MAAqB;AACzC,UAAM,KAAM,OAA4D;AACxE,QAAI;AACF,YAAM,IAAI,IAAI,kBAAkB;AAChC,aAAO,OAAO,MAAM,YAAY,EAAE,SAAS,IAAI,IAAI;AAAA,IACrD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,QAAQ,MAAc;AAC1B,UAAM,IAAK,OAAsD;AACjE,WAAO,OAAO,GAAG,UAAU,WAAW,EAAE,QAAQ;AAAA,EAClD;AAQA,QAAM,SAAS,cAAc,EAAE,KAAK,OAAO,cAAc,CAAC;AAI1D,EAAC,OAAqD,wBAAwB,MAC5E,OAAO,MAAM;AACf,EAAAA,SAAQ,OAAO,UAAU,CAAC,GAAG,CAAC,QAAiB;AAC7C,UAAM,IAAI;AAMV,QAAI,CAAC,GAAG,KAAM;AACd,UAAM,KAAK,OAAO,EAAE,OAAO,WAAW,EAAE,KAAK,KAAK,IAAI;AAatD,QAAI,EAAE,WAAW,WAAW;AAC1B,YAAM,WAAW,EAAE,OAAO;AAC1B,UAAI,OAAO,aAAa,YAAY,SAAS,WAAW,EAAG;AAC3D,YAAM,aAAsC,EAAE,GAAI,EAAE,SAAS,CAAC,EAAG;AACjE,UAAI,OAAO,EAAE,OAAO,aAAa,SAAU,YAAW,YAAY,EAAE,MAAM;AAC1E,UAAI,OAAO,EAAE,OAAO,QAAQ,SAAU,YAAW,eAAe,EAAE,MAAM;AACxE,aAAO,OAAO,EAAE,OAAO,UAAU,WAAW,IAAI,WAAW,CAAC;AAC5D;AAAA,IACF;AAIA,WAAO,OAAO;AAAA,MACZ,OAAO,EAAE;AAAA,MACT,WAAW;AAAA,MACX,YAAY,EAAE,GAAI,EAAE,SAAS,CAAC,EAAG;AAAA,IACnC,CAAC;AAAA,EACH,CAAC;AACD,qBAAmB;AACrB;AAEA,SAAS,cAAc,KAAsB,OAAgC;AAC3E,QAAM,gBAAgB,CAAC,MAAa;AAClC,UAAM,OAAQ,EAAoC,OAAO;AACzD,gBAAY,KAAK,IAAI;AAMrB,QAAI,CAAC,YAAY,aAAa,GAAG;AAC/B,kBAAY,MAAM,yEAAoE;AAAA,IACxF;AAAA,EACF;AACA,QAAM,cAAc,MAAM;AACxB,gBAAY,UAAU;AAAA,EACxB;AACA,QAAM,qBAAqB,CAAC,MAAa;AACvC,UAAM,SAAU,EAA6D;AAK7E,gBAAY,gBAAgB,OAAO,YAAY,CAAC,GAAG,OAAO,QAAQ;AAAA,EACpE;AAGA,QAAM,UAAU,MAAM;AACpB,UAAM,IAAI,UAAU;AAAA,EACtB;AACA,MAAI,iBAAiB,qBAAqB,aAAa;AACvD,MAAI,iBAAiB,kBAAkB,WAAW;AAClD,MAAI,iBAAiB,gBAAgB,OAAO;AAC5C,MAAI,iBAAiB,2BAA2B,kBAAkB;AAClE,SAAO,MAAM;AACX,QAAI,oBAAoB,qBAAqB,aAAa;AAC1D,QAAI,oBAAoB,kBAAkB,WAAW;AACrD,QAAI,oBAAoB,gBAAgB,OAAO;AAC/C,QAAI,oBAAoB,2BAA2B,kBAAkB;AAAA,EACvE;AACF;AAEO,IAAM,2BAA2B;AAAA,EACtC,MAAM,WAAwB,aAAmD;AAC/E,UAAM,MAAO,eAAe,CAAC;AAC7B,iCAA6B,GAAG;AAChC,UAAM,MAAM,SAAS,cAAc,mBAAmB;AACtD,qBAAiB,KAAK,GAAG;AAIzB,UAAM,eAAe,YAAY,UAAU,CAAC,MAAM;AAChD,UAAI,WAAW,CAAC,GAAG,EAAE,QAAQ;AAC7B,UAAI,WAAW,EAAE;AAAA,IACnB,CAAC;AAID,UAAM,QAAQ,EAAE,KAAK,SAAS,MAAM;AAAA,IAAC,GAAG,IAAI;AAC5C,UAAM,kBAAkB,cAAc,KAAK,KAAK;AAEhD,cAAU,YAAY,GAAG;AAMzB,UAAM,gBAAgB,cAAc,WAAW,MAAM;AACnD,UAAI,OAAO;AACX,gBAAU,YAAY,mBAAmB,MAAM,IAAI,QAAQ;AAAA,IAC7D,CAAC;AAED,UAAM,UAAU,MAAM;AACpB,mBAAa;AACb,oBAAc;AACd,sBAAgB;AAChB,UAAI,OAAO;AACX,eAAS,WAAW,IAAI;AAAA,IAC1B;AAEA,aAAS,WAAW,KAAK;AACzB,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,OAAO,WAAwB,aAA6C;AAC1E,UAAM,QAAQ,SAAS,SAAS;AAChC,QAAI,CAAC,MAAO;AACZ,UAAM,MAAO,eAAe,CAAC;AAC7B,iCAA6B,GAAG;AAChC,qBAAiB,MAAM,KAAK,GAAG;AAC/B,UAAM,MAAM;AAAA,EACd;AACF;;;ACzaA,IAAMC,aAAY;AAElB,SAASC,UAAS,WAA2C;AAC3D,SAAQ,UAAgED,UAAS,KAAK;AACxF;AACA,SAASE,UAAS,WAAwB,OAAgC;AACxE,EAAC,UAA2DF,UAAS,IAAI;AAC3E;AAEA,SAAS,WAAW,OAA2B,KAAkC;AAC/E,MAAI,IAAI,UAAU,OAAW,OAAM,QAAQ,IAAI;AAG/C,MAAI,IAAI,YAAY,QAAW;AAC7B,UAAM,aAAa,IAAI;AAAA,EACzB;AACA,MAAI,IAAI,eAAe,OAAW,OAAM,aAAa,IAAI;AAC3D;AAEO,IAAM,8BAA8B;AAAA,EACzC,MAAM,WAAwB,aAAmD;AAC/E,UAAM,MAAO,eAAe,CAAC;AAC7B,UAAM,QAAQ,SAAS,cAAc,sBAAsB;AAC3D,eAAW,OAAO,GAAG;AAErB,UAAM,QAAoB;AAAA,MACxB;AAAA,MACA,WAAW;AAAA,QACT,UAAU,CAAC,MAAM;AACf,gBAAM,KAAK,IAAI;AACf,cAAI,IAAI;AACN;AAAA,cACG,EACE;AAAA,YACL;AAAA,UACF;AAAA,QACF;AAAA,QACA,WAAW,CAAC,MAAM;AAChB,gBAAM,KAAK,IAAI;AACf,cAAI,GAAI,IAAI,EAAkC,MAAM;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AACA,UAAM,iBAAiB,iBAAiB,MAAM,UAAU,QAAQ;AAChE,UAAM,iBAAiB,kBAAkB,MAAM,UAAU,SAAS;AAElE,cAAU,YAAY,KAAK;AAC3B,IAAAE,UAAS,WAAW,KAAK;AAEzB,WAAO,MAAM;AACX,YAAM,oBAAoB,iBAAiB,MAAM,UAAU,QAAQ;AACnE,YAAM,oBAAoB,kBAAkB,MAAM,UAAU,SAAS;AACrE,YAAM,OAAO;AACb,MAAAA,UAAS,WAAW,IAAI;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,OAAO,WAAwB,aAA6C;AAC1E,UAAM,QAAQD,UAAS,SAAS;AAChC,QAAI,CAAC,MAAO;AACZ,UAAM,MAAO,eAAe,CAAC;AAC7B,eAAW,MAAM,OAAO,GAAG;AAE3B,UAAM,MAAM,oBAAoB,iBAAiB,MAAM,UAAU,QAAQ;AACzE,UAAM,MAAM,oBAAoB,kBAAkB,MAAM,UAAU,SAAS;AAC3E,UAAM,UAAU,WAAW,CAAC,MAAM;AAChC,YAAM,KAAK,IAAI;AACf,UAAI,IAAI;AACN,WAAI,EAAgF,MAAM;AAAA,MAC5F;AAAA,IACF;AACA,UAAM,UAAU,YAAY,CAAC,MAAM;AACjC,YAAM,KAAK,IAAI;AACf,UAAI,GAAI,IAAI,EAAkC,MAAM;AAAA,IACtD;AACA,UAAM,MAAM,iBAAiB,iBAAiB,MAAM,UAAU,QAAQ;AACtE,UAAM,MAAM,iBAAiB,kBAAkB,MAAM,UAAU,SAAS;AAAA,EAC1E;AACF;;;ACrFA,IAAME,aAAY;AAElB,SAASC,UAAS,WAA2C;AAC3D,SAAQ,UAAgED,UAAS,KAAK;AACxF;AACA,SAASE,UAAS,WAAwB,OAAgC;AACxE,EAAC,UAA2DF,UAAS,IAAI;AAC3E;AAEA,SAAS,WAAW,QAAsB;AACxC,MAAI,CAAC,OAAQ;AACb,MAAI;AACJ,MAAI;AACF,eAAW,IAAI,IAAI,QAAQ,OAAO,SAAS,MAAM;AAAA,EACnD,QAAQ;AACN;AAAA,EACF;AACA,MAAI,SAAS,WAAW,OAAO,SAAS,OAAQ;AAChD,MAAI,SAAS,aAAa,WAAW,SAAS,aAAa,SAAU;AACrE,SAAO,QAAQ,UAAU,MAAM,IAAI,SAAS,SAAS,CAAC;AACtD,SAAO,cAAc,IAAI,cAAc,UAAU,CAAC;AACpD;AAEA,SAAS,YAAY,KAAsC;AACzD,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,OAAO;AACd,SAAO,QAAQ,gBAAgB;AAC/B,SAAO,MAAM,UAAU;AACvB,SAAO,MAAM,aAAa;AAC1B,SAAO,MAAM,MAAM;AACnB,SAAO,MAAM,UAAU;AACvB,SAAO,MAAM,eAAe;AAC5B,SAAO,MAAM,aAAa;AAC1B,SAAO,MAAM,WAAW;AACxB,SAAO,MAAM,aAAa;AAC1B,SAAO,MAAM,SAAS;AACtB,SAAO,MAAM,QAAQ;AACrB,SAAO,MAAM,aAAa;AAC1B,SAAO,MAAM,SAAS;AACtB,aAAW,QAAQ,GAAG;AACtB,SAAO;AACT;AAEA,SAAS,WAAW,QAA2B,KAAyB;AACtE,QAAM,MAAM,OAAO,IAAI,OAAO,EAAE;AAChC,QAAM,QAAQ,IAAI,UAAU,MAAM,SAAS,GAAG,KAAK;AAGnD,SAAO,cAAc;AACvB;AAEO,IAAM,mBAAmB;AAAA,EAC9B,MAAM,WAAwB,aAAmD;AAC/E,UAAM,MAAO,eAAe,CAAC;AAC7B,UAAM,SAAS,YAAY,GAAG;AAC9B,UAAM,UAAU,CAAC,OAAoB;AACnC,YAAM,UAAUC,UAAS,SAAS;AAClC,YAAM,MAAM,SAAS,IAAI,OAAO,IAAI;AACpC,iBAAW,OAAO,OAAO,EAAE,CAAC;AAAA,IAC9B;AACA,WAAO,iBAAiB,SAAS,OAAO;AACxC,cAAU,YAAY,MAAM;AAC5B,IAAAC,UAAS,WAAW,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAC5C,WAAO,MAAM;AACX,aAAO,oBAAoB,SAAS,OAAO;AAC3C,aAAO,OAAO;AACd,MAAAA,UAAS,WAAW,IAAI;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,OAAO,WAAwB,aAA6C;AAC1E,UAAM,QAAQD,UAAS,SAAS;AAChC,QAAI,CAAC,MAAO;AACZ,UAAM,MAAO,eAAe,CAAC;AAC7B,eAAW,MAAM,QAAQ,GAAG;AAC5B,UAAM,MAAM;AAAA,EACd;AACF;;;AC1FA,IAAME,aAAY;AAElB,SAASC,UAAS,WAA2C;AAC3D,SAAQ,UAAgED,UAAS,KAAK;AACxF;AACA,SAASE,UAAS,WAAwB,OAAgC;AACxE,EAAC,UAA2DF,UAAS,IAAI;AAC3E;AAEA,SAAS,UAAU,GAAyB,MAAoB;AAC9D,IAAE,cAAc;AAClB;AAEO,IAAM,sBAAsB;AAAA,EACjC,MAAM,WAAwB,aAAmD;AAC/E,UAAM,MAAO,eAAe,CAAC;AAC7B,UAAM,YAAY,SAAS,cAAc,GAAG;AAC5C,cAAU,QAAQ,mBAAmB;AAIrC,cAAU,MAAM,SAAS;AACzB,cAAU,MAAM,WAAW;AAC3B,cAAU,MAAM,aAAa;AAC7B,cAAU,MAAM,QAAQ;AACxB,cAAU,WAAW,OAAO,IAAI,QAAQ,EAAE,CAAC;AAC3C,cAAU,YAAY,SAAS;AAE/B,IAAAE,UAAS,WAAW,EAAE,WAAW,IAAI,CAAC;AACtC,WAAO,MAAM;AACX,gBAAU,OAAO;AACjB,MAAAA,UAAS,WAAW,IAAI;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,OAAO,WAAwB,aAA6C;AAC1E,UAAM,QAAQD,UAAS,SAAS;AAChC,QAAI,CAAC,MAAO;AACZ,UAAM,MAAO,eAAe,CAAC;AAC7B,cAAU,MAAM,WAAW,OAAO,IAAI,QAAQ,EAAE,CAAC;AACjD,UAAM,MAAM;AAAA,EACd;AACF;;;AC1CO,IAAM,UAAU;AAAA,EACrB,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,MAAM;AAAA,EACN,aAAa;AAAA,EAEb,WAAW,CAAC;AAAA,EAEZ,SAAS;AAAA,IACP;AAAA,MACE,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,UAAU;AAAA,QACR,MAAM;AAAA,QACN,aAAa;AAAA,QACb,MAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA;AAAA,MACE,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,UAAU;AAAA,QACR,MAAM;AAAA,QACN,aACE;AAAA,QACF,MAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA,MACE,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,UAAU;AAAA,QACR,MAAM;AAAA,QACN,aAAa;AAAA,QACb,MAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA;AAAA,MACE,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,UAAU;AAAA,QACR,MAAM;AAAA,QACN,aAAa;AAAA,QACb,MAAM;AAAA,MACR;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA;AAAA,MACE,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,UAAU;AAAA,QACR,MAAM;AAAA,QACN,aACE;AAAA,QACF,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAO,kBAAQ;",
|
|
4
|
+
"sourcesContent": ["/**\n * ChatSession \u2014 singleton holder of the chat conversation state.\n *\n * The chat is conceptually one thing. Whether it's rendered in the\n * mini-canvas's lid, the drawer's lid, or as a tile inside any slot,\n * they're all VIEWS of the same conversation. This module owns that\n * shared state.\n *\n * Why a module-level singleton (not on `runtime`):\n * - Per-page scope is the right granularity for a chat (one user,\n * one conversation, however many canvas instances on the page).\n * - Avoids a new SmartCanvasRuntime API surface for now. Easy to\n * promote to `runtime.chat` later without breaking the widget API.\n * - Module identity is stable per page; multiple imports return the\n * same instance.\n *\n * Separation of concerns:\n * - `ChatSession` owns state: messages, inFlight.\n * - Views (AdaptiveChatBar via AdaptiveChatBarMountable) subscribe\n * to state changes and dispatch user actions back via send() /\n * interrupt().\n * - Transports (the LLM call, SSE pipeline, stub timers) listen\n * for \"send\" / \"interrupt\" events and eventually call receive()\n * with the assistant's reply. Transports are NOT owned by this\n * module \u2014 adapters live separately.\n *\n * No persistence in this slice. Future: snapshot to runtime.state\n * for cross-session continuity.\n */\n\nimport type { TrailMessage, TrailToolCall } from './AdaptiveChatTrail';\n\nexport interface ChatSessionState {\n readonly messages: readonly TrailMessage[];\n readonly inFlight: boolean;\n}\n\nexport interface ToolResultEvent {\n toolCallId: string;\n result: unknown;\n approved: boolean;\n}\n\nexport type ChatSessionSubscriber = (state: ChatSessionState) => void;\nexport type SendListener = (event: { text: string; activeLidSlot?: string }) => void;\nexport type InterruptListener = () => void;\nexport type ToolResultListener = (event: ToolResultEvent) => void;\n\n/** Optional per-send envelope. */\nexport interface SendOptions {\n /**\n * The slot the calling chat-bar lives in (e.g. ``\"drawer\"``,\n * ``\"adaptive-chat\"``). Forwarded to transport listeners so the\n * outbound request can tag the correct ``X-Active-Lid-Slot`` regardless\n * of which bar most recently configured the singleton transport.\n * Without per-send threading, two coexisting chat-bars race over the\n * transport's cached ``activeLidSlot`` and the user-facing routing\n * silently follows whichever bar configured last.\n */\n activeLidSlot?: string;\n}\nexport type Unsubscribe = () => void;\n\nexport const CHAT_SESSION_STORAGE_KEY = 'syntro:chat:v1';\n\ninterface PersistedShape {\n messages: TrailMessage[];\n nextId: number;\n}\n\nfunction isValidMessage(value: unknown): value is TrailMessage {\n if (typeof value !== 'object' || value === null) return false;\n const m = value as Record<string, unknown>;\n return (\n (typeof m.id === 'number' || typeof m.id === 'string') &&\n (m.role === 'user' || m.role === 'assistant' || m.role === 'system') &&\n typeof m.text === 'string'\n );\n}\n\nfunction loadFromStorage(): PersistedShape | null {\n try {\n const raw = globalThis.localStorage?.getItem(CHAT_SESSION_STORAGE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (!parsed || !Array.isArray(parsed.messages)) return null;\n const messages = parsed.messages.filter(isValidMessage);\n const nextId = typeof parsed.nextId === 'number' ? parsed.nextId : messages.length + 1;\n return { messages, nextId };\n } catch {\n return null;\n }\n}\n\nexport class ChatSession {\n private _messages: TrailMessage[] = [];\n private _inFlight = false;\n private _nextId = 1;\n\n private subscribers = new Set<ChatSessionSubscriber>();\n private sendListeners = new Set<SendListener>();\n private interruptListeners = new Set<InterruptListener>();\n private toolResultListeners = new Set<ToolResultListener>();\n\n constructor() {\n const restored = loadFromStorage();\n if (restored) {\n this._messages = restored.messages;\n this._nextId = restored.nextId;\n }\n }\n\n /** Snapshot the current state. Always returns a fresh immutable view. */\n getState(): ChatSessionState {\n return { messages: [...this._messages], inFlight: this._inFlight };\n }\n\n /**\n * Subscribe to state changes. Called immediately with the current\n * state, then again on every change. Returns an unsubscribe function.\n */\n subscribe(cb: ChatSessionSubscriber): Unsubscribe {\n this.subscribers.add(cb);\n cb(this.getState());\n return () => {\n this.subscribers.delete(cb);\n };\n }\n\n /**\n * User submitted a message. Appends a user-role message, sets\n * inFlight=true, notifies state subscribers, and fires a \"send\"\n * event so transports can pick it up. Empty/whitespace text is a\n * no-op (matches the chat bar's local guard).\n */\n send(text: string, opts?: SendOptions): void {\n const trimmed = text.trim();\n if (!trimmed) return;\n this._messages.push({ id: this._nextId++, role: 'user', text: trimmed });\n this._inFlight = true;\n this.notify();\n const event: { text: string; activeLidSlot?: string } = { text: trimmed };\n if (opts?.activeLidSlot) event.activeLidSlot = opts.activeLidSlot;\n for (const listener of this.sendListeners) listener(event);\n }\n\n /**\n * Single-shot assistant reply (no streaming). Equivalent to\n * receiveStart + receiveDelta + receiveEnd in one call. Useful for\n * stub transports and tests that don't model streaming.\n */\n receive(text: string): void {\n const id = `m-${this._nextId++}`;\n this._messages.push({ id, role: 'assistant', text, status: 'complete' });\n this._inFlight = false;\n this.notify();\n }\n\n /**\n * Begin a streaming assistant message. Appends an empty assistant\n * message with status='streaming'. Caller (transport adapter) feeds\n * deltas via receiveDelta(id, text) and signals completion via\n * receiveEnd(id). `inFlight` stays true through the stream.\n */\n receiveStart(id: string): void {\n this._messages.push({ id, role: 'assistant', text: '', status: 'streaming' });\n this._inFlight = true;\n this.notify();\n }\n\n /**\n * Append a delta to a streaming message. No-op when the id is\n * unknown (race between transport events and reset, etc.) \u2014 never\n * throws so transports can fire-and-forget.\n */\n receiveDelta(id: string, delta: string): void {\n const msg = this._messages.find((m) => m.id === id);\n if (!msg || msg.status !== 'streaming') return;\n msg.text += delta;\n this.notify();\n }\n\n /**\n * Mark a streaming message complete and clear inFlight. No-op when\n * the id is unknown (defensive against transport double-fires).\n */\n receiveEnd(id: string): void {\n const msg = this._messages.find((m) => m.id === id);\n if (msg && msg.status === 'streaming') {\n msg.status = 'complete';\n }\n this._inFlight = false;\n this.notify();\n }\n\n /**\n * Transport reports a fatal error. Marks any in-flight streaming\n * message as 'error' (so the trail can render a styled error chip\n * instead of pretending the partial text was a complete answer),\n * appends a system-role message with the error text for visibility,\n * and clears inFlight.\n */\n error(message: string): void {\n for (const m of this._messages) {\n if (m.status === 'streaming') m.status = 'error';\n }\n this._messages.push({\n id: `err-${this._nextId++}`,\n role: 'system',\n text: message,\n status: 'error',\n });\n this._inFlight = false;\n this.notify();\n }\n\n /**\n * User clicked the in-flight stop button. Clears inFlight and\n * fires an \"interrupt\" event so transports can cancel their\n * in-flight request. No-op if not in-flight (idempotent).\n */\n interrupt(): void {\n if (!this._inFlight) return;\n this._inFlight = false;\n this.notify();\n for (const listener of this.interruptListeners) listener();\n }\n\n /**\n * Wipe state. Used by the canvas-close path (start a fresh\n * conversation next time) and by tests.\n */\n reset(): void {\n this._messages = [];\n this._inFlight = false;\n this._nextId = 1;\n this.notify();\n }\n\n /** Register a transport's send listener. Returns unsubscribe. */\n onSend(listener: SendListener): Unsubscribe {\n this.sendListeners.add(listener);\n return () => {\n this.sendListeners.delete(listener);\n };\n }\n\n /**\n * True when at least one transport has wired itself to the session's\n * send pipeline. Views can use this to surface \"no chat backend\n * connected\" affordances instead of hanging in `inFlight` after a\n * send fires into the void.\n */\n hasTransport(): boolean {\n return this.sendListeners.size > 0;\n }\n\n /** Register a transport's interrupt listener. Returns unsubscribe. */\n onInterrupt(listener: InterruptListener): Unsubscribe {\n this.interruptListeners.add(listener);\n return () => {\n this.interruptListeners.delete(listener);\n };\n }\n\n /**\n * Register a transport's tool-result listener. The transport\n * forwards `tool-result` actions back to the agent after the user\n * approves or rejects a client-tool call. Returns unsubscribe.\n */\n onToolResult(listener: ToolResultListener): Unsubscribe {\n this.toolResultListeners.add(listener);\n return () => {\n this.toolResultListeners.delete(listener);\n };\n }\n\n // -------------------------------------------------------------------------\n // Tool calls\n // -------------------------------------------------------------------------\n\n /**\n * Attach a tool call to a streaming assistant message. No-op when\n * the message id is unknown (race between transport events and\n * reset / late mount).\n */\n addToolCall(messageId: string | number, toolCall: TrailToolCall): void {\n const msg = this._messages.find((m) => m.id === messageId);\n if (!msg) return;\n msg.toolCalls = [...(msg.toolCalls ?? []), { ...toolCall }];\n this.notify();\n }\n\n /**\n * Partially update a tool call by id. Used by the transport to\n * advance status (args-streaming \u2192 running \u2192 done) as AG-UI events\n * arrive. No-op when the id is unknown.\n */\n updateToolCall(toolCallId: string, patch: Partial<TrailToolCall>): void {\n for (const msg of this._messages) {\n const tcs = msg.toolCalls;\n if (!tcs) continue;\n const idx = tcs.findIndex((tc) => tc.id === toolCallId);\n if (idx === -1) continue;\n const next = [...tcs];\n next[idx] = { ...next[idx], ...patch } as TrailToolCall;\n msg.toolCalls = next;\n this.notify();\n return;\n }\n }\n\n /**\n * Resolve a (client-) tool call. Marks the call done, persists, and\n * fires onToolResult so the transport can forward the result + the\n * user's approve/reject decision back to the agent. No-op when the\n * id is unknown.\n */\n resolveToolCall(toolCallId: string, result: unknown, approved: boolean): void {\n let found = false;\n for (const msg of this._messages) {\n const tcs = msg.toolCalls;\n if (!tcs) continue;\n const idx = tcs.findIndex((tc) => tc.id === toolCallId);\n if (idx === -1) continue;\n const next = [...tcs];\n next[idx] = { ...next[idx], status: 'done' } as TrailToolCall;\n msg.toolCalls = next;\n found = true;\n break;\n }\n if (!found) return;\n this.notify();\n for (const listener of this.toolResultListeners) {\n listener({ toolCallId, result, approved });\n }\n }\n\n private notify(): void {\n const state = this.getState();\n this.persist();\n for (const sub of this.subscribers) sub(state);\n }\n\n private persist(): void {\n try {\n if (this._messages.length === 0) {\n globalThis.localStorage?.removeItem(CHAT_SESSION_STORAGE_KEY);\n return;\n }\n const payload: PersistedShape = { messages: this._messages, nextId: this._nextId };\n globalThis.localStorage?.setItem(CHAT_SESSION_STORAGE_KEY, JSON.stringify(payload));\n } catch {\n // private mode / quota / SSR \u2014 swallow; in-memory state is still valid\n }\n }\n}\n\n/**\n * The module-level singleton. Every `<adaptive-chat-bar>` (regardless\n * of which slot it lives in) reads from and writes to this instance.\n * Multiple imports of this module return the same object.\n *\n * Scope: per-page. Correct for the canonical case (one user, one\n * conversation, however many canvas views surface it). Multiple\n * `<smart-canvas>` instances on the same page will share state \u2014\n * tracked in project_future_work.md for per-runtime scoping.\n */\nexport const chatSession = new ChatSession();\n", "/**\n * ChatTransport \u2014 singleton transport adapter that bridges chatSession\n * (the view-side state holder) to the real backend chat pipeline\n * (AG-UI SSE at `/api/adaptive/stream`).\n *\n * This is the unification of two formerly separate paths:\n * - `ChatAssistantLit` (old) owns the transport plumbing \u2014\n * AgUiTransport, Cloudflare Turnstile, headers, A2UI passthrough,\n * telemetry, fallback card.\n * - `AdaptiveChatBar` + `chatSession` (new) owns the canvas-lid UX \u2014\n * glassmorphism bar, bubble-up trail, per-page persistence.\n *\n * This module ports every transport-side concern from ChatAssistantLit\n * into a session-shaped adapter so the new bar gets full backend\n * parity. The bar stays a pure view; the transport stays a pure pipe.\n *\n * Lifecycle:\n * - `configure({ backendUrl, runtime, ... })` \u2014 called once by the\n * SDK runtime at bootstrap from chat config. Idempotent; second\n * call with the same backendUrl is a no-op.\n * - Connection is LAZY. The transport doesn't acquire Turnstile or\n * open the SSE until the first chatSession.send() \u2014 saves cost\n * on pages where the user never opens chat.\n * - On chatSession.send \u2192 transport ensures connected (acquires\n * Turnstile token, builds AgUiTransport) then forwards\n * `{type:'user-message', text}` to the agent.\n * - On chatSession.onInterrupt \u2192 transport sends stop-generation.\n * - AgUi events stream into chatSession via receiveStart / Delta /\n * End / error.\n * - A2UI custom events forward to runtime.actions.applyBatch so the\n * agent can drive canvas updates.\n *\n * Telemetry parity with ChatAssistantLit:\n * - chatbot.transport_error (every error, with status/body/name)\n * - chatbot.a2ui_applied\n * - chatbot.fallback_rendered \u2014 emitted when the transport gives up\n * (Turnstile failed AND backend rejected) so existing PostHog\n * queries keep working.\n *\n * Threading model: single-flight per page. Multiple concurrent sends\n * are queued by AgUiTransport itself. Multiple bar mounts share this\n * one transport via chatSession.\n */\n\nimport type { ServerEvent } from '@syntrologie/chat';\n// AgUiTransport / Turnstile helpers live in the existing packages \u2014\n// we reuse them instead of re-implementing.\nimport { AgUiTransport } from '@syntrologie/chat/transport/agui';\n\nimport type { TrailToolCall } from './AdaptiveChatTrail';\nimport { chatSession } from './ChatSession';\nimport type { ElementMutation } from './elements';\nimport { decodeMutationEnvelope } from './elements';\nimport { acquireTokenWithChallenge } from './Turnstile';\nimport type { ChatbotWidgetRuntime } from './types';\n\n/**\n * Per-customer \"chat unavailable\" card config. Surfaced via onFallback\n * when the transport gives up after repeated failures. Mirrors\n * ChatbotFallback in types.ts so consumers can pass the same config.\n */\nexport interface ChatbotFallbackConfig {\n title?: string;\n message?: string;\n ctaLabel?: string;\n ctaHref?: string;\n}\n\nexport interface ChatTransportConfig {\n /** Backend host, e.g. \"https://demo-api.syntrologie.com\" or \"\" for same-origin. */\n backendUrl: string;\n /** Runtime hooks for A2UI apply + telemetry. */\n runtime: ChatbotWidgetRuntime;\n /** Optional thread id for conversation continuity across reloads. */\n threadId?: string;\n /**\n * Optional set of client-tool names the transport should treat as\n * \"needs user approval\" (surfaced via chatSession.toolCalls instead\n * of auto-executed server-side). Empty by default \u2014 all tool calls\n * are server-driven and the transport just emits the \"tool call\n * happened\" event.\n */\n clientTools?: Set<string>;\n /**\n * Per-customer \"chat unavailable\" card. Rendered by the host\n * (typically AdaptiveChatBarMountable) after repeated connect\n * failures wipe the chat surface \u2014 exactly the same UX\n * ChatAssistantLit's fallback path provides.\n */\n fallback?: ChatbotFallbackConfig;\n /**\n * Arbitrary JSON object attached to every AG-UI request as\n * `forwardedProps`. Used by the adaptive chat surface to ship the\n * LLM-authored UI element config (`uiTemplates`, `elementsEnabled`)\n * per request \u2014 the backend reads these to enable the\n * `mount_element` / `patch_element` / `unmount_element` tools.\n * Callable form is re-evaluated on every turn so a config edit can\n * land mid-conversation.\n */\n forwardedProps?: Record<string, unknown> | (() => Record<string, unknown> | undefined);\n /**\n * Optional callback for `syntro.element.mutation` AG-UI custom events.\n * The transport decodes the envelope on receipt; if it matches the\n * element-mutation schema, mutations are routed here instead of the\n * generic `runtime.actions.applyBatch` legacy path. Consumers are\n * expected to forward to `ElementInstanceStore.apply(mutations)` \u2014\n * we don't take a store reference directly so the transport stays\n * agnostic of which surface owns the store (the chat-bar widget\n * may own one; ChatAssistantLit owns its own; both share this\n * singleton transport).\n *\n * When unset, element-mutation envelopes fall back to applyBatch,\n * matching legacy behaviour (which would no-op since applyBatch\n * doesn't know about MutationEnvelope).\n */\n onElementMutation?: (mutations: ElementMutation[]) => void;\n /**\n * Slot the chat-bar widget is mounted into (e.g. ``\"drawer\"``,\n * ``\"adaptive-chat\"``). Forwarded as ``X-Active-Lid-Slot`` on every\n * ``/api/adaptive/stream`` request so the backend can route mounts to\n * the canvas next to whichever lid the visitor sent from. Optional \u2014\n * omitting it falls back to the template's static ``default_slot``\n * server-side, which is the pre-change behaviour.\n */\n activeLidSlot?: string;\n}\n\n/**\n * Debounce window for connect errors. Single transient errors\n * (cold-start 502, brief CORS preflight failure) should NOT swap the\n * chat to the fallback card; only sustained failure should. Matches\n * ChatAssistantLit's ERROR_DEBOUNCE_MS.\n */\nexport const FALLBACK_DEBOUNCE_MS = 1_500;\n\nexport interface FallbackPayload {\n reason: 'connect_failed' | 'connect_timeout';\n fallback: ChatbotFallbackConfig;\n transportId: string;\n transportAgeMs: number;\n messagesSucceeded: number;\n hadTurnstileToken: boolean | null;\n errorStatus: number | null;\n errorBody: string | null;\n errorMessage: string | null;\n errorName: string | null;\n}\n\nexport type FallbackListener = (payload: FallbackPayload) => void;\n\ntype ChatTransportStatus =\n | 'idle' // configure() not called yet\n | 'configured' // ready but not connected\n | 'acquiring' // Turnstile token acquisition in flight\n | 'connected' // AgUiTransport up and ready\n | 'error'; // last attempt failed; will retry on next send\n\ninterface SyntroGlobalConfig {\n token?: string;\n}\n\n/**\n * Read the workspace's syn_* token from runtime-config.js. The SDK\n * sets this global at bootstrap; for non-CDN test environments the\n * test page sets it directly. Returns undefined when the global is\n * missing \u2014 the connect will then fall through to the unauthenticated\n * path and the backend will 401 (caught by error handling below).\n */\nfunction readSyntroToken(): string | undefined {\n if (typeof window === 'undefined') return undefined;\n const cfg = (window as unknown as { __SYNTRO_CONFIG__?: SyntroGlobalConfig }).__SYNTRO_CONFIG__;\n const token = cfg?.token;\n return typeof token === 'string' && token.length > 0 ? token : undefined;\n}\n\n/**\n * Debug logger gated on `window.__SYNTRO_CHAT_DEBUG__`. Mirrors\n * ChatAssistantLit so flipping that flag in the customer's DevTools\n * enables verbose tracing across the whole chat pipeline (the bar\n * AND the legacy assistant) without rebuilding the SDK.\n */\nfunction debug(...args: unknown[]): void {\n if (typeof window === 'undefined') return;\n if ((window as unknown as { __SYNTRO_CHAT_DEBUG__?: boolean }).__SYNTRO_CHAT_DEBUG__) {\n console.debug('[chat-transport]', ...args);\n }\n}\n\nexport class ChatTransport {\n private _config: ChatTransportConfig | null = null;\n private _status: ChatTransportStatus = 'idle';\n private _agui: AgUiTransport | null = null;\n private _transportUnsub: (() => void) | null = null;\n private _sessionUnsubSend: (() => void) | null = null;\n private _sessionUnsubInterrupt: (() => void) | null = null;\n private _sessionUnsubToolResult: (() => void) | null = null;\n private _connectInFlight: Promise<boolean> | null = null;\n /** Bounded streaming-message id for the currently-being-typed assistant turn. */\n private _currentAssistantMessageId: string | null = null;\n /** Outcome bookkeeping for telemetry. */\n private _hadTurnstileToken: boolean | null = null;\n /** Count of successful round-trips for telemetry payloads. */\n private _messagesSucceeded = 0;\n /** True once a successful assistant message has landed \u2014 gates fallback. */\n private _hasSucceeded = false;\n /** True once fallback has fired (one-shot). */\n private _fallbackRendered = false;\n /**\n * Per-send override for ``X-Active-Lid-Slot``. Set in the\n * ``chatSession.onSend`` listener immediately before each\n * ``_forwardUserMessage`` and consumed by ``buildHeaders`` on the\n * outbound request. The singleton transport is shared by every\n * mounted chat-bar (drawer + inline) so cached ``_config.activeLidSlot``\n * follows whichever bar last reconfigured \u2014 using that for routing\n * silently misroutes tiles when both bars coexist. Per-send threading\n * pins the header to the bar that actually sent the message.\n */\n private _pendingLidSlot: string | null = null;\n /** Active debounce timer; null when no debounce pending. */\n private _errorDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n /** Most recent error payload, captured so debounced fallback can attach it. */\n private _lastErrorPayload: {\n message?: string;\n status?: number | null;\n body?: string | null;\n errorName?: string | null;\n } | null = null;\n private _fallbackListeners = new Set<FallbackListener>();\n /**\n * Per-configure-cycle id for correlating telemetry events from a\n * single transport lifetime. Mirrors ChatAssistantLit's mountId\n * but scoped to configure cycles since the transport is a\n * singleton across mounts.\n */\n private _transportId = `tx_${Math.random().toString(36).slice(2, 8)}`;\n private _configuredAt = 0;\n\n /**\n * Configure the transport. Idempotent \u2014 calling again with the same\n * backendUrl is a no-op; calling with a different backendUrl tears\n * the connection down and re-arms.\n */\n configure(config: ChatTransportConfig): void {\n const same =\n this._config &&\n this._config.backendUrl === config.backendUrl &&\n this._config.threadId === config.threadId;\n if (same) {\n // Allow runtime + clientTools to be replaced without reconnect \u2014\n // the bar may remount with a fresh runtime closure.\n this._config = { ...this._config, ...config };\n return;\n }\n this._disconnect();\n this._config = config;\n this._status = 'configured';\n this._transportId = `tx_${Math.random().toString(36).slice(2, 8)}`;\n this._configuredAt = Date.now();\n this._wireSession();\n debug('configured', {\n transportId: this._transportId,\n backendUrl: config.backendUrl,\n threadId: config.threadId,\n });\n }\n\n /** ms since the most recent configure() call. 0 before any configure. */\n private _ageMs(): number {\n return this._configuredAt === 0 ? 0 : Date.now() - this._configuredAt;\n }\n\n /** True when configure() has been called and we're ready to lazy-connect on send. */\n get isConfigured(): boolean {\n return this._status !== 'idle';\n }\n\n /** True when AgUiTransport is up. */\n get isConnected(): boolean {\n return this._status === 'connected';\n }\n\n /**\n * Subscribe to fallback events \u2014 fires once per configure cycle\n * when the transport gives up after sustained failure. Hosts\n * (typically AdaptiveChatBarMountable) use this to swap the chat\n * bar for a static \"contact support\" card.\n */\n onFallback(listener: FallbackListener): () => void {\n this._fallbackListeners.add(listener);\n return () => {\n this._fallbackListeners.delete(listener);\n };\n }\n\n /**\n * Test seam \u2014 drive a synthetic error event through the transport's\n * error handling without standing up a real AgUi transport. Production\n * code path uses _onTransportEvent. Exported as a public method to\n * keep the test isolation simple; not part of the documented API.\n */\n simulateError(payload: {\n message?: string;\n status?: number | null;\n body?: string | null;\n errorName?: string | null;\n }): void {\n this._handleErrorEvent(payload);\n }\n\n /**\n * Test seam \u2014 register a synthetic successful message-complete so\n * the hasSucceeded gate flips without a real AgUi round-trip.\n */\n simulateSuccessfulMessage(): void {\n this._hasSucceeded = true;\n this._messagesSucceeded += 1;\n this._clearDebounceTimer();\n }\n\n /**\n * Test seam \u2014 return the lid slot that the next outbound request\n * WOULD tag ``X-Active-Lid-Slot`` with, given current state. Mirrors\n * the exact resolution buildHeaders uses (per-send slot wins over\n * cached config). Not part of the documented API.\n */\n getActiveLidSlotForTest(): string | null {\n return this._pendingLidSlot ?? this._config?.activeLidSlot ?? null;\n }\n\n /**\n * Tear connection-level state down. Used internally by configure()\n * to swap backends; preserves host-registered fallback listeners\n * because the host UI handler (e.g. AdaptiveChatBarMountable's\n * \"swap to fallback card\" callback) is configuration-independent.\n */\n private _disconnect(): void {\n if (this._transportUnsub) {\n this._transportUnsub();\n this._transportUnsub = null;\n }\n if (this._sessionUnsubSend) {\n this._sessionUnsubSend();\n this._sessionUnsubSend = null;\n }\n if (this._sessionUnsubInterrupt) {\n this._sessionUnsubInterrupt();\n this._sessionUnsubInterrupt = null;\n }\n if (this._sessionUnsubToolResult) {\n this._sessionUnsubToolResult();\n this._sessionUnsubToolResult = null;\n }\n if (this._agui) {\n this._agui.disconnect();\n this._agui = null;\n }\n this._clearDebounceTimer();\n this._config = null;\n this._status = 'idle';\n this._connectInFlight = null;\n this._currentAssistantMessageId = null;\n this._hadTurnstileToken = null;\n this._messagesSucceeded = 0;\n this._hasSucceeded = false;\n this._fallbackRendered = false;\n this._lastErrorPayload = null;\n this._pendingLidSlot = null;\n }\n\n /**\n * Tear everything down \u2014 connection state PLUS host listeners.\n * Use this in test teardown or when fully shutting the transport\n * (page unload, integration test reset). The mountable calls\n * _disconnect indirectly via reconfigure.\n */\n reset(): void {\n this._disconnect();\n this._fallbackListeners.clear();\n }\n\n private _clearDebounceTimer(): void {\n if (this._errorDebounceTimer) {\n clearTimeout(this._errorDebounceTimer);\n this._errorDebounceTimer = null;\n }\n }\n\n /**\n * Shared error-handling kernel \u2014 called by the AG-UI subscriber and\n * by the simulateError test seam. Publishes transport_error\n * telemetry, captures lastErrorPayload, and starts the debounce\n * timer that will fire fallback if no successful message arrives\n * before it expires. Gated by hasSucceeded (post-success errors\n * never fallback) and _fallbackRendered (one-shot).\n */\n private _handleErrorEvent(payload: {\n message?: string;\n status?: number | null;\n body?: string | null;\n errorName?: string | null;\n }): void {\n const status = payload.status ?? null;\n const body = payload.body ? String(payload.body).slice(0, 200) : null;\n this._lastErrorPayload = {\n message: payload.message,\n status,\n body,\n errorName: payload.errorName ?? null,\n };\n\n this._config?.runtime.events.publish('chatbot.transport_error', {\n source: 'chat-transport',\n transportId: this._transportId,\n transportAgeMs: this._ageMs(),\n messagesSucceeded: this._messagesSucceeded,\n hadTurnstileToken: this._hadTurnstileToken,\n hasSucceeded: this._hasSucceeded,\n errorMessage: payload.message ?? null,\n errorStatus: status,\n errorBody: body,\n errorName: payload.errorName ?? null,\n });\n\n if (this._hasSucceeded || this._fallbackRendered || this._errorDebounceTimer) return;\n this._errorDebounceTimer = setTimeout(() => {\n this._errorDebounceTimer = null;\n if (this._hasSucceeded || this._fallbackRendered) return;\n this._renderFallback('connect_failed');\n }, FALLBACK_DEBOUNCE_MS);\n }\n\n /**\n * Fire the fallback. One-shot per configure cycle. Notifies all\n * fallback listeners with the per-customer card config and the\n * diagnostic snapshot for telemetry/debug.\n */\n private _renderFallback(reason: FallbackPayload['reason']): void {\n if (this._fallbackRendered) return;\n this._fallbackRendered = true;\n debug('fallback', { reason, transportId: this._transportId, ageMs: this._ageMs() });\n const fallback = this._config?.fallback ?? {};\n const payload: FallbackPayload = {\n reason,\n fallback,\n transportId: this._transportId,\n transportAgeMs: this._ageMs(),\n messagesSucceeded: this._messagesSucceeded,\n hadTurnstileToken: this._hadTurnstileToken,\n errorStatus: this._lastErrorPayload?.status ?? null,\n errorBody: this._lastErrorPayload?.body ?? null,\n errorMessage: this._lastErrorPayload?.message ?? null,\n errorName: this._lastErrorPayload?.errorName ?? null,\n };\n this._config?.runtime.events.publish(\n 'chatbot.fallback_rendered',\n payload as unknown as Record<string, unknown>\n );\n for (const listener of this._fallbackListeners) listener(payload);\n }\n\n // -------------------------------------------------------------------------\n // Internal: chatSession wiring\n // -------------------------------------------------------------------------\n\n private _wireSession(): void {\n this._sessionUnsubSend = chatSession.onSend(({ text, activeLidSlot }) => {\n // Capture the sending bar's slot BEFORE awaiting the connect /\n // forward chain. `_pendingLidSlot` is consumed by buildHeaders on\n // the outbound request \u2014 see the field doc on `_pendingLidSlot`\n // for why we can't rely on `_config.activeLidSlot` here.\n this._pendingLidSlot =\n typeof activeLidSlot === 'string' && activeLidSlot.length > 0 ? activeLidSlot : null;\n void this._forwardUserMessage(text);\n });\n this._sessionUnsubInterrupt = chatSession.onInterrupt(() => {\n this._agui?.send({ type: 'stop-generation' });\n });\n this._sessionUnsubToolResult = chatSession.onToolResult(({ toolCallId, result, approved }) => {\n this._agui?.send({ type: 'tool-result', toolCallId, result, approved });\n });\n }\n\n private async _forwardUserMessage(text: string): Promise<void> {\n const ok = await this._ensureConnected();\n if (!ok || !this._agui) {\n // Connect failed; surface to the session so the bar shows an error\n // chip and clears inFlight (otherwise the user is stuck on the\n // \u23F9 stop button forever).\n chatSession.error(\"Couldn't connect to chat. Please try again.\");\n return;\n }\n this._agui.send({ type: 'user-message', text });\n }\n\n // -------------------------------------------------------------------------\n // Internal: connect (lazy, Turnstile-gated)\n // -------------------------------------------------------------------------\n\n /**\n * Ensure AgUiTransport is up. Idempotent \u2014 multiple concurrent calls\n * dedupe to a single Turnstile acquisition + transport setup.\n * Returns true on success, false on terminal failure.\n */\n private async _ensureConnected(): Promise<boolean> {\n if (this._status === 'connected' && this._agui) return true;\n if (!this._config) return false;\n if (this._connectInFlight) return this._connectInFlight;\n\n this._connectInFlight = (async () => {\n this._status = 'acquiring';\n const cft = await this._acquireTurnstileWithChallenge();\n this._hadTurnstileToken = cft !== null;\n\n if (this._config === null) return false; // raced with reset()\n\n const baseUrl = this._config.backendUrl.replace(/\\/$/, '');\n const streamUrl = `${baseUrl}/api/adaptive/stream`;\n const token = readSyntroToken();\n const buildHeaders = (): Record<string, string> => {\n const h: Record<string, string> = {};\n if (token) h.Authorization = `Bearer ${token}`;\n if (cft) h['CF-Turnstile-Token'] = cft;\n // Forward the slot the chat-bar that initiated this send lives\n // in so the backend can route mount_element results to the\n // canvas next to it. Prefer `_pendingLidSlot` (set on each\n // chatSession.onSend) over `_config.activeLidSlot` (last value\n // cached by configure): when drawer + inline bars coexist they\n // share this singleton transport, so the cached config follows\n // whichever bar reconfigured most recently \u2014 not the bar that\n // actually sent the current message. `_pendingLidSlot` pins the\n // header to the sender. Fall back to the cached config so older\n // call sites that haven't been migrated still get a value.\n const lidSlot = this._pendingLidSlot ?? this._config?.activeLidSlot;\n if (typeof lidSlot === 'string' && lidSlot.length > 0) {\n h['X-Active-Lid-Slot'] = lidSlot;\n }\n // Forward PostHog distinct_id so the backend can resolve historical\n // context (KNOWN ABOUT VISITOR block, persona summaries). Two\n // sources, in order:\n // 1. runtime.telemetry.getDistinctId() \u2014 preferred, mirrors what\n // the rest of the SDK uses for capture identity.\n // 2. window.posthog.get_distinct_id() \u2014 fallback for embeds where\n // the host page initialises PostHog directly.\n // Defensive: missing/blocked PostHog \u2192 header omitted \u2192 backend\n // falls back to cold-start.\n try {\n const rt = this._config?.runtime as\n | { telemetry?: { getDistinctId?: () => string | null | undefined } }\n | undefined;\n const fromRuntime = rt?.telemetry?.getDistinctId?.();\n const fromWindow = (\n window as unknown as { posthog?: { get_distinct_id?: () => string } }\n ).posthog?.get_distinct_id?.();\n const did = fromRuntime || fromWindow;\n if (typeof did === 'string' && did.length > 0) {\n h['X-Distinct-Id'] = did;\n }\n } catch {\n // PostHog throw on get_distinct_id is extremely rare but cheap to guard.\n }\n return h;\n };\n\n const runtime = this._config.runtime;\n // Resolve forwardedProps at run-time (each AG-UI request), not at\n // transport construction. The config can be updated via\n // `configure()` with the same backendUrl (no reconnect), so the\n // late-bound closure keeps the transport in sync with the most\n // recent uiTemplates / elementsEnabled declarations.\n const resolveForwardedProps = (): Record<string, unknown> | undefined => {\n const raw = this._config?.forwardedProps;\n return typeof raw === 'function' ? raw() : raw;\n };\n this._agui = new AgUiTransport({\n url: streamUrl,\n headers: buildHeaders,\n threadId: this._config.threadId,\n clientTools: this._config.clientTools,\n // Adaptive runtime SDK needs the `syntro_chat_session` cookie to\n // round-trip cross-origin so subsequent boot fetches can rehydrate\n // LLM-authored UI elements. Editor / action-plan chat surfaces\n // auth via `?token=` and intentionally leave this unset (see\n // AgUiTransportOptions.credentials docstring).\n credentials: 'include',\n forwardedProps: resolveForwardedProps,\n onA2UIEvent: (payload) => {\n // Discriminate `syntro.element.mutation` envelopes (LLM-\n // authored UI element mounts/patches/unmounts) from legacy\n // A2UI / raw ActionStep payloads. Mirrors ChatAssistantLit's\n // routing \u2014 the chat-bar lid surface needs the same wiring so\n // mount_element / patch_element / unmount_element results\n // actually land on the host page.\n const mutations = decodeMutationEnvelope(payload);\n if (mutations !== null) {\n const handler = this._config?.onElementMutation;\n if (handler) {\n try {\n handler(mutations);\n runtime.events.publish('chatbot.element_mutation_applied', {\n source: 'chat-transport',\n count: mutations.length,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[chat-transport] element mutation apply failed:', msg);\n }\n return;\n }\n // No handler registered \u2014 the surface using this transport\n // didn't opt into element mutations. Drop silently rather\n // than feeding a MutationEnvelope into applyBatch (which\n // would no-op or warn).\n return;\n }\n runtime.actions\n .applyBatch([payload as unknown as Record<string, unknown>])\n .then(() => {\n runtime.events.publish('chatbot.a2ui_applied', { source: 'chat-transport' });\n })\n .catch((err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err);\n console.error('[chat-transport] A2UI apply failed:', msg);\n });\n },\n });\n this._agui.connect();\n this._transportUnsub = this._agui.subscribe((event) => this._onTransportEvent(event));\n this._status = 'connected';\n return true;\n })();\n\n try {\n return await this._connectInFlight;\n } finally {\n this._connectInFlight = null;\n }\n }\n\n /**\n * Acquire a Turnstile token via the managed-challenge flow.\n * Delegates to the shared Turnstile helper that owns the verify\n * panel lifecycle. Returns null when Turnstile is disabled at\n * build time or acquisition fails.\n */\n private async _acquireTurnstileWithChallenge(): Promise<string | null> {\n const { token } = await acquireTokenWithChallenge();\n return token;\n }\n\n // -------------------------------------------------------------------------\n // Internal: AgUi event \u2192 chatSession\n // -------------------------------------------------------------------------\n\n /**\n * Look up a tool call's current chatSession-side status by id.\n * Used to decide between addToolCall (first sighting) and\n * updateToolCall (subsequent updates) when AG-UI re-emits\n * `tool-call` events for client tools transitioning to 'pending'.\n */\n private _findToolCallStatus(toolCallId: string): TrailToolCall['status'] | null {\n const state = chatSession.getState();\n for (const msg of state.messages) {\n const tc = msg.toolCalls?.find((t) => t.id === toolCallId);\n if (tc) return tc.status;\n }\n return null;\n }\n\n /** Map AG-UI ToolCallStatus to TrailToolCall status. */\n private _mapToolCallStatus(status: string): TrailToolCall['status'] {\n switch (status) {\n case 'args-streaming':\n return 'args-streaming';\n case 'pending':\n return 'pending';\n case 'running':\n return 'running';\n case 'done':\n return 'done';\n case 'error':\n return 'error';\n default:\n return 'running';\n }\n }\n\n private _onTransportEvent(event: ServerEvent): void {\n const runtime = this._config?.runtime;\n\n switch (event.type) {\n case 'session-ready':\n case 'messages-snapshot':\n case 'typing':\n // Local-only events from AgUiTransport.connect() \u2014 no UI impact.\n return;\n\n case 'message-append': {\n // Start of a new streaming assistant message.\n this._currentAssistantMessageId = event.message.id;\n chatSession.receiveStart(event.message.id);\n if (event.message.content && event.message.content.length > 0) {\n chatSession.receiveDelta(event.message.id, event.message.content);\n }\n return;\n }\n\n case 'message-delta': {\n const id = event.messageId ?? this._currentAssistantMessageId;\n if (!id || !event.delta) return;\n chatSession.receiveDelta(id, event.delta);\n return;\n }\n\n case 'message-complete': {\n const id = event.messageId ?? this._currentAssistantMessageId;\n if (!id) return;\n chatSession.receiveEnd(id);\n this._currentAssistantMessageId = null;\n this._messagesSucceeded += 1;\n // Flip the hasSucceeded gate: errors after this point will no\n // longer trigger a fallback swap (matches ChatAssistantLit).\n this._hasSucceeded = true;\n this._clearDebounceTimer();\n return;\n }\n\n case 'tool-call': {\n // tool-call arrives twice in the AG-UI flow: once at start\n // (status='args-streaming') and once at end for client tools\n // with status='pending' awaiting user approval. Add on the\n // first sighting, update on the second.\n const targetMessageId = event.messageId ?? this._currentAssistantMessageId;\n if (!targetMessageId) return;\n const existing = this._findToolCallStatus(event.toolCall.id);\n if (!existing) {\n chatSession.addToolCall(targetMessageId, {\n id: event.toolCall.id,\n name: event.toolCall.name,\n status: this._mapToolCallStatus(event.toolCall.status),\n });\n } else {\n chatSession.updateToolCall(event.toolCall.id, {\n name: event.toolCall.name,\n status: this._mapToolCallStatus(event.toolCall.status),\n });\n }\n return;\n }\n\n case 'tool-call-args-delta':\n // We don't currently surface streaming args in the trail chip\n // (too noisy for the compact UI), but a future expanded view\n // could subscribe and render them. Logged under debug.\n debug('tool-call-args-delta', event);\n return;\n\n case 'tool-call-done':\n // Server-side tool finished. Mark complete in the trail so the\n // chip transitions from \"running\" to \"done\". Client-tool\n // resolution goes through chatSession.resolveToolCall instead.\n chatSession.updateToolCall(event.toolCallId, { status: 'done' });\n return;\n\n case 'a2ui':\n // A2UI events also flow via onA2UIEvent in the transport\n // constructor \u2014 that path is what applies the batch. This\n // duplicate event is the public mirror; ignore here.\n return;\n\n case 'error': {\n const status = event.status ?? null;\n const body = event.body ? String(event.body).slice(0, 200) : null;\n console.warn(\n `[chat-transport] error status=${status ?? 'no-status'} succeeded=${this._messagesSucceeded}`,\n event\n );\n // Route through the shared error-handling kernel so the\n // debounce / hasSucceeded gate / fallback path apply uniformly\n // regardless of whether the error came from AG-UI or a test seam.\n this._handleErrorEvent({\n message: event.message,\n status,\n body,\n errorName: event.errorName ?? null,\n });\n // The chip-level error chip (shown immediately, no debounce)\n // gives the user feedback even when we're still waiting to see\n // if the failure is sustained enough to swap to the fallback.\n chatSession.error(event.message ?? 'Chat connection failed');\n this._currentAssistantMessageId = null;\n // Tear AgUiTransport down so the next send re-acquires Turnstile\n // and re-opens. Avoids reusing a broken HttpAgent under us.\n if (this._agui) {\n this._agui.disconnect();\n this._agui = null;\n }\n if (this._transportUnsub) {\n this._transportUnsub();\n this._transportUnsub = null;\n }\n this._status = 'error';\n return;\n }\n }\n }\n}\n\n/**\n * The module-level singleton. Imported by both the SDK runtime\n * bootstrap (to call configure) and any code that needs to read\n * transport state. Mirrors the chatSession singleton shape.\n */\nexport const chatTransport = new ChatTransport();\n", "/**\n * Pure mapping from raw PostHog events to ObservationEvents.\n *\n * One function: matchEvent(raw, opts) \u2192 ObservationEvent | null. Null means\n * \"drop, not significant.\" This module is the single source of truth for what\n * the chat agent sees on the in-session timeline; the SDK observer never\n * forwards anything matchEvent returns null for.\n *\n * Kept dependency-free (no DOM access, no PostHog SDK imports) so the\n * Vitest unit tests run without any browser shim.\n */\n\nexport type ObservationKind =\n | 'nav'\n | 'click'\n | 'form'\n | 'rage'\n | 'dead'\n | 'scroll'\n | 'view'\n | 'idle'\n | 'hover'\n | 'hesitation'\n | 'custom';\n\nexport interface ObservationEvent {\n ts: number;\n kind: ObservationKind;\n text: string;\n ref?: string;\n}\n\n/** Shape of a raw event reaching matchEvent. Loose by design \u2014 PostHog's\n * event shape evolves, and we want matchEvent to be resilient to extra\n * properties. */\nexport interface RawEvent {\n event: string;\n timestamp: number;\n properties: Record<string, unknown>;\n}\n\nexport interface MatchOptions {\n /** Workspace-configured custom event names to forward as kind=\"custom\". */\n observableEvents?: readonly string[];\n}\n\nconst MAX_TEXT_LEN = 200;\nconst SIGNIFICANT_CLICK_TAGS = new Set(['button', 'a']);\n\nfunction truncate(s: string): string {\n return s.length <= MAX_TEXT_LEN ? s : `${s.slice(0, MAX_TEXT_LEN - 1)}\u2026`;\n}\n\nfunction firstElement(props: Record<string, unknown>): Record<string, unknown> | null {\n const els = props.$elements;\n if (Array.isArray(els) && els.length > 0 && typeof els[0] === 'object' && els[0] !== null) {\n return els[0] as Record<string, unknown>;\n }\n return null;\n}\n\nfunction elementText(props: Record<string, unknown>): string {\n const el = firstElement(props);\n if (!el) return '';\n const t = el.text;\n return typeof t === 'string' ? t.trim() : '';\n}\n\nfunction elementTag(props: Record<string, unknown>): string {\n const explicit = props.$element_tag_name;\n if (typeof explicit === 'string') return explicit.toLowerCase();\n const el = firstElement(props);\n if (el && typeof el.tag_name === 'string') return (el.tag_name as string).toLowerCase();\n return '';\n}\n\nfunction elementRole(props: Record<string, unknown>): string {\n const el = firstElement(props);\n if (!el) return '';\n const role = el.attr__role;\n return typeof role === 'string' ? role.toLowerCase() : '';\n}\n\nfunction formName(props: Record<string, unknown>): string {\n const el = firstElement(props);\n if (!el) return 'unnamed';\n const name = el.attr__name;\n if (typeof name === 'string' && name) return name;\n const id = el.attr__id;\n if (typeof id === 'string' && id) return id;\n return 'unnamed';\n}\n\nfunction isSignificantClickTarget(props: Record<string, unknown>): boolean {\n const tag = elementTag(props);\n if (SIGNIFICANT_CLICK_TAGS.has(tag)) return true;\n if (elementRole(props) === 'button') return true;\n return false;\n}\n\nfunction pathname(props: Record<string, unknown>): string {\n const pn = props.$pathname;\n return typeof pn === 'string' ? pn : '/';\n}\n\nfunction renderCustomEvent(raw: RawEvent): string {\n // Stable summary: event name + up to two scalar props.\n const fields: string[] = [];\n for (const [k, v] of Object.entries(raw.properties)) {\n if (k.startsWith('$')) continue;\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n fields.push(`${k}=${v}`);\n if (fields.length >= 2) break;\n }\n }\n return fields.length > 0 ? `${raw.event} (${fields.join(', ')})` : raw.event;\n}\n\nexport function matchEvent(raw: RawEvent, opts: MatchOptions = {}): ObservationEvent | null {\n const props = raw.properties;\n\n switch (raw.event) {\n case '$pageview': {\n const path = pathname(props);\n return {\n ts: raw.timestamp,\n kind: 'nav',\n text: truncate(`navigated to ${path}`),\n ref: path,\n };\n }\n\n case '$autocapture': {\n const eventType = props.$event_type;\n\n if (eventType === 'click') {\n if (!isSignificantClickTarget(props)) return null;\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'click',\n text: truncate(`clicked '${text}'`),\n };\n }\n\n if (eventType === 'submit' && elementTag(props) === 'form') {\n return {\n ts: raw.timestamp,\n kind: 'form',\n text: truncate(`submitted form '${formName(props)}'`),\n };\n }\n\n return null;\n }\n\n case '$rageclick': {\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'rage',\n text: truncate(`rage-clicked '${text}'`),\n };\n }\n\n case '$dead_click': {\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'dead',\n text: truncate(`clicked '${text}' (no response)`),\n };\n }\n\n // \u2500\u2500 Canonical runtime-bus events (sources: `'canvas'` instrumentation\n // or the event-processor's rrweb detectors). These don't go through\n // PostHog; the chat-bar's bus translator forwards them as-is with\n // the canonical event name, and matchEvent picks the right slot\n // here. Keeps a single allowlist as the source of truth for what\n // the agent's observation tail can carry.\n case 'nav.section_viewed': {\n const section = typeof props.section === 'string' ? props.section : '';\n if (!section) return null;\n return {\n ts: raw.timestamp,\n kind: 'view',\n text: truncate(`viewed the '${section}' section`),\n ref: section,\n };\n }\n\n case 'nav.scroll_depth': {\n const pct = typeof props.percent === 'number' ? props.percent : null;\n if (pct === null) return null;\n return {\n ts: raw.timestamp,\n kind: 'scroll',\n text: truncate(`scrolled to ${pct}% of the page`),\n };\n }\n\n case 'ui.scroll_thrash': {\n return {\n ts: raw.timestamp,\n kind: 'scroll',\n text: 'scrolled up and down repeatedly (looking for something)',\n };\n }\n\n case 'ui.idle': {\n const ms = typeof props.durationMs === 'number' ? props.durationMs : null;\n const secs = ms !== null ? Math.round(ms / 1000) : null;\n return {\n ts: raw.timestamp,\n kind: 'idle',\n text: secs !== null ? `idle for ${secs}s` : 'idle',\n };\n }\n\n case 'ui.hover': {\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'hover',\n text: truncate(`hovered on '${text}'`),\n };\n }\n\n case 'ui.hesitation': {\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'hesitation',\n text: truncate(`hesitated near '${text}'`),\n };\n }\n\n case 'ui.focus_bounce': {\n const text = elementText(props) || elementTag(props);\n return {\n ts: raw.timestamp,\n kind: 'form',\n text: truncate(`focused '${text}' but didn't fill it`),\n };\n }\n\n default: {\n const allow = opts.observableEvents ?? [];\n if (allow.includes(raw.event)) {\n return {\n ts: raw.timestamp,\n kind: 'custom',\n text: truncate(renderCustomEvent(raw)),\n };\n }\n return null;\n }\n }\n}\n", "/**\n * In-memory batching queue for ObservationEvents.\n *\n * Holds events until either a size threshold or a time interval triggers\n * a flush. The flush function is injected so transport choice (fetch vs.\n * sendBeacon) and auth wiring stay out of this module.\n *\n * Backoff strategy: pure exponential, starting at 1s and capping at 30s\n * (1s \u2192 2s \u2192 4s \u2192 8s \u2192 16s \u2192 30s). Reset on first successful flush.\n * Jitter is intentionally omitted \u2014 the observer queue is per-client, so\n * thundering-herd at recovery is not a meaningful risk, and deterministic\n * timing keeps unit tests fast and stable. A \"permanent\" failure (4xx\n * marked by the caller) disables the queue entirely \u2014 no further flushes\n * are attempted; lastError is exposed via stats().\n */\n\nimport type { ObservationEvent } from './allowlist';\n\nexport interface FlushError extends Error {\n /** When true, the queue stops trying forever. Set by transport for 4xx. */\n permanent?: boolean;\n}\n\nexport interface ObserverQueueOptions {\n batchSize: number;\n flushIntervalMs: number;\n queueCap: number;\n flush: (batch: ObservationEvent[]) => Promise<void>;\n backoffStartMs?: number;\n backoffCapMs?: number;\n}\n\nexport interface ObserverStats {\n queued: number;\n sent: number;\n dropped: number;\n lastError: string | null;\n disabled: boolean;\n}\n\nexport class ObserverQueue {\n private readonly _opts: Required<ObserverQueueOptions>;\n private readonly _buffer: ObservationEvent[] = [];\n private _sent = 0;\n private _dropped = 0;\n private _lastError: string | null = null;\n private _disabled = false;\n private _intervalTimer: ReturnType<typeof setTimeout> | null = null;\n private _backoffTimer: ReturnType<typeof setTimeout> | null = null;\n private _currentBackoffMs = 0;\n private _inFlight = false;\n\n constructor(opts: ObserverQueueOptions) {\n this._opts = {\n backoffStartMs: 1000,\n backoffCapMs: 30_000,\n ...opts,\n };\n }\n\n push(event: ObservationEvent): void {\n if (this._disabled) return;\n if (this._buffer.length >= this._opts.queueCap) {\n this._buffer.shift();\n this._dropped += 1;\n }\n this._buffer.push(event);\n\n if (this._buffer.length >= this._opts.batchSize) {\n this._scheduleImmediate();\n } else {\n this._scheduleInterval();\n }\n }\n\n async flushNow(): Promise<void> {\n this._clearInterval();\n await this._flush();\n }\n\n stats(): ObserverStats {\n return {\n queued: this._buffer.length,\n sent: this._sent,\n dropped: this._dropped,\n lastError: this._lastError,\n disabled: this._disabled,\n };\n }\n\n private _scheduleImmediate(): void {\n queueMicrotask(() => {\n void this._flush();\n });\n }\n\n private _scheduleInterval(): void {\n if (this._intervalTimer != null) return;\n this._intervalTimer = setTimeout(() => {\n this._intervalTimer = null;\n void this._flush();\n }, this._opts.flushIntervalMs);\n }\n\n private _clearInterval(): void {\n if (this._intervalTimer != null) {\n clearTimeout(this._intervalTimer);\n this._intervalTimer = null;\n }\n }\n\n private async _flush(): Promise<void> {\n if (this._disabled || this._inFlight || this._buffer.length === 0) return;\n this._clearInterval();\n\n const batch = this._buffer.splice(0, this._opts.batchSize);\n this._inFlight = true;\n try {\n await this._opts.flush(batch);\n this._sent += batch.length;\n this._currentBackoffMs = 0;\n this._lastError = null;\n } catch (err) {\n this._buffer.unshift(...batch);\n const perm = (err as FlushError)?.permanent === true;\n this._lastError =\n err instanceof Error ? err.message : String((err as { message?: unknown })?.message ?? err);\n if (perm) {\n this._disabled = true;\n } else {\n this._scheduleBackoff();\n }\n } finally {\n this._inFlight = false;\n }\n }\n\n private _scheduleBackoff(): void {\n const next =\n this._currentBackoffMs === 0\n ? this._opts.backoffStartMs\n : Math.min(this._currentBackoffMs * 2, this._opts.backoffCapMs);\n this._currentBackoffMs = next;\n\n if (this._backoffTimer != null) clearTimeout(this._backoffTimer);\n this._backoffTimer = setTimeout(() => {\n this._backoffTimer = null;\n void this._flush();\n }, next);\n }\n}\n", "/**\n * HTTP transport for the observer queue.\n *\n * Two send paths:\n * - send(batch) \u2014 async fetch. Used for normal flushes. Throws on\n * non-2xx; sets the FlushError.permanent flag for 4xx so the queue\n * stops trying.\n * - sendBeacon(batch) \u2014 fire-and-forget via navigator.sendBeacon.\n * Used on `pagehide` so the last batch survives navigation. No\n * error path \u2014 beacon failure is invisible by design.\n *\n * Auth: same syn_ Bearer token mechanism as /stream. The token is read\n * via a getter so SDK tokens that rotate live get refreshed naturally.\n */\n\nimport type { ObservationEvent } from './allowlist';\n\nexport interface TransportOptions {\n url: string;\n token: () => string;\n getDistinctId: () => string | null;\n}\n\nexport interface Transport {\n send(batch: ObservationEvent[]): Promise<void>;\n sendBeacon(batch: ObservationEvent[]): boolean;\n}\n\ninterface RequestBody {\n distinct_id: string | null;\n batch: ObservationEvent[];\n}\n\nfunction buildBody(distinctId: string | null, batch: ObservationEvent[]): string {\n const body: RequestBody = { distinct_id: distinctId, batch };\n return JSON.stringify(body);\n}\n\nexport function createTransport(opts: TransportOptions): Transport {\n return {\n async send(batch: ObservationEvent[]): Promise<void> {\n const body = buildBody(opts.getDistinctId(), batch);\n const resp = await fetch(opts.url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${opts.token()}`,\n 'Content-Type': 'application/json',\n },\n body,\n keepalive: true,\n credentials: 'include',\n });\n if (!resp.ok) {\n const err = new Error(`observation POST ${resp.status}`) as Error & {\n permanent?: boolean;\n };\n // 4xx is permanent (bad token, malformed payload, etc.) EXCEPT 429:\n // the rate-limit middleware buckets /api/adaptive by workspace token,\n // so a busy site hitting 200/min should back off, not give up forever.\n if (resp.status >= 400 && resp.status < 500 && resp.status !== 429) {\n err.permanent = true;\n }\n throw err;\n }\n },\n\n sendBeacon(batch: ObservationEvent[]): boolean {\n const body = buildBody(opts.getDistinctId(), batch);\n const blob = new Blob([body], { type: 'application/json' });\n const beacon = navigator?.sendBeacon;\n if (typeof beacon !== 'function') return false;\n return beacon.call(navigator, opts.url, blob);\n },\n };\n}\n", "/**\n * Observer entry point.\n *\n * startObserver wires the four pieces \u2014 allowlist filter + queue +\n * transport + PostHog subscription \u2014 into a single lifecycle controlled\n * via the returned handle. The handle is reference-counted: multiple\n * call sites (e.g. multiple chatbot widgets on the same page) share\n * one observer.\n *\n * Idempotent: calling startObserver twice with equivalent options\n * returns the same instance. Calling stop() decrements the ref count;\n * the observer tears down only when the count reaches zero.\n */\n\nimport { matchEvent, type RawEvent } from './allowlist';\nimport { ObserverQueue, type ObserverStats } from './queue';\nimport { createTransport, type Transport } from './transport';\n\nexport interface StartObserverOptions {\n url: string;\n token: () => string;\n getDistinctId: () => string | null;\n observableEvents?: readonly string[];\n /** Test seam: override fetch/timer behavior by injecting a custom transport. */\n transport?: Transport;\n}\n\nexport interface ObserverHandle {\n stop(): void;\n stats(): ObserverStats;\n /** Test seam: ingest a raw event directly without depending on PostHog being loaded. */\n ingest(raw: RawEvent): void;\n flushNow(): Promise<void>;\n}\n\ninterface ActiveObserver {\n refCount: number;\n queue: ObserverQueue;\n unsubscribe: () => void;\n options: StartObserverOptions;\n}\n\nlet _active: ActiveObserver | null = null;\n\nfunction _attachPostHog(\n ingest: (raw: RawEvent) => void,\n _observableEvents: readonly string[]\n): () => void {\n const ph = (globalThis as { posthog?: unknown }).posthog;\n if (!ph) return () => {};\n\n // PostHog's internal hook for \"an event was just captured\". The hook\n // fires for $pageview, $autocapture, $rageclick, $dead_click, and any\n // custom posthog.capture(name, props) call \u2014 exactly what the observer\n // wants. Used by the runtime SDK's bundled dist (smart-canvas.*.js).\n const addHook = (ph as { _addCaptureHook?: unknown })._addCaptureHook;\n if (typeof addHook !== 'function') return () => {};\n\n const handler = (eventName: string, properties: Record<string, unknown> | undefined) => {\n if (typeof eventName !== 'string') return;\n ingest({\n event: eventName,\n timestamp: Date.now(),\n properties: properties ?? {},\n });\n };\n\n // _addCaptureHook returns void in current PostHog SDK versions (no\n // unsubscribe). We accept that the listener leaks for the page lifetime \u2014\n // disabling it lives on the queue's `_disabled` flag instead.\n (addHook as (cb: typeof handler) => void).call(ph, handler);\n return () => {};\n}\n\nfunction _attachPageHide(_transport: Transport, queue: ObserverQueue): () => void {\n const handler = () => {\n const stats = queue.stats();\n if (stats.queued > 0) {\n void queue.flushNow();\n }\n };\n window.addEventListener('pagehide', handler, { capture: true });\n return () => window.removeEventListener('pagehide', handler, { capture: true });\n}\n\nexport function startObserver(opts: StartObserverOptions): ObserverHandle {\n if (_active) {\n _active.refCount += 1;\n return _makeHandle();\n }\n\n const transport = opts.transport ?? createTransport(opts);\n\n const queue = new ObserverQueue({\n batchSize: 10,\n flushIntervalMs: 2000,\n queueCap: 200,\n flush: (batch) => transport.send(batch),\n });\n\n const ingest = (raw: RawEvent) => {\n const ev = matchEvent(raw, { observableEvents: opts.observableEvents });\n if (ev !== null) {\n queue.push(ev);\n }\n };\n\n const unsubscribePh = _attachPostHog(ingest, opts.observableEvents ?? []);\n const unsubscribePageHide = _attachPageHide(transport, queue);\n\n _active = {\n refCount: 1,\n queue,\n unsubscribe: () => {\n unsubscribePh();\n unsubscribePageHide();\n },\n options: opts,\n };\n\n return _makeHandle();\n}\n\nfunction _makeHandle(): ObserverHandle {\n return {\n stop(): void {\n if (!_active) return;\n _active.refCount -= 1;\n if (_active.refCount <= 0) {\n _active.unsubscribe();\n _active = null;\n }\n },\n stats(): ObserverStats {\n return (\n _active?.queue.stats() ?? {\n queued: 0,\n sent: 0,\n dropped: 0,\n lastError: null,\n disabled: true,\n }\n );\n },\n ingest(raw: RawEvent): void {\n if (!_active) return;\n const ev = matchEvent(raw, {\n observableEvents: _active.options.observableEvents,\n });\n if (ev !== null) _active.queue.push(ev);\n },\n flushNow(): Promise<void> {\n return _active?.queue.flushNow() ?? Promise.resolve();\n },\n };\n}\n\n/** Test-only: reset module singleton state. */\nexport function _resetObserverForTests(): void {\n if (_active) {\n _active.unsubscribe();\n _active = null;\n }\n}\n", "/**\n * AdaptiveChatBarMountable \u2014 `MountableWidget` adapter that turns the\n * standalone `<adaptive-chat-bar>` Lit element into something the\n * runtime widget registry can mount.\n *\n * Registered as widget id `adaptive-chatbot:chat-bar`. Customers\n * reference it from canvas config \u2014 either as a slot's `lid` widget\n * (replaces the launcher when referenced from `slots.drawer.lid`) or\n * as a regular tile widget.\n *\n * The bar is a VIEW. State lives in the singleton `chatSession` \u2014\n * whether the bar mounts in the mini-canvas lid, the drawer lid, or\n * both, they're all views of the same conversation. The mountable:\n * - subscribes to chatSession.subscribe() and pushes state into\n * the bar's `messages` + `inFlight` props on every change\n * - routes the bar's `chat-message-sent` event \u2192 chatSession.send()\n * - routes the bar's `chat-interrupt` event \u2192 chatSession.interrupt()\n * - bubbles the bar's `canvas-close` event \u2192 optional onClose\n * callback (canvas-level concern, not session-level)\n *\n * Props (passed via mountConfig):\n * - `placeholder?: string` \u2014 input placeholder copy\n * - `onClose?: () => void` \u2014 fires on \u2715 click (canvas-level)\n *\n * Note: messages and inFlight are NOT props. They flow from chatSession.\n * A canvas-config author who wants to pre-seed messages should do so\n * via the session directly (e.g. via a startup action) \u2014 but typical\n * use is to let the conversation start empty.\n */\n\nimport './AdaptiveChatBar';\nimport type { AdaptiveChatBar } from './AdaptiveChatBar';\nimport { renderFallbackHtml } from './ChatAssistantLit';\nimport type { Unsubscribe } from './ChatSession';\nimport { chatSession } from './ChatSession';\nimport type { ChatTransportConfig } from './ChatTransport';\nimport { chatTransport } from './ChatTransport';\nimport {\n ActionHandler,\n ElementInstanceStore,\n type ElementMutation,\n fetchMountedElements,\n ItemHandler,\n TileHandler,\n} from './elements';\nimport { startObserver } from './observer';\nimport type { ChatbotFallback, ChatbotWidgetRuntime } from './types.js';\n\ninterface ChatBarMountConfig {\n placeholder?: string;\n /** Initial assistant greeting shown before any real conversation. */\n greeting?: string;\n onClose?: () => void;\n /**\n * Backend host for the live chat transport. Same shape as\n * ChatbotConfig.backendUrl. When provided alongside `runtime`, the\n * bar configures the singleton ChatTransport on first mount so\n * sends hit the real `/api/adaptive/stream` SSE pipeline. Omitting\n * either disables the transport \u2014 the bar stays a pure view and\n * nothing replies. Useful for storybook / config-preview surfaces.\n */\n backendUrl?: string;\n /** Runtime injected by WidgetRegistry \u2014 required for backendUrl wiring. */\n runtime?: ChatbotWidgetRuntime;\n /** Optional thread id for conversation continuity across reloads. */\n threadId?: string;\n /**\n * Per-customer \"chat unavailable\" card. Rendered in place of the\n * chat bar when the transport gives up after sustained failure.\n * Mirrors ChatAssistantLit's fallback behaviour.\n */\n fallback?: ChatbotFallback;\n /**\n * Declarations for the LLM-authored UI element pipeline (Phase 5+).\n * When `elementsEnabled === true` AND `uiTemplates` is non-null, the\n * backend exposes `mount_element` / `patch_element` / `unmount_element`\n * tools to the chat agent, scoped to the templates declared here.\n *\n * Shape mirrors `UiTemplatesBlock` from `syntrologie_common.sdk.templates`\n * \u2014 typed loosely on the SDK side because the SDK never introspects\n * templates (it only receives mount/patch/unmount mutations); the\n * backend Pydantic models are the validation gate.\n *\n * Passed verbatim as `forwardedProps.uiTemplates` to the AG-UI\n * transport so the backend's `/api/adaptive/stream` reads them off\n * the inbound request body.\n */\n uiTemplates?: Record<string, unknown>;\n elementsEnabled?: boolean;\n /**\n * Slot name the runtime mounted this chat-bar into (e.g. ``\"drawer\"``,\n * ``\"adaptive-chat\"``). Injected by the host SDK slot components\n * (SyntroCanvasOverlay for the drawer, SyntroInlineSlot for inline\n * slots) so the chat-bar can forward it to the backend as\n * ``X-Active-Lid-Slot``. The backend uses it to mount tiles into the\n * canvas spatially nearest to the lid the visitor is engaging with.\n * Optional \u2014 older host bundles that don't inject this still work;\n * the backend falls back to the template's static default_slot.\n */\n _syntroSlotName?: string;\n}\n\ninterface MountState {\n bar: AdaptiveChatBar;\n cleanup: () => void;\n cfg: ChatBarMountConfig;\n}\n\nconst STATE_KEY = '__syntroChatBarMount';\n\nfunction getState(container: HTMLElement): MountState | null {\n return (container as unknown as Record<string, MountState | undefined>)[STATE_KEY] ?? null;\n}\nfunction setState(container: HTMLElement, state: MountState | null): void {\n (container as unknown as Record<string, MountState | null>)[STATE_KEY] = state;\n}\n\nfunction applyPlaceholder(bar: AdaptiveChatBar, cfg: ChatBarMountConfig): void {\n if (cfg.placeholder !== undefined) bar.placeholder = cfg.placeholder;\n if (cfg.greeting !== undefined) bar.greeting = cfg.greeting;\n}\n\n/**\n * Configure the singleton transport if the caller supplied a backend\n * URL + runtime. Idempotent \u2014 second mount with same args is a no-op.\n * Missing backendUrl OR runtime leaves the transport untouched (the\n * bar is then a pure local view; useful for previews / storybook).\n *\n * Spread (not cherry-pick) so the bar-only fields (placeholder,\n * onClose) flow through silently; ChatTransport ignores them. Cast\n * narrows after the guard.\n */\n/**\n * Lazily-constructed ElementInstanceStore singleton for the chat-bar\n * surface. Mounted on first configure with `elementsEnabled` so the\n * `runtime` closure is captured; subsequent reconfigures with the same\n * runtime reuse it. ChatAssistantLit owns its own store separately \u2014\n * each surface keeps independent state to avoid cross-surface\n * double-mounts on the same instance_id.\n */\nlet _elementStore: ElementInstanceStore | null = null;\n/**\n * Live ``template_id \u2192 widget`` map. Re-derived on each ``configure()``\n * from the chat-bar's ``uiTemplates`` prop (which mirrors what the admin\n * declared in canvas-config). Both the TileHandler (live mount path) and\n * the ElementInstanceStore (rehydrate replay path) read through this map\n * so the widget id stays consistent regardless of mount provenance.\n *\n * Without this, an LLM-authored mount with ``template_id: \"product-card\"``\n * emits ``widget: \"product-card\"`` to the runtime, which then renders the\n * tile chrome with a \"Widget not available: product-card\" body because\n * the actual widget is registered as ``adaptive-product:card``.\n */\nconst _templateWidgetMap = new Map<string, string>();\n\nfunction resolveTileWidget(templateId: string): string | undefined {\n return _templateWidgetMap.get(templateId);\n}\n\nfunction refreshTemplateWidgetMap(uiTemplates: Record<string, unknown> | undefined): void {\n _templateWidgetMap.clear();\n if (!uiTemplates) return;\n const tiles = (uiTemplates as { tiles?: Array<{ id?: unknown; widget?: unknown }> }).tiles;\n if (!Array.isArray(tiles)) return;\n for (const t of tiles) {\n const id = typeof t?.id === 'string' ? t.id : null;\n const widget = typeof t?.widget === 'string' ? t.widget : null;\n if (id && widget) _templateWidgetMap.set(id, widget);\n }\n}\n\nfunction getOrCreateElementStore(runtime: ChatbotWidgetRuntime): ElementInstanceStore {\n if (_elementStore) return _elementStore;\n _elementStore = new ElementInstanceStore({\n actions: runtime.actions,\n // Pass the runtime's event bus so ItemHandler can broadcast\n // `element.compositional_append` / `_patch` / `_remove` events\n // to container widgets (chips strip, FAQ accordion, nav tips).\n events: {\n publish: runtime.events.publish.bind(runtime.events),\n subscribe: runtime.events.subscribe?.bind(runtime.events),\n },\n handlers: [new TileHandler(resolveTileWidget), new ActionHandler(), new ItemHandler()],\n resolveTileWidget,\n });\n return _elementStore;\n}\n\n/**\n * Track whether we've already hydrated this store's snapshot. The store\n * itself is a singleton across mounts in the same page session, so we\n * want to hydrate exactly ONCE \u2014 repeated mounts (e.g. after an SPA\n * navigation that unmounts + remounts the chat-bar) reuse the warm\n * store without re-firing handler.mount() for every persisted item.\n *\n * The store's own version-dedup also prevents double-application, but\n * we still don't want to issue redundant HTTP requests on every mount.\n */\nlet _hydrationStarted = false;\n\nfunction hydrateOnce(runtime: ChatbotWidgetRuntime, backendUrl: string): void {\n if (_hydrationStarted) return;\n _hydrationStarted = true;\n const store = getOrCreateElementStore(runtime);\n // The fetcher reads `window.__SYNTRO_CONFIG__.token` by default; the\n // boot path already populated that. Empty/missing backendUrl falls\n // back to a same-origin relative endpoint so dev-server proxies\n // (Vite, Webpack) and host pages serving the SDK from their own\n // domain work without extra config. Same-origin is also the only\n // path that lets the `syntro_chat_session` cookie ride along \u2014 Lax\n // cookies don't follow cross-origin fetches.\n const trimmed = backendUrl.replace(/\\/$/, '');\n const endpoint = trimmed\n ? `${trimmed}/api/adaptive/mounted_elements`\n : '/api/adaptive/mounted_elements';\n fetchMountedElements({ endpoint }).then((response) => {\n if (!response) return; // 404 / network error / feature off \u2014 silent no-op\n // Hydrate replays each instance through its handler.mount(); for\n // ItemHandler that publishes `element.compositional_append` events,\n // which the chips strip subscribes to and re-inserts. Effects are\n // NOT replayed \u2014 they were never persisted in mounted_elements\n // (`_emit_effect_envelope` in the agent skips persistence).\n void store.hydrate(response.mounted_elements);\n });\n}\n\nfunction configureTransportIfPossible(cfg: ChatBarMountConfig): void {\n // backendUrl === \"\" is a valid configuration \u2014 the chat-bar makes\n // relative-URL fetches and the host page's dev-server proxy (or\n // production reverse proxy) forwards `/api/...` to the backend.\n // This keeps the chat on the page's own origin, which lets cookies\n // ride along even when the backend container is on a different host.\n if (cfg.backendUrl === undefined || !cfg.runtime) return;\n // Translate the element-instantiation declarations into the opaque\n // `forwardedProps` bag the transport ships on every AG-UI request.\n // Only attach when the feature is on AND templates are declared \u2014\n // otherwise the backend stays in its safe-default (feature_disabled)\n // path and the tools are never exposed.\n const elementsActive = cfg.elementsEnabled === true && cfg.uiTemplates != null;\n // Refresh the template\u2192widget map on every configure (and clear it\n // when elements are off) so live mounts and replays resolve the same\n // widget id. Done before getOrCreateElementStore below since the\n // store reads through ``resolveTileWidget`` at construction.\n refreshTemplateWidgetMap(elementsActive ? cfg.uiTemplates : undefined);\n const forwardedProps: Record<string, unknown> | undefined = elementsActive\n ? { elementsEnabled: true, uiTemplates: cfg.uiTemplates }\n : undefined;\n\n // Wire the `syntro.element.mutation` envelope route to a per-surface\n // ElementInstanceStore. The store applies mounts/patches/unmounts to\n // the host page via the runtime's ActionEngine. ChatAssistantLit has\n // its own equivalent wiring (it instantiates AgUiTransport directly,\n // not via this singleton); the lid surface needs the same routing\n // here so mount_element results actually land.\n const runtime = cfg.runtime;\n const onElementMutation = elementsActive\n ? (mutations: ElementMutation[]) => {\n void getOrCreateElementStore(runtime).apply(mutations);\n }\n : undefined;\n\n // Hydrate the element store from the backend session on first chat-bar\n // mount. Async \u2014 by the time the response arrives, container widgets\n // (chips strip, FAQ accordion) have already subscribed to the event\n // bus, so the replay events land in their subscribers. Items mounted\n // by the LLM in previous turns survive SPA navigation + page reload\n // for the lifetime of the AdaptiveSession (~24h default).\n if (elementsActive) {\n hydrateOnce(runtime, cfg.backendUrl);\n }\n\n chatTransport.configure({\n ...cfg,\n forwardedProps,\n onElementMutation,\n activeLidSlot: cfg._syntroSlotName,\n } as ChatTransportConfig);\n\n // Wire the visitor-activity observer once the transport is configured.\n // The observer subscribes to PostHog's capture hook and POSTs batched\n // `nav` / `click` / `form` / `rage` / `dead` events to\n // `/api/adaptive/observation` so the next ``/stream`` turn arrives\n // with `recent_observations` populated \u2014 that's what answers\n // \"what did the visitor just do?\" from the agent's perspective.\n // Without this the observer module is dead code: events sit in\n // PostHog with no path into the agent prompt.\n //\n // Idempotent + ref-counted in `startObserver`, so multiple chat-bar\n // mounts (drawer lid + page anchor) share one observer.\n startObserverIfPossible(cfg);\n}\n\nlet _observerStarted = false;\n\nfunction startObserverIfPossible(cfg: ChatBarMountConfig): void {\n if (_observerStarted) return;\n if (typeof window === 'undefined') return;\n const runtime = cfg.runtime as\n | undefined\n | { events?: { subscribe?: (filter: unknown, cb: (e: unknown) => void) => () => void } };\n if (!runtime?.events?.subscribe) return;\n // Same-origin or backend-relative URL \u2014 mirror the transport's path\n // building so the observer hits the same backend instance the chat\n // is talking to.\n const trimmed = (cfg.backendUrl ?? '').replace(/\\/$/, '');\n const url = trimmed ? `${trimmed}/api/adaptive/observation` : '/api/adaptive/observation';\n // Distinct id from PostHog when available; falls back to null and\n // the backend keys observations purely by session id in that case.\n const getDistinctId = (): string | null => {\n const ph = (window as { posthog?: { get_distinct_id?: () => string } }).posthog;\n try {\n const v = ph?.get_distinct_id?.();\n return typeof v === 'string' && v.length > 0 ? v : null;\n } catch {\n return null;\n }\n };\n const token = (): string => {\n const c = (window as { __SYNTRO_CONFIG__?: { token?: string } }).__SYNTRO_CONFIG__;\n return typeof c?.token === 'string' ? c.token : '';\n };\n // startObserver's PostHog auto-attach is a no-op in environments where\n // `window.posthog` isn't directly exposed (most production builds \u2014\n // PostHog is wrapped by the SDK telemetry layer and surfaced through\n // `SynOS.runtime.events`, not via the global). We always start it for\n // the queue + transport plumbing, then subscribe to the runtime event\n // bus and translate normalized events back into the `RawEvent` shape\n // the observer's allowlist expects.\n const handle = startObserver({ url, token, getDistinctId });\n // Expose queue stats on the window for in-page diagnostics. Lets a\n // tester verify events are queueing / flushing via the devtools\n // console without bouncing into source. Cheap; harmless in prod.\n (window as { __syntroObserverStats?: () => unknown }).__syntroObserverStats = () =>\n handle.stats();\n runtime.events.subscribe({}, (evt: unknown) => {\n const e = evt as {\n ts?: number;\n name?: string;\n source?: string;\n props?: Record<string, unknown> & { originalEvent?: string };\n };\n if (!e?.name) return;\n const ts = typeof e.ts === 'number' ? e.ts : Date.now();\n // Two-path translation. The allowlist's `matchEvent` switches on\n // `event` name, so we just hand it the right name in either case:\n //\n // 1. PostHog-originated events arrive with `source: 'posthog'`\n // and `props.originalEvent` carrying the raw `$pageview` /\n // `$autocapture` name. Re-prefix `pathname`/`url` to their\n // `$`-prefixed forms so the PostHog matchers find them.\n // 2. Canonical runtime-bus events (`nav.section_viewed`,\n // `nav.scroll_depth`, `ui.scroll_thrash`, `ui.hover`, \u2026)\n // come straight from runtime-sdk instrumentation. Forward the\n // canonical name as-is \u2014 the allowlist has explicit cases for\n // each one.\n if (e.source === 'posthog') {\n const original = e.props?.originalEvent;\n if (typeof original !== 'string' || original.length === 0) return;\n const properties: Record<string, unknown> = { ...(e.props ?? {}) };\n if (typeof e.props?.pathname === 'string') properties.$pathname = e.props.pathname;\n if (typeof e.props?.url === 'string') properties.$current_url = e.props.url;\n handle.ingest({ event: original, timestamp: ts, properties });\n return;\n }\n // Forward canonical names directly. The allowlist drops any name\n // it doesn't know, so listing everything here is safe \u2014 match\n // decides what reaches the agent's observation tail.\n handle.ingest({\n event: e.name,\n timestamp: ts,\n properties: { ...(e.props ?? {}) },\n });\n });\n _observerStarted = true;\n}\n\nfunction wireListeners(bar: AdaptiveChatBar, state: MountState): Unsubscribe {\n const onMessageSent = (e: Event) => {\n const text = (e as CustomEvent<{ text: string }>).detail.text;\n // Read `_syntroSlotName` from `state.cfg` (the per-bar snapshot)\n // on EVERY send so the singleton transport tags the outbound\n // request with THIS bar's slot, regardless of which bar most\n // recently called `chatTransport.configure()`. Without this,\n // two coexisting bars (drawer + inline) race over the singleton's\n // cached `activeLidSlot` and tile-routing follows the wrong bar.\n chatSession.send(text, { activeLidSlot: state.cfg._syntroSlotName });\n // If no transport is listening for sends (no backendUrl in\n // mountConfig, the runtime injection didn't happen, or a test\n // didn't wire one up) the session would sit in `inFlight: true`\n // forever. Surface a clear, actionable error so the user sees\n // *something* rather than an indefinitely-spinning stop button.\n if (!chatSession.hasTransport()) {\n chatSession.error('Chat backend not configured \u2014 set backendUrl in the canvas config.');\n }\n };\n const onInterrupt = () => {\n chatSession.interrupt();\n };\n const onToolCallApproved = (e: Event) => {\n const detail = (e as CustomEvent<{ toolCallId: string; approved: boolean }>).detail;\n // Default to an empty-object result \u2014 the agent re-runs with the\n // approval signal. Hosts that want richer results (e.g. a form\n // result payload) can listen for `trail-toolcall-approved` higher\n // up and call chatSession.resolveToolCall themselves.\n chatSession.resolveToolCall(detail.toolCallId, {}, detail.approved);\n };\n // onClose reads state.cfg fresh on each invocation so update() can\n // swap the callback without re-wiring listeners.\n const onClose = () => {\n state.cfg.onClose?.();\n };\n bar.addEventListener('chat-message-sent', onMessageSent);\n bar.addEventListener('chat-interrupt', onInterrupt);\n bar.addEventListener('canvas-close', onClose);\n bar.addEventListener('trail-toolcall-approved', onToolCallApproved);\n return () => {\n bar.removeEventListener('chat-message-sent', onMessageSent);\n bar.removeEventListener('chat-interrupt', onInterrupt);\n bar.removeEventListener('canvas-close', onClose);\n bar.removeEventListener('trail-toolcall-approved', onToolCallApproved);\n };\n}\n\nexport const AdaptiveChatBarMountable = {\n mount(container: HTMLElement, mountConfig?: Record<string, unknown>): () => void {\n const cfg = (mountConfig ?? {}) as ChatBarMountConfig;\n configureTransportIfPossible(cfg);\n const bar = document.createElement('adaptive-chat-bar') as AdaptiveChatBar;\n applyPlaceholder(bar, cfg);\n\n // Subscribe to the shared session. Fires immediately with the\n // current state so the bar reflects any pre-existing conversation.\n const unsubSession = chatSession.subscribe((s) => {\n bar.messages = [...s.messages];\n bar.inFlight = s.inFlight;\n });\n\n // state holds the mutable cfg so update() can swap callbacks\n // without forcing a listener re-wire.\n const state = { bar, cleanup: () => {}, cfg };\n const unwireListeners = wireListeners(bar, state);\n\n container.appendChild(bar);\n\n // Subscribe to the transport's fallback signal. When the transport\n // gives up after sustained failure, replace the bar with the\n // per-customer \"chat unavailable\" card. One-shot \u2014 fallback fires\n // once per configure cycle, so we don't need to track re-mounts.\n const unsubFallback = chatTransport.onFallback(() => {\n bar.remove();\n container.innerHTML = renderFallbackHtml(state.cfg.fallback);\n });\n\n state.cleanup = () => {\n unsubSession();\n unsubFallback();\n unwireListeners();\n bar.remove();\n setState(container, null);\n };\n\n setState(container, state);\n return state.cleanup;\n },\n\n update(container: HTMLElement, mountConfig?: Record<string, unknown>): void {\n const state = getState(container);\n if (!state) return;\n const cfg = (mountConfig ?? {}) as ChatBarMountConfig;\n configureTransportIfPossible(cfg);\n applyPlaceholder(state.bar, cfg);\n state.cfg = cfg;\n },\n};\n", "/**\n * AdaptiveChipsStripMountable \u2014 `MountableWidget` adapter for\n * `<adaptive-chips-strip>`. Registered as widget id\n * `adaptive-chatbot:chips-strip`.\n *\n * Mirrors `AdaptiveChatBarMountable`: creates the Lit element, forwards\n * props, bridges DOM events \u2192 prop callbacks, cleans up on unmount.\n *\n * Props (passed via mountConfig):\n * - `chips: SuggestionChip[]` \u2014 the strip's contents (required)\n * - `onChipRevealed?: ({id, payload}) => void` \u2014 fires when a chip\n * is opened\n * - `onChipDismissed?: ({id}) => void` \u2014 fires when \u00D7 is clicked\n *\n * The runtime registry injects `runtime` into mountConfig (see\n * `WidgetRegistry.mount`). We forward it as `runtimeRef` on the strip\n * so it can mount chip payload widgets through the same registry.\n */\n\nimport './AdaptiveChipsStrip';\nimport type { AdaptiveChipsStrip, SuggestionChip } from './AdaptiveChipsStrip';\n\ninterface ChipsStripMountConfig {\n chips?: SuggestionChip[];\n onChipRevealed?: (detail: { id: string; payload: SuggestionChip['config']['payload'] }) => void;\n onChipDismissed?: (detail: { id: string }) => void;\n // Injected by WidgetRegistry \u2014 see runtime-sdk/src/widgets/WidgetRegistry.ts.\n runtime?: unknown;\n // Injected by SyntroTileCard from the tile's resolved chromeless\n // state (which itself comes from `slot.theme.chromeless` with\n // `tile.chromeless` as the per-tile override).\n chromeless?: boolean;\n}\n\ninterface MountState {\n strip: AdaptiveChipsStrip;\n listeners: {\n revealed: (e: Event) => void;\n dismissed: (e: Event) => void;\n };\n}\n\nconst STATE_KEY = '__syntroChipsStripMount';\n\nfunction getState(container: HTMLElement): MountState | null {\n return (container as unknown as Record<string, MountState | undefined>)[STATE_KEY] ?? null;\n}\nfunction setState(container: HTMLElement, state: MountState | null): void {\n (container as unknown as Record<string, MountState | null>)[STATE_KEY] = state;\n}\n\nfunction applyProps(strip: AdaptiveChipsStrip, cfg: ChipsStripMountConfig): void {\n if (cfg.chips !== undefined) strip.chips = cfg.chips;\n // `runtime` arrives in every mountConfig from the WidgetRegistry \u2014\n // forward it so the strip can resolve + mount payload widgets.\n if (cfg.runtime !== undefined) {\n strip.runtimeRef = cfg.runtime as AdaptiveChipsStrip['runtimeRef'];\n }\n if (cfg.chromeless !== undefined) strip.chromeless = cfg.chromeless;\n}\n\nexport const AdaptiveChipsStripMountable = {\n mount(container: HTMLElement, mountConfig?: Record<string, unknown>): () => void {\n const cfg = (mountConfig ?? {}) as ChipsStripMountConfig;\n const strip = document.createElement('adaptive-chips-strip') as AdaptiveChipsStrip;\n applyProps(strip, cfg);\n\n const state: MountState = {\n strip,\n listeners: {\n revealed: (e) => {\n const cb = cfg.onChipRevealed;\n if (cb) {\n cb(\n (e as CustomEvent<{ id: string; payload: SuggestionChip['config']['payload'] }>)\n .detail\n );\n }\n },\n dismissed: (e) => {\n const cb = cfg.onChipDismissed;\n if (cb) cb((e as CustomEvent<{ id: string }>).detail);\n },\n },\n };\n strip.addEventListener('chip-revealed', state.listeners.revealed);\n strip.addEventListener('chip-dismissed', state.listeners.dismissed);\n\n container.appendChild(strip);\n setState(container, state);\n\n return () => {\n strip.removeEventListener('chip-revealed', state.listeners.revealed);\n strip.removeEventListener('chip-dismissed', state.listeners.dismissed);\n strip.remove();\n setState(container, null);\n };\n },\n\n update(container: HTMLElement, mountConfig?: Record<string, unknown>): void {\n const state = getState(container);\n if (!state) return;\n const cfg = (mountConfig ?? {}) as ChipsStripMountConfig;\n applyProps(state.strip, cfg);\n // Re-wire callback listeners so the new cfg's handlers fire.\n state.strip.removeEventListener('chip-revealed', state.listeners.revealed);\n state.strip.removeEventListener('chip-dismissed', state.listeners.dismissed);\n state.listeners.revealed = (e) => {\n const cb = cfg.onChipRevealed;\n if (cb) {\n cb((e as CustomEvent<{ id: string; payload: SuggestionChip['config']['payload'] }>).detail);\n }\n };\n state.listeners.dismissed = (e) => {\n const cb = cfg.onChipDismissed;\n if (cb) cb((e as CustomEvent<{ id: string }>).detail);\n };\n state.strip.addEventListener('chip-revealed', state.listeners.revealed);\n state.strip.addEventListener('chip-dismissed', state.listeners.dismissed);\n },\n};\n", "/**\n * NavLinkMountable \u2014 `MountableWidget` used as the payload of an\n * LLM-authored navigation chip.\n *\n * Flow:\n * LLM mounts `suggest-navigation` ItemTemplate with `{title, url}`\n * \u2192 backend builds chip with payload `{widget: 'adaptive-chatbot:nav-link', props: {url}}`\n * \u2192 user clicks the chip \u2192 chips-strip mounts THIS widget into the\n * chip's drawer\n * \u2192 user clicks the \"Go to <url>\" button this widget renders\n * \u2192 same-origin SPA navigation via pushState + popstate (matches\n * `adaptive-nav`'s `executeNavigate` path for SPA-router compatibility)\n *\n * Registered as widget id `adaptive-chatbot:nav-link`.\n *\n * Security note: only http(s), same-origin destinations are honored.\n * `javascript:`, `data:`, and cross-origin URLs are silently dropped at\n * URL construction. The ItemTemplate's EnumField allowlist is the\n * primary constraint; this is defense-in-depth.\n */\n\ninterface NavLinkProps {\n url?: string;\n /** Optional override for the button label. Defaults to \"Go to <url>\".\n * The chip's title already advertises the destination; this is just\n * the call-to-action verb. */\n label?: string;\n}\n\ninterface MountState {\n button: HTMLButtonElement;\n cfg: NavLinkProps;\n onClick: (e: Event) => void;\n}\n\nconst STATE_KEY = '__syntroNavLinkMount';\n\nfunction getState(container: HTMLElement): MountState | null {\n return (container as unknown as Record<string, MountState | undefined>)[STATE_KEY] ?? null;\n}\nfunction setState(container: HTMLElement, state: MountState | null): void {\n (container as unknown as Record<string, MountState | null>)[STATE_KEY] = state;\n}\n\nfunction navigateTo(rawUrl: string): void {\n if (!rawUrl) return;\n let resolved: URL;\n try {\n resolved = new URL(rawUrl, window.location.origin);\n } catch {\n return;\n }\n if (resolved.origin !== window.location.origin) return;\n if (resolved.protocol !== 'http:' && resolved.protocol !== 'https:') return;\n window.history.pushState(null, '', resolved.toString());\n window.dispatchEvent(new PopStateEvent('popstate'));\n}\n\nfunction buildButton(cfg: NavLinkProps): HTMLButtonElement {\n const button = document.createElement('button');\n button.type = 'button';\n button.dataset.syntroNavLink = '';\n button.style.display = 'inline-flex';\n button.style.alignItems = 'center';\n button.style.gap = '6px';\n button.style.padding = '6px 12px';\n button.style.borderRadius = '8px';\n button.style.fontFamily = \"var(--sc-font-family, 'system-ui')\";\n button.style.fontSize = '12px';\n button.style.fontWeight = '600';\n button.style.cursor = 'pointer';\n button.style.color = 'var(--sc-accent-foreground, currentColor)';\n button.style.background = 'hsl(var(--sc-accent-color) / 0.85)';\n button.style.border = '1px solid hsl(var(--sc-accent-color) / 0.30)';\n applyLabel(button, cfg);\n return button;\n}\n\nfunction applyLabel(button: HTMLButtonElement, cfg: NavLinkProps): void {\n const url = String(cfg.url ?? '');\n const label = cfg.label ?? (url ? `Go to ${url}` : 'Go');\n // textContent (not innerHTML) \u2014 LLM-authored URLs are an enum on the\n // backend so injection isn't realistic, but defense-in-depth is cheap.\n button.textContent = label;\n}\n\nexport const NavLinkMountable = {\n mount(container: HTMLElement, mountConfig?: Record<string, unknown>): () => void {\n const cfg = (mountConfig ?? {}) as NavLinkProps;\n const button = buildButton(cfg);\n const onClick = (_e: Event): void => {\n const current = getState(container);\n const url = current?.cfg.url ?? cfg.url;\n navigateTo(String(url ?? ''));\n };\n button.addEventListener('click', onClick);\n container.appendChild(button);\n setState(container, { button, cfg, onClick });\n return () => {\n button.removeEventListener('click', onClick);\n button.remove();\n setState(container, null);\n };\n },\n\n update(container: HTMLElement, mountConfig?: Record<string, unknown>): void {\n const state = getState(container);\n if (!state) return;\n const cfg = (mountConfig ?? {}) as NavLinkProps;\n applyLabel(state.button, cfg);\n state.cfg = cfg;\n },\n};\n", "/**\n * TextAnswerMountable \u2014 `MountableWidget` for the simplest chip payload\n * kind: a single paragraph of body text.\n *\n * Registered as widget id `adaptive-chatbot:text-answer`. Used by\n * `AdaptiveChipsStrip` when a chip's payload references it.\n *\n * Replaces the old hand-rolled resolver path. Customers wanting richer\n * payloads (markdown, mini-product cards, embedded charts, etc.) ship\n * their own mountable through the same registry \u2014 no special\n * resolver-map seam.\n */\n\ninterface TextAnswerProps {\n text?: string;\n}\n\ninterface MountState {\n paragraph: HTMLParagraphElement;\n cfg: TextAnswerProps;\n}\n\nconst STATE_KEY = '__syntroTextAnswerMount';\n\nfunction getState(container: HTMLElement): MountState | null {\n return (container as unknown as Record<string, MountState | undefined>)[STATE_KEY] ?? null;\n}\nfunction setState(container: HTMLElement, state: MountState | null): void {\n (container as unknown as Record<string, MountState | null>)[STATE_KEY] = state;\n}\n\nfunction applyText(p: HTMLParagraphElement, text: string): void {\n p.textContent = text;\n}\n\nexport const TextAnswerMountable = {\n mount(container: HTMLElement, mountConfig?: Record<string, unknown>): () => void {\n const cfg = (mountConfig ?? {}) as TextAnswerProps;\n const paragraph = document.createElement('p');\n paragraph.dataset.syntroTextAnswer = '';\n // Keep the styling minimal \u2014 paragraph inherits the slot's\n // `--sc-tile-text-color` (set by the chips strip's drawer chrome)\n // so the text reads consistently against the host's surface.\n paragraph.style.margin = '0';\n paragraph.style.fontSize = '12px';\n paragraph.style.lineHeight = '1.55';\n paragraph.style.color = 'var(--sc-tile-text-color, currentColor)';\n applyText(paragraph, String(cfg.text ?? ''));\n container.appendChild(paragraph);\n\n setState(container, { paragraph, cfg });\n return () => {\n paragraph.remove();\n setState(container, null);\n };\n },\n\n update(container: HTMLElement, mountConfig?: Record<string, unknown>): void {\n const state = getState(container);\n if (!state) return;\n const cfg = (mountConfig ?? {}) as TextAnswerProps;\n applyText(state.paragraph, String(cfg.text ?? ''));\n state.cfg = cfg;\n },\n};\n", "/**\n * Adaptive Chatbot - Runtime Module\n *\n * Runtime manifest for the AI chat assistant adaptive.\n * Uses @syntrologie/chat for the UI \u2014 no React dependency.\n *\n * Chat surfaces are config-driven: customers reference the chat-bar\n * widget id (`adaptive-chatbot:chat-bar`) from `slots.drawer.lid` (to\n * replace the launcher FAB) or any other slot's `lid` / tile slot. The\n * adaptive no longer auto-registers a canvas lid renderer.\n */\n\n// Side-effect imports so the custom elements register with the global\n// registry as soon as the adaptive is loaded.\nimport './AdaptiveChatBar';\nimport './AdaptiveChatTrail';\nimport { AdaptiveChatBarMountable } from './AdaptiveChatBarMountable';\nimport { AdaptiveChipsStripMountable } from './AdaptiveChipsStripMountable';\nimport { ChatAssistantLitMountable } from './ChatAssistantLit';\nimport { NavLinkMountable } from './NavLinkMountable';\nimport { TextAnswerMountable } from './TextAnswerMountable';\n\nexport const runtime = {\n id: 'adaptive-chatbot',\n version: '2.0.0',\n name: 'Chat Assistant',\n description: 'AI chat assistant powered by @syntrologie/chat with SSE transport',\n\n executors: [],\n\n widgets: [\n {\n id: 'adaptive-chatbot:assistant',\n component: ChatAssistantLitMountable,\n metadata: {\n name: 'Chat Assistant',\n description: 'AI-powered chat assistant with SSE streaming and A2UI support',\n icon: '\uD83D\uDCAC',\n },\n },\n // PRD \u00A73 chat lid: the standalone chat bar UI shell. Used as a slot\n // `lid` widget (where it replaces the launcher) or as a regular\n // tile widget (renders inside the drawer). Headless of any chat\n // transport \u2014 emits chat-message-sent / chat-interrupt / canvas-close\n // for the parent to wire to whatever pipeline it owns.\n {\n id: 'adaptive-chatbot:chat-bar',\n component: AdaptiveChatBarMountable,\n metadata: {\n name: 'Chat Bar',\n description:\n 'Always-visible chat input row with bubble-up trail. Headless \u2014 wire to your own transport.',\n icon: '\u2726',\n },\n },\n // PRD \u00A74.5 suggested-chips tile: horizontally-wrapping chip strip\n // with click-to-reveal payload drawer. Each chip is a\n // `suggestions:chip` action.\n {\n id: 'adaptive-chatbot:chips-strip',\n component: AdaptiveChipsStripMountable,\n metadata: {\n name: 'Suggested Chips',\n description: 'Wrapping chip strip with click-to-reveal payloads.',\n icon: '\u2728',\n },\n },\n // Built-in chip payload \u2014 a single paragraph of body text. Chip\n // payloads are widget references (same {widget,props} shape as\n // tile/lid configs); this is the simplest one shipped out of the\n // box so the chip pattern works without requiring a downstream\n // adaptive for a \"just answer with text\" case.\n {\n id: 'adaptive-chatbot:text-answer',\n component: TextAnswerMountable,\n metadata: {\n name: 'Text Answer',\n description: 'Single paragraph payload \u2014 the default chip-drawer content.',\n icon: '\u00B6',\n },\n },\n // Chip payload for LLM-authored navigation suggestions. Backed by\n // the `suggest-navigation` ItemTemplate: the backend wraps a curated\n // URL into props.url, the chip's payload-drawer mounts this widget,\n // user clicks \"Go to <url>\" \u2192 same-origin SPA navigation. Kept here\n // (not in adaptive-nav) so chip payloads ship with the chatbot\n // bundle that already provides chips-strip + text-answer.\n {\n id: 'adaptive-chatbot:nav-link',\n component: NavLinkMountable,\n metadata: {\n name: 'Nav Link',\n description:\n 'Same-origin navigation button \u2014 used as a chip payload for LLM-authored nav suggestions.',\n icon: '\u2192',\n },\n },\n ],\n};\n\nexport default runtime;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["runtime", "runtime", "STATE_KEY", "getState", "setState", "STATE_KEY", "getState", "setState", "STATE_KEY", "getState", "setState"]
|
|
7
7
|
}
|
package/package.json
CHANGED