@smooai/smooth-operator 1.22.6 → 1.22.8
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/client.d.ts +40 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +22 -1
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/widget/chat-widget.iife.js +24 -1
- package/dist/widget/chat-widget.iife.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +42 -2
- package/src/index.ts +2 -0
package/dist/client.d.ts
CHANGED
|
@@ -48,6 +48,22 @@ export interface SmoothAgentClientOptions {
|
|
|
48
48
|
*/
|
|
49
49
|
turnTimeout?: number;
|
|
50
50
|
}
|
|
51
|
+
/** One row returned by {@link SmoothAgentClient.listConversations} — enough to
|
|
52
|
+
* render a sidebar entry and resume the conversation on click. */
|
|
53
|
+
export interface ConversationSummary {
|
|
54
|
+
/** Pass to {@link SmoothAgentClient.createConversationSession} as `conversationId` to resume. */
|
|
55
|
+
conversationId: string;
|
|
56
|
+
/** Short preview title derived from the first message (may be empty). */
|
|
57
|
+
title: string;
|
|
58
|
+
/** ISO-8601 last-activity timestamp (rows come most-recent first). */
|
|
59
|
+
updatedAt: string;
|
|
60
|
+
/** Number of messages in the conversation. */
|
|
61
|
+
messageCount: number;
|
|
62
|
+
}
|
|
63
|
+
/** Payload of the `list_conversations` `immediate_response`. */
|
|
64
|
+
export interface ListConversationsResponse {
|
|
65
|
+
conversations: ConversationSummary[];
|
|
66
|
+
}
|
|
51
67
|
/**
|
|
52
68
|
* A streaming turn that received no terminal `eventual_response` / `error` within the
|
|
53
69
|
* configured {@link SmoothAgentClientOptions.turnTimeout}. The turn rejects with this
|
|
@@ -117,8 +133,30 @@ export declare class SmoothAgentClient {
|
|
|
117
133
|
disconnect(reason?: string): void;
|
|
118
134
|
/** Subscribe to unsolicited / uncorrelated server events (e.g. keepalive). */
|
|
119
135
|
onEvent(listener: (event: ServerEvent) => void): () => void;
|
|
120
|
-
/**
|
|
121
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Start a new conversation session — or **resume** an existing one by passing
|
|
138
|
+
* its `conversationId`. On resume the server binds the new session to that
|
|
139
|
+
* conversation (reusing its id + org + persisted history) so subsequent
|
|
140
|
+
* `send_message`s append to it; pair it with {@link getMessages} to load the
|
|
141
|
+
* transcript. Resolves with the session descriptor.
|
|
142
|
+
*/
|
|
143
|
+
createConversationSession(req: Omit<CreateConversationSessionRequest, 'action' | 'requestId'> & {
|
|
144
|
+
conversationId?: string;
|
|
145
|
+
}): Promise<CreateConversationSessionResponse>;
|
|
146
|
+
/**
|
|
147
|
+
* List the org's conversations that have at least one message, most-recent
|
|
148
|
+
* first — the substrate for a conversation sidebar / resume picker. Each row
|
|
149
|
+
* carries a short title preview, `updatedAt`, and a message count. Pass
|
|
150
|
+
* `limit` to cap the result (server default 50).
|
|
151
|
+
*
|
|
152
|
+
* `list_conversations` has no dedicated action schema in `spec/` yet, so it is
|
|
153
|
+
* not a member of the generated `ClientAction` union — hence the local cast.
|
|
154
|
+
* ponytail: promote to a real spec/actions schema if a second consumer needs
|
|
155
|
+
* it typed end-to-end.
|
|
156
|
+
*/
|
|
157
|
+
listConversations(req?: {
|
|
158
|
+
limit?: number;
|
|
159
|
+
}): Promise<ListConversationsResponse>;
|
|
122
160
|
/** Fetch a session snapshot by ID. */
|
|
123
161
|
getSession(req: Omit<GetSessionRequest, 'action' | 'requestId'>): Promise<GetSessionResponse>;
|
|
124
162
|
/** Fetch a page of conversation messages. */
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -220,11 +220,32 @@ export class SmoothAgentClient {
|
|
|
220
220
|
return () => this.listeners.delete(listener);
|
|
221
221
|
}
|
|
222
222
|
// ───────────────────────────── Actions ─────────────────────────────────
|
|
223
|
-
/**
|
|
223
|
+
/**
|
|
224
|
+
* Start a new conversation session — or **resume** an existing one by passing
|
|
225
|
+
* its `conversationId`. On resume the server binds the new session to that
|
|
226
|
+
* conversation (reusing its id + org + persisted history) so subsequent
|
|
227
|
+
* `send_message`s append to it; pair it with {@link getMessages} to load the
|
|
228
|
+
* transcript. Resolves with the session descriptor.
|
|
229
|
+
*/
|
|
224
230
|
async createConversationSession(req) {
|
|
225
231
|
const event = await this.request({ action: 'create_conversation_session', ...req });
|
|
226
232
|
return extractImmediateData(event);
|
|
227
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* List the org's conversations that have at least one message, most-recent
|
|
236
|
+
* first — the substrate for a conversation sidebar / resume picker. Each row
|
|
237
|
+
* carries a short title preview, `updatedAt`, and a message count. Pass
|
|
238
|
+
* `limit` to cap the result (server default 50).
|
|
239
|
+
*
|
|
240
|
+
* `list_conversations` has no dedicated action schema in `spec/` yet, so it is
|
|
241
|
+
* not a member of the generated `ClientAction` union — hence the local cast.
|
|
242
|
+
* ponytail: promote to a real spec/actions schema if a second consumer needs
|
|
243
|
+
* it typed end-to-end.
|
|
244
|
+
*/
|
|
245
|
+
async listConversations(req = {}) {
|
|
246
|
+
const event = await this.request({ action: 'list_conversations', ...req });
|
|
247
|
+
return extractImmediateData(event);
|
|
248
|
+
}
|
|
228
249
|
/** Fetch a session snapshot by ID. */
|
|
229
250
|
async getSession(req) {
|
|
230
251
|
const event = await this.request({ action: 'get_session', ...req });
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
* unions and guards on top.
|
|
9
9
|
*/
|
|
10
10
|
export * from './types.js';
|
|
11
|
-
export { SmoothAgentClient, MessageTurn, ProtocolError, TurnTimeoutError, type SmoothAgentClientOptions, } from './client.js';
|
|
11
|
+
export { SmoothAgentClient, MessageTurn, ProtocolError, TurnTimeoutError, type SmoothAgentClientOptions, type ConversationSummary, type ListConversationsResponse, } from './client.js';
|
|
12
12
|
export { WebSocketTransport, type Transport, type TransportState, type WebSocketLike, type WebSocketFactory, } from './transport.js';
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EACH,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,KAAK,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EACH,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,GACjC,MAAM,aAAa,CAAC;AACrB,OAAO,EACH,kBAAkB,EAClB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,gBAAgB,GACxB,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EACH,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EACH,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,gBAAgB,GAInB,MAAM,aAAa,CAAC;AACrB,OAAO,EACH,kBAAkB,GAKrB,MAAM,gBAAgB,CAAC;AAExB,6EAA6E;AAC7E,4EAA4E;AAC5E,gFAAgF;AAChF,gFAAgF;AAChF,mBAAmB;AACnB,0EAA0E"}
|
|
@@ -370,13 +370,36 @@ var SmoothAgentChat = (function(exports) {
|
|
|
370
370
|
this.listeners.add(listener);
|
|
371
371
|
return () => this.listeners.delete(listener);
|
|
372
372
|
}
|
|
373
|
-
/**
|
|
373
|
+
/**
|
|
374
|
+
* Start a new conversation session — or **resume** an existing one by passing
|
|
375
|
+
* its `conversationId`. On resume the server binds the new session to that
|
|
376
|
+
* conversation (reusing its id + org + persisted history) so subsequent
|
|
377
|
+
* `send_message`s append to it; pair it with {@link getMessages} to load the
|
|
378
|
+
* transcript. Resolves with the session descriptor.
|
|
379
|
+
*/
|
|
374
380
|
async createConversationSession(req) {
|
|
375
381
|
return extractImmediateData(await this.request({
|
|
376
382
|
action: "create_conversation_session",
|
|
377
383
|
...req
|
|
378
384
|
}));
|
|
379
385
|
}
|
|
386
|
+
/**
|
|
387
|
+
* List the org's conversations that have at least one message, most-recent
|
|
388
|
+
* first — the substrate for a conversation sidebar / resume picker. Each row
|
|
389
|
+
* carries a short title preview, `updatedAt`, and a message count. Pass
|
|
390
|
+
* `limit` to cap the result (server default 50).
|
|
391
|
+
*
|
|
392
|
+
* `list_conversations` has no dedicated action schema in `spec/` yet, so it is
|
|
393
|
+
* not a member of the generated `ClientAction` union — hence the local cast.
|
|
394
|
+
* ponytail: promote to a real spec/actions schema if a second consumer needs
|
|
395
|
+
* it typed end-to-end.
|
|
396
|
+
*/
|
|
397
|
+
async listConversations(req = {}) {
|
|
398
|
+
return extractImmediateData(await this.request({
|
|
399
|
+
action: "list_conversations",
|
|
400
|
+
...req
|
|
401
|
+
}));
|
|
402
|
+
}
|
|
380
403
|
/** Fetch a session snapshot by ID. */
|
|
381
404
|
async getSession(req) {
|
|
382
405
|
return extractImmediateData(await this.request({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-widget.iife.js","names":[],"sources":["../../src/widget/config.ts","../../src/transport.ts","../../src/types.ts","../../src/client.ts","../../src/widget/conversation.ts","../../src/widget/logo.ts","../../src/widget/styles.ts","../../src/widget/element.ts","../../src/widget/standalone.ts"],"sourcesContent":["/**\n * Public configuration surface for the chat widget.\n *\n * A host page configures the widget either declaratively (HTML attributes on the\n * `<smooth-agent-chat>` element) or programmatically (passing this object to\n * {@link mountChatWidget} / `element.configure(...)`).\n */\nexport interface ChatWidgetTheme {\n /** Foreground text color for the widget chrome. */\n text?: string;\n /** Panel background color. */\n background?: string;\n /** Primary accent (launcher button, send button, outbound bubble). */\n primary?: string;\n /** Text color rendered on top of `primary`. */\n primaryText?: string;\n /** Inbound (assistant) chat bubble background. */\n assistantBubble?: string;\n /** Inbound (assistant) chat bubble text color. */\n assistantBubbleText?: string;\n /** Outbound (user) chat bubble background. Defaults to `primary`. */\n userBubble?: string;\n /** Outbound (user) chat bubble text color. Defaults to `primaryText`. */\n userBubbleText?: string;\n /** Border color for the panel and input. */\n border?: string;\n}\n\n/**\n * Layout mode for the widget.\n *\n * - `\"popover\"` (default) — the embeddable launcher bubble + floating panel.\n * - `\"fullpage\"` — no launcher; the chat fills its container/viewport with a\n * branded header, a scrollable message list, and an input bar. Ideal for a\n * dedicated support page (`/chat`, a docs site sidebar, an iframe, …).\n */\nexport type ChatWidgetMode = 'popover' | 'fullpage';\n\nexport interface ChatWidgetConfig {\n /**\n * smooth-operator WebSocket endpoint, e.g.\n * `ws://localhost:8787/ws` (local dev) or your deployed `wss://…/ws` URL.\n */\n endpoint: string;\n /**\n * Layout mode — `\"popover\"` (default, launcher + floating panel) or\n * `\"fullpage\"` (chat fills its container; no launcher). See {@link ChatWidgetMode}.\n */\n mode?: ChatWidgetMode;\n /** UUID of the agent to start a conversation session with. */\n agentId: string;\n /** Display name for the agent (header label). Defaults to \"Assistant\". */\n agentName?: string;\n /** Optional display name for the user participant. */\n userName?: string;\n /** Optional email address for the user participant. */\n userEmail?: string;\n /** Placeholder text for the message input. */\n placeholder?: string;\n /** Greeting rendered when the conversation opens (before any messages). */\n greeting?: string;\n /** Message shown when the connection cannot be (re)established. */\n connectionErrorMessage?: string;\n /** Start the panel open instead of collapsed to the launcher. */\n startOpen?: boolean;\n /** Theme overrides. */\n theme?: ChatWidgetTheme;\n}\n\n/** Resolve a partial config against the built-in defaults. */\nexport function resolveConfig(config: ChatWidgetConfig): Required<Omit<ChatWidgetConfig, 'theme' | 'userName' | 'userEmail'>> & {\n theme: Required<ChatWidgetTheme>;\n userName?: string;\n userEmail?: string;\n} {\n const theme = config.theme ?? {};\n const primary = theme.primary ?? '#00a6a6';\n const primaryText = theme.primaryText ?? '#f8fafc';\n return {\n endpoint: config.endpoint,\n mode: config.mode ?? 'popover',\n agentId: config.agentId,\n agentName: config.agentName ?? 'Assistant',\n userName: config.userName,\n userEmail: config.userEmail,\n placeholder: config.placeholder ?? 'Type a message…',\n greeting: config.greeting ?? 'Hi! How can I help you today?',\n connectionErrorMessage: config.connectionErrorMessage ?? \"We couldn't reach the chat. Please try again in a moment.\",\n startOpen: config.startOpen ?? false,\n theme: {\n text: theme.text ?? '#f8fafc',\n background: theme.background ?? '#040d30',\n primary,\n primaryText,\n assistantBubble: theme.assistantBubble ?? '#06134b',\n assistantBubbleText: theme.assistantBubbleText ?? '#f8fafc',\n userBubble: theme.userBubble ?? primary,\n userBubbleText: theme.userBubbleText ?? primaryText,\n border: theme.border ?? '#0a1f7a',\n },\n };\n}\n","/**\n * Transport abstraction for the client.\n *\n * The client is deliberately decoupled from any concrete WebSocket implementation\n * so it can be unit-tested with a mock and run on Node, the browser, or a custom\n * socket. A transport is anything that can send a string frame and surface\n * incoming string frames + lifecycle events.\n */\n\nexport type TransportState = 'connecting' | 'open' | 'closing' | 'closed';\n\n/** Minimal injectable transport contract. Mirrors the browser `WebSocket` subset. */\nexport interface Transport {\n readonly state: TransportState;\n /** Send a serialized frame. Throws / rejects if the transport is not open. */\n send(data: string): void;\n /** Open the connection. Resolves once the transport reaches `open`. */\n connect(): Promise<void>;\n /** Close the connection. */\n close(code?: number, reason?: string): void;\n /** Register a handler for incoming string frames. Returns an unsubscribe fn. */\n onMessage(handler: (data: string) => void): () => void;\n /** Register a handler for transport close. Returns an unsubscribe fn. */\n onClose(handler: (info: { code?: number; reason?: string }) => void): () => void;\n /** Register a handler for transport-level errors. Returns an unsubscribe fn. */\n onError(handler: (err: unknown) => void): () => void;\n}\n\n/** The subset of the standard `WebSocket` interface the default transport needs. */\nexport interface WebSocketLike {\n readonly readyState: number;\n send(data: string): void;\n close(code?: number, reason?: string): void;\n addEventListener(type: 'open', listener: () => void): void;\n addEventListener(type: 'close', listener: (ev: { code?: number; reason?: string }) => void): void;\n addEventListener(type: 'error', listener: (ev: unknown) => void): void;\n addEventListener(type: 'message', listener: (ev: { data: unknown }) => void): void;\n}\n\nexport type WebSocketFactory = (url: string) => WebSocketLike;\n\nconst WS_CONNECTING = 0;\nconst WS_OPEN = 1;\nconst WS_CLOSING = 2;\n\n/** Default connect timeout (ms) for the WebSocket transport. */\nconst DEFAULT_CONNECT_TIMEOUT = 30_000;\n\n/**\n * Default transport backed by a `WebSocket`-like object. By default it uses the\n * global `WebSocket`; pass a `factory` to inject one (e.g. the `ws` package on\n * Node, or a mock in tests).\n */\nexport class WebSocketTransport implements Transport {\n private socket: WebSocketLike | null = null;\n private readonly url: string;\n private readonly factory: WebSocketFactory;\n private readonly connectTimeout: number;\n private readonly messageHandlers = new Set<(data: string) => void>();\n private readonly closeHandlers = new Set<(info: { code?: number; reason?: string }) => void>();\n private readonly errorHandlers = new Set<(err: unknown) => void>();\n\n constructor(url: string, factory?: WebSocketFactory, connectTimeout = DEFAULT_CONNECT_TIMEOUT) {\n this.url = url;\n this.connectTimeout = connectTimeout;\n if (factory) {\n this.factory = factory;\n } else {\n const G = globalThis as { WebSocket?: new (url: string) => WebSocketLike };\n if (!G.WebSocket) {\n throw new Error('No global WebSocket available; pass a WebSocketFactory to WebSocketTransport.');\n }\n const Ctor = G.WebSocket;\n this.factory = (u) => new Ctor(u);\n }\n }\n\n get state(): TransportState {\n if (!this.socket) return 'closed';\n switch (this.socket.readyState) {\n case WS_CONNECTING:\n return 'connecting';\n case WS_OPEN:\n return 'open';\n case WS_CLOSING:\n return 'closing';\n default:\n return 'closed';\n }\n }\n\n connect(): Promise<void> {\n if (this.socket && this.socket.readyState === WS_OPEN) return Promise.resolve();\n\n // A prior socket that never reached OPEN (failed/half-open dial, or a closed\n // socket from a previous attempt) would otherwise be orphaned: its listeners\n // stay registered and keep dispatching into the shared handler sets, so a late\n // message/close from the dead socket double-fires. Close it and detach it\n // before dialing a fresh one. (WebSocketLike has no removeEventListener, so we\n // also guard every handler below with an identity check on `this.socket`.)\n if (this.socket && this.socket.readyState !== WS_OPEN) {\n const stale = this.socket;\n this.socket = null;\n try {\n stale.close();\n } catch {\n // ignore — best-effort teardown of a half-open socket\n }\n }\n\n return new Promise<void>((resolve, reject) => {\n const socket = this.factory(this.url);\n this.socket = socket;\n\n let settled = false;\n const timer =\n this.connectTimeout > 0\n ? setTimeout(() => {\n if (settled) return;\n settled = true;\n // Tear down the half-open socket so it can't leak / fire later.\n if (this.socket === socket) this.socket = null;\n try {\n socket.close();\n } catch {\n // ignore\n }\n reject(new Error(`WebSocket connect to ${this.url} timed out after ${this.connectTimeout}ms`));\n }, this.connectTimeout)\n : undefined;\n\n socket.addEventListener('open', () => {\n // Ignore events from a socket we've already replaced/abandoned.\n if (this.socket !== socket) return;\n if (settled) return;\n settled = true;\n if (timer) clearTimeout(timer);\n resolve();\n });\n socket.addEventListener('error', (ev: unknown) => {\n if (this.socket !== socket) return;\n for (const h of this.errorHandlers) h(ev);\n if (!settled && this.state !== 'open') {\n settled = true;\n if (timer) clearTimeout(timer);\n if (this.socket === socket) this.socket = null;\n // Release the failed socket so it can't linger / fire later.\n try {\n socket.close();\n } catch {\n // ignore\n }\n reject(ev instanceof Error ? ev : new Error('WebSocket connection error'));\n }\n });\n socket.addEventListener('close', (ev: { code?: number; reason?: string }) => {\n if (this.socket !== socket) return;\n if (timer) clearTimeout(timer);\n for (const h of this.closeHandlers) h({ code: ev.code, reason: ev.reason });\n });\n socket.addEventListener('message', (ev: { data: unknown }) => {\n if (this.socket !== socket) return;\n const data = typeof ev.data === 'string' ? ev.data : String(ev.data);\n for (const h of this.messageHandlers) h(data);\n });\n });\n }\n\n send(data: string): void {\n if (!this.socket || this.socket.readyState !== WS_OPEN) {\n throw new Error(`Cannot send: transport is \"${this.state}\"`);\n }\n this.socket.send(data);\n }\n\n close(code?: number, reason?: string): void {\n this.socket?.close(code, reason);\n }\n\n onMessage(handler: (data: string) => void): () => void {\n this.messageHandlers.add(handler);\n return () => this.messageHandlers.delete(handler);\n }\n\n onClose(handler: (info: { code?: number; reason?: string }) => void): () => void {\n this.closeHandlers.add(handler);\n return () => this.closeHandlers.delete(handler);\n }\n\n onError(handler: (err: unknown) => void): () => void {\n this.errorHandlers.add(handler);\n return () => this.errorHandlers.delete(handler);\n }\n}\n","/**\n * Ergonomic, hand-curated types layered on top of the generated ones.\n *\n * The generated types in `./generated/types.ts` are a faithful 1:1 reflection of\n * the JSON Schemas — one interface per schema/`$def`. They are correct but flat:\n * there is no single discriminated union over the wire frames, and the generated\n * `Error` interface collides with the global `Error`.\n *\n * This module fixes both: it re-exports the generated types under stable names and\n * builds the two discriminated unions consumers actually want —\n * `ClientAction` (everything sent client→server, discriminated by `action`) and\n * `ServerEvent` (everything received server→client, discriminated by `type`).\n */\nimport type {\n ConfirmToolActionRequest,\n CreateConversationSessionRequest,\n CreateConversationSessionResponse,\n Error as GeneratedErrorEvent,\n EventualResponse,\n GetMessagesRequest,\n GetMessagesResponse,\n GetSessionRequest,\n GetSessionResponse,\n ImmediateResponse,\n InteractionInvalid,\n InteractionRequired,\n Keepalive,\n OtpInvalid,\n OtpSent,\n OtpVerificationRequired,\n OtpVerified,\n PingRequest,\n Pong,\n SendMessageRequest,\n SendMessageResponse,\n StreamChunk,\n StreamToken,\n SubmitInteractionRequest,\n VerifyOtpRequest,\n WriteConfirmationRequired,\n} from './generated/types.js';\n\nexport * from './generated/types.js';\n\n/**\n * The generated `error` event interface is named `Error`, which shadows the\n * global `Error`. Re-export it under an unambiguous name.\n */\nexport type { GeneratedErrorEvent as ErrorEvent };\n\n// ───────────────────────────── Discriminators ──────────────────────────────\n\n/** Every client→server `action` discriminator value. */\nexport const ACTION_TYPES = [\n 'create_conversation_session',\n 'send_message',\n 'get_session',\n 'get_conversation_messages',\n 'confirm_tool_action',\n 'verify_otp',\n 'submit_interaction',\n 'ping',\n] as const;\nexport type ActionType = (typeof ACTION_TYPES)[number];\n\n/** Every server→client `type` discriminator value. */\nexport const EVENT_TYPES = [\n 'immediate_response',\n 'eventual_response',\n 'stream_chunk',\n 'stream_token',\n 'keepalive',\n 'write_confirmation_required',\n 'otp_verification_required',\n 'otp_sent',\n 'otp_verified',\n 'otp_invalid',\n 'interaction_required',\n 'interaction_invalid',\n 'error',\n 'pong',\n] as const;\nexport type EventType = (typeof EVENT_TYPES)[number];\n\n// ───────────────────────────── Client actions ──────────────────────────────\n\n/**\n * Discriminated union over every client→server action frame, keyed on `action`.\n * Narrow with `action.action === 'send_message'` to get the concrete request type.\n */\nexport type ClientAction =\n | CreateConversationSessionRequest\n | SendMessageRequest\n | GetSessionRequest\n | GetMessagesRequest\n | ConfirmToolActionRequest\n | VerifyOtpRequest\n | SubmitInteractionRequest\n | PingRequest;\n\n// ───────────────────────────── Server events ───────────────────────────────\n\n/**\n * Discriminated union over every server→client event frame, keyed on `type`.\n * Narrow with `event.type === 'stream_token'` to get the concrete event type.\n */\nexport type ServerEvent =\n | ImmediateResponse\n | EventualResponse\n | StreamChunk\n | StreamToken\n | Keepalive\n | WriteConfirmationRequired\n | OtpVerificationRequired\n | OtpSent\n | OtpVerified\n | OtpInvalid\n | InteractionRequired\n | InteractionInvalid\n | GeneratedErrorEvent\n | Pong;\n\n// ─────────────────────── Per-type narrowed convenience ──────────────────────\n\n/** Map from event `type` → the concrete generated event interface. */\nexport interface ServerEventByType {\n immediate_response: ImmediateResponse;\n eventual_response: EventualResponse;\n stream_chunk: StreamChunk;\n stream_token: StreamToken;\n keepalive: Keepalive;\n write_confirmation_required: WriteConfirmationRequired;\n otp_verification_required: OtpVerificationRequired;\n otp_sent: OtpSent;\n otp_verified: OtpVerified;\n otp_invalid: OtpInvalid;\n interaction_required: InteractionRequired;\n interaction_invalid: InteractionInvalid;\n error: GeneratedErrorEvent;\n pong: Pong;\n}\n\n/** Map from action `action` → the concrete generated request interface. */\nexport interface ClientActionByType {\n create_conversation_session: CreateConversationSessionRequest;\n send_message: SendMessageRequest;\n get_session: GetSessionRequest;\n get_conversation_messages: GetMessagesRequest;\n confirm_tool_action: ConfirmToolActionRequest;\n verify_otp: VerifyOtpRequest;\n submit_interaction: SubmitInteractionRequest;\n ping: PingRequest;\n}\n\n// ───────────────────────────── Type guards ─────────────────────────────────\n\n/** True if `frame` is a server event of the given `type`, narrowing accordingly. */\nexport function isEvent<T extends EventType>(frame: unknown, type: T): frame is ServerEventByType[T] {\n return isServerEvent(frame) && frame.type === type;\n}\n\n/** True if `frame` looks like any server event (has a known `type` discriminator). */\nexport function isServerEvent(frame: unknown): frame is ServerEvent {\n return (\n typeof frame === 'object' &&\n frame !== null &&\n 'type' in frame &&\n typeof (frame as { type: unknown }).type === 'string' &&\n (EVENT_TYPES as readonly string[]).includes((frame as { type: string }).type)\n );\n}\n\n/** True if `frame` looks like any client action (has a known `action` discriminator). */\nexport function isClientAction(frame: unknown): frame is ClientAction {\n return (\n typeof frame === 'object' &&\n frame !== null &&\n 'action' in frame &&\n typeof (frame as { action: unknown }).action === 'string' &&\n (ACTION_TYPES as readonly string[]).includes((frame as { action: string }).action)\n );\n}\n\n// ──────────────────────── Decoded response payloads ────────────────────────\n\n/**\n * The typed `data` payload returned in the `immediate_response` for each\n * non-streaming action. These are the generated `*Response` shapes, surfaced so\n * the client's typed methods can return them directly.\n */\nexport type {\n CreateConversationSessionResponse,\n GetSessionResponse,\n GetMessagesResponse,\n SendMessageResponse,\n};\n","/**\n * SmoothAgentClient — a minimal, idiomatic, transport-agnostic client for the\n * smooth-operator WebSocket protocol.\n *\n * Design goals\n * ------------\n * - **Transport-agnostic.** The client never touches a real socket directly; it\n * talks to an injectable {@link Transport}. The default ({@link WebSocketTransport})\n * uses the global `WebSocket`, but tests inject a mock and Node can inject `ws`.\n * - **Request/response correlation by `requestId`.** Every action gets a generated\n * `requestId`; the client routes incoming events back to the originating call.\n * - **Streaming as an async iterator.** `sendMessage` returns a {@link MessageTurn}\n * that is both awaitable (resolves with the terminal `eventual_response`) and\n * async-iterable (yields each `stream_token` / `stream_chunk` / HITL event in\n * order). This models the `stream_token`/`stream_chunk` → `eventual_response`\n * flow without forcing a callback style on the caller.\n * - **No live server required.** Correctness is fully unit-testable with a mock\n * transport (see `test/client.test.ts`).\n */\nimport {\n WebSocketTransport,\n type Transport,\n type WebSocketFactory,\n} from './transport.js';\nimport type {\n ClientAction,\n CreateConversationSessionRequest,\n CreateConversationSessionResponse,\n EventualResponse,\n GetMessagesRequest,\n GetMessagesResponse,\n GetSessionRequest,\n GetSessionResponse,\n SendMessageRequest,\n ServerEvent,\n} from './types.js';\nimport { isServerEvent } from './types.js';\n\nexport interface SmoothAgentClientOptions {\n /** WebSocket URL, e.g. `wss://realtime.prod.smooth-agent.dev`. */\n url: string;\n /**\n * Optional connection auth token for token-gated servers (e.g. the local-flavor\n * server). When set, the token is appended to the connection URL as a `?token=`\n * query parameter — browsers can't set custom headers on a WebSocket handshake,\n * so the token rides the query string, which is where the server reads it from.\n * Any existing query string on `url` is preserved. This applies to the default\n * transport only; if a custom {@link transport} is injected, supply the token to\n * that transport yourself.\n */\n token?: string;\n /** Inject a transport (for tests / non-browser runtimes). Defaults to a WebSocket transport. */\n transport?: Transport;\n /** Inject a WebSocket factory used by the default transport (e.g. the `ws` package on Node). */\n webSocketFactory?: WebSocketFactory;\n /** Generate request IDs. Defaults to `crypto.randomUUID()` with a `req-` prefix. */\n generateRequestId?: () => string;\n /** Per-request timeout in ms for non-streaming actions. Default 30000. */\n requestTimeout?: number;\n /**\n * Overall timeout in ms for a streaming `sendMessage` turn: if the server accepts\n * the message but never emits a terminal `eventual_response` / `error`, the turn\n * rejects with a {@link TurnTimeoutError} instead of hanging forever. Default\n * 120000. Set to 0 (or a negative number) to disable.\n */\n turnTimeout?: number;\n}\n\n/** Events that terminate a streaming turn (success or error). */\nconst TURN_TERMINAL = new Set(['eventual_response', 'error']);\n\n/** A timeout that yields no terminal event. */\nclass RequestTimeoutError extends Error {\n constructor(requestId: string, ms: number) {\n super(`Request ${requestId} timed out after ${ms}ms`);\n this.name = 'RequestTimeoutError';\n }\n}\n\n/**\n * A streaming turn that received no terminal `eventual_response` / `error` within the\n * configured {@link SmoothAgentClientOptions.turnTimeout}. The turn rejects with this\n * and its async iteration throws it, so a stuck server can never hang the caller.\n */\nexport class TurnTimeoutError extends Error {\n readonly requestId: string;\n constructor(requestId: string, ms: number) {\n super(`Turn ${requestId} timed out after ${ms}ms without a terminal response`);\n this.name = 'TurnTimeoutError';\n this.requestId = requestId;\n }\n}\n\n/** A protocol-level error event surfaced as a throwable. */\nexport class ProtocolError extends Error {\n readonly code: string;\n readonly requestId?: string;\n constructor(code: string, message: string, requestId?: string) {\n super(message);\n this.name = 'ProtocolError';\n this.code = code;\n this.requestId = requestId;\n }\n}\n\n/** Internal record for an in-flight single-response request. */\ninterface PendingRequest {\n resolve: (event: ServerEvent) => void;\n reject: (err: unknown) => void;\n timer: ReturnType<typeof setTimeout> | undefined;\n}\n\n/**\n * A streaming message turn. Await it for the terminal {@link EventualResponse},\n * or async-iterate it to receive every intermediate event in arrival order.\n *\n * ```ts\n * const turn = client.sendMessage({ sessionId, message: 'hi' });\n * for await (const ev of turn) {\n * if (ev.type === 'stream_token') process.stdout.write(ev.token ?? '');\n * }\n * const final = await turn; // EventualResponse\n * ```\n */\nexport class MessageTurn implements AsyncIterable<ServerEvent>, PromiseLike<EventualResponse> {\n /** The requestId this turn is correlated on. */\n readonly requestId: string;\n\n private readonly queue: ServerEvent[] = [];\n private waiter: {\n resolve: (result: IteratorResult<ServerEvent>) => void;\n reject: (err: unknown) => void;\n } | null = null;\n private done = false;\n private finalEvent: EventualResponse | null = null;\n private error: unknown = null;\n private readonly settled: Promise<EventualResponse>;\n private settle!: (value: EventualResponse) => void;\n private fail!: (err: unknown) => void;\n private readonly onClose: () => void;\n private timeoutTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(requestId: string, onClose: () => void, turnTimeout = 0) {\n this.requestId = requestId;\n this.onClose = onClose;\n this.settled = new Promise<EventualResponse>((resolve, reject) => {\n this.settle = resolve;\n this.fail = reject;\n });\n // Avoid unhandled-rejection noise if the caller only iterates and never awaits.\n this.settled.catch(() => {});\n // Bound the turn: a server that accepts the message but never emits a terminal\n // event must not hang the caller forever.\n if (turnTimeout > 0) {\n this.timeoutTimer = setTimeout(() => {\n this.finish(null, new TurnTimeoutError(this.requestId, turnTimeout));\n }, turnTimeout);\n }\n }\n\n /** Feed an event into the turn (called by the client's dispatcher). */\n push(event: ServerEvent): void {\n if (this.done) return;\n\n if (event.type === 'error') {\n const code = event.data?.error?.code ?? 'INTERNAL_ERROR';\n const message = event.data?.error?.message ?? 'Unknown protocol error';\n this.deliver(event);\n this.finish(null, new ProtocolError(code, message, this.requestId));\n return;\n }\n\n this.deliver(event);\n\n if (event.type === 'eventual_response') {\n this.finish(event, null);\n }\n }\n\n /** Force-close the turn (e.g. on disconnect) with an error. */\n abort(err: unknown): void {\n if (this.done) return;\n this.finish(null, err);\n }\n\n private deliver(event: ServerEvent): void {\n if (this.waiter) {\n const w = this.waiter;\n this.waiter = null;\n w.resolve({ value: event, done: false });\n } else {\n this.queue.push(event);\n }\n }\n\n private finish(final: EventualResponse | null, err: unknown): void {\n if (this.done) return;\n this.done = true;\n this.finalEvent = final;\n this.error = err;\n if (this.timeoutTimer) {\n clearTimeout(this.timeoutTimer);\n this.timeoutTimer = undefined;\n }\n this.onClose();\n\n if (err) this.fail(err);\n else if (final) this.settle(final);\n\n // Release any pending iterator waiter now that the stream has ended. On error\n // the parked next() must *reject* (mirroring the queued-error path in next())\n // so a pure `for await` consumer sees the terminal error thrown instead of a\n // silent, indistinguishable `{ done: true }`.\n if (this.waiter) {\n const w = this.waiter;\n this.waiter = null;\n if (err) {\n w.reject(err);\n } else {\n w.resolve({ value: undefined as never, done: true });\n }\n }\n }\n\n [Symbol.asyncIterator](): AsyncIterator<ServerEvent> {\n return {\n next: (): Promise<IteratorResult<ServerEvent>> => {\n if (this.queue.length > 0) {\n return Promise.resolve({ value: this.queue.shift()!, done: false });\n }\n if (this.done) {\n if (this.error) return Promise.reject(this.error);\n return Promise.resolve({ value: undefined as never, done: true });\n }\n return new Promise<IteratorResult<ServerEvent>>((resolve, reject) => {\n this.waiter = { resolve, reject };\n });\n },\n };\n }\n\n // PromiseLike — `await turn` resolves with the EventualResponse.\n then<TResult1 = EventualResponse, TResult2 = never>(\n onfulfilled?: ((value: EventualResponse) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.settled.then(onfulfilled, onrejected);\n }\n}\n\nexport class SmoothAgentClient {\n private readonly transport: Transport;\n private readonly generateRequestId: () => string;\n private readonly requestTimeout: number;\n private readonly turnTimeout: number;\n\n /** requestId → single-response waiter (create_session, get_session, ping, …). */\n private readonly pending = new Map<string, PendingRequest>();\n /** requestId → active streaming turn (send_message, and HITL resumes). */\n private readonly turns = new Map<string, MessageTurn>();\n /** Unsolicited-event listeners (keepalive, server-push). */\n private readonly listeners = new Set<(event: ServerEvent) => void>();\n\n private unsubscribe: Array<() => void> = [];\n\n constructor(options: SmoothAgentClientOptions) {\n this.transport =\n options.transport ??\n new WebSocketTransport(withConnectionToken(options.url, options.token), options.webSocketFactory);\n this.requestTimeout = options.requestTimeout ?? 30_000;\n this.turnTimeout = options.turnTimeout ?? 120_000;\n this.generateRequestId =\n options.generateRequestId ??\n (() => `req-${(globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2))}`);\n\n this.unsubscribe.push(this.transport.onMessage((data) => this.handleFrame(data)));\n this.unsubscribe.push(\n this.transport.onClose(() => this.failAll(new Error('Transport closed'))),\n );\n }\n\n /** Open the underlying transport. */\n async connect(): Promise<void> {\n await this.transport.connect();\n }\n\n /** Close the transport and reject all in-flight work. */\n disconnect(reason = 'client disconnect'): void {\n this.failAll(new Error(reason));\n for (const u of this.unsubscribe) u();\n this.unsubscribe = [];\n this.transport.close(1000, reason);\n }\n\n /** Subscribe to unsolicited / uncorrelated server events (e.g. keepalive). */\n onEvent(listener: (event: ServerEvent) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n // ───────────────────────────── Actions ─────────────────────────────────\n\n /** Start a new conversation session. Resolves with the session descriptor. */\n async createConversationSession(\n req: Omit<CreateConversationSessionRequest, 'action' | 'requestId'>,\n ): Promise<CreateConversationSessionResponse> {\n const event = await this.request({ action: 'create_conversation_session', ...req });\n return extractImmediateData<CreateConversationSessionResponse>(event);\n }\n\n /** Fetch a session snapshot by ID. */\n async getSession(req: Omit<GetSessionRequest, 'action' | 'requestId'>): Promise<GetSessionResponse> {\n const event = await this.request({ action: 'get_session', ...req });\n return extractImmediateData<GetSessionResponse>(event);\n }\n\n /** Fetch a page of conversation messages. */\n async getMessages(req: Omit<GetMessagesRequest, 'action' | 'requestId'>): Promise<GetMessagesResponse> {\n const event = await this.request({ action: 'get_conversation_messages', ...req });\n return extractImmediateData<GetMessagesResponse>(event);\n }\n\n /** Keepalive ping. Resolves with the server timestamp from the `pong` event. */\n async ping(): Promise<number> {\n const event = await this.request({ action: 'ping' });\n if (event.type === 'pong') return event.timestamp ?? event.data?.timestamp ?? Date.now();\n return Date.now();\n }\n\n /**\n * Submit a user message and return a {@link MessageTurn}: await it for the\n * terminal `eventual_response`, or async-iterate it for the streaming events.\n */\n sendMessage(req: Omit<SendMessageRequest, 'action' | 'requestId'>): MessageTurn {\n const requestId = this.generateRequestId();\n const turn = new MessageTurn(requestId, () => this.turns.delete(requestId), this.turnTimeout);\n this.turns.set(requestId, turn);\n try {\n this.transport.send(JSON.stringify({ action: 'send_message', requestId, ...req }));\n } catch (err) {\n this.turns.delete(requestId);\n turn.abort(err);\n }\n return turn;\n }\n\n /**\n * Approve or reject a pending tool write, resuming the paused turn identified\n * by `requestId`. The resumed streaming events flow back into the original\n * {@link MessageTurn} for that `requestId`.\n */\n confirmToolAction(req: { sessionId: string; requestId: string; approved: boolean }): void {\n this.transport.send(JSON.stringify({ action: 'confirm_tool_action', ...req }));\n }\n\n /**\n * Submit an OTP code, resuming the paused turn identified by `requestId`.\n * The resumed streaming events flow back into the original {@link MessageTurn}.\n */\n verifyOtp(req: { sessionId: string; requestId: string; code: string }): void {\n this.transport.send(JSON.stringify({ action: 'verify_otp', ...req }));\n }\n\n /**\n * Submit (or decline) a Rich Interaction, resuming the turn parked by an\n * `interaction_required` event. This ONE verb serves every interaction kind\n * (identity intake, future date pickers, choice chips, …) — adding a kind\n * needs no new client method. Server-side validation may reply with an\n * `interaction_invalid` event (the turn stays parked — resubmit); a valid\n * submit resumes the stream back into the original {@link MessageTurn}.\n */\n submitInteraction(req: {\n sessionId: string;\n requestId: string;\n /** Echo of the `interaction_required` event's `interactionId`. */\n interactionId: string;\n /** Optional kind cross-check (e.g. `identity_intake`). */\n kind?: string;\n /** Kind-shaped values (identity_intake: `{ name?, email?, phone? }`). */\n values?: Record<string, unknown>;\n declined?: boolean;\n }): void {\n this.transport.send(JSON.stringify({ action: 'submit_interaction', ...req }));\n }\n\n // ─────────────────────────── Internals ─────────────────────────────────\n\n /** Send an action that expects a single correlated response event. */\n private request(action: Omit<ClientAction, 'requestId'> & { requestId?: string }): Promise<ServerEvent> {\n const requestId = action.requestId ?? this.generateRequestId();\n const frame = { ...action, requestId } as ClientAction;\n\n return new Promise<ServerEvent>((resolve, reject) => {\n const timer =\n this.requestTimeout > 0\n ? setTimeout(() => {\n this.pending.delete(requestId);\n reject(new RequestTimeoutError(requestId, this.requestTimeout));\n }, this.requestTimeout)\n : undefined;\n\n this.pending.set(requestId, { resolve, reject, timer });\n try {\n this.transport.send(JSON.stringify(frame));\n } catch (err) {\n if (timer) clearTimeout(timer);\n this.pending.delete(requestId);\n reject(err);\n }\n });\n }\n\n /** Parse and route an incoming frame to the right consumer. */\n private handleFrame(data: string): void {\n let frame: unknown;\n try {\n frame = JSON.parse(data);\n } catch {\n return; // ignore malformed frames\n }\n if (!isServerEvent(frame)) return;\n const event = frame;\n const requestId = event.requestId;\n\n // 1. Streaming turn? Route every related event into it.\n if (requestId && this.turns.has(requestId)) {\n this.turns.get(requestId)!.push(event);\n return;\n }\n\n // 2. Single-response request awaiting resolution?\n if (requestId && this.pending.has(requestId)) {\n const pending = this.pending.get(requestId)!;\n this.pending.delete(requestId);\n if (pending.timer) clearTimeout(pending.timer);\n\n if (event.type === 'error') {\n const code = event.data?.error?.code ?? 'INTERNAL_ERROR';\n const message = event.data?.error?.message ?? 'Unknown protocol error';\n pending.reject(new ProtocolError(code, message, requestId));\n } else {\n pending.resolve(event);\n }\n return;\n }\n\n // 3. Unsolicited / uncorrelated event (keepalive, server push).\n for (const l of this.listeners) l(event);\n }\n\n private failAll(err: unknown): void {\n for (const [, p] of this.pending) {\n if (p.timer) clearTimeout(p.timer);\n p.reject(err);\n }\n this.pending.clear();\n for (const [, turn] of this.turns) turn.abort(err);\n this.turns.clear();\n }\n}\n\n/**\n * Merge a connection auth `token` into a WebSocket URL as a `?token=` query param,\n * preserving any existing query string. Returns `url` unchanged when no token is\n * given, so the no-token path is byte-for-byte identical to before. Uses `URL` /\n * `URLSearchParams` so an existing `?foo=bar` becomes `?foo=bar&token=…` (and the\n * value is properly percent-encoded) rather than a naive `?`/`&` string-concat.\n *\n * Falls back to manual concatenation if `url` is not absolute (so `URL` can't parse\n * it) — e.g. a relative or mock URL used in tests.\n */\nfunction withConnectionToken(url: string, token?: string): string {\n if (!token) return url;\n try {\n const parsed = new URL(url);\n parsed.searchParams.set('token', token);\n return parsed.toString();\n } catch {\n const separator = url.includes('?') ? '&' : '?';\n return `${url}${separator}token=${encodeURIComponent(token)}`;\n }\n}\n\n/** Pull the typed `data` payload out of an `immediate_response` event. */\nfunction extractImmediateData<T>(event: ServerEvent): T {\n if (event.type === 'immediate_response') return event.data as T;\n // Some servers may answer a non-streaming action with the payload elsewhere;\n // fall back to `data` if present.\n if ('data' in event && event.data && typeof event.data === 'object') return event.data as T;\n throw new ProtocolError('UNEXPECTED_EVENT', `Expected immediate_response, got \"${event.type}\"`, event.requestId);\n}\n","/**\n * ConversationController — the bridge between the widget UI and the\n * `@smooai/smooth-operator` protocol client.\n *\n * This is the piece that was rewired: the original smooai widget spoke to\n * `@smooai/realtime`; here every protocol action goes through {@link SmoothAgentClient}.\n * The wire shapes are identical (the protocol was lifted from `@smooai/realtime`),\n * so the swap is purely at the client-library boundary.\n *\n * Flow:\n * 1. `connect()` → opens the WebSocket transport and `create_conversation_session`.\n * 2. `send(text)` → `send_message`, streaming `stream_token` deltas into the\n * in-progress assistant message, then the terminal\n * `eventual_response`.\n *\n * The controller is UI-agnostic: it emits typed events and the view renders them.\n */\nimport { ProtocolError, SmoothAgentClient, type SmoothAgentClientOptions } from '../client.js';\nimport type { Citation } from '../types.js';\nimport type { ChatWidgetConfig } from './config.js';\n\nexport type { Citation };\n\nexport type Role = 'user' | 'assistant';\n\n/**\n * A chat-native interactive prompt rendered as buttons inside an assistant\n * bubble. Backs SEP `ui/confirm` and `ui/select`: the agent (or an extension it\n * hosts) pauses the turn asking for a choice, and the click flows back as an\n * action frame that resumes the same turn.\n *\n * `confirm` projects the protocol's `write_confirmation_required` event (Yes/No\n * → `confirm_tool_action`); `select` projects a `ui/select` (one option → its\n * value). Each option's `value` is what the resume action carries.\n */\nexport interface ChatPrompt {\n /** The turn's `requestId` — the resume action must echo it. */\n requestId: string;\n kind: 'confirm' | 'select';\n /** Human-readable prompt text (the confirmation description / select prompt). */\n text: string;\n /** The buttons. For `confirm`: Yes (`true`) / No (`false`). */\n options: Array<{ label: string; value: string | boolean }>;\n /** Set once the user picks — disables the buttons and records the choice. */\n answered?: string;\n}\n\nexport interface ChatMessage {\n id: string;\n role: Role;\n /** Accumulated text (assistant messages grow as tokens stream in). */\n text: string;\n /** True while an assistant message is still streaming. */\n streaming: boolean;\n /**\n * Sources that grounded an assistant answer, when the terminal\n * `eventual_response` carried any. Optional + back-compatible: absent when\n * the turn used no knowledge sources (or for user messages). Read\n * defensively off the terminal event — see {@link extractCitations}.\n */\n citations?: Citation[];\n /**\n * A pending (or answered) chat-native button prompt. Present only on the\n * bubble that carries a `write_confirmation_required` / `ui/select` request.\n */\n prompt?: ChatPrompt;\n}\n\nexport type ConnectionStatus = 'idle' | 'connecting' | 'ready' | 'error' | 'closed';\n\nexport interface ConversationEvents {\n /** Fired whenever the message list changes (append, token delta, finalize). */\n onMessages: (messages: ChatMessage[]) => void;\n /** Fired on connection-status transitions. */\n onStatus: (status: ConnectionStatus, detail?: string) => void;\n}\n\n/** Pull the final assistant text out of an `eventual_response` data payload. */\nfunction extractFinalText(response: unknown): string | null {\n if (!response || typeof response !== 'object') return null;\n const r = response as { responseParts?: unknown };\n if (Array.isArray(r.responseParts)) {\n return r.responseParts.filter((p): p is string => typeof p === 'string').join('\\n\\n');\n }\n return null;\n}\n\n/**\n * Pull the grounding {@link Citation}s out of a terminal `eventual_response`.\n *\n * The protocol client types these (`eventual_response.data.data.citations`),\n * but they're optional and back-compatible — absent when the turn used no\n * knowledge sources. We read them defensively (tolerating their total absence,\n * non-array shapes, and missing fields) so a server that doesn't emit them, or\n * an older client, can't break rendering. Each citation always carries\n * `id`/`title`/`snippet`/`score`; `url` is present only for web-sourced docs.\n */\nfunction extractCitations(inner: unknown): Citation[] {\n if (!inner || typeof inner !== 'object') return [];\n const raw = (inner as { citations?: unknown }).citations;\n if (!Array.isArray(raw)) return [];\n const out: Citation[] = [];\n for (const c of raw) {\n if (!c || typeof c !== 'object') continue;\n const obj = c as Record<string, unknown>;\n const id = typeof obj.id === 'string' ? obj.id : '';\n const title = typeof obj.title === 'string' ? obj.title : id || 'Source';\n const snippet = typeof obj.snippet === 'string' ? obj.snippet : '';\n const url = typeof obj.url === 'string' && obj.url ? obj.url : undefined;\n const score = typeof obj.score === 'number' ? obj.score : 0;\n out.push({ id, title, snippet, score, url });\n }\n return out;\n}\n\nexport class ConversationController {\n private readonly config: ChatWidgetConfig;\n private readonly events: ConversationEvents;\n private client: SmoothAgentClient | null = null;\n private sessionId: string | null = null;\n private readonly messages: ChatMessage[] = [];\n private status: ConnectionStatus = 'idle';\n private seq = 0;\n /**\n * requestId → resolver for a pending button prompt. The turn loop parks on\n * the promise; {@link answerPrompt} (called by the view on a button click)\n * resolves it and the loop resumes consuming the (now un-paused) stream.\n */\n private readonly pendingPrompts = new Map<string, (choice: string | boolean) => void>();\n /** Extra client options — a test seam for injecting a mock transport. */\n private readonly clientOptions?: Partial<SmoothAgentClientOptions>;\n\n constructor(config: ChatWidgetConfig, events: ConversationEvents, clientOptions?: Partial<SmoothAgentClientOptions>) {\n this.config = config;\n this.events = events;\n this.clientOptions = clientOptions;\n }\n\n get connectionStatus(): ConnectionStatus {\n return this.status;\n }\n\n private nextId(prefix: string): string {\n this.seq += 1;\n return `${prefix}-${this.seq}-${Date.now().toString(36)}`;\n }\n\n private setStatus(status: ConnectionStatus, detail?: string): void {\n this.status = status;\n this.events.onStatus(status, detail);\n }\n\n private emitMessages(): void {\n // Hand out a shallow copy so the view can't mutate internal state.\n this.events.onMessages(this.messages.map((m) => ({ ...m })));\n }\n\n /** Open the transport and create a conversation session. Idempotent. */\n async connect(): Promise<void> {\n if (this.status === 'connecting' || this.status === 'ready') return;\n this.setStatus('connecting');\n try {\n this.client = new SmoothAgentClient({ url: this.config.endpoint, ...this.clientOptions });\n await this.client.connect();\n const session = await this.client.createConversationSession({\n agentId: this.config.agentId,\n userName: this.config.userName,\n userEmail: this.config.userEmail,\n });\n this.sessionId = session.sessionId;\n this.setStatus('ready');\n } catch (err) {\n this.setStatus('error', err instanceof Error ? err.message : String(err));\n throw err;\n }\n }\n\n /**\n * Submit a user message. Appends the user bubble immediately, then streams the\n * assistant reply token-by-token, finalizing on `eventual_response`.\n */\n async send(text: string): Promise<void> {\n const trimmed = text.trim();\n if (!trimmed) return;\n if (!this.client || !this.sessionId || this.status !== 'ready') {\n await this.connect();\n }\n if (!this.client || !this.sessionId) {\n throw new Error('Conversation is not connected');\n }\n\n // 1. User bubble.\n this.messages.push({ id: this.nextId('u'), role: 'user', text: trimmed, streaming: false });\n\n // 2. Placeholder assistant bubble we grow as tokens arrive.\n const assistant: ChatMessage = { id: this.nextId('a'), role: 'assistant', text: '', streaming: true };\n this.messages.push(assistant);\n this.emitMessages();\n\n try {\n const turn = this.client.sendMessage({ sessionId: this.sessionId, message: trimmed, stream: true });\n\n for await (const event of turn) {\n if (event.type === 'stream_token') {\n const token = event.token ?? event.data?.token ?? '';\n if (token) {\n assistant.text += token;\n this.emitMessages();\n }\n } else if (event.type === 'write_confirmation_required') {\n // The turn is paused server-side awaiting a confirm_tool_action.\n // Render Yes/No buttons and block the loop until the user clicks\n // (or the transport drops). The click sends the resume action\n // via answerPrompt(); the stream then flows back into `turn`.\n const description = event.data?.data?.actionDescription ?? 'Approve this action?';\n const approved = await this.awaitPromptChoice(turn.requestId, {\n requestId: turn.requestId,\n kind: 'confirm',\n text: String(description),\n options: [\n { label: 'Yes', value: true },\n { label: 'No', value: false },\n ],\n });\n this.client?.confirmToolAction({ sessionId: this.sessionId!, requestId: turn.requestId, approved: approved === true });\n }\n }\n\n const final = await turn;\n const inner = final.data?.data;\n const finalText = extractFinalText(inner?.response);\n if (finalText && finalText.length > assistant.text.length) {\n assistant.text = finalText;\n }\n if (!assistant.text) {\n assistant.text = '(no response)';\n }\n // Attach grounding sources from the terminal event, when present.\n const citations = extractCitations(inner);\n if (citations.length > 0) {\n assistant.citations = citations;\n }\n assistant.streaming = false;\n this.emitMessages();\n } catch (err) {\n assistant.streaming = false;\n const message =\n err instanceof ProtocolError\n ? `Error: ${err.message}`\n : (this.config.connectionErrorMessage ?? \"We couldn't reach the chat.\");\n assistant.text = assistant.text ? `${assistant.text}\\n\\n${message}` : message;\n this.emitMessages();\n this.setStatus('error', err instanceof Error ? err.message : String(err));\n }\n }\n\n /**\n * Attach a pending `prompt` to the current assistant bubble and return a\n * promise that resolves when the user clicks a button (via\n * {@link answerPrompt}). The bubble carrying the prompt is the last\n * assistant message.\n */\n private awaitPromptChoice(requestId: string, prompt: ChatPrompt): Promise<string | boolean> {\n const last = this.messages[this.messages.length - 1];\n if (last && last.role === 'assistant') {\n last.prompt = prompt;\n last.streaming = false; // stop the typing cursor while we wait\n }\n this.emitMessages();\n return new Promise<string | boolean>((resolve) => {\n this.pendingPrompts.set(requestId, resolve);\n });\n }\n\n /**\n * Resolve a pending button prompt — called by the view when the user clicks\n * an option. Marks the prompt answered (buttons disable, choice sticks) and\n * unblocks the turn loop. No-op if the prompt was already answered.\n */\n answerPrompt(requestId: string, value: string | boolean): void {\n const resolve = this.pendingPrompts.get(requestId);\n if (!resolve) return;\n this.pendingPrompts.delete(requestId);\n const msg = this.messages.find((m) => m.prompt?.requestId === requestId);\n if (msg?.prompt) {\n msg.prompt.answered = msg.prompt.options.find((o) => o.value === value)?.label ?? String(value);\n }\n this.emitMessages();\n resolve(value);\n }\n\n /** Tear down the underlying client. */\n disconnect(): void {\n // Unblock any parked prompt so a pending turn loop doesn't hang forever.\n for (const [requestId, resolve] of this.pendingPrompts) {\n this.pendingPrompts.delete(requestId);\n resolve(false);\n }\n this.client?.disconnect('widget closed');\n this.client = null;\n this.sessionId = null;\n this.setStatus('closed');\n }\n}\n","/**\n * The Smooth logo, inlined as an SVG string so the full-page header can render\n * it without a separate network fetch (the IIFE bundle is self-contained).\n *\n * GENERATED from `assets/smooth-logo.svg` — do not edit by hand. Regenerate with:\n * node -e ... (see the commit that added this file)\n */\n/* eslint-disable */\nexport const SMOOTH_LOGO_SVG = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n<svg id=\\\"Layer_1\\\" data-name=\\\"Layer 1\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\" viewBox=\\\"0 0 550 135\\\">\\n <defs>\\n <style>\\n .cls-1 {\\n fill: url(#linear-gradient-3);\\n }\\n\\n .cls-2 {\\n fill: url(#linear-gradient-2);\\n }\\n\\n .cls-3 {\\n fill: url(#linear-gradient);\\n fill-rule: evenodd;\\n }\\n </style>\\n <linearGradient id=\\\"linear-gradient\\\" x1=\\\"115.59\\\" y1=\\\"112.81\\\" x2=\\\"25.08\\\" y2=\\\"22.3\\\" gradientUnits=\\\"userSpaceOnUse\\\">\\n <stop offset=\\\".3\\\" stop-color=\\\"#f49f0a\\\"/>\\n <stop offset=\\\".79\\\" stop-color=\\\"#fb7a4d\\\"/>\\n <stop offset=\\\"1\\\" stop-color=\\\"#ff6b6c\\\"/>\\n </linearGradient>\\n <linearGradient id=\\\"linear-gradient-2\\\" x1=\\\"360.91\\\" y1=\\\"152.01\\\" x2=\\\"202.32\\\" y2=\\\"-6.59\\\" xlink:href=\\\"#linear-gradient\\\"/>\\n <linearGradient id=\\\"linear-gradient-3\\\" x1=\\\"443.91\\\" y1=\\\"30.15\\\" x2=\\\"531.36\\\" y2=\\\"117.59\\\" gradientUnits=\\\"userSpaceOnUse\\\">\\n <stop offset=\\\".43\\\" stop-color=\\\"#00a6a6\\\"/>\\n <stop offset=\\\"1\\\" stop-color=\\\"#1238dd\\\"/>\\n </linearGradient>\\n </defs>\\n <path class=\\\"cls-3\\\" d=\\\"M48.28,14.96c-12.39,5.21-22.54,14.64-28.65,26.61-6.12,11.97-7.8,25.72-4.77,38.81,3.04,13.09,10.6,24.69,21.36,32.75,10.76,8.06,24.02,12.05,37.44,11.28,13.42-.77,26.13-6.26,35.9-15.5,9.76-9.24,15.95-21.63,17.46-34.99,1.51-13.36-1.74-26.82-9.19-38.01-1.07-1.61-.64-3.78.97-4.85,1.61-1.07,3.78-.64,4.85.97,8.36,12.56,12.02,27.68,10.32,42.67-1.7,15-8.64,28.91-19.61,39.28-10.96,10.37-25.24,16.54-40.31,17.4-15.07.87-29.96-3.62-42.04-12.66-12.08-9.05-20.58-22.07-23.99-36.77-3.41-14.7-1.51-30.14,5.35-43.58,6.87-13.44,18.26-24.02,32.17-29.87,13.91-5.85,29.44-6.6,43.85-2.11,1.85.57,2.88,2.54,2.3,4.38-.57,1.85-2.54,2.88-4.38,2.3-12.83-4-26.67-3.33-39.06,1.88ZM111.39,19.75c0,2.07-1.68,3.75-3.75,3.75s-3.75-1.68-3.75-3.75,1.68-3.75,3.75-3.75,3.75,1.68,3.75,3.75ZM64.64,59.93c0,1.91,2.39,2.56,7.69,3.88,3.89.97,6.6,2.18,8.15,3.63,1.53,1.45,2.29,3.53,2.29,6.25,0,3.57-1.03,6.26-3.11,8.08-2.07,1.82-5.09,2.73-9.09,2.73h-9.6c-1.97,0-3.57-1.6-3.59-3.57-.01-1.99,1.6-3.61,3.59-3.61h9.41c3.15-.12,4.79-.95,4.91-2.47,0-1.3-1.03-2.21-3.07-2.73-6.91-1.72-11.11-3.44-12.6-5.15-1.48-1.71-2.23-3.77-2.23-6.19,0-6.59,3.2-9.85,9.59-9.8h10.77c1.99,0,3.6,1.61,3.6,3.59s-1.61,3.59-3.6,3.59h-9.69c-1.83,0-3.43.06-3.43,1.77Z\\\"/>\\n <path class=\\\"cls-2\\\" d=\\\"M205.52,48.44h-8.86c-.44-3.75-2.23-6.65-5.38-8.72-3.16-2.07-7.03-3.1-11.6-3.1h0c-3.35,0-6.27.54-8.78,1.62-2.49,1.09-4.44,2.59-5.84,4.48-1.39,1.89-2.08,4.05-2.08,6.46h0c0,2.01.49,3.75,1.46,5.2.97,1.44,2.22,2.63,3.74,3.58,1.53.95,3.13,1.72,4.8,2.32,1.68.6,3.22,1.09,4.62,1.46h0l7.68,2.06c1.97.52,4.17,1.23,6.6,2.14,2.43.92,4.75,2.16,6.98,3.72,2.23,1.56,4.07,3.56,5.52,6,1.45,2.44,2.18,5.43,2.18,8.98h0c0,4.08-1.07,7.77-3.2,11.08-2.12,3.29-5.22,5.91-9.3,7.86-4.08,1.95-9.02,2.92-14.82,2.92h0c-5.43,0-10.11-.87-14.06-2.62-3.95-1.75-7.05-4.19-9.3-7.32-2.25-3.12-3.53-6.75-3.84-10.88h9.46c.25,2.85,1.22,5.21,2.9,7.06,1.69,1.87,3.83,3.25,6.42,4.14,2.6.89,5.41,1.34,8.42,1.34h0c3.49,0,6.63-.57,9.4-1.72,2.79-1.13,4.99-2.73,6.62-4.8,1.63-2.05,2.44-4.46,2.44-7.22h0c0-2.51-.7-4.55-2.1-6.12-1.41-1.57-3.26-2.85-5.54-3.84-2.29-.99-4.77-1.85-7.44-2.58h0l-9.3-2.66c-5.91-1.71-10.59-4.13-14.04-7.28-3.44-3.16-5.16-7.29-5.16-12.38h0c0-4.23,1.15-7.93,3.46-11.1,2.29-3.16,5.39-5.62,9.3-7.38,3.91-1.76,8.27-2.64,13.08-2.64h0c4.88,0,9.21.87,13,2.6,3.8,1.73,6.81,4.11,9.04,7.12,2.23,3,3.4,6.41,3.52,10.22h0ZM229.16,105.18h-8.72v-56.74h8.42v8.86h.74c1.19-3.03,3.1-5.38,5.74-7.06,2.63-1.69,5.79-2.54,9.48-2.54h0c3.75,0,6.87.85,9.36,2.54,2.51,1.68,4.46,4.03,5.86,7.06h.58c1.45-2.92,3.63-5.25,6.54-7,2.91-1.73,6.39-2.6,10.46-2.6h0c5.07,0,9.21,1.58,12.44,4.74,3.23,3.17,4.84,8.09,4.84,14.76h0v37.98h-8.72v-37.98c0-4.19-1.14-7.18-3.42-8.98-2.29-1.79-4.99-2.68-8.1-2.68h0c-3.99,0-7.07,1.2-9.26,3.6-2.2,2.4-3.3,5.43-3.3,9.1h0v36.94h-8.86v-38.86c0-3.23-1.05-5.83-3.14-7.82-2.09-1.97-4.79-2.96-8.08-2.96h0c-2.27,0-4.38.6-6.34,1.8-1.96,1.21-3.53,2.88-4.72,5-1.2,2.13-1.8,4.59-1.8,7.38h0v35.46ZM333.9,106.36h0c-5.12,0-9.61-1.22-13.46-3.66-3.85-2.44-6.86-5.85-9.02-10.24-2.15-4.37-3.22-9.49-3.22-15.36h0c0-5.91,1.07-11.07,3.22-15.48,2.16-4.4,5.17-7.82,9.02-10.26,3.85-2.44,8.34-3.66,13.46-3.66h0c5.12,0,9.61,1.22,13.46,3.66,3.85,2.44,6.86,5.86,9.02,10.26,2.15,4.41,3.22,9.57,3.22,15.48h0c0,5.87-1.07,10.99-3.22,15.36-2.16,4.39-5.17,7.8-9.02,10.24-3.85,2.44-8.34,3.66-13.46,3.66ZM333.9,98.52h0c3.89,0,7.09-.99,9.6-2.98,2.52-2,4.38-4.63,5.58-7.88,1.21-3.25,1.82-6.77,1.82-10.56h0c0-3.79-.61-7.32-1.82-10.6-1.2-3.27-3.06-5.91-5.58-7.94-2.51-2.01-5.71-3.02-9.6-3.02h0c-3.89,0-7.09,1.01-9.6,3.02-2.51,2.03-4.37,4.67-5.58,7.94-1.2,3.28-1.8,6.81-1.8,10.6h0c0,3.79.6,7.31,1.8,10.56,1.21,3.25,3.07,5.88,5.58,7.88,2.51,1.99,5.71,2.98,9.6,2.98ZM395.94,106.36h0c-5.12,0-9.61-1.22-13.46-3.66-3.85-2.44-6.85-5.85-9-10.24-2.16-4.37-3.24-9.49-3.24-15.36h0c0-5.91,1.08-11.07,3.24-15.48,2.15-4.4,5.15-7.82,9-10.26,3.85-2.44,8.34-3.66,13.46-3.66h0c5.12,0,9.61,1.22,13.46,3.66,3.85,2.44,6.86,5.86,9.02,10.26,2.16,4.41,3.24,9.57,3.24,15.48h0c0,5.87-1.08,10.99-3.24,15.36-2.16,4.39-5.17,7.8-9.02,10.24-3.85,2.44-8.34,3.66-13.46,3.66ZM395.94,98.52h0c3.89,0,7.09-.99,9.6-2.98,2.52-2,4.38-4.63,5.58-7.88,1.21-3.25,1.82-6.77,1.82-10.56h0c0-3.79-.61-7.32-1.82-10.6-1.2-3.27-3.06-5.91-5.58-7.94-2.51-2.01-5.71-3.02-9.6-3.02h0c-3.88,0-7.08,1.01-9.6,3.02-2.51,2.03-4.37,4.67-5.58,7.94-1.2,3.28-1.8,6.81-1.8,10.6h0c0,3.79.6,7.31,1.8,10.56,1.21,3.25,3.07,5.88,5.58,7.88,2.52,1.99,5.72,2.98,9.6,2.98Z\\\"/>\\n <path class=\\\"cls-1\\\" d=\\\"M467.88,48.02v13.28h-35.79v-13.28h35.79ZM439.68,34.38h17.89v53.42c0,1.5.36,2.62,1.08,3.36.72.74,1.88,1.1,3.49,1.1.62,0,1.48-.07,2.59-.21,1.11-.14,1.91-.27,2.38-.41l2.31,13.02c-2.02.58-3.97.97-5.84,1.18-1.88.21-3.66.31-5.33.31-6.08,0-10.7-1.43-13.84-4.28-3.15-2.85-4.72-7.01-4.72-12.48v-55.01ZM506.59,72.63v32.71h-17.89V28.95h17.53v33.53h-1.13c1.4-4.55,3.6-8.21,6.59-11,2.99-2.79,7.01-4.18,12.07-4.18,4,0,7.48.89,10.46,2.67,2.97,1.78,5.28,4.29,6.92,7.54,1.64,3.25,2.46,7.02,2.46,11.33v36.5h-17.89v-33.02c0-3.21-.82-5.73-2.46-7.56-1.64-1.83-3.93-2.74-6.87-2.74-1.92,0-3.62.42-5.1,1.26-1.49.84-2.64,2.04-3.46,3.61-.82,1.57-1.23,3.49-1.23,5.74Z\\\"/>\\n</svg>\";\n","import type { ChatWidgetMode, ChatWidgetTheme } from './config.js';\n\n/**\n * Render the widget's scoped stylesheet. All theme values are injected as CSS\n * custom properties on `:host` so they can be overridden per-instance and so the\n * styles below stay static. Kept deliberately framework-light — no Tailwind, no\n * runtime CSS-in-JS; just a string the web component drops into its shadow root.\n *\n * `mode` switches the host positioning + panel sizing between the floating\n * popover (default) and the full-page layout (fills its container/viewport).\n */\nexport function buildStyles(theme: Required<ChatWidgetTheme>, mode: ChatWidgetMode = 'popover'): string {\n return `\n:host {\n --sac-text: ${theme.text};\n --sac-bg: ${theme.background};\n --sac-primary: ${theme.primary};\n --sac-primary-text: ${theme.primaryText};\n --sac-assistant-bubble: ${theme.assistantBubble};\n --sac-assistant-bubble-text: ${theme.assistantBubbleText};\n --sac-user-bubble: ${theme.userBubble};\n --sac-user-bubble-text: ${theme.userBubbleText};\n --sac-border: ${theme.border};\n\n ${\n mode === 'fullpage'\n ? `/* Full-page: fill the host's box (the element should be sized by its\n container, or it falls back to filling the viewport). */\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n min-height: 100vh;`\n : `/* Popover: float in the bottom-right corner. */\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 2147483000;`\n }\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;\n}\n\n* { box-sizing: border-box; }\n\n.launcher {\n width: 56px;\n height: 56px;\n border-radius: 50%;\n border: none;\n cursor: pointer;\n background: var(--sac-primary);\n color: var(--sac-primary-text);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 24px;\n transition: transform 0.15s ease;\n}\n.launcher:hover { transform: scale(1.05); }\n\n.panel {\n width: 360px;\n max-width: calc(100vw - 40px);\n height: 520px;\n max-height: calc(100vh - 40px);\n display: flex;\n flex-direction: column;\n background: var(--sac-bg);\n color: var(--sac-text);\n border: 1px solid var(--sac-border);\n border-radius: 14px;\n overflow: hidden;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);\n}\n\n/* Full-page: the panel becomes the whole surface — no floating box, no shadow,\n no rounded corners; it fills the host. */\n.panel.fullpage {\n width: 100%;\n height: 100%;\n min-height: 100vh;\n max-width: none;\n max-height: none;\n border: none;\n border-radius: 0;\n box-shadow: none;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 14px;\n background: var(--sac-primary);\n color: var(--sac-primary-text);\n}\n.header .brand { display: flex; align-items: center; gap: 10px; min-width: 0; }\n.header .logo { height: 24px; width: auto; display: block; }\n.header .title { font-weight: 600; font-size: 15px; }\n.header .status { font-size: 11px; opacity: 0.85; }\n.header .powered {\n font-size: 10px;\n opacity: 0.7;\n letter-spacing: 0.02em;\n}\n.header .close {\n background: transparent;\n border: none;\n color: inherit;\n cursor: pointer;\n font-size: 18px;\n line-height: 1;\n padding: 4px;\n}\n\n/* Full-page header: taller, logo-led, centered max-width content row. */\n.panel.fullpage .header { padding: 14px 20px; }\n.panel.fullpage .logo { height: 30px; }\n\n.messages {\n flex: 1;\n overflow-y: auto;\n padding: 14px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.bubble {\n max-width: 80%;\n padding: 9px 12px;\n border-radius: 12px;\n font-size: 14px;\n line-height: 1.4;\n white-space: pre-wrap;\n word-break: break-word;\n}\n.bubble.assistant {\n align-self: flex-start;\n background: var(--sac-assistant-bubble);\n color: var(--sac-assistant-bubble-text);\n border-bottom-left-radius: 4px;\n}\n.bubble.user {\n align-self: flex-end;\n background: var(--sac-user-bubble);\n color: var(--sac-user-bubble-text);\n border-bottom-right-radius: 4px;\n}\n.bubble.greeting { opacity: 0.85; font-style: italic; }\n\n/* Full-page: center the conversation in a readable column and let bubbles\n breathe a little wider. */\n.panel.fullpage .messages {\n padding: 24px 20px;\n align-items: stretch;\n}\n.panel.fullpage .messages > * {\n width: 100%;\n max-width: 760px;\n margin-left: auto;\n margin-right: auto;\n}\n.panel.fullpage .bubble { max-width: 100%; }\n.panel.fullpage .bubble.user { align-self: flex-end; max-width: 80%; margin-right: auto; }\n.panel.fullpage .bubble.assistant { align-self: flex-start; max-width: 100%; }\n\n/* Sources panel — rendered under an assistant bubble whose terminal\n eventual_response carried citations. */\n.prompt {\n align-self: flex-start;\n max-width: 80%;\n margin-top: -2px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.panel.fullpage .prompt { max-width: 100%; }\n.prompt-text { font-size: 13.5px; color: var(--sac-text); opacity: 0.9; }\n.prompt-buttons { display: flex; gap: 8px; flex-wrap: wrap; }\n.prompt-button {\n cursor: pointer;\n border: 1px solid var(--sac-border);\n background: var(--sac-bg);\n color: var(--sac-text);\n border-radius: 999px;\n padding: 6px 16px;\n font-size: 13px;\n font-weight: 600;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n}\n.prompt-button:hover {\n background: var(--sac-primary);\n color: var(--sac-primary-text);\n border-color: var(--sac-primary);\n}\n.prompt-answered { font-size: 12.5px; opacity: 0.7; font-style: italic; }\n\n.sources {\n align-self: flex-start;\n max-width: 80%;\n margin-top: -4px;\n font-size: 12.5px;\n color: var(--sac-text);\n}\n.panel.fullpage .sources { max-width: 100%; }\n.sources details { background: transparent; }\n.sources summary {\n cursor: pointer;\n font-weight: 600;\n opacity: 0.85;\n list-style: none;\n user-select: none;\n padding: 2px 0;\n}\n.sources summary::-webkit-details-marker { display: none; }\n.sources summary::before {\n content: '▸';\n display: inline-block;\n margin-right: 6px;\n transition: transform 0.15s ease;\n}\n.sources details[open] summary::before { transform: rotate(90deg); }\n.sources ol {\n margin: 6px 0 0;\n padding-left: 0;\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.sources li {\n border-left: 2px solid var(--sac-primary);\n padding-left: 10px;\n}\n.sources .src-title {\n color: var(--sac-primary);\n text-decoration: none;\n font-weight: 600;\n word-break: break-word;\n}\n.sources a.src-title:hover { text-decoration: underline; }\n.sources span.src-title { color: var(--sac-text); opacity: 0.95; }\n.sources .src-snippet {\n display: block;\n margin-top: 2px;\n opacity: 0.7;\n line-height: 1.4;\n white-space: normal;\n}\n\n.cursor::after {\n content: '▋';\n margin-left: 1px;\n animation: sac-blink 1s steps(2, start) infinite;\n}\n@keyframes sac-blink { to { visibility: hidden; } }\n\n.composer {\n display: flex;\n gap: 8px;\n padding: 10px;\n border-top: 1px solid var(--sac-border);\n}\n.composer textarea {\n flex: 1;\n resize: none;\n border: 1px solid var(--sac-border);\n border-radius: 8px;\n padding: 8px 10px;\n font-family: inherit;\n font-size: 14px;\n background: transparent;\n color: var(--sac-text);\n max-height: 96px;\n line-height: 1.4;\n}\n.composer textarea:focus { outline: 1px solid var(--sac-primary); }\n.composer button {\n border: none;\n border-radius: 8px;\n padding: 0 14px;\n cursor: pointer;\n background: var(--sac-primary);\n color: var(--sac-primary-text);\n font-weight: 600;\n font-size: 14px;\n}\n.composer button:disabled { opacity: 0.5; cursor: default; }\n\n.hidden { display: none !important; }\n`;\n}\n","/**\n * `<smooth-agent-chat>` — a framework-light embeddable chat web component.\n *\n * Ported (and simplified) from smooai's `@smooai/ui-chat-widget`. The original is a\n * React custom element that mounts the heavyweight `@smooai/ui` ChatWidget and\n * pulls in the whole monorepo (Tailwind, shadcn, react-phone-number-input, MSW,\n * Supabase auth …). This is a clean, dependency-light rewrite that preserves the\n * embedding model — a custom element with a launcher + popover panel, declarative\n * HTML attributes, and a programmatic API — while talking to the\n * `@smooai/smooth-operator` protocol client instead of `@smooai/realtime`.\n *\n * Embedding model:\n * <smooth-agent-chat endpoint=\"ws://localhost:8787/ws\" agent-id=\"…\"></smooth-agent-chat>\n * or programmatically via {@link mountChatWidget}.\n */\nimport type { ChatWidgetConfig, ChatWidgetMode, ChatWidgetTheme } from './config.js';\nimport { resolveConfig } from './config.js';\nimport { type ChatMessage, type ChatPrompt, type Citation, type ConnectionStatus, ConversationController } from './conversation.js';\nimport { SMOOTH_LOGO_SVG } from './logo.js';\nimport { buildStyles } from './styles.js';\n\nexport const ELEMENT_TAG = 'smooth-agent-chat';\n\nconst OBSERVED = ['endpoint', 'agent-id', 'agent-name', 'placeholder', 'greeting', 'start-open', 'mode'] as const;\n\n/**\n * Return `url` only if it is a valid absolute `http(s)` URL, else `null`.\n *\n * SECURITY: citation URLs originate from indexed content (web / GitHub\n * connectors), which can be attacker-influenceable. Assigning an arbitrary\n * string to `<a>.href` allows `javascript:`/`data:`/`vbscript:` URLs that\n * execute on click — a stored-XSS vector. Only http(s) links are rendered as\n * anchors; anything else falls back to plain text.\n */\nexport function safeHttpUrl(url: string | undefined | null): string | null {\n if (!url) return null;\n try {\n const parsed = new URL(url);\n return parsed.protocol === 'http:' || parsed.protocol === 'https:' ? parsed.href : null;\n } catch {\n return null;\n }\n}\n\nexport class SmoothAgentChatElement extends HTMLElement {\n static get observedAttributes(): readonly string[] {\n return OBSERVED;\n }\n\n private readonly root: ShadowRoot;\n private controller: ConversationController | null = null;\n private overrides: Partial<ChatWidgetConfig> = {};\n private open = false;\n private messages: ChatMessage[] = [];\n private status: ConnectionStatus = 'idle';\n private mounted = false;\n\n // Cached DOM refs (populated in render()).\n private panelEl: HTMLElement | null = null;\n private launcherEl: HTMLElement | null = null;\n private messagesEl: HTMLElement | null = null;\n private statusEl: HTMLElement | null = null;\n private inputEl: HTMLTextAreaElement | null = null;\n private sendBtn: HTMLButtonElement | null = null;\n\n constructor() {\n super();\n this.root = this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback(): void {\n this.mounted = true;\n this.render();\n }\n\n disconnectedCallback(): void {\n this.mounted = false;\n this.controller?.disconnect();\n this.controller = null;\n }\n\n attributeChangedCallback(): void {\n if (this.mounted) this.render();\n }\n\n /**\n * Programmatically merge config overrides (endpoint, agentId, theme, …). Values\n * set here take precedence over HTML attributes. Re-renders the widget.\n */\n configure(config: Partial<ChatWidgetConfig>): void {\n this.overrides = { ...this.overrides, ...config };\n if (config.theme) {\n this.overrides.theme = { ...(this.overrides.theme ?? {}), ...config.theme };\n }\n if (this.mounted) this.render();\n }\n\n /** Open the chat panel. */\n openChat(): void {\n this.open = true;\n this.syncOpenState();\n void this.controller?.connect().catch(() => {});\n }\n\n /** Collapse the chat panel back to the launcher. */\n closeChat(): void {\n this.open = false;\n this.syncOpenState();\n }\n\n // ─────────────────────────── Config resolution ─────────────────────────────\n\n private readConfig(): ChatWidgetConfig | null {\n const endpoint = this.overrides.endpoint ?? this.getAttribute('endpoint') ?? '';\n const agentId = this.overrides.agentId ?? this.getAttribute('agent-id') ?? '';\n if (!endpoint || !agentId) return null;\n\n const theme: ChatWidgetTheme | undefined = this.overrides.theme;\n const modeAttr = this.getAttribute('mode');\n const mode: ChatWidgetMode = this.overrides.mode ?? (modeAttr === 'fullpage' ? 'fullpage' : modeAttr === 'popover' ? 'popover' : undefined) ?? 'popover';\n return {\n endpoint,\n mode,\n agentId,\n agentName: this.overrides.agentName ?? this.getAttribute('agent-name') ?? undefined,\n userName: this.overrides.userName,\n userEmail: this.overrides.userEmail,\n placeholder: this.overrides.placeholder ?? this.getAttribute('placeholder') ?? undefined,\n greeting: this.overrides.greeting ?? this.getAttribute('greeting') ?? undefined,\n connectionErrorMessage: this.overrides.connectionErrorMessage,\n startOpen: this.overrides.startOpen ?? this.hasAttribute('start-open'),\n theme,\n };\n }\n\n // ───────────────────────────────── Render ──────────────────────────────────\n\n private render(): void {\n const config = this.readConfig();\n if (!config) {\n this.root.innerHTML = '';\n return;\n }\n const resolved = resolveConfig(config);\n\n // (Re)create the controller only when there isn't one yet. Attribute churn\n // (e.g. theme tweaks) re-renders the view without dropping the session.\n if (!this.controller) {\n this.controller = new ConversationController(config, {\n onMessages: (messages) => {\n this.messages = messages;\n this.renderMessages(resolved.greeting);\n },\n onStatus: (status) => {\n this.status = status;\n this.renderStatus();\n this.renderComposerState();\n },\n });\n if (resolved.startOpen) this.open = true;\n }\n\n const fullpage = resolved.mode === 'fullpage';\n // Full-page mode is always \"open\" — it fills its container and has no\n // launcher to toggle.\n if (fullpage) this.open = true;\n\n const style = document.createElement('style');\n style.textContent = buildStyles(resolved.theme, resolved.mode);\n\n // Header: in full-page mode lead with the Smooth logo (falls back to the\n // agent name) + a subtle \"powered by smooth-operator\"; in popover mode the\n // compact agent-name title we've always shown. The close button only\n // exists in popover mode (full-page has nothing to collapse to).\n const headerBrand = fullpage\n ? `<div class=\"brand\">\n <span class=\"logo-wrap\">${SMOOTH_LOGO_SVG}</span>\n <div>\n <div class=\"title\">${escapeHtml(resolved.agentName)}</div>\n <div class=\"status\"></div>\n </div>\n </div>\n <div class=\"powered\">powered by smooth-operator</div>`\n : `<div class=\"brand\">\n <div>\n <div class=\"title\">${escapeHtml(resolved.agentName)}</div>\n <div class=\"status\"></div>\n </div>\n </div>\n <button class=\"close\" aria-label=\"Close chat\">×</button>`;\n\n const container = document.createElement('div');\n container.innerHTML = `\n ${fullpage ? '' : '<button class=\"launcher\" part=\"launcher\" aria-label=\"Open chat\">💬</button>'}\n <div class=\"panel${fullpage ? ' fullpage' : ' hidden'}\" part=\"panel\" role=\"${fullpage ? 'region' : 'dialog'}\" aria-label=\"${escapeHtml(resolved.agentName)} chat\">\n <div class=\"header\">\n ${headerBrand}\n </div>\n <div class=\"messages\"></div>\n <div class=\"composer\">\n <textarea rows=\"1\" placeholder=\"${escapeHtml(resolved.placeholder)}\"></textarea>\n <button class=\"send\" type=\"button\">Send</button>\n </div>\n </div>\n `;\n\n // Tag the logo <svg> so styles can size it (the inlined SVG has its own id).\n const logoSvg = container.querySelector('.logo-wrap svg');\n if (logoSvg) logoSvg.setAttribute('class', 'logo');\n\n this.root.replaceChildren(style, container);\n\n this.launcherEl = container.querySelector('.launcher');\n this.panelEl = container.querySelector('.panel');\n this.messagesEl = container.querySelector('.messages');\n this.statusEl = container.querySelector('.status');\n this.inputEl = container.querySelector('textarea');\n this.sendBtn = container.querySelector('.send');\n\n this.launcherEl?.addEventListener('click', () => this.openChat());\n container.querySelector('.close')?.addEventListener('click', () => this.closeChat());\n this.sendBtn?.addEventListener('click', () => this.submit());\n this.inputEl?.addEventListener('keydown', (ev) => {\n if (ev.key === 'Enter' && !ev.shiftKey) {\n ev.preventDefault();\n this.submit();\n }\n });\n\n // Full-page mode connects eagerly (there's no launcher click to trigger it).\n if (fullpage) void this.controller?.connect().catch(() => {});\n\n this.syncOpenState();\n this.renderMessages(resolved.greeting);\n this.renderStatus();\n this.renderComposerState();\n }\n\n private syncOpenState(): void {\n // In full-page mode the panel always fills the host; nothing to toggle.\n if (this.panelEl?.classList.contains('fullpage')) {\n this.inputEl?.focus();\n return;\n }\n this.panelEl?.classList.toggle('hidden', !this.open);\n this.launcherEl?.classList.toggle('hidden', this.open);\n if (this.open) this.inputEl?.focus();\n }\n\n private renderMessages(greeting: string): void {\n if (!this.messagesEl) return;\n this.messagesEl.replaceChildren();\n\n if (this.messages.length === 0 && greeting) {\n const g = document.createElement('div');\n g.className = 'bubble assistant greeting';\n g.textContent = greeting;\n this.messagesEl.appendChild(g);\n }\n\n for (const msg of this.messages) {\n const el = document.createElement('div');\n el.className = `bubble ${msg.role}`;\n if (msg.streaming && !msg.text) {\n el.classList.add('cursor');\n } else if (msg.streaming) {\n el.classList.add('cursor');\n el.textContent = msg.text;\n } else {\n el.textContent = msg.text;\n }\n this.messagesEl.appendChild(el);\n\n // Render chat-native button prompts (SEP ui/confirm + ui/select,\n // projected from write_confirmation_required). The click resumes the\n // paused turn via the controller.\n if (msg.prompt) {\n this.messagesEl.appendChild(this.renderPrompt(msg.prompt));\n }\n\n // Render a \"Sources (N)\" section under any assistant message whose\n // terminal eventual_response carried citations. Back-compatible: most\n // turns have none, so this is skipped.\n if (msg.role === 'assistant' && !msg.streaming && msg.citations && msg.citations.length > 0) {\n this.messagesEl.appendChild(this.renderSources(msg.citations));\n }\n }\n this.messagesEl.scrollTop = this.messagesEl.scrollHeight;\n }\n\n /**\n * Render a chat-native button prompt (SEP `ui/confirm` / `ui/select`). Each\n * option is a button; clicking one resumes the paused turn via\n * {@link ConversationController.answerPrompt}. Once answered the buttons\n * disable and the chosen label is shown, so the record stays in the\n * transcript. Built with DOM APIs (no innerHTML) — prompt text is untrusted.\n */\n private renderPrompt(prompt: ChatPrompt): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'prompt';\n wrap.setAttribute('part', 'prompt');\n\n const text = document.createElement('div');\n text.className = 'prompt-text';\n text.textContent = prompt.text;\n wrap.appendChild(text);\n\n if (prompt.answered) {\n const chosen = document.createElement('div');\n chosen.className = 'prompt-answered';\n chosen.textContent = `You chose: ${prompt.answered}`;\n wrap.appendChild(chosen);\n return wrap;\n }\n\n const buttons = document.createElement('div');\n buttons.className = 'prompt-buttons';\n for (const opt of prompt.options) {\n const btn = document.createElement('button');\n btn.className = 'prompt-button';\n btn.type = 'button';\n btn.textContent = opt.label;\n btn.addEventListener('click', () => {\n this.controller?.answerPrompt(prompt.requestId, opt.value);\n });\n buttons.appendChild(btn);\n }\n wrap.appendChild(buttons);\n return wrap;\n }\n\n /**\n * Build the collapsible \"Sources (N)\" block for an assistant message's\n * citations. Each source renders its `title` (linked to `citation.url` when\n * present — `target=_blank rel=noopener` — plain text otherwise) plus the\n * grounding `snippet`. Built with DOM APIs (not innerHTML) so citation text\n * can't inject markup.\n */\n private renderSources(citations: Citation[]): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'sources';\n wrap.setAttribute('part', 'sources');\n\n const details = document.createElement('details');\n details.open = true;\n\n const summary = document.createElement('summary');\n summary.textContent = `Sources (${citations.length})`;\n details.appendChild(summary);\n\n const list = document.createElement('ol');\n for (const c of citations) {\n const li = document.createElement('li');\n\n let titleEl: HTMLElement;\n // SECURITY: only absolute http(s) URLs may become a link href. A\n // citation URL comes from indexed content (web/GitHub connectors), so\n // an attacker-influenceable doc could carry `javascript:`/`data:`/\n // `vbscript:` — assigning those to `a.href` is a one-click XSS. Anything\n // that isn't a valid absolute http(s) URL renders as plain text.\n const safeUrl = safeHttpUrl(c.url);\n if (safeUrl) {\n const a = document.createElement('a');\n a.className = 'src-title';\n a.href = safeUrl;\n a.target = '_blank';\n a.rel = 'noopener noreferrer';\n titleEl = a;\n } else {\n titleEl = document.createElement('span');\n titleEl.className = 'src-title';\n }\n titleEl.textContent = c.title || c.id || 'Source';\n li.appendChild(titleEl);\n\n if (c.snippet) {\n const snip = document.createElement('span');\n snip.className = 'src-snippet';\n snip.textContent = c.snippet;\n li.appendChild(snip);\n }\n list.appendChild(li);\n }\n details.appendChild(list);\n wrap.appendChild(details);\n return wrap;\n }\n\n private renderStatus(): void {\n if (!this.statusEl) return;\n const label: Record<ConnectionStatus, string> = {\n idle: '',\n connecting: 'Connecting…',\n ready: 'Online',\n error: 'Connection issue',\n closed: 'Disconnected',\n };\n this.statusEl.textContent = label[this.status];\n }\n\n private renderComposerState(): void {\n const busy = this.status === 'connecting';\n if (this.sendBtn) this.sendBtn.disabled = busy;\n if (this.inputEl) this.inputEl.disabled = busy;\n }\n\n private submit(): void {\n if (!this.inputEl || !this.controller) return;\n const text = this.inputEl.value;\n if (!text.trim()) return;\n this.inputEl.value = '';\n void this.controller.send(text);\n }\n}\n\nfunction escapeHtml(value: string): string {\n return value.replace(/[&<>\"']/g, (c) => {\n switch (c) {\n case '&':\n return '&';\n case '<':\n return '<';\n case '>':\n return '>';\n case '\"':\n return '"';\n default:\n return ''';\n }\n });\n}\n\n/** Register the custom element once. Safe to call multiple times. */\nexport function defineChatWidget(): void {\n if (typeof customElements !== 'undefined' && !customElements.get(ELEMENT_TAG)) {\n customElements.define(ELEMENT_TAG, SmoothAgentChatElement);\n }\n}\n\n/**\n * Programmatically create, configure, and append a widget to the page.\n * Returns the element so the host can drive `openChat()` / `closeChat()`.\n */\nexport function mountChatWidget(config: ChatWidgetConfig, target: HTMLElement = document.body): SmoothAgentChatElement {\n defineChatWidget();\n const el = document.createElement(ELEMENT_TAG) as SmoothAgentChatElement;\n el.configure(config);\n target.appendChild(el);\n return el;\n}\n\n/**\n * Ergonomic helper for the full-page layout: mounts a `<smooth-agent-chat>` in\n * `mode: \"fullpage\"` (no launcher — the chat fills its container/viewport with a\n * Smooth-branded header, a scrollable message list, and an input bar) and\n * returns the element.\n *\n * `target` defaults to `document.body`; pass a sized container to embed the\n * full-page chat inside a layout region (e.g. a `/chat` route shell or an\n * iframe). The `mode` is forced to `\"fullpage\"` regardless of the passed config.\n *\n * ```ts\n * mountFullPageChat({ endpoint: 'wss://…/ws', agentId: '…', agentName: 'Support' });\n * ```\n */\nexport function mountFullPageChat(config: Omit<ChatWidgetConfig, 'mode'>, target: HTMLElement = document.body): SmoothAgentChatElement {\n return mountChatWidget({ ...config, mode: 'fullpage' }, target);\n}\n","/**\n * Standalone IIFE entry. Bundled (with the protocol client inlined) into\n * `dist/chat-widget.global.js` for a plain `<script src=\"…\">` embed.\n *\n * On load it:\n * - registers the `<smooth-agent-chat>` custom element, and\n * - exposes the programmatic API on the IIFE global `SmoothAgentChat`\n * (`window.SmoothAgentChat.mount({ endpoint, agentId })`).\n *\n * A host page can then either drop the element in markup:\n * <smooth-agent-chat endpoint=\"wss://…/ws\" agent-id=\"…\"></smooth-agent-chat>\n * or mount it programmatically:\n * SmoothAgentChat.mount({ endpoint: 'wss://…/ws', agentId: '…' });\n */\nimport type { ChatWidgetConfig } from './config.js';\nimport { defineChatWidget, mountChatWidget, mountFullPageChat, SmoothAgentChatElement } from './element.js';\n\ndefineChatWidget();\n\nexport { defineChatWidget, mountChatWidget, mountFullPageChat, SmoothAgentChatElement };\n\n/** Convenience alias matching the global API surface (`SmoothAgentChat.mount`). */\nexport function mount(config: ChatWidgetConfig, target?: HTMLElement): SmoothAgentChatElement {\n return mountChatWidget(config, target);\n}\n\n/**\n * Full-page convenience alias (`SmoothAgentChat.mountFullPage`): mounts the chat\n * in `mode: \"fullpage\"` so it fills its container/viewport with no launcher.\n */\nexport function mountFullPage(config: Omit<ChatWidgetConfig, 'mode'>, target?: HTMLElement): SmoothAgentChatElement {\n return mountFullPageChat(config, target);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chat-widget.iife.js","names":[],"sources":["../../src/widget/config.ts","../../src/transport.ts","../../src/types.ts","../../src/client.ts","../../src/widget/conversation.ts","../../src/widget/logo.ts","../../src/widget/styles.ts","../../src/widget/element.ts","../../src/widget/standalone.ts"],"sourcesContent":["/**\n * Public configuration surface for the chat widget.\n *\n * A host page configures the widget either declaratively (HTML attributes on the\n * `<smooth-agent-chat>` element) or programmatically (passing this object to\n * {@link mountChatWidget} / `element.configure(...)`).\n */\nexport interface ChatWidgetTheme {\n /** Foreground text color for the widget chrome. */\n text?: string;\n /** Panel background color. */\n background?: string;\n /** Primary accent (launcher button, send button, outbound bubble). */\n primary?: string;\n /** Text color rendered on top of `primary`. */\n primaryText?: string;\n /** Inbound (assistant) chat bubble background. */\n assistantBubble?: string;\n /** Inbound (assistant) chat bubble text color. */\n assistantBubbleText?: string;\n /** Outbound (user) chat bubble background. Defaults to `primary`. */\n userBubble?: string;\n /** Outbound (user) chat bubble text color. Defaults to `primaryText`. */\n userBubbleText?: string;\n /** Border color for the panel and input. */\n border?: string;\n}\n\n/**\n * Layout mode for the widget.\n *\n * - `\"popover\"` (default) — the embeddable launcher bubble + floating panel.\n * - `\"fullpage\"` — no launcher; the chat fills its container/viewport with a\n * branded header, a scrollable message list, and an input bar. Ideal for a\n * dedicated support page (`/chat`, a docs site sidebar, an iframe, …).\n */\nexport type ChatWidgetMode = 'popover' | 'fullpage';\n\nexport interface ChatWidgetConfig {\n /**\n * smooth-operator WebSocket endpoint, e.g.\n * `ws://localhost:8787/ws` (local dev) or your deployed `wss://…/ws` URL.\n */\n endpoint: string;\n /**\n * Layout mode — `\"popover\"` (default, launcher + floating panel) or\n * `\"fullpage\"` (chat fills its container; no launcher). See {@link ChatWidgetMode}.\n */\n mode?: ChatWidgetMode;\n /** UUID of the agent to start a conversation session with. */\n agentId: string;\n /** Display name for the agent (header label). Defaults to \"Assistant\". */\n agentName?: string;\n /** Optional display name for the user participant. */\n userName?: string;\n /** Optional email address for the user participant. */\n userEmail?: string;\n /** Placeholder text for the message input. */\n placeholder?: string;\n /** Greeting rendered when the conversation opens (before any messages). */\n greeting?: string;\n /** Message shown when the connection cannot be (re)established. */\n connectionErrorMessage?: string;\n /** Start the panel open instead of collapsed to the launcher. */\n startOpen?: boolean;\n /** Theme overrides. */\n theme?: ChatWidgetTheme;\n}\n\n/** Resolve a partial config against the built-in defaults. */\nexport function resolveConfig(config: ChatWidgetConfig): Required<Omit<ChatWidgetConfig, 'theme' | 'userName' | 'userEmail'>> & {\n theme: Required<ChatWidgetTheme>;\n userName?: string;\n userEmail?: string;\n} {\n const theme = config.theme ?? {};\n const primary = theme.primary ?? '#00a6a6';\n const primaryText = theme.primaryText ?? '#f8fafc';\n return {\n endpoint: config.endpoint,\n mode: config.mode ?? 'popover',\n agentId: config.agentId,\n agentName: config.agentName ?? 'Assistant',\n userName: config.userName,\n userEmail: config.userEmail,\n placeholder: config.placeholder ?? 'Type a message…',\n greeting: config.greeting ?? 'Hi! How can I help you today?',\n connectionErrorMessage: config.connectionErrorMessage ?? \"We couldn't reach the chat. Please try again in a moment.\",\n startOpen: config.startOpen ?? false,\n theme: {\n text: theme.text ?? '#f8fafc',\n background: theme.background ?? '#040d30',\n primary,\n primaryText,\n assistantBubble: theme.assistantBubble ?? '#06134b',\n assistantBubbleText: theme.assistantBubbleText ?? '#f8fafc',\n userBubble: theme.userBubble ?? primary,\n userBubbleText: theme.userBubbleText ?? primaryText,\n border: theme.border ?? '#0a1f7a',\n },\n };\n}\n","/**\n * Transport abstraction for the client.\n *\n * The client is deliberately decoupled from any concrete WebSocket implementation\n * so it can be unit-tested with a mock and run on Node, the browser, or a custom\n * socket. A transport is anything that can send a string frame and surface\n * incoming string frames + lifecycle events.\n */\n\nexport type TransportState = 'connecting' | 'open' | 'closing' | 'closed';\n\n/** Minimal injectable transport contract. Mirrors the browser `WebSocket` subset. */\nexport interface Transport {\n readonly state: TransportState;\n /** Send a serialized frame. Throws / rejects if the transport is not open. */\n send(data: string): void;\n /** Open the connection. Resolves once the transport reaches `open`. */\n connect(): Promise<void>;\n /** Close the connection. */\n close(code?: number, reason?: string): void;\n /** Register a handler for incoming string frames. Returns an unsubscribe fn. */\n onMessage(handler: (data: string) => void): () => void;\n /** Register a handler for transport close. Returns an unsubscribe fn. */\n onClose(handler: (info: { code?: number; reason?: string }) => void): () => void;\n /** Register a handler for transport-level errors. Returns an unsubscribe fn. */\n onError(handler: (err: unknown) => void): () => void;\n}\n\n/** The subset of the standard `WebSocket` interface the default transport needs. */\nexport interface WebSocketLike {\n readonly readyState: number;\n send(data: string): void;\n close(code?: number, reason?: string): void;\n addEventListener(type: 'open', listener: () => void): void;\n addEventListener(type: 'close', listener: (ev: { code?: number; reason?: string }) => void): void;\n addEventListener(type: 'error', listener: (ev: unknown) => void): void;\n addEventListener(type: 'message', listener: (ev: { data: unknown }) => void): void;\n}\n\nexport type WebSocketFactory = (url: string) => WebSocketLike;\n\nconst WS_CONNECTING = 0;\nconst WS_OPEN = 1;\nconst WS_CLOSING = 2;\n\n/** Default connect timeout (ms) for the WebSocket transport. */\nconst DEFAULT_CONNECT_TIMEOUT = 30_000;\n\n/**\n * Default transport backed by a `WebSocket`-like object. By default it uses the\n * global `WebSocket`; pass a `factory` to inject one (e.g. the `ws` package on\n * Node, or a mock in tests).\n */\nexport class WebSocketTransport implements Transport {\n private socket: WebSocketLike | null = null;\n private readonly url: string;\n private readonly factory: WebSocketFactory;\n private readonly connectTimeout: number;\n private readonly messageHandlers = new Set<(data: string) => void>();\n private readonly closeHandlers = new Set<(info: { code?: number; reason?: string }) => void>();\n private readonly errorHandlers = new Set<(err: unknown) => void>();\n\n constructor(url: string, factory?: WebSocketFactory, connectTimeout = DEFAULT_CONNECT_TIMEOUT) {\n this.url = url;\n this.connectTimeout = connectTimeout;\n if (factory) {\n this.factory = factory;\n } else {\n const G = globalThis as { WebSocket?: new (url: string) => WebSocketLike };\n if (!G.WebSocket) {\n throw new Error('No global WebSocket available; pass a WebSocketFactory to WebSocketTransport.');\n }\n const Ctor = G.WebSocket;\n this.factory = (u) => new Ctor(u);\n }\n }\n\n get state(): TransportState {\n if (!this.socket) return 'closed';\n switch (this.socket.readyState) {\n case WS_CONNECTING:\n return 'connecting';\n case WS_OPEN:\n return 'open';\n case WS_CLOSING:\n return 'closing';\n default:\n return 'closed';\n }\n }\n\n connect(): Promise<void> {\n if (this.socket && this.socket.readyState === WS_OPEN) return Promise.resolve();\n\n // A prior socket that never reached OPEN (failed/half-open dial, or a closed\n // socket from a previous attempt) would otherwise be orphaned: its listeners\n // stay registered and keep dispatching into the shared handler sets, so a late\n // message/close from the dead socket double-fires. Close it and detach it\n // before dialing a fresh one. (WebSocketLike has no removeEventListener, so we\n // also guard every handler below with an identity check on `this.socket`.)\n if (this.socket && this.socket.readyState !== WS_OPEN) {\n const stale = this.socket;\n this.socket = null;\n try {\n stale.close();\n } catch {\n // ignore — best-effort teardown of a half-open socket\n }\n }\n\n return new Promise<void>((resolve, reject) => {\n const socket = this.factory(this.url);\n this.socket = socket;\n\n let settled = false;\n const timer =\n this.connectTimeout > 0\n ? setTimeout(() => {\n if (settled) return;\n settled = true;\n // Tear down the half-open socket so it can't leak / fire later.\n if (this.socket === socket) this.socket = null;\n try {\n socket.close();\n } catch {\n // ignore\n }\n reject(new Error(`WebSocket connect to ${this.url} timed out after ${this.connectTimeout}ms`));\n }, this.connectTimeout)\n : undefined;\n\n socket.addEventListener('open', () => {\n // Ignore events from a socket we've already replaced/abandoned.\n if (this.socket !== socket) return;\n if (settled) return;\n settled = true;\n if (timer) clearTimeout(timer);\n resolve();\n });\n socket.addEventListener('error', (ev: unknown) => {\n if (this.socket !== socket) return;\n for (const h of this.errorHandlers) h(ev);\n if (!settled && this.state !== 'open') {\n settled = true;\n if (timer) clearTimeout(timer);\n if (this.socket === socket) this.socket = null;\n // Release the failed socket so it can't linger / fire later.\n try {\n socket.close();\n } catch {\n // ignore\n }\n reject(ev instanceof Error ? ev : new Error('WebSocket connection error'));\n }\n });\n socket.addEventListener('close', (ev: { code?: number; reason?: string }) => {\n if (this.socket !== socket) return;\n if (timer) clearTimeout(timer);\n for (const h of this.closeHandlers) h({ code: ev.code, reason: ev.reason });\n });\n socket.addEventListener('message', (ev: { data: unknown }) => {\n if (this.socket !== socket) return;\n const data = typeof ev.data === 'string' ? ev.data : String(ev.data);\n for (const h of this.messageHandlers) h(data);\n });\n });\n }\n\n send(data: string): void {\n if (!this.socket || this.socket.readyState !== WS_OPEN) {\n throw new Error(`Cannot send: transport is \"${this.state}\"`);\n }\n this.socket.send(data);\n }\n\n close(code?: number, reason?: string): void {\n this.socket?.close(code, reason);\n }\n\n onMessage(handler: (data: string) => void): () => void {\n this.messageHandlers.add(handler);\n return () => this.messageHandlers.delete(handler);\n }\n\n onClose(handler: (info: { code?: number; reason?: string }) => void): () => void {\n this.closeHandlers.add(handler);\n return () => this.closeHandlers.delete(handler);\n }\n\n onError(handler: (err: unknown) => void): () => void {\n this.errorHandlers.add(handler);\n return () => this.errorHandlers.delete(handler);\n }\n}\n","/**\n * Ergonomic, hand-curated types layered on top of the generated ones.\n *\n * The generated types in `./generated/types.ts` are a faithful 1:1 reflection of\n * the JSON Schemas — one interface per schema/`$def`. They are correct but flat:\n * there is no single discriminated union over the wire frames, and the generated\n * `Error` interface collides with the global `Error`.\n *\n * This module fixes both: it re-exports the generated types under stable names and\n * builds the two discriminated unions consumers actually want —\n * `ClientAction` (everything sent client→server, discriminated by `action`) and\n * `ServerEvent` (everything received server→client, discriminated by `type`).\n */\nimport type {\n ConfirmToolActionRequest,\n CreateConversationSessionRequest,\n CreateConversationSessionResponse,\n Error as GeneratedErrorEvent,\n EventualResponse,\n GetMessagesRequest,\n GetMessagesResponse,\n GetSessionRequest,\n GetSessionResponse,\n ImmediateResponse,\n InteractionInvalid,\n InteractionRequired,\n Keepalive,\n OtpInvalid,\n OtpSent,\n OtpVerificationRequired,\n OtpVerified,\n PingRequest,\n Pong,\n SendMessageRequest,\n SendMessageResponse,\n StreamChunk,\n StreamToken,\n SubmitInteractionRequest,\n VerifyOtpRequest,\n WriteConfirmationRequired,\n} from './generated/types.js';\n\nexport * from './generated/types.js';\n\n/**\n * The generated `error` event interface is named `Error`, which shadows the\n * global `Error`. Re-export it under an unambiguous name.\n */\nexport type { GeneratedErrorEvent as ErrorEvent };\n\n// ───────────────────────────── Discriminators ──────────────────────────────\n\n/** Every client→server `action` discriminator value. */\nexport const ACTION_TYPES = [\n 'create_conversation_session',\n 'send_message',\n 'get_session',\n 'get_conversation_messages',\n 'confirm_tool_action',\n 'verify_otp',\n 'submit_interaction',\n 'ping',\n] as const;\nexport type ActionType = (typeof ACTION_TYPES)[number];\n\n/** Every server→client `type` discriminator value. */\nexport const EVENT_TYPES = [\n 'immediate_response',\n 'eventual_response',\n 'stream_chunk',\n 'stream_token',\n 'keepalive',\n 'write_confirmation_required',\n 'otp_verification_required',\n 'otp_sent',\n 'otp_verified',\n 'otp_invalid',\n 'interaction_required',\n 'interaction_invalid',\n 'error',\n 'pong',\n] as const;\nexport type EventType = (typeof EVENT_TYPES)[number];\n\n// ───────────────────────────── Client actions ──────────────────────────────\n\n/**\n * Discriminated union over every client→server action frame, keyed on `action`.\n * Narrow with `action.action === 'send_message'` to get the concrete request type.\n */\nexport type ClientAction =\n | CreateConversationSessionRequest\n | SendMessageRequest\n | GetSessionRequest\n | GetMessagesRequest\n | ConfirmToolActionRequest\n | VerifyOtpRequest\n | SubmitInteractionRequest\n | PingRequest;\n\n// ───────────────────────────── Server events ───────────────────────────────\n\n/**\n * Discriminated union over every server→client event frame, keyed on `type`.\n * Narrow with `event.type === 'stream_token'` to get the concrete event type.\n */\nexport type ServerEvent =\n | ImmediateResponse\n | EventualResponse\n | StreamChunk\n | StreamToken\n | Keepalive\n | WriteConfirmationRequired\n | OtpVerificationRequired\n | OtpSent\n | OtpVerified\n | OtpInvalid\n | InteractionRequired\n | InteractionInvalid\n | GeneratedErrorEvent\n | Pong;\n\n// ─────────────────────── Per-type narrowed convenience ──────────────────────\n\n/** Map from event `type` → the concrete generated event interface. */\nexport interface ServerEventByType {\n immediate_response: ImmediateResponse;\n eventual_response: EventualResponse;\n stream_chunk: StreamChunk;\n stream_token: StreamToken;\n keepalive: Keepalive;\n write_confirmation_required: WriteConfirmationRequired;\n otp_verification_required: OtpVerificationRequired;\n otp_sent: OtpSent;\n otp_verified: OtpVerified;\n otp_invalid: OtpInvalid;\n interaction_required: InteractionRequired;\n interaction_invalid: InteractionInvalid;\n error: GeneratedErrorEvent;\n pong: Pong;\n}\n\n/** Map from action `action` → the concrete generated request interface. */\nexport interface ClientActionByType {\n create_conversation_session: CreateConversationSessionRequest;\n send_message: SendMessageRequest;\n get_session: GetSessionRequest;\n get_conversation_messages: GetMessagesRequest;\n confirm_tool_action: ConfirmToolActionRequest;\n verify_otp: VerifyOtpRequest;\n submit_interaction: SubmitInteractionRequest;\n ping: PingRequest;\n}\n\n// ───────────────────────────── Type guards ─────────────────────────────────\n\n/** True if `frame` is a server event of the given `type`, narrowing accordingly. */\nexport function isEvent<T extends EventType>(frame: unknown, type: T): frame is ServerEventByType[T] {\n return isServerEvent(frame) && frame.type === type;\n}\n\n/** True if `frame` looks like any server event (has a known `type` discriminator). */\nexport function isServerEvent(frame: unknown): frame is ServerEvent {\n return (\n typeof frame === 'object' &&\n frame !== null &&\n 'type' in frame &&\n typeof (frame as { type: unknown }).type === 'string' &&\n (EVENT_TYPES as readonly string[]).includes((frame as { type: string }).type)\n );\n}\n\n/** True if `frame` looks like any client action (has a known `action` discriminator). */\nexport function isClientAction(frame: unknown): frame is ClientAction {\n return (\n typeof frame === 'object' &&\n frame !== null &&\n 'action' in frame &&\n typeof (frame as { action: unknown }).action === 'string' &&\n (ACTION_TYPES as readonly string[]).includes((frame as { action: string }).action)\n );\n}\n\n// ──────────────────────── Decoded response payloads ────────────────────────\n\n/**\n * The typed `data` payload returned in the `immediate_response` for each\n * non-streaming action. These are the generated `*Response` shapes, surfaced so\n * the client's typed methods can return them directly.\n */\nexport type {\n CreateConversationSessionResponse,\n GetSessionResponse,\n GetMessagesResponse,\n SendMessageResponse,\n};\n","/**\n * SmoothAgentClient — a minimal, idiomatic, transport-agnostic client for the\n * smooth-operator WebSocket protocol.\n *\n * Design goals\n * ------------\n * - **Transport-agnostic.** The client never touches a real socket directly; it\n * talks to an injectable {@link Transport}. The default ({@link WebSocketTransport})\n * uses the global `WebSocket`, but tests inject a mock and Node can inject `ws`.\n * - **Request/response correlation by `requestId`.** Every action gets a generated\n * `requestId`; the client routes incoming events back to the originating call.\n * - **Streaming as an async iterator.** `sendMessage` returns a {@link MessageTurn}\n * that is both awaitable (resolves with the terminal `eventual_response`) and\n * async-iterable (yields each `stream_token` / `stream_chunk` / HITL event in\n * order). This models the `stream_token`/`stream_chunk` → `eventual_response`\n * flow without forcing a callback style on the caller.\n * - **No live server required.** Correctness is fully unit-testable with a mock\n * transport (see `test/client.test.ts`).\n */\nimport {\n WebSocketTransport,\n type Transport,\n type WebSocketFactory,\n} from './transport.js';\nimport type {\n ClientAction,\n CreateConversationSessionRequest,\n CreateConversationSessionResponse,\n EventualResponse,\n GetMessagesRequest,\n GetMessagesResponse,\n GetSessionRequest,\n GetSessionResponse,\n SendMessageRequest,\n ServerEvent,\n} from './types.js';\nimport { isServerEvent } from './types.js';\n\nexport interface SmoothAgentClientOptions {\n /** WebSocket URL, e.g. `wss://realtime.prod.smooth-agent.dev`. */\n url: string;\n /**\n * Optional connection auth token for token-gated servers (e.g. the local-flavor\n * server). When set, the token is appended to the connection URL as a `?token=`\n * query parameter — browsers can't set custom headers on a WebSocket handshake,\n * so the token rides the query string, which is where the server reads it from.\n * Any existing query string on `url` is preserved. This applies to the default\n * transport only; if a custom {@link transport} is injected, supply the token to\n * that transport yourself.\n */\n token?: string;\n /** Inject a transport (for tests / non-browser runtimes). Defaults to a WebSocket transport. */\n transport?: Transport;\n /** Inject a WebSocket factory used by the default transport (e.g. the `ws` package on Node). */\n webSocketFactory?: WebSocketFactory;\n /** Generate request IDs. Defaults to `crypto.randomUUID()` with a `req-` prefix. */\n generateRequestId?: () => string;\n /** Per-request timeout in ms for non-streaming actions. Default 30000. */\n requestTimeout?: number;\n /**\n * Overall timeout in ms for a streaming `sendMessage` turn: if the server accepts\n * the message but never emits a terminal `eventual_response` / `error`, the turn\n * rejects with a {@link TurnTimeoutError} instead of hanging forever. Default\n * 120000. Set to 0 (or a negative number) to disable.\n */\n turnTimeout?: number;\n}\n\n/** One row returned by {@link SmoothAgentClient.listConversations} — enough to\n * render a sidebar entry and resume the conversation on click. */\nexport interface ConversationSummary {\n /** Pass to {@link SmoothAgentClient.createConversationSession} as `conversationId` to resume. */\n conversationId: string;\n /** Short preview title derived from the first message (may be empty). */\n title: string;\n /** ISO-8601 last-activity timestamp (rows come most-recent first). */\n updatedAt: string;\n /** Number of messages in the conversation. */\n messageCount: number;\n}\n\n/** Payload of the `list_conversations` `immediate_response`. */\nexport interface ListConversationsResponse {\n conversations: ConversationSummary[];\n}\n\n/** Events that terminate a streaming turn (success or error). */\nconst TURN_TERMINAL = new Set(['eventual_response', 'error']);\n\n/** A timeout that yields no terminal event. */\nclass RequestTimeoutError extends Error {\n constructor(requestId: string, ms: number) {\n super(`Request ${requestId} timed out after ${ms}ms`);\n this.name = 'RequestTimeoutError';\n }\n}\n\n/**\n * A streaming turn that received no terminal `eventual_response` / `error` within the\n * configured {@link SmoothAgentClientOptions.turnTimeout}. The turn rejects with this\n * and its async iteration throws it, so a stuck server can never hang the caller.\n */\nexport class TurnTimeoutError extends Error {\n readonly requestId: string;\n constructor(requestId: string, ms: number) {\n super(`Turn ${requestId} timed out after ${ms}ms without a terminal response`);\n this.name = 'TurnTimeoutError';\n this.requestId = requestId;\n }\n}\n\n/** A protocol-level error event surfaced as a throwable. */\nexport class ProtocolError extends Error {\n readonly code: string;\n readonly requestId?: string;\n constructor(code: string, message: string, requestId?: string) {\n super(message);\n this.name = 'ProtocolError';\n this.code = code;\n this.requestId = requestId;\n }\n}\n\n/** Internal record for an in-flight single-response request. */\ninterface PendingRequest {\n resolve: (event: ServerEvent) => void;\n reject: (err: unknown) => void;\n timer: ReturnType<typeof setTimeout> | undefined;\n}\n\n/**\n * A streaming message turn. Await it for the terminal {@link EventualResponse},\n * or async-iterate it to receive every intermediate event in arrival order.\n *\n * ```ts\n * const turn = client.sendMessage({ sessionId, message: 'hi' });\n * for await (const ev of turn) {\n * if (ev.type === 'stream_token') process.stdout.write(ev.token ?? '');\n * }\n * const final = await turn; // EventualResponse\n * ```\n */\nexport class MessageTurn implements AsyncIterable<ServerEvent>, PromiseLike<EventualResponse> {\n /** The requestId this turn is correlated on. */\n readonly requestId: string;\n\n private readonly queue: ServerEvent[] = [];\n private waiter: {\n resolve: (result: IteratorResult<ServerEvent>) => void;\n reject: (err: unknown) => void;\n } | null = null;\n private done = false;\n private finalEvent: EventualResponse | null = null;\n private error: unknown = null;\n private readonly settled: Promise<EventualResponse>;\n private settle!: (value: EventualResponse) => void;\n private fail!: (err: unknown) => void;\n private readonly onClose: () => void;\n private timeoutTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(requestId: string, onClose: () => void, turnTimeout = 0) {\n this.requestId = requestId;\n this.onClose = onClose;\n this.settled = new Promise<EventualResponse>((resolve, reject) => {\n this.settle = resolve;\n this.fail = reject;\n });\n // Avoid unhandled-rejection noise if the caller only iterates and never awaits.\n this.settled.catch(() => {});\n // Bound the turn: a server that accepts the message but never emits a terminal\n // event must not hang the caller forever.\n if (turnTimeout > 0) {\n this.timeoutTimer = setTimeout(() => {\n this.finish(null, new TurnTimeoutError(this.requestId, turnTimeout));\n }, turnTimeout);\n }\n }\n\n /** Feed an event into the turn (called by the client's dispatcher). */\n push(event: ServerEvent): void {\n if (this.done) return;\n\n if (event.type === 'error') {\n const code = event.data?.error?.code ?? 'INTERNAL_ERROR';\n const message = event.data?.error?.message ?? 'Unknown protocol error';\n this.deliver(event);\n this.finish(null, new ProtocolError(code, message, this.requestId));\n return;\n }\n\n this.deliver(event);\n\n if (event.type === 'eventual_response') {\n this.finish(event, null);\n }\n }\n\n /** Force-close the turn (e.g. on disconnect) with an error. */\n abort(err: unknown): void {\n if (this.done) return;\n this.finish(null, err);\n }\n\n private deliver(event: ServerEvent): void {\n if (this.waiter) {\n const w = this.waiter;\n this.waiter = null;\n w.resolve({ value: event, done: false });\n } else {\n this.queue.push(event);\n }\n }\n\n private finish(final: EventualResponse | null, err: unknown): void {\n if (this.done) return;\n this.done = true;\n this.finalEvent = final;\n this.error = err;\n if (this.timeoutTimer) {\n clearTimeout(this.timeoutTimer);\n this.timeoutTimer = undefined;\n }\n this.onClose();\n\n if (err) this.fail(err);\n else if (final) this.settle(final);\n\n // Release any pending iterator waiter now that the stream has ended. On error\n // the parked next() must *reject* (mirroring the queued-error path in next())\n // so a pure `for await` consumer sees the terminal error thrown instead of a\n // silent, indistinguishable `{ done: true }`.\n if (this.waiter) {\n const w = this.waiter;\n this.waiter = null;\n if (err) {\n w.reject(err);\n } else {\n w.resolve({ value: undefined as never, done: true });\n }\n }\n }\n\n [Symbol.asyncIterator](): AsyncIterator<ServerEvent> {\n return {\n next: (): Promise<IteratorResult<ServerEvent>> => {\n if (this.queue.length > 0) {\n return Promise.resolve({ value: this.queue.shift()!, done: false });\n }\n if (this.done) {\n if (this.error) return Promise.reject(this.error);\n return Promise.resolve({ value: undefined as never, done: true });\n }\n return new Promise<IteratorResult<ServerEvent>>((resolve, reject) => {\n this.waiter = { resolve, reject };\n });\n },\n };\n }\n\n // PromiseLike — `await turn` resolves with the EventualResponse.\n then<TResult1 = EventualResponse, TResult2 = never>(\n onfulfilled?: ((value: EventualResponse) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.settled.then(onfulfilled, onrejected);\n }\n}\n\nexport class SmoothAgentClient {\n private readonly transport: Transport;\n private readonly generateRequestId: () => string;\n private readonly requestTimeout: number;\n private readonly turnTimeout: number;\n\n /** requestId → single-response waiter (create_session, get_session, ping, …). */\n private readonly pending = new Map<string, PendingRequest>();\n /** requestId → active streaming turn (send_message, and HITL resumes). */\n private readonly turns = new Map<string, MessageTurn>();\n /** Unsolicited-event listeners (keepalive, server-push). */\n private readonly listeners = new Set<(event: ServerEvent) => void>();\n\n private unsubscribe: Array<() => void> = [];\n\n constructor(options: SmoothAgentClientOptions) {\n this.transport =\n options.transport ??\n new WebSocketTransport(withConnectionToken(options.url, options.token), options.webSocketFactory);\n this.requestTimeout = options.requestTimeout ?? 30_000;\n this.turnTimeout = options.turnTimeout ?? 120_000;\n this.generateRequestId =\n options.generateRequestId ??\n (() => `req-${(globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2))}`);\n\n this.unsubscribe.push(this.transport.onMessage((data) => this.handleFrame(data)));\n this.unsubscribe.push(\n this.transport.onClose(() => this.failAll(new Error('Transport closed'))),\n );\n }\n\n /** Open the underlying transport. */\n async connect(): Promise<void> {\n await this.transport.connect();\n }\n\n /** Close the transport and reject all in-flight work. */\n disconnect(reason = 'client disconnect'): void {\n this.failAll(new Error(reason));\n for (const u of this.unsubscribe) u();\n this.unsubscribe = [];\n this.transport.close(1000, reason);\n }\n\n /** Subscribe to unsolicited / uncorrelated server events (e.g. keepalive). */\n onEvent(listener: (event: ServerEvent) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n // ───────────────────────────── Actions ─────────────────────────────────\n\n /**\n * Start a new conversation session — or **resume** an existing one by passing\n * its `conversationId`. On resume the server binds the new session to that\n * conversation (reusing its id + org + persisted history) so subsequent\n * `send_message`s append to it; pair it with {@link getMessages} to load the\n * transcript. Resolves with the session descriptor.\n */\n async createConversationSession(\n req: Omit<CreateConversationSessionRequest, 'action' | 'requestId'> & { conversationId?: string },\n ): Promise<CreateConversationSessionResponse> {\n const event = await this.request({ action: 'create_conversation_session', ...req });\n return extractImmediateData<CreateConversationSessionResponse>(event);\n }\n\n /**\n * List the org's conversations that have at least one message, most-recent\n * first — the substrate for a conversation sidebar / resume picker. Each row\n * carries a short title preview, `updatedAt`, and a message count. Pass\n * `limit` to cap the result (server default 50).\n *\n * `list_conversations` has no dedicated action schema in `spec/` yet, so it is\n * not a member of the generated `ClientAction` union — hence the local cast.\n * ponytail: promote to a real spec/actions schema if a second consumer needs\n * it typed end-to-end.\n */\n async listConversations(req: { limit?: number } = {}): Promise<ListConversationsResponse> {\n const event = await this.request({ action: 'list_conversations', ...req } as unknown as Omit<ClientAction, 'requestId'>);\n return extractImmediateData<ListConversationsResponse>(event);\n }\n\n /** Fetch a session snapshot by ID. */\n async getSession(req: Omit<GetSessionRequest, 'action' | 'requestId'>): Promise<GetSessionResponse> {\n const event = await this.request({ action: 'get_session', ...req });\n return extractImmediateData<GetSessionResponse>(event);\n }\n\n /** Fetch a page of conversation messages. */\n async getMessages(req: Omit<GetMessagesRequest, 'action' | 'requestId'>): Promise<GetMessagesResponse> {\n const event = await this.request({ action: 'get_conversation_messages', ...req });\n return extractImmediateData<GetMessagesResponse>(event);\n }\n\n /** Keepalive ping. Resolves with the server timestamp from the `pong` event. */\n async ping(): Promise<number> {\n const event = await this.request({ action: 'ping' });\n if (event.type === 'pong') return event.timestamp ?? event.data?.timestamp ?? Date.now();\n return Date.now();\n }\n\n /**\n * Submit a user message and return a {@link MessageTurn}: await it for the\n * terminal `eventual_response`, or async-iterate it for the streaming events.\n */\n sendMessage(req: Omit<SendMessageRequest, 'action' | 'requestId'>): MessageTurn {\n const requestId = this.generateRequestId();\n const turn = new MessageTurn(requestId, () => this.turns.delete(requestId), this.turnTimeout);\n this.turns.set(requestId, turn);\n try {\n this.transport.send(JSON.stringify({ action: 'send_message', requestId, ...req }));\n } catch (err) {\n this.turns.delete(requestId);\n turn.abort(err);\n }\n return turn;\n }\n\n /**\n * Approve or reject a pending tool write, resuming the paused turn identified\n * by `requestId`. The resumed streaming events flow back into the original\n * {@link MessageTurn} for that `requestId`.\n */\n confirmToolAction(req: { sessionId: string; requestId: string; approved: boolean }): void {\n this.transport.send(JSON.stringify({ action: 'confirm_tool_action', ...req }));\n }\n\n /**\n * Submit an OTP code, resuming the paused turn identified by `requestId`.\n * The resumed streaming events flow back into the original {@link MessageTurn}.\n */\n verifyOtp(req: { sessionId: string; requestId: string; code: string }): void {\n this.transport.send(JSON.stringify({ action: 'verify_otp', ...req }));\n }\n\n /**\n * Submit (or decline) a Rich Interaction, resuming the turn parked by an\n * `interaction_required` event. This ONE verb serves every interaction kind\n * (identity intake, future date pickers, choice chips, …) — adding a kind\n * needs no new client method. Server-side validation may reply with an\n * `interaction_invalid` event (the turn stays parked — resubmit); a valid\n * submit resumes the stream back into the original {@link MessageTurn}.\n */\n submitInteraction(req: {\n sessionId: string;\n requestId: string;\n /** Echo of the `interaction_required` event's `interactionId`. */\n interactionId: string;\n /** Optional kind cross-check (e.g. `identity_intake`). */\n kind?: string;\n /** Kind-shaped values (identity_intake: `{ name?, email?, phone? }`). */\n values?: Record<string, unknown>;\n declined?: boolean;\n }): void {\n this.transport.send(JSON.stringify({ action: 'submit_interaction', ...req }));\n }\n\n // ─────────────────────────── Internals ─────────────────────────────────\n\n /** Send an action that expects a single correlated response event. */\n private request(action: Omit<ClientAction, 'requestId'> & { requestId?: string }): Promise<ServerEvent> {\n const requestId = action.requestId ?? this.generateRequestId();\n const frame = { ...action, requestId } as ClientAction;\n\n return new Promise<ServerEvent>((resolve, reject) => {\n const timer =\n this.requestTimeout > 0\n ? setTimeout(() => {\n this.pending.delete(requestId);\n reject(new RequestTimeoutError(requestId, this.requestTimeout));\n }, this.requestTimeout)\n : undefined;\n\n this.pending.set(requestId, { resolve, reject, timer });\n try {\n this.transport.send(JSON.stringify(frame));\n } catch (err) {\n if (timer) clearTimeout(timer);\n this.pending.delete(requestId);\n reject(err);\n }\n });\n }\n\n /** Parse and route an incoming frame to the right consumer. */\n private handleFrame(data: string): void {\n let frame: unknown;\n try {\n frame = JSON.parse(data);\n } catch {\n return; // ignore malformed frames\n }\n if (!isServerEvent(frame)) return;\n const event = frame;\n const requestId = event.requestId;\n\n // 1. Streaming turn? Route every related event into it.\n if (requestId && this.turns.has(requestId)) {\n this.turns.get(requestId)!.push(event);\n return;\n }\n\n // 2. Single-response request awaiting resolution?\n if (requestId && this.pending.has(requestId)) {\n const pending = this.pending.get(requestId)!;\n this.pending.delete(requestId);\n if (pending.timer) clearTimeout(pending.timer);\n\n if (event.type === 'error') {\n const code = event.data?.error?.code ?? 'INTERNAL_ERROR';\n const message = event.data?.error?.message ?? 'Unknown protocol error';\n pending.reject(new ProtocolError(code, message, requestId));\n } else {\n pending.resolve(event);\n }\n return;\n }\n\n // 3. Unsolicited / uncorrelated event (keepalive, server push).\n for (const l of this.listeners) l(event);\n }\n\n private failAll(err: unknown): void {\n for (const [, p] of this.pending) {\n if (p.timer) clearTimeout(p.timer);\n p.reject(err);\n }\n this.pending.clear();\n for (const [, turn] of this.turns) turn.abort(err);\n this.turns.clear();\n }\n}\n\n/**\n * Merge a connection auth `token` into a WebSocket URL as a `?token=` query param,\n * preserving any existing query string. Returns `url` unchanged when no token is\n * given, so the no-token path is byte-for-byte identical to before. Uses `URL` /\n * `URLSearchParams` so an existing `?foo=bar` becomes `?foo=bar&token=…` (and the\n * value is properly percent-encoded) rather than a naive `?`/`&` string-concat.\n *\n * Falls back to manual concatenation if `url` is not absolute (so `URL` can't parse\n * it) — e.g. a relative or mock URL used in tests.\n */\nfunction withConnectionToken(url: string, token?: string): string {\n if (!token) return url;\n try {\n const parsed = new URL(url);\n parsed.searchParams.set('token', token);\n return parsed.toString();\n } catch {\n const separator = url.includes('?') ? '&' : '?';\n return `${url}${separator}token=${encodeURIComponent(token)}`;\n }\n}\n\n/** Pull the typed `data` payload out of an `immediate_response` event. */\nfunction extractImmediateData<T>(event: ServerEvent): T {\n if (event.type === 'immediate_response') return event.data as T;\n // Some servers may answer a non-streaming action with the payload elsewhere;\n // fall back to `data` if present.\n if ('data' in event && event.data && typeof event.data === 'object') return event.data as T;\n throw new ProtocolError('UNEXPECTED_EVENT', `Expected immediate_response, got \"${event.type}\"`, event.requestId);\n}\n","/**\n * ConversationController — the bridge between the widget UI and the\n * `@smooai/smooth-operator` protocol client.\n *\n * This is the piece that was rewired: the original smooai widget spoke to\n * `@smooai/realtime`; here every protocol action goes through {@link SmoothAgentClient}.\n * The wire shapes are identical (the protocol was lifted from `@smooai/realtime`),\n * so the swap is purely at the client-library boundary.\n *\n * Flow:\n * 1. `connect()` → opens the WebSocket transport and `create_conversation_session`.\n * 2. `send(text)` → `send_message`, streaming `stream_token` deltas into the\n * in-progress assistant message, then the terminal\n * `eventual_response`.\n *\n * The controller is UI-agnostic: it emits typed events and the view renders them.\n */\nimport { ProtocolError, SmoothAgentClient, type SmoothAgentClientOptions } from '../client.js';\nimport type { Citation } from '../types.js';\nimport type { ChatWidgetConfig } from './config.js';\n\nexport type { Citation };\n\nexport type Role = 'user' | 'assistant';\n\n/**\n * A chat-native interactive prompt rendered as buttons inside an assistant\n * bubble. Backs SEP `ui/confirm` and `ui/select`: the agent (or an extension it\n * hosts) pauses the turn asking for a choice, and the click flows back as an\n * action frame that resumes the same turn.\n *\n * `confirm` projects the protocol's `write_confirmation_required` event (Yes/No\n * → `confirm_tool_action`); `select` projects a `ui/select` (one option → its\n * value). Each option's `value` is what the resume action carries.\n */\nexport interface ChatPrompt {\n /** The turn's `requestId` — the resume action must echo it. */\n requestId: string;\n kind: 'confirm' | 'select';\n /** Human-readable prompt text (the confirmation description / select prompt). */\n text: string;\n /** The buttons. For `confirm`: Yes (`true`) / No (`false`). */\n options: Array<{ label: string; value: string | boolean }>;\n /** Set once the user picks — disables the buttons and records the choice. */\n answered?: string;\n}\n\nexport interface ChatMessage {\n id: string;\n role: Role;\n /** Accumulated text (assistant messages grow as tokens stream in). */\n text: string;\n /** True while an assistant message is still streaming. */\n streaming: boolean;\n /**\n * Sources that grounded an assistant answer, when the terminal\n * `eventual_response` carried any. Optional + back-compatible: absent when\n * the turn used no knowledge sources (or for user messages). Read\n * defensively off the terminal event — see {@link extractCitations}.\n */\n citations?: Citation[];\n /**\n * A pending (or answered) chat-native button prompt. Present only on the\n * bubble that carries a `write_confirmation_required` / `ui/select` request.\n */\n prompt?: ChatPrompt;\n}\n\nexport type ConnectionStatus = 'idle' | 'connecting' | 'ready' | 'error' | 'closed';\n\nexport interface ConversationEvents {\n /** Fired whenever the message list changes (append, token delta, finalize). */\n onMessages: (messages: ChatMessage[]) => void;\n /** Fired on connection-status transitions. */\n onStatus: (status: ConnectionStatus, detail?: string) => void;\n}\n\n/** Pull the final assistant text out of an `eventual_response` data payload. */\nfunction extractFinalText(response: unknown): string | null {\n if (!response || typeof response !== 'object') return null;\n const r = response as { responseParts?: unknown };\n if (Array.isArray(r.responseParts)) {\n return r.responseParts.filter((p): p is string => typeof p === 'string').join('\\n\\n');\n }\n return null;\n}\n\n/**\n * Pull the grounding {@link Citation}s out of a terminal `eventual_response`.\n *\n * The protocol client types these (`eventual_response.data.data.citations`),\n * but they're optional and back-compatible — absent when the turn used no\n * knowledge sources. We read them defensively (tolerating their total absence,\n * non-array shapes, and missing fields) so a server that doesn't emit them, or\n * an older client, can't break rendering. Each citation always carries\n * `id`/`title`/`snippet`/`score`; `url` is present only for web-sourced docs.\n */\nfunction extractCitations(inner: unknown): Citation[] {\n if (!inner || typeof inner !== 'object') return [];\n const raw = (inner as { citations?: unknown }).citations;\n if (!Array.isArray(raw)) return [];\n const out: Citation[] = [];\n for (const c of raw) {\n if (!c || typeof c !== 'object') continue;\n const obj = c as Record<string, unknown>;\n const id = typeof obj.id === 'string' ? obj.id : '';\n const title = typeof obj.title === 'string' ? obj.title : id || 'Source';\n const snippet = typeof obj.snippet === 'string' ? obj.snippet : '';\n const url = typeof obj.url === 'string' && obj.url ? obj.url : undefined;\n const score = typeof obj.score === 'number' ? obj.score : 0;\n out.push({ id, title, snippet, score, url });\n }\n return out;\n}\n\nexport class ConversationController {\n private readonly config: ChatWidgetConfig;\n private readonly events: ConversationEvents;\n private client: SmoothAgentClient | null = null;\n private sessionId: string | null = null;\n private readonly messages: ChatMessage[] = [];\n private status: ConnectionStatus = 'idle';\n private seq = 0;\n /**\n * requestId → resolver for a pending button prompt. The turn loop parks on\n * the promise; {@link answerPrompt} (called by the view on a button click)\n * resolves it and the loop resumes consuming the (now un-paused) stream.\n */\n private readonly pendingPrompts = new Map<string, (choice: string | boolean) => void>();\n /** Extra client options — a test seam for injecting a mock transport. */\n private readonly clientOptions?: Partial<SmoothAgentClientOptions>;\n\n constructor(config: ChatWidgetConfig, events: ConversationEvents, clientOptions?: Partial<SmoothAgentClientOptions>) {\n this.config = config;\n this.events = events;\n this.clientOptions = clientOptions;\n }\n\n get connectionStatus(): ConnectionStatus {\n return this.status;\n }\n\n private nextId(prefix: string): string {\n this.seq += 1;\n return `${prefix}-${this.seq}-${Date.now().toString(36)}`;\n }\n\n private setStatus(status: ConnectionStatus, detail?: string): void {\n this.status = status;\n this.events.onStatus(status, detail);\n }\n\n private emitMessages(): void {\n // Hand out a shallow copy so the view can't mutate internal state.\n this.events.onMessages(this.messages.map((m) => ({ ...m })));\n }\n\n /** Open the transport and create a conversation session. Idempotent. */\n async connect(): Promise<void> {\n if (this.status === 'connecting' || this.status === 'ready') return;\n this.setStatus('connecting');\n try {\n this.client = new SmoothAgentClient({ url: this.config.endpoint, ...this.clientOptions });\n await this.client.connect();\n const session = await this.client.createConversationSession({\n agentId: this.config.agentId,\n userName: this.config.userName,\n userEmail: this.config.userEmail,\n });\n this.sessionId = session.sessionId;\n this.setStatus('ready');\n } catch (err) {\n this.setStatus('error', err instanceof Error ? err.message : String(err));\n throw err;\n }\n }\n\n /**\n * Submit a user message. Appends the user bubble immediately, then streams the\n * assistant reply token-by-token, finalizing on `eventual_response`.\n */\n async send(text: string): Promise<void> {\n const trimmed = text.trim();\n if (!trimmed) return;\n if (!this.client || !this.sessionId || this.status !== 'ready') {\n await this.connect();\n }\n if (!this.client || !this.sessionId) {\n throw new Error('Conversation is not connected');\n }\n\n // 1. User bubble.\n this.messages.push({ id: this.nextId('u'), role: 'user', text: trimmed, streaming: false });\n\n // 2. Placeholder assistant bubble we grow as tokens arrive.\n const assistant: ChatMessage = { id: this.nextId('a'), role: 'assistant', text: '', streaming: true };\n this.messages.push(assistant);\n this.emitMessages();\n\n try {\n const turn = this.client.sendMessage({ sessionId: this.sessionId, message: trimmed, stream: true });\n\n for await (const event of turn) {\n if (event.type === 'stream_token') {\n const token = event.token ?? event.data?.token ?? '';\n if (token) {\n assistant.text += token;\n this.emitMessages();\n }\n } else if (event.type === 'write_confirmation_required') {\n // The turn is paused server-side awaiting a confirm_tool_action.\n // Render Yes/No buttons and block the loop until the user clicks\n // (or the transport drops). The click sends the resume action\n // via answerPrompt(); the stream then flows back into `turn`.\n const description = event.data?.data?.actionDescription ?? 'Approve this action?';\n const approved = await this.awaitPromptChoice(turn.requestId, {\n requestId: turn.requestId,\n kind: 'confirm',\n text: String(description),\n options: [\n { label: 'Yes', value: true },\n { label: 'No', value: false },\n ],\n });\n this.client?.confirmToolAction({ sessionId: this.sessionId!, requestId: turn.requestId, approved: approved === true });\n }\n }\n\n const final = await turn;\n const inner = final.data?.data;\n const finalText = extractFinalText(inner?.response);\n if (finalText && finalText.length > assistant.text.length) {\n assistant.text = finalText;\n }\n if (!assistant.text) {\n assistant.text = '(no response)';\n }\n // Attach grounding sources from the terminal event, when present.\n const citations = extractCitations(inner);\n if (citations.length > 0) {\n assistant.citations = citations;\n }\n assistant.streaming = false;\n this.emitMessages();\n } catch (err) {\n assistant.streaming = false;\n const message =\n err instanceof ProtocolError\n ? `Error: ${err.message}`\n : (this.config.connectionErrorMessage ?? \"We couldn't reach the chat.\");\n assistant.text = assistant.text ? `${assistant.text}\\n\\n${message}` : message;\n this.emitMessages();\n this.setStatus('error', err instanceof Error ? err.message : String(err));\n }\n }\n\n /**\n * Attach a pending `prompt` to the current assistant bubble and return a\n * promise that resolves when the user clicks a button (via\n * {@link answerPrompt}). The bubble carrying the prompt is the last\n * assistant message.\n */\n private awaitPromptChoice(requestId: string, prompt: ChatPrompt): Promise<string | boolean> {\n const last = this.messages[this.messages.length - 1];\n if (last && last.role === 'assistant') {\n last.prompt = prompt;\n last.streaming = false; // stop the typing cursor while we wait\n }\n this.emitMessages();\n return new Promise<string | boolean>((resolve) => {\n this.pendingPrompts.set(requestId, resolve);\n });\n }\n\n /**\n * Resolve a pending button prompt — called by the view when the user clicks\n * an option. Marks the prompt answered (buttons disable, choice sticks) and\n * unblocks the turn loop. No-op if the prompt was already answered.\n */\n answerPrompt(requestId: string, value: string | boolean): void {\n const resolve = this.pendingPrompts.get(requestId);\n if (!resolve) return;\n this.pendingPrompts.delete(requestId);\n const msg = this.messages.find((m) => m.prompt?.requestId === requestId);\n if (msg?.prompt) {\n msg.prompt.answered = msg.prompt.options.find((o) => o.value === value)?.label ?? String(value);\n }\n this.emitMessages();\n resolve(value);\n }\n\n /** Tear down the underlying client. */\n disconnect(): void {\n // Unblock any parked prompt so a pending turn loop doesn't hang forever.\n for (const [requestId, resolve] of this.pendingPrompts) {\n this.pendingPrompts.delete(requestId);\n resolve(false);\n }\n this.client?.disconnect('widget closed');\n this.client = null;\n this.sessionId = null;\n this.setStatus('closed');\n }\n}\n","/**\n * The Smooth logo, inlined as an SVG string so the full-page header can render\n * it without a separate network fetch (the IIFE bundle is self-contained).\n *\n * GENERATED from `assets/smooth-logo.svg` — do not edit by hand. Regenerate with:\n * node -e ... (see the commit that added this file)\n */\n/* eslint-disable */\nexport const SMOOTH_LOGO_SVG = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n<svg id=\\\"Layer_1\\\" data-name=\\\"Layer 1\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\" viewBox=\\\"0 0 550 135\\\">\\n <defs>\\n <style>\\n .cls-1 {\\n fill: url(#linear-gradient-3);\\n }\\n\\n .cls-2 {\\n fill: url(#linear-gradient-2);\\n }\\n\\n .cls-3 {\\n fill: url(#linear-gradient);\\n fill-rule: evenodd;\\n }\\n </style>\\n <linearGradient id=\\\"linear-gradient\\\" x1=\\\"115.59\\\" y1=\\\"112.81\\\" x2=\\\"25.08\\\" y2=\\\"22.3\\\" gradientUnits=\\\"userSpaceOnUse\\\">\\n <stop offset=\\\".3\\\" stop-color=\\\"#f49f0a\\\"/>\\n <stop offset=\\\".79\\\" stop-color=\\\"#fb7a4d\\\"/>\\n <stop offset=\\\"1\\\" stop-color=\\\"#ff6b6c\\\"/>\\n </linearGradient>\\n <linearGradient id=\\\"linear-gradient-2\\\" x1=\\\"360.91\\\" y1=\\\"152.01\\\" x2=\\\"202.32\\\" y2=\\\"-6.59\\\" xlink:href=\\\"#linear-gradient\\\"/>\\n <linearGradient id=\\\"linear-gradient-3\\\" x1=\\\"443.91\\\" y1=\\\"30.15\\\" x2=\\\"531.36\\\" y2=\\\"117.59\\\" gradientUnits=\\\"userSpaceOnUse\\\">\\n <stop offset=\\\".43\\\" stop-color=\\\"#00a6a6\\\"/>\\n <stop offset=\\\"1\\\" stop-color=\\\"#1238dd\\\"/>\\n </linearGradient>\\n </defs>\\n <path class=\\\"cls-3\\\" d=\\\"M48.28,14.96c-12.39,5.21-22.54,14.64-28.65,26.61-6.12,11.97-7.8,25.72-4.77,38.81,3.04,13.09,10.6,24.69,21.36,32.75,10.76,8.06,24.02,12.05,37.44,11.28,13.42-.77,26.13-6.26,35.9-15.5,9.76-9.24,15.95-21.63,17.46-34.99,1.51-13.36-1.74-26.82-9.19-38.01-1.07-1.61-.64-3.78.97-4.85,1.61-1.07,3.78-.64,4.85.97,8.36,12.56,12.02,27.68,10.32,42.67-1.7,15-8.64,28.91-19.61,39.28-10.96,10.37-25.24,16.54-40.31,17.4-15.07.87-29.96-3.62-42.04-12.66-12.08-9.05-20.58-22.07-23.99-36.77-3.41-14.7-1.51-30.14,5.35-43.58,6.87-13.44,18.26-24.02,32.17-29.87,13.91-5.85,29.44-6.6,43.85-2.11,1.85.57,2.88,2.54,2.3,4.38-.57,1.85-2.54,2.88-4.38,2.3-12.83-4-26.67-3.33-39.06,1.88ZM111.39,19.75c0,2.07-1.68,3.75-3.75,3.75s-3.75-1.68-3.75-3.75,1.68-3.75,3.75-3.75,3.75,1.68,3.75,3.75ZM64.64,59.93c0,1.91,2.39,2.56,7.69,3.88,3.89.97,6.6,2.18,8.15,3.63,1.53,1.45,2.29,3.53,2.29,6.25,0,3.57-1.03,6.26-3.11,8.08-2.07,1.82-5.09,2.73-9.09,2.73h-9.6c-1.97,0-3.57-1.6-3.59-3.57-.01-1.99,1.6-3.61,3.59-3.61h9.41c3.15-.12,4.79-.95,4.91-2.47,0-1.3-1.03-2.21-3.07-2.73-6.91-1.72-11.11-3.44-12.6-5.15-1.48-1.71-2.23-3.77-2.23-6.19,0-6.59,3.2-9.85,9.59-9.8h10.77c1.99,0,3.6,1.61,3.6,3.59s-1.61,3.59-3.6,3.59h-9.69c-1.83,0-3.43.06-3.43,1.77Z\\\"/>\\n <path class=\\\"cls-2\\\" d=\\\"M205.52,48.44h-8.86c-.44-3.75-2.23-6.65-5.38-8.72-3.16-2.07-7.03-3.1-11.6-3.1h0c-3.35,0-6.27.54-8.78,1.62-2.49,1.09-4.44,2.59-5.84,4.48-1.39,1.89-2.08,4.05-2.08,6.46h0c0,2.01.49,3.75,1.46,5.2.97,1.44,2.22,2.63,3.74,3.58,1.53.95,3.13,1.72,4.8,2.32,1.68.6,3.22,1.09,4.62,1.46h0l7.68,2.06c1.97.52,4.17,1.23,6.6,2.14,2.43.92,4.75,2.16,6.98,3.72,2.23,1.56,4.07,3.56,5.52,6,1.45,2.44,2.18,5.43,2.18,8.98h0c0,4.08-1.07,7.77-3.2,11.08-2.12,3.29-5.22,5.91-9.3,7.86-4.08,1.95-9.02,2.92-14.82,2.92h0c-5.43,0-10.11-.87-14.06-2.62-3.95-1.75-7.05-4.19-9.3-7.32-2.25-3.12-3.53-6.75-3.84-10.88h9.46c.25,2.85,1.22,5.21,2.9,7.06,1.69,1.87,3.83,3.25,6.42,4.14,2.6.89,5.41,1.34,8.42,1.34h0c3.49,0,6.63-.57,9.4-1.72,2.79-1.13,4.99-2.73,6.62-4.8,1.63-2.05,2.44-4.46,2.44-7.22h0c0-2.51-.7-4.55-2.1-6.12-1.41-1.57-3.26-2.85-5.54-3.84-2.29-.99-4.77-1.85-7.44-2.58h0l-9.3-2.66c-5.91-1.71-10.59-4.13-14.04-7.28-3.44-3.16-5.16-7.29-5.16-12.38h0c0-4.23,1.15-7.93,3.46-11.1,2.29-3.16,5.39-5.62,9.3-7.38,3.91-1.76,8.27-2.64,13.08-2.64h0c4.88,0,9.21.87,13,2.6,3.8,1.73,6.81,4.11,9.04,7.12,2.23,3,3.4,6.41,3.52,10.22h0ZM229.16,105.18h-8.72v-56.74h8.42v8.86h.74c1.19-3.03,3.1-5.38,5.74-7.06,2.63-1.69,5.79-2.54,9.48-2.54h0c3.75,0,6.87.85,9.36,2.54,2.51,1.68,4.46,4.03,5.86,7.06h.58c1.45-2.92,3.63-5.25,6.54-7,2.91-1.73,6.39-2.6,10.46-2.6h0c5.07,0,9.21,1.58,12.44,4.74,3.23,3.17,4.84,8.09,4.84,14.76h0v37.98h-8.72v-37.98c0-4.19-1.14-7.18-3.42-8.98-2.29-1.79-4.99-2.68-8.1-2.68h0c-3.99,0-7.07,1.2-9.26,3.6-2.2,2.4-3.3,5.43-3.3,9.1h0v36.94h-8.86v-38.86c0-3.23-1.05-5.83-3.14-7.82-2.09-1.97-4.79-2.96-8.08-2.96h0c-2.27,0-4.38.6-6.34,1.8-1.96,1.21-3.53,2.88-4.72,5-1.2,2.13-1.8,4.59-1.8,7.38h0v35.46ZM333.9,106.36h0c-5.12,0-9.61-1.22-13.46-3.66-3.85-2.44-6.86-5.85-9.02-10.24-2.15-4.37-3.22-9.49-3.22-15.36h0c0-5.91,1.07-11.07,3.22-15.48,2.16-4.4,5.17-7.82,9.02-10.26,3.85-2.44,8.34-3.66,13.46-3.66h0c5.12,0,9.61,1.22,13.46,3.66,3.85,2.44,6.86,5.86,9.02,10.26,2.15,4.41,3.22,9.57,3.22,15.48h0c0,5.87-1.07,10.99-3.22,15.36-2.16,4.39-5.17,7.8-9.02,10.24-3.85,2.44-8.34,3.66-13.46,3.66ZM333.9,98.52h0c3.89,0,7.09-.99,9.6-2.98,2.52-2,4.38-4.63,5.58-7.88,1.21-3.25,1.82-6.77,1.82-10.56h0c0-3.79-.61-7.32-1.82-10.6-1.2-3.27-3.06-5.91-5.58-7.94-2.51-2.01-5.71-3.02-9.6-3.02h0c-3.89,0-7.09,1.01-9.6,3.02-2.51,2.03-4.37,4.67-5.58,7.94-1.2,3.28-1.8,6.81-1.8,10.6h0c0,3.79.6,7.31,1.8,10.56,1.21,3.25,3.07,5.88,5.58,7.88,2.51,1.99,5.71,2.98,9.6,2.98ZM395.94,106.36h0c-5.12,0-9.61-1.22-13.46-3.66-3.85-2.44-6.85-5.85-9-10.24-2.16-4.37-3.24-9.49-3.24-15.36h0c0-5.91,1.08-11.07,3.24-15.48,2.15-4.4,5.15-7.82,9-10.26,3.85-2.44,8.34-3.66,13.46-3.66h0c5.12,0,9.61,1.22,13.46,3.66,3.85,2.44,6.86,5.86,9.02,10.26,2.16,4.41,3.24,9.57,3.24,15.48h0c0,5.87-1.08,10.99-3.24,15.36-2.16,4.39-5.17,7.8-9.02,10.24-3.85,2.44-8.34,3.66-13.46,3.66ZM395.94,98.52h0c3.89,0,7.09-.99,9.6-2.98,2.52-2,4.38-4.63,5.58-7.88,1.21-3.25,1.82-6.77,1.82-10.56h0c0-3.79-.61-7.32-1.82-10.6-1.2-3.27-3.06-5.91-5.58-7.94-2.51-2.01-5.71-3.02-9.6-3.02h0c-3.88,0-7.08,1.01-9.6,3.02-2.51,2.03-4.37,4.67-5.58,7.94-1.2,3.28-1.8,6.81-1.8,10.6h0c0,3.79.6,7.31,1.8,10.56,1.21,3.25,3.07,5.88,5.58,7.88,2.52,1.99,5.72,2.98,9.6,2.98Z\\\"/>\\n <path class=\\\"cls-1\\\" d=\\\"M467.88,48.02v13.28h-35.79v-13.28h35.79ZM439.68,34.38h17.89v53.42c0,1.5.36,2.62,1.08,3.36.72.74,1.88,1.1,3.49,1.1.62,0,1.48-.07,2.59-.21,1.11-.14,1.91-.27,2.38-.41l2.31,13.02c-2.02.58-3.97.97-5.84,1.18-1.88.21-3.66.31-5.33.31-6.08,0-10.7-1.43-13.84-4.28-3.15-2.85-4.72-7.01-4.72-12.48v-55.01ZM506.59,72.63v32.71h-17.89V28.95h17.53v33.53h-1.13c1.4-4.55,3.6-8.21,6.59-11,2.99-2.79,7.01-4.18,12.07-4.18,4,0,7.48.89,10.46,2.67,2.97,1.78,5.28,4.29,6.92,7.54,1.64,3.25,2.46,7.02,2.46,11.33v36.5h-17.89v-33.02c0-3.21-.82-5.73-2.46-7.56-1.64-1.83-3.93-2.74-6.87-2.74-1.92,0-3.62.42-5.1,1.26-1.49.84-2.64,2.04-3.46,3.61-.82,1.57-1.23,3.49-1.23,5.74Z\\\"/>\\n</svg>\";\n","import type { ChatWidgetMode, ChatWidgetTheme } from './config.js';\n\n/**\n * Render the widget's scoped stylesheet. All theme values are injected as CSS\n * custom properties on `:host` so they can be overridden per-instance and so the\n * styles below stay static. Kept deliberately framework-light — no Tailwind, no\n * runtime CSS-in-JS; just a string the web component drops into its shadow root.\n *\n * `mode` switches the host positioning + panel sizing between the floating\n * popover (default) and the full-page layout (fills its container/viewport).\n */\nexport function buildStyles(theme: Required<ChatWidgetTheme>, mode: ChatWidgetMode = 'popover'): string {\n return `\n:host {\n --sac-text: ${theme.text};\n --sac-bg: ${theme.background};\n --sac-primary: ${theme.primary};\n --sac-primary-text: ${theme.primaryText};\n --sac-assistant-bubble: ${theme.assistantBubble};\n --sac-assistant-bubble-text: ${theme.assistantBubbleText};\n --sac-user-bubble: ${theme.userBubble};\n --sac-user-bubble-text: ${theme.userBubbleText};\n --sac-border: ${theme.border};\n\n ${\n mode === 'fullpage'\n ? `/* Full-page: fill the host's box (the element should be sized by its\n container, or it falls back to filling the viewport). */\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n min-height: 100vh;`\n : `/* Popover: float in the bottom-right corner. */\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 2147483000;`\n }\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;\n}\n\n* { box-sizing: border-box; }\n\n.launcher {\n width: 56px;\n height: 56px;\n border-radius: 50%;\n border: none;\n cursor: pointer;\n background: var(--sac-primary);\n color: var(--sac-primary-text);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 24px;\n transition: transform 0.15s ease;\n}\n.launcher:hover { transform: scale(1.05); }\n\n.panel {\n width: 360px;\n max-width: calc(100vw - 40px);\n height: 520px;\n max-height: calc(100vh - 40px);\n display: flex;\n flex-direction: column;\n background: var(--sac-bg);\n color: var(--sac-text);\n border: 1px solid var(--sac-border);\n border-radius: 14px;\n overflow: hidden;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);\n}\n\n/* Full-page: the panel becomes the whole surface — no floating box, no shadow,\n no rounded corners; it fills the host. */\n.panel.fullpage {\n width: 100%;\n height: 100%;\n min-height: 100vh;\n max-width: none;\n max-height: none;\n border: none;\n border-radius: 0;\n box-shadow: none;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 14px;\n background: var(--sac-primary);\n color: var(--sac-primary-text);\n}\n.header .brand { display: flex; align-items: center; gap: 10px; min-width: 0; }\n.header .logo { height: 24px; width: auto; display: block; }\n.header .title { font-weight: 600; font-size: 15px; }\n.header .status { font-size: 11px; opacity: 0.85; }\n.header .powered {\n font-size: 10px;\n opacity: 0.7;\n letter-spacing: 0.02em;\n}\n.header .close {\n background: transparent;\n border: none;\n color: inherit;\n cursor: pointer;\n font-size: 18px;\n line-height: 1;\n padding: 4px;\n}\n\n/* Full-page header: taller, logo-led, centered max-width content row. */\n.panel.fullpage .header { padding: 14px 20px; }\n.panel.fullpage .logo { height: 30px; }\n\n.messages {\n flex: 1;\n overflow-y: auto;\n padding: 14px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.bubble {\n max-width: 80%;\n padding: 9px 12px;\n border-radius: 12px;\n font-size: 14px;\n line-height: 1.4;\n white-space: pre-wrap;\n word-break: break-word;\n}\n.bubble.assistant {\n align-self: flex-start;\n background: var(--sac-assistant-bubble);\n color: var(--sac-assistant-bubble-text);\n border-bottom-left-radius: 4px;\n}\n.bubble.user {\n align-self: flex-end;\n background: var(--sac-user-bubble);\n color: var(--sac-user-bubble-text);\n border-bottom-right-radius: 4px;\n}\n.bubble.greeting { opacity: 0.85; font-style: italic; }\n\n/* Full-page: center the conversation in a readable column and let bubbles\n breathe a little wider. */\n.panel.fullpage .messages {\n padding: 24px 20px;\n align-items: stretch;\n}\n.panel.fullpage .messages > * {\n width: 100%;\n max-width: 760px;\n margin-left: auto;\n margin-right: auto;\n}\n.panel.fullpage .bubble { max-width: 100%; }\n.panel.fullpage .bubble.user { align-self: flex-end; max-width: 80%; margin-right: auto; }\n.panel.fullpage .bubble.assistant { align-self: flex-start; max-width: 100%; }\n\n/* Sources panel — rendered under an assistant bubble whose terminal\n eventual_response carried citations. */\n.prompt {\n align-self: flex-start;\n max-width: 80%;\n margin-top: -2px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.panel.fullpage .prompt { max-width: 100%; }\n.prompt-text { font-size: 13.5px; color: var(--sac-text); opacity: 0.9; }\n.prompt-buttons { display: flex; gap: 8px; flex-wrap: wrap; }\n.prompt-button {\n cursor: pointer;\n border: 1px solid var(--sac-border);\n background: var(--sac-bg);\n color: var(--sac-text);\n border-radius: 999px;\n padding: 6px 16px;\n font-size: 13px;\n font-weight: 600;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n}\n.prompt-button:hover {\n background: var(--sac-primary);\n color: var(--sac-primary-text);\n border-color: var(--sac-primary);\n}\n.prompt-answered { font-size: 12.5px; opacity: 0.7; font-style: italic; }\n\n.sources {\n align-self: flex-start;\n max-width: 80%;\n margin-top: -4px;\n font-size: 12.5px;\n color: var(--sac-text);\n}\n.panel.fullpage .sources { max-width: 100%; }\n.sources details { background: transparent; }\n.sources summary {\n cursor: pointer;\n font-weight: 600;\n opacity: 0.85;\n list-style: none;\n user-select: none;\n padding: 2px 0;\n}\n.sources summary::-webkit-details-marker { display: none; }\n.sources summary::before {\n content: '▸';\n display: inline-block;\n margin-right: 6px;\n transition: transform 0.15s ease;\n}\n.sources details[open] summary::before { transform: rotate(90deg); }\n.sources ol {\n margin: 6px 0 0;\n padding-left: 0;\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.sources li {\n border-left: 2px solid var(--sac-primary);\n padding-left: 10px;\n}\n.sources .src-title {\n color: var(--sac-primary);\n text-decoration: none;\n font-weight: 600;\n word-break: break-word;\n}\n.sources a.src-title:hover { text-decoration: underline; }\n.sources span.src-title { color: var(--sac-text); opacity: 0.95; }\n.sources .src-snippet {\n display: block;\n margin-top: 2px;\n opacity: 0.7;\n line-height: 1.4;\n white-space: normal;\n}\n\n.cursor::after {\n content: '▋';\n margin-left: 1px;\n animation: sac-blink 1s steps(2, start) infinite;\n}\n@keyframes sac-blink { to { visibility: hidden; } }\n\n.composer {\n display: flex;\n gap: 8px;\n padding: 10px;\n border-top: 1px solid var(--sac-border);\n}\n.composer textarea {\n flex: 1;\n resize: none;\n border: 1px solid var(--sac-border);\n border-radius: 8px;\n padding: 8px 10px;\n font-family: inherit;\n font-size: 14px;\n background: transparent;\n color: var(--sac-text);\n max-height: 96px;\n line-height: 1.4;\n}\n.composer textarea:focus { outline: 1px solid var(--sac-primary); }\n.composer button {\n border: none;\n border-radius: 8px;\n padding: 0 14px;\n cursor: pointer;\n background: var(--sac-primary);\n color: var(--sac-primary-text);\n font-weight: 600;\n font-size: 14px;\n}\n.composer button:disabled { opacity: 0.5; cursor: default; }\n\n.hidden { display: none !important; }\n`;\n}\n","/**\n * `<smooth-agent-chat>` — a framework-light embeddable chat web component.\n *\n * Ported (and simplified) from smooai's `@smooai/ui-chat-widget`. The original is a\n * React custom element that mounts the heavyweight `@smooai/ui` ChatWidget and\n * pulls in the whole monorepo (Tailwind, shadcn, react-phone-number-input, MSW,\n * Supabase auth …). This is a clean, dependency-light rewrite that preserves the\n * embedding model — a custom element with a launcher + popover panel, declarative\n * HTML attributes, and a programmatic API — while talking to the\n * `@smooai/smooth-operator` protocol client instead of `@smooai/realtime`.\n *\n * Embedding model:\n * <smooth-agent-chat endpoint=\"ws://localhost:8787/ws\" agent-id=\"…\"></smooth-agent-chat>\n * or programmatically via {@link mountChatWidget}.\n */\nimport type { ChatWidgetConfig, ChatWidgetMode, ChatWidgetTheme } from './config.js';\nimport { resolveConfig } from './config.js';\nimport { type ChatMessage, type ChatPrompt, type Citation, type ConnectionStatus, ConversationController } from './conversation.js';\nimport { SMOOTH_LOGO_SVG } from './logo.js';\nimport { buildStyles } from './styles.js';\n\nexport const ELEMENT_TAG = 'smooth-agent-chat';\n\nconst OBSERVED = ['endpoint', 'agent-id', 'agent-name', 'placeholder', 'greeting', 'start-open', 'mode'] as const;\n\n/**\n * Return `url` only if it is a valid absolute `http(s)` URL, else `null`.\n *\n * SECURITY: citation URLs originate from indexed content (web / GitHub\n * connectors), which can be attacker-influenceable. Assigning an arbitrary\n * string to `<a>.href` allows `javascript:`/`data:`/`vbscript:` URLs that\n * execute on click — a stored-XSS vector. Only http(s) links are rendered as\n * anchors; anything else falls back to plain text.\n */\nexport function safeHttpUrl(url: string | undefined | null): string | null {\n if (!url) return null;\n try {\n const parsed = new URL(url);\n return parsed.protocol === 'http:' || parsed.protocol === 'https:' ? parsed.href : null;\n } catch {\n return null;\n }\n}\n\nexport class SmoothAgentChatElement extends HTMLElement {\n static get observedAttributes(): readonly string[] {\n return OBSERVED;\n }\n\n private readonly root: ShadowRoot;\n private controller: ConversationController | null = null;\n private overrides: Partial<ChatWidgetConfig> = {};\n private open = false;\n private messages: ChatMessage[] = [];\n private status: ConnectionStatus = 'idle';\n private mounted = false;\n\n // Cached DOM refs (populated in render()).\n private panelEl: HTMLElement | null = null;\n private launcherEl: HTMLElement | null = null;\n private messagesEl: HTMLElement | null = null;\n private statusEl: HTMLElement | null = null;\n private inputEl: HTMLTextAreaElement | null = null;\n private sendBtn: HTMLButtonElement | null = null;\n\n constructor() {\n super();\n this.root = this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback(): void {\n this.mounted = true;\n this.render();\n }\n\n disconnectedCallback(): void {\n this.mounted = false;\n this.controller?.disconnect();\n this.controller = null;\n }\n\n attributeChangedCallback(): void {\n if (this.mounted) this.render();\n }\n\n /**\n * Programmatically merge config overrides (endpoint, agentId, theme, …). Values\n * set here take precedence over HTML attributes. Re-renders the widget.\n */\n configure(config: Partial<ChatWidgetConfig>): void {\n this.overrides = { ...this.overrides, ...config };\n if (config.theme) {\n this.overrides.theme = { ...(this.overrides.theme ?? {}), ...config.theme };\n }\n if (this.mounted) this.render();\n }\n\n /** Open the chat panel. */\n openChat(): void {\n this.open = true;\n this.syncOpenState();\n void this.controller?.connect().catch(() => {});\n }\n\n /** Collapse the chat panel back to the launcher. */\n closeChat(): void {\n this.open = false;\n this.syncOpenState();\n }\n\n // ─────────────────────────── Config resolution ─────────────────────────────\n\n private readConfig(): ChatWidgetConfig | null {\n const endpoint = this.overrides.endpoint ?? this.getAttribute('endpoint') ?? '';\n const agentId = this.overrides.agentId ?? this.getAttribute('agent-id') ?? '';\n if (!endpoint || !agentId) return null;\n\n const theme: ChatWidgetTheme | undefined = this.overrides.theme;\n const modeAttr = this.getAttribute('mode');\n const mode: ChatWidgetMode = this.overrides.mode ?? (modeAttr === 'fullpage' ? 'fullpage' : modeAttr === 'popover' ? 'popover' : undefined) ?? 'popover';\n return {\n endpoint,\n mode,\n agentId,\n agentName: this.overrides.agentName ?? this.getAttribute('agent-name') ?? undefined,\n userName: this.overrides.userName,\n userEmail: this.overrides.userEmail,\n placeholder: this.overrides.placeholder ?? this.getAttribute('placeholder') ?? undefined,\n greeting: this.overrides.greeting ?? this.getAttribute('greeting') ?? undefined,\n connectionErrorMessage: this.overrides.connectionErrorMessage,\n startOpen: this.overrides.startOpen ?? this.hasAttribute('start-open'),\n theme,\n };\n }\n\n // ───────────────────────────────── Render ──────────────────────────────────\n\n private render(): void {\n const config = this.readConfig();\n if (!config) {\n this.root.innerHTML = '';\n return;\n }\n const resolved = resolveConfig(config);\n\n // (Re)create the controller only when there isn't one yet. Attribute churn\n // (e.g. theme tweaks) re-renders the view without dropping the session.\n if (!this.controller) {\n this.controller = new ConversationController(config, {\n onMessages: (messages) => {\n this.messages = messages;\n this.renderMessages(resolved.greeting);\n },\n onStatus: (status) => {\n this.status = status;\n this.renderStatus();\n this.renderComposerState();\n },\n });\n if (resolved.startOpen) this.open = true;\n }\n\n const fullpage = resolved.mode === 'fullpage';\n // Full-page mode is always \"open\" — it fills its container and has no\n // launcher to toggle.\n if (fullpage) this.open = true;\n\n const style = document.createElement('style');\n style.textContent = buildStyles(resolved.theme, resolved.mode);\n\n // Header: in full-page mode lead with the Smooth logo (falls back to the\n // agent name) + a subtle \"powered by smooth-operator\"; in popover mode the\n // compact agent-name title we've always shown. The close button only\n // exists in popover mode (full-page has nothing to collapse to).\n const headerBrand = fullpage\n ? `<div class=\"brand\">\n <span class=\"logo-wrap\">${SMOOTH_LOGO_SVG}</span>\n <div>\n <div class=\"title\">${escapeHtml(resolved.agentName)}</div>\n <div class=\"status\"></div>\n </div>\n </div>\n <div class=\"powered\">powered by smooth-operator</div>`\n : `<div class=\"brand\">\n <div>\n <div class=\"title\">${escapeHtml(resolved.agentName)}</div>\n <div class=\"status\"></div>\n </div>\n </div>\n <button class=\"close\" aria-label=\"Close chat\">×</button>`;\n\n const container = document.createElement('div');\n container.innerHTML = `\n ${fullpage ? '' : '<button class=\"launcher\" part=\"launcher\" aria-label=\"Open chat\">💬</button>'}\n <div class=\"panel${fullpage ? ' fullpage' : ' hidden'}\" part=\"panel\" role=\"${fullpage ? 'region' : 'dialog'}\" aria-label=\"${escapeHtml(resolved.agentName)} chat\">\n <div class=\"header\">\n ${headerBrand}\n </div>\n <div class=\"messages\"></div>\n <div class=\"composer\">\n <textarea rows=\"1\" placeholder=\"${escapeHtml(resolved.placeholder)}\"></textarea>\n <button class=\"send\" type=\"button\">Send</button>\n </div>\n </div>\n `;\n\n // Tag the logo <svg> so styles can size it (the inlined SVG has its own id).\n const logoSvg = container.querySelector('.logo-wrap svg');\n if (logoSvg) logoSvg.setAttribute('class', 'logo');\n\n this.root.replaceChildren(style, container);\n\n this.launcherEl = container.querySelector('.launcher');\n this.panelEl = container.querySelector('.panel');\n this.messagesEl = container.querySelector('.messages');\n this.statusEl = container.querySelector('.status');\n this.inputEl = container.querySelector('textarea');\n this.sendBtn = container.querySelector('.send');\n\n this.launcherEl?.addEventListener('click', () => this.openChat());\n container.querySelector('.close')?.addEventListener('click', () => this.closeChat());\n this.sendBtn?.addEventListener('click', () => this.submit());\n this.inputEl?.addEventListener('keydown', (ev) => {\n if (ev.key === 'Enter' && !ev.shiftKey) {\n ev.preventDefault();\n this.submit();\n }\n });\n\n // Full-page mode connects eagerly (there's no launcher click to trigger it).\n if (fullpage) void this.controller?.connect().catch(() => {});\n\n this.syncOpenState();\n this.renderMessages(resolved.greeting);\n this.renderStatus();\n this.renderComposerState();\n }\n\n private syncOpenState(): void {\n // In full-page mode the panel always fills the host; nothing to toggle.\n if (this.panelEl?.classList.contains('fullpage')) {\n this.inputEl?.focus();\n return;\n }\n this.panelEl?.classList.toggle('hidden', !this.open);\n this.launcherEl?.classList.toggle('hidden', this.open);\n if (this.open) this.inputEl?.focus();\n }\n\n private renderMessages(greeting: string): void {\n if (!this.messagesEl) return;\n this.messagesEl.replaceChildren();\n\n if (this.messages.length === 0 && greeting) {\n const g = document.createElement('div');\n g.className = 'bubble assistant greeting';\n g.textContent = greeting;\n this.messagesEl.appendChild(g);\n }\n\n for (const msg of this.messages) {\n const el = document.createElement('div');\n el.className = `bubble ${msg.role}`;\n if (msg.streaming && !msg.text) {\n el.classList.add('cursor');\n } else if (msg.streaming) {\n el.classList.add('cursor');\n el.textContent = msg.text;\n } else {\n el.textContent = msg.text;\n }\n this.messagesEl.appendChild(el);\n\n // Render chat-native button prompts (SEP ui/confirm + ui/select,\n // projected from write_confirmation_required). The click resumes the\n // paused turn via the controller.\n if (msg.prompt) {\n this.messagesEl.appendChild(this.renderPrompt(msg.prompt));\n }\n\n // Render a \"Sources (N)\" section under any assistant message whose\n // terminal eventual_response carried citations. Back-compatible: most\n // turns have none, so this is skipped.\n if (msg.role === 'assistant' && !msg.streaming && msg.citations && msg.citations.length > 0) {\n this.messagesEl.appendChild(this.renderSources(msg.citations));\n }\n }\n this.messagesEl.scrollTop = this.messagesEl.scrollHeight;\n }\n\n /**\n * Render a chat-native button prompt (SEP `ui/confirm` / `ui/select`). Each\n * option is a button; clicking one resumes the paused turn via\n * {@link ConversationController.answerPrompt}. Once answered the buttons\n * disable and the chosen label is shown, so the record stays in the\n * transcript. Built with DOM APIs (no innerHTML) — prompt text is untrusted.\n */\n private renderPrompt(prompt: ChatPrompt): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'prompt';\n wrap.setAttribute('part', 'prompt');\n\n const text = document.createElement('div');\n text.className = 'prompt-text';\n text.textContent = prompt.text;\n wrap.appendChild(text);\n\n if (prompt.answered) {\n const chosen = document.createElement('div');\n chosen.className = 'prompt-answered';\n chosen.textContent = `You chose: ${prompt.answered}`;\n wrap.appendChild(chosen);\n return wrap;\n }\n\n const buttons = document.createElement('div');\n buttons.className = 'prompt-buttons';\n for (const opt of prompt.options) {\n const btn = document.createElement('button');\n btn.className = 'prompt-button';\n btn.type = 'button';\n btn.textContent = opt.label;\n btn.addEventListener('click', () => {\n this.controller?.answerPrompt(prompt.requestId, opt.value);\n });\n buttons.appendChild(btn);\n }\n wrap.appendChild(buttons);\n return wrap;\n }\n\n /**\n * Build the collapsible \"Sources (N)\" block for an assistant message's\n * citations. Each source renders its `title` (linked to `citation.url` when\n * present — `target=_blank rel=noopener` — plain text otherwise) plus the\n * grounding `snippet`. Built with DOM APIs (not innerHTML) so citation text\n * can't inject markup.\n */\n private renderSources(citations: Citation[]): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'sources';\n wrap.setAttribute('part', 'sources');\n\n const details = document.createElement('details');\n details.open = true;\n\n const summary = document.createElement('summary');\n summary.textContent = `Sources (${citations.length})`;\n details.appendChild(summary);\n\n const list = document.createElement('ol');\n for (const c of citations) {\n const li = document.createElement('li');\n\n let titleEl: HTMLElement;\n // SECURITY: only absolute http(s) URLs may become a link href. A\n // citation URL comes from indexed content (web/GitHub connectors), so\n // an attacker-influenceable doc could carry `javascript:`/`data:`/\n // `vbscript:` — assigning those to `a.href` is a one-click XSS. Anything\n // that isn't a valid absolute http(s) URL renders as plain text.\n const safeUrl = safeHttpUrl(c.url);\n if (safeUrl) {\n const a = document.createElement('a');\n a.className = 'src-title';\n a.href = safeUrl;\n a.target = '_blank';\n a.rel = 'noopener noreferrer';\n titleEl = a;\n } else {\n titleEl = document.createElement('span');\n titleEl.className = 'src-title';\n }\n titleEl.textContent = c.title || c.id || 'Source';\n li.appendChild(titleEl);\n\n if (c.snippet) {\n const snip = document.createElement('span');\n snip.className = 'src-snippet';\n snip.textContent = c.snippet;\n li.appendChild(snip);\n }\n list.appendChild(li);\n }\n details.appendChild(list);\n wrap.appendChild(details);\n return wrap;\n }\n\n private renderStatus(): void {\n if (!this.statusEl) return;\n const label: Record<ConnectionStatus, string> = {\n idle: '',\n connecting: 'Connecting…',\n ready: 'Online',\n error: 'Connection issue',\n closed: 'Disconnected',\n };\n this.statusEl.textContent = label[this.status];\n }\n\n private renderComposerState(): void {\n const busy = this.status === 'connecting';\n if (this.sendBtn) this.sendBtn.disabled = busy;\n if (this.inputEl) this.inputEl.disabled = busy;\n }\n\n private submit(): void {\n if (!this.inputEl || !this.controller) return;\n const text = this.inputEl.value;\n if (!text.trim()) return;\n this.inputEl.value = '';\n void this.controller.send(text);\n }\n}\n\nfunction escapeHtml(value: string): string {\n return value.replace(/[&<>\"']/g, (c) => {\n switch (c) {\n case '&':\n return '&';\n case '<':\n return '<';\n case '>':\n return '>';\n case '\"':\n return '"';\n default:\n return ''';\n }\n });\n}\n\n/** Register the custom element once. Safe to call multiple times. */\nexport function defineChatWidget(): void {\n if (typeof customElements !== 'undefined' && !customElements.get(ELEMENT_TAG)) {\n customElements.define(ELEMENT_TAG, SmoothAgentChatElement);\n }\n}\n\n/**\n * Programmatically create, configure, and append a widget to the page.\n * Returns the element so the host can drive `openChat()` / `closeChat()`.\n */\nexport function mountChatWidget(config: ChatWidgetConfig, target: HTMLElement = document.body): SmoothAgentChatElement {\n defineChatWidget();\n const el = document.createElement(ELEMENT_TAG) as SmoothAgentChatElement;\n el.configure(config);\n target.appendChild(el);\n return el;\n}\n\n/**\n * Ergonomic helper for the full-page layout: mounts a `<smooth-agent-chat>` in\n * `mode: \"fullpage\"` (no launcher — the chat fills its container/viewport with a\n * Smooth-branded header, a scrollable message list, and an input bar) and\n * returns the element.\n *\n * `target` defaults to `document.body`; pass a sized container to embed the\n * full-page chat inside a layout region (e.g. a `/chat` route shell or an\n * iframe). The `mode` is forced to `\"fullpage\"` regardless of the passed config.\n *\n * ```ts\n * mountFullPageChat({ endpoint: 'wss://…/ws', agentId: '…', agentName: 'Support' });\n * ```\n */\nexport function mountFullPageChat(config: Omit<ChatWidgetConfig, 'mode'>, target: HTMLElement = document.body): SmoothAgentChatElement {\n return mountChatWidget({ ...config, mode: 'fullpage' }, target);\n}\n","/**\n * Standalone IIFE entry. Bundled (with the protocol client inlined) into\n * `dist/chat-widget.global.js` for a plain `<script src=\"…\">` embed.\n *\n * On load it:\n * - registers the `<smooth-agent-chat>` custom element, and\n * - exposes the programmatic API on the IIFE global `SmoothAgentChat`\n * (`window.SmoothAgentChat.mount({ endpoint, agentId })`).\n *\n * A host page can then either drop the element in markup:\n * <smooth-agent-chat endpoint=\"wss://…/ws\" agent-id=\"…\"></smooth-agent-chat>\n * or mount it programmatically:\n * SmoothAgentChat.mount({ endpoint: 'wss://…/ws', agentId: '…' });\n */\nimport type { ChatWidgetConfig } from './config.js';\nimport { defineChatWidget, mountChatWidget, mountFullPageChat, SmoothAgentChatElement } from './element.js';\n\ndefineChatWidget();\n\nexport { defineChatWidget, mountChatWidget, mountFullPageChat, SmoothAgentChatElement };\n\n/** Convenience alias matching the global API surface (`SmoothAgentChat.mount`). */\nexport function mount(config: ChatWidgetConfig, target?: HTMLElement): SmoothAgentChatElement {\n return mountChatWidget(config, target);\n}\n\n/**\n * Full-page convenience alias (`SmoothAgentChat.mountFullPage`): mounts the chat\n * in `mode: \"fullpage\"` so it fills its container/viewport with no launcher.\n */\nexport function mountFullPage(config: Omit<ChatWidgetConfig, 'mode'>, target?: HTMLElement): SmoothAgentChatElement {\n return mountFullPageChat(config, target);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smooai/smooth-operator",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.8",
|
|
4
4
|
"description": "TypeScript SDK for the smooth-operator WebSocket protocol: the native client (`.`), React bindings (`./react`), and the embeddable web-component chat widget (`./widget`). Generated from the language-neutral JSON Schemas in spec/.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/src/client.ts
CHANGED
|
@@ -66,6 +66,24 @@ export interface SmoothAgentClientOptions {
|
|
|
66
66
|
turnTimeout?: number;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/** One row returned by {@link SmoothAgentClient.listConversations} — enough to
|
|
70
|
+
* render a sidebar entry and resume the conversation on click. */
|
|
71
|
+
export interface ConversationSummary {
|
|
72
|
+
/** Pass to {@link SmoothAgentClient.createConversationSession} as `conversationId` to resume. */
|
|
73
|
+
conversationId: string;
|
|
74
|
+
/** Short preview title derived from the first message (may be empty). */
|
|
75
|
+
title: string;
|
|
76
|
+
/** ISO-8601 last-activity timestamp (rows come most-recent first). */
|
|
77
|
+
updatedAt: string;
|
|
78
|
+
/** Number of messages in the conversation. */
|
|
79
|
+
messageCount: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Payload of the `list_conversations` `immediate_response`. */
|
|
83
|
+
export interface ListConversationsResponse {
|
|
84
|
+
conversations: ConversationSummary[];
|
|
85
|
+
}
|
|
86
|
+
|
|
69
87
|
/** Events that terminate a streaming turn (success or error). */
|
|
70
88
|
const TURN_TERMINAL = new Set(['eventual_response', 'error']);
|
|
71
89
|
|
|
@@ -300,14 +318,36 @@ export class SmoothAgentClient {
|
|
|
300
318
|
|
|
301
319
|
// ───────────────────────────── Actions ─────────────────────────────────
|
|
302
320
|
|
|
303
|
-
/**
|
|
321
|
+
/**
|
|
322
|
+
* Start a new conversation session — or **resume** an existing one by passing
|
|
323
|
+
* its `conversationId`. On resume the server binds the new session to that
|
|
324
|
+
* conversation (reusing its id + org + persisted history) so subsequent
|
|
325
|
+
* `send_message`s append to it; pair it with {@link getMessages} to load the
|
|
326
|
+
* transcript. Resolves with the session descriptor.
|
|
327
|
+
*/
|
|
304
328
|
async createConversationSession(
|
|
305
|
-
req: Omit<CreateConversationSessionRequest, 'action' | 'requestId'
|
|
329
|
+
req: Omit<CreateConversationSessionRequest, 'action' | 'requestId'> & { conversationId?: string },
|
|
306
330
|
): Promise<CreateConversationSessionResponse> {
|
|
307
331
|
const event = await this.request({ action: 'create_conversation_session', ...req });
|
|
308
332
|
return extractImmediateData<CreateConversationSessionResponse>(event);
|
|
309
333
|
}
|
|
310
334
|
|
|
335
|
+
/**
|
|
336
|
+
* List the org's conversations that have at least one message, most-recent
|
|
337
|
+
* first — the substrate for a conversation sidebar / resume picker. Each row
|
|
338
|
+
* carries a short title preview, `updatedAt`, and a message count. Pass
|
|
339
|
+
* `limit` to cap the result (server default 50).
|
|
340
|
+
*
|
|
341
|
+
* `list_conversations` has no dedicated action schema in `spec/` yet, so it is
|
|
342
|
+
* not a member of the generated `ClientAction` union — hence the local cast.
|
|
343
|
+
* ponytail: promote to a real spec/actions schema if a second consumer needs
|
|
344
|
+
* it typed end-to-end.
|
|
345
|
+
*/
|
|
346
|
+
async listConversations(req: { limit?: number } = {}): Promise<ListConversationsResponse> {
|
|
347
|
+
const event = await this.request({ action: 'list_conversations', ...req } as unknown as Omit<ClientAction, 'requestId'>);
|
|
348
|
+
return extractImmediateData<ListConversationsResponse>(event);
|
|
349
|
+
}
|
|
350
|
+
|
|
311
351
|
/** Fetch a session snapshot by ID. */
|
|
312
352
|
async getSession(req: Omit<GetSessionRequest, 'action' | 'requestId'>): Promise<GetSessionResponse> {
|
|
313
353
|
const event = await this.request({ action: 'get_session', ...req });
|