@dabalabs/agent 0.0.1-beta → 0.0.4-beta

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.
Files changed (44) hide show
  1. package/README.md +56 -3
  2. package/dist/chunk-3BQ6LE6X.cjs +222 -0
  3. package/dist/chunk-3BQ6LE6X.cjs.map +1 -0
  4. package/dist/chunk-ETI4LRM7.js +5936 -0
  5. package/dist/chunk-ETI4LRM7.js.map +1 -0
  6. package/dist/chunk-TYOHYQDK.js +220 -0
  7. package/dist/chunk-TYOHYQDK.js.map +1 -0
  8. package/dist/chunk-VAIC5ACS.cjs +5939 -0
  9. package/dist/chunk-VAIC5ACS.cjs.map +1 -0
  10. package/dist/custom-element.cjs +4 -4
  11. package/dist/custom-element.d.cts +191 -2
  12. package/dist/custom-element.d.ts +191 -2
  13. package/dist/custom-element.js +2 -2
  14. package/dist/daba-agent.cjs +5 -14
  15. package/dist/daba-agent.d.cts +2 -4
  16. package/dist/daba-agent.d.ts +2 -4
  17. package/dist/daba-agent.js +2 -3
  18. package/dist/daba-agent.min.js +1847 -215
  19. package/dist/daba-agent.min.js.map +1 -1
  20. package/dist/react.cjs +41 -14
  21. package/dist/react.cjs.map +1 -1
  22. package/dist/react.d.cts +1 -1
  23. package/dist/react.d.ts +1 -1
  24. package/dist/react.js +38 -2
  25. package/dist/react.js.map +1 -1
  26. package/dist/types-BQRgqD4n.d.cts +305 -0
  27. package/dist/types-BQRgqD4n.d.ts +305 -0
  28. package/package.json +2 -2
  29. package/dist/chunk-EF6D33VT.cjs +0 -103
  30. package/dist/chunk-EF6D33VT.cjs.map +0 -1
  31. package/dist/chunk-G22V7GGM.js +0 -1667
  32. package/dist/chunk-G22V7GGM.js.map +0 -1
  33. package/dist/chunk-N4TBGDUO.cjs +0 -1669
  34. package/dist/chunk-N4TBGDUO.cjs.map +0 -1
  35. package/dist/chunk-QM6HDEVV.js +0 -39
  36. package/dist/chunk-QM6HDEVV.js.map +0 -1
  37. package/dist/chunk-WJQ444GI.js +0 -100
  38. package/dist/chunk-WJQ444GI.js.map +0 -1
  39. package/dist/chunk-ZXZX2D55.cjs +0 -45
  40. package/dist/chunk-ZXZX2D55.cjs.map +0 -1
  41. package/dist/custom-element-CpPr7b2Z.d.ts +0 -66
  42. package/dist/custom-element-XiZg8UN8.d.cts +0 -66
  43. package/dist/types-DYRGPzyp.d.cts +0 -76
  44. package/dist/types-DYRGPzyp.d.ts +0 -76
package/README.md CHANGED
@@ -61,6 +61,8 @@ import '@dabalabs/agent/custom-element';
61
61
 
62
62
  ### 2. React Component (`<DabaAgent />`) — React & Next.js
63
63
 
64
+ Import it at the top of the file like any other component and pass the configuration as props. No `useEffect`, no dynamic `import()`, no `next/dynamic`.
65
+
64
66
  ```tsx
65
67
  "use client";
66
68
 
@@ -72,12 +74,24 @@ export function App() {
72
74
  projectId="YOUR_PROJECT_ID"
73
75
  apiKey="YOUR_API_KEY"
74
76
  position="bottom-right"
77
+ historyEnabled
78
+ launcher={{ size: "64px", iconText: "👋" }}
79
+ panel={{ width: "440px", height: "700px" }}
75
80
  onStatusChange={(status) => console.log("Agent status:", status)}
76
81
  />
77
82
  );
78
83
  }
79
84
  ```
80
85
 
86
+ Props are `DabaAgentOptions` minus `container` — the component owns where the widget mounts. They are compared by value, so an inline `theme={{ accentColor: "#0c8c5e" }}` does not rebuild the widget on every render of the parent.
87
+
88
+ **Note the entry point.** `@dabalabs/agent/react` gives you the React *component*; the package root gives you the *class*. Both are named `DabaAgent`, because in each context that is the right thing to get:
89
+
90
+ ```ts
91
+ import { DabaAgent } from "@dabalabs/agent"; // class — new DabaAgent({...})
92
+ import { DabaAgent } from "@dabalabs/agent/react"; // component — <DabaAgent {...} />
93
+ ```
94
+
81
95
  ---
82
96
 
83
97
  ### 3. Programmatic Class API (`new DabaAgent()`)
@@ -92,6 +106,8 @@ const agent = new DabaAgent({
92
106
  });
93
107
  ```
94
108
 
109
+ Every entry point is safe to import on a server: the module evaluates to nothing that touches the DOM, so Next.js, Remix and Astro can render the file that imports it. The widget itself is created when you construct it or when the component mounts, both of which only ever happen in a browser.
110
+
95
111
  Get a project ID and API key from the Developer section of your [dabalabs dashboard](https://dabalabs.com/dashboard/developer) — the same API key used for the [dabalabs](https://www.npmjs.com/package/dabalabs) video player works here too.
96
112
 
97
113
  ## Custom Events on Web Component (`<daba-agent>`)
@@ -122,7 +138,26 @@ The API key is meant to sit in your site's frontend source, the same trust model
122
138
  | `apiKey` / `api-key` | `string` | Your publishable API key |
123
139
  | `position` | `"bottom-right" \| "bottom-left" \| "top-right" \| "top-left"` | Corner of the viewport for the default badge (default: `"bottom-right"`). |
124
140
  | `accentColor` / `accent-color` | `string` | Accent color hex for the badge's active-state indicator |
125
- | `hotkey` | `string \| null` | Keyboard shortcut to toggle the agent (default: `"ctrl+space"`). Pass `null` to disable. |
141
+ | `hotkey` | `string \| null` | Keyboard shortcut. A combination (`"ctrl+space"`, `"alt+k"`) **toggles** the assistant. A modifier held alone (`"hold:ctrl"`, also `hold:alt`, `hold:shift`, `hold:meta`) **starts** it after ~600ms and never stops it — the launcher ends a conversation. The hold is abandoned the moment another key or a click joins it, so `Ctrl+C` and a Mac's Control-click never trip it. Defaults to `alt+space` on macOS (the OS takes Ctrl+Space) and `ctrl+space` elsewhere. `null` disables it. |
142
+ | `historyEnabled` / `history-enabled` | `boolean` | Keep past conversations in this browser so the visitor can go back to one. **Off by default** — see [Where your visitors' data lives](#where-your-visitors-data-lives). |
143
+ | `launcher.size` / `launcher-size` | CSS length | The launcher button (default `56px`; `52px` below 480px wide, which an explicit value overrides). |
144
+ | `launcher.iconSize` / `launcher-icon-size` | CSS length | The mark inside the button (default `100%`). |
145
+ | `launcher.iconUrl` / `launcher-icon-url` | `string` | Replace the mark with an image. |
146
+ | `launcher.iconSvg` / `launcher-icon-svg` | `string` | Replace the mark with inline SVG. Wins over `iconUrl`, and unlike an `<img>` it survives a strict `img-src` CSP and can inherit `currentColor`. Sanitised before it is inserted. |
147
+ | `launcher.iconText` / `launcher-icon-text` | `string` | Replace the mark with an emoji or a letter or two. |
148
+ | `launcher.shape` / `launcher-shape` | `"rounded" \| "circle" \| "pill"` | The launcher's silhouette. |
149
+ | `launcher.label` / `launcher-label` | `string` | Text beside the mark, turning the badge into a labelled pill. |
150
+ | `panel.width` / `panel-width` | CSS length | The chat panel (default `400px`). Ignored below 480px wide, where the panel goes full-screen. |
151
+ | `panel.height` / `panel-height` | CSS length | The chat panel (default `740px`), still clamped to the viewport. |
152
+ | `logoUrl` / `logo-url` | `string` | Your logo in the panel header and on the intro screen. |
153
+ | `logoSvg` / `logo-svg` | `string` | The same, as inline SVG. |
154
+ | `iconBackgroundColor` / `icon-background-color` | `string` | Recolour the shipped mark's background, in the launcher **and** the panel. |
155
+ | `iconMarkColor` / `icon-mark-color` | `string` | Recolour the shipped mark's centre shape. |
156
+ | `mode` | `"hybrid" \| "voice" \| "chat"` | Which media the assistant offers (default: the project's dashboard setting, then `hybrid`). |
157
+ | `theme` | `DabaTheme` | Colour and shape overrides — `accentColor`, `surfaceColor`, `textColor`, `radius`, `fontFamily`, and `theme: "auto" \| "light" \| "dark"`. |
158
+ | `intro` | `DabaIntro` | The first-open screen: `headline`, `subheadline`, `suggestedPrompts`, optional media. |
159
+ | `uiLanguage` / `ui-language` | `string` | BCP-47 code for the panel's own chrome, or `"auto"` to follow the page's `lang`. Independent of what the assistant replies in. |
160
+ | `direction` | `"auto" \| "ltr" \| "rtl"` | Text direction of the panel (default `auto`). |
126
161
  | `gatewayUrl` / `gateway-url` | `string` (optional) | Base URL of the gateway (defaults to `"https://api.dabalabs.com"`) |
127
162
  | `onStatusChange` | `(status: DabaAgentStatus) => void` | Fired as the agent moves through status lifecycle (React / JS API) |
128
163
  | `onTranscript` | `(role: "user" \| "agent", text: string, isFinal: boolean) => void` | Fired with transcript deltas (React / JS API) |
@@ -131,7 +166,13 @@ The API key is meant to sit in your site's frontend source, the same trust model
131
166
  ## Methods (on `agent` instance or `element.dabaAgent`)
132
167
 
133
168
  - `agent.toggle()` — start or stop a session
134
- - `agent.destroy()` — tear down the session, remove the badge, and detach all listeners
169
+ - `agent.sendText(text)` — send a text turn
170
+ - `agent.openChat()` / `closeChat()` / `toggleChat()` — the panel
171
+ - `agent.resetConversation()` — start a fresh thread
172
+ - `agent.listConversations()` — the archive, newest first (empty unless `historyEnabled`)
173
+ - `agent.openConversation(id)` — reopen an archived thread as the live one
174
+ - `agent.deleteConversation(id)` / `agent.clearHistory()`
175
+ - `agent.destroy()` — tear down the session, release the microphone, remove the badge, and detach all listeners
135
176
  - `agent.currentStatus` — the current `DabaAgentStatus`
136
177
  - `agent.isActive` — whether a session is currently running
137
178
 
@@ -148,6 +189,18 @@ The API key is meant to sit in your site's frontend source, the same trust model
148
189
  - `data-daba-agent-restricted` on `<html>`, or `<meta name="daba-agent-restricted">` in `<head>`, opts an entire page out — the agent won't read the page or start a session there at all. Use this on account, billing, or checkout pages.
149
190
  - Password fields, payment fields (`autocomplete="cc-*"`), and labels that read like a PIN or security code are never filled or spoken back, regardless of how the model was asked.
150
191
 
192
+ ## Where your visitors' data lives
193
+
194
+ Everything the widget stores is in the visitor's own browser. None of it is sent anywhere by the widget itself.
195
+
196
+ | What | Where | How long |
197
+ | --- | --- | --- |
198
+ | The open conversation's id and transcript | `sessionStorage` | The tab. A conversation is a visit, not an identity. |
199
+ | A short-lived key for resuming a voice session across a page navigation | `sessionStorage` | 30 seconds |
200
+ | Past conversations, **only with `historyEnabled`** | `localStorage` | 30 days, 20 conversations |
201
+
202
+ `historyEnabled` is off by default on purpose: an archive outlives the tab, and on a shared or public machine that is a decision an embed should make deliberately rather than inherit. When it is on, the visitor gets a history button in the panel header and can delete any single thread or clear the lot.
203
+
151
204
  ## Browser support
152
205
 
153
206
  Requires `WebSocket`, `AudioContext`, and `getUserMedia` — every evergreen browser. The widget itself renders no UI beyond the floating badge, so it has no layout dependencies on the host page.
@@ -158,7 +211,7 @@ MIT
158
211
 
159
212
  ## Environments
160
213
 
161
- By default the widget talks to Dabalabs production. Point it at staging
214
+ By default the widget talks to DabaLabs production. Point it at staging
162
215
  with `env`:
163
216
 
164
217
  ```html
@@ -0,0 +1,222 @@
1
+ 'use strict';
2
+
3
+ var chunkVAIC5ACS_cjs = require('./chunk-VAIC5ACS.cjs');
4
+
5
+ // src/components/custom-element.ts
6
+ var VALID_POSITIONS = [
7
+ "bottom-right",
8
+ "bottom-left",
9
+ "top-right",
10
+ "top-left"
11
+ ];
12
+ var VALID_MODES = ["voice", "chat", "hybrid"];
13
+ var VALID_DIRECTIONS = ["auto", "ltr", "rtl"];
14
+ var VALID_THEMES = ["auto", "light", "dark"];
15
+ var VALID_LAUNCHER_SHAPES = ["rounded", "circle", "pill"];
16
+ var VALID_MEDIA_TYPES = ["video", "image", "none"];
17
+ var PROMPT_SEPARATOR = "|";
18
+ function readAttr(el, name) {
19
+ for (const attr of [name, `data-${name}`]) {
20
+ const raw = el.getAttribute(attr);
21
+ if (raw === null) continue;
22
+ const value = raw.trim();
23
+ if (value === "") continue;
24
+ return { attr, value };
25
+ }
26
+ return void 0;
27
+ }
28
+ function stringAttr(el, name) {
29
+ return readAttr(el, name)?.value;
30
+ }
31
+ function enumAttr(el, name, allowed) {
32
+ const found = readAttr(el, name);
33
+ if (!found) return void 0;
34
+ if (allowed.includes(found.value)) return found.value;
35
+ console.error(
36
+ `daba-agent: invalid ${found.attr} "${found.value}" on <daba-agent>. Expected one of ${allowed.join(
37
+ ", "
38
+ )} \u2014 ignoring it.`,
39
+ el
40
+ );
41
+ return void 0;
42
+ }
43
+ function flagAttr(el, name) {
44
+ for (const attr of [name, `data-${name}`]) {
45
+ const raw = el.getAttribute(attr);
46
+ if (raw === null) continue;
47
+ const value = raw.trim().toLowerCase();
48
+ return value !== "false" && value !== "0" && value !== "no";
49
+ }
50
+ return void 0;
51
+ }
52
+ function promptsAttr(el, name) {
53
+ const found = readAttr(el, name);
54
+ if (!found) return void 0;
55
+ const prompts = found.value.split(PROMPT_SEPARATOR).map((prompt) => prompt.trim()).filter((prompt) => prompt !== "");
56
+ return prompts.length > 0 ? prompts : void 0;
57
+ }
58
+ function lengthAttr(el, name) {
59
+ const found = readAttr(el, name);
60
+ if (!found) return void 0;
61
+ const length = chunkVAIC5ACS_cjs.cssLength(found.value, false);
62
+ if (length) return length;
63
+ console.error(
64
+ `daba-agent: invalid ${found.attr} "${found.value}" on <daba-agent>. Expected a CSS length such as "400px", "28rem" or "90%".`,
65
+ el
66
+ );
67
+ return void 0;
68
+ }
69
+ function group(fields) {
70
+ return Object.values(fields).some((value) => value !== void 0) ? fields : void 0;
71
+ }
72
+ function buildElementClass() {
73
+ return class DabaAgentElement extends HTMLElement {
74
+ constructor() {
75
+ super(...arguments);
76
+ this.agent = null;
77
+ }
78
+ connectedCallback() {
79
+ if (this.agent) return;
80
+ const projectId = stringAttr(this, "project-id");
81
+ const apiKey = stringAttr(this, "api-key");
82
+ if (!projectId || !apiKey) {
83
+ console.error(
84
+ "daba-agent: <daba-agent> custom element requires project-id and api-key attributes.",
85
+ this
86
+ );
87
+ return;
88
+ }
89
+ const position = enumAttr(this, "position", VALID_POSITIONS);
90
+ const accentColor = stringAttr(this, "accent-color");
91
+ const mode = enumAttr(this, "mode", VALID_MODES);
92
+ const title = stringAttr(this, "title");
93
+ const placeholder = stringAttr(this, "placeholder");
94
+ const initialOpen = flagAttr(this, "initial-open");
95
+ const hotkey = stringAttr(this, "hotkey");
96
+ const gatewayUrl = stringAttr(this, "gateway-url");
97
+ const env = stringAttr(this, "env");
98
+ const theme = group({
99
+ accentColor,
100
+ accentContrast: stringAttr(this, "accent-contrast"),
101
+ surfaceColor: stringAttr(this, "surface-color"),
102
+ textColor: stringAttr(this, "text-color"),
103
+ radius: stringAttr(this, "radius"),
104
+ fontFamily: stringAttr(this, "font-family"),
105
+ theme: enumAttr(this, "theme", VALID_THEMES)
106
+ });
107
+ const introDisabled = flagAttr(this, "intro-disabled");
108
+ const intro = group({
109
+ enabled: introDisabled === void 0 ? void 0 : !introDisabled,
110
+ headline: stringAttr(this, "intro-headline"),
111
+ subheadline: stringAttr(this, "intro-subheadline"),
112
+ mediaUrl: stringAttr(this, "intro-media-url"),
113
+ mediaType: enumAttr(this, "intro-media-type", VALID_MEDIA_TYPES),
114
+ suggestedPrompts: promptsAttr(this, "suggested-prompts")
115
+ });
116
+ const launcher = group({
117
+ shape: enumAttr(this, "launcher-shape", VALID_LAUNCHER_SHAPES),
118
+ iconUrl: stringAttr(this, "launcher-icon-url"),
119
+ iconSvg: stringAttr(this, "launcher-icon-svg"),
120
+ iconText: stringAttr(this, "launcher-icon-text"),
121
+ label: stringAttr(this, "launcher-label"),
122
+ size: lengthAttr(this, "launcher-size"),
123
+ iconSize: lengthAttr(this, "launcher-icon-size")
124
+ });
125
+ const panel = group({
126
+ width: lengthAttr(this, "panel-width"),
127
+ height: lengthAttr(this, "panel-height")
128
+ });
129
+ this.agent = new chunkVAIC5ACS_cjs.DabaAgent({
130
+ container: this,
131
+ projectId,
132
+ apiKey,
133
+ position,
134
+ accentColor,
135
+ mode,
136
+ title,
137
+ placeholder,
138
+ initialOpen,
139
+ historyEnabled: flagAttr(this, "history-enabled"),
140
+ hotkey,
141
+ gatewayUrl,
142
+ env,
143
+ theme,
144
+ intro,
145
+ launcher,
146
+ panel,
147
+ logoUrl: stringAttr(this, "logo-url"),
148
+ logoSvg: stringAttr(this, "logo-svg"),
149
+ iconBackgroundColor: stringAttr(this, "icon-background-color"),
150
+ iconMarkColor: stringAttr(this, "icon-mark-color"),
151
+ uiLanguage: stringAttr(this, "ui-language"),
152
+ direction: enumAttr(this, "direction", VALID_DIRECTIONS),
153
+ onStatusChange: (status) => {
154
+ this.dispatchEvent(
155
+ new CustomEvent("daba-status-change", { detail: { status }, bubbles: true, composed: true })
156
+ );
157
+ },
158
+ onTranscript: (role, text, isFinal) => {
159
+ this.dispatchEvent(
160
+ new CustomEvent("daba-transcript", {
161
+ detail: { role, text, isFinal },
162
+ bubbles: true,
163
+ composed: true
164
+ })
165
+ );
166
+ },
167
+ onError: (error) => {
168
+ this.dispatchEvent(
169
+ new CustomEvent("daba-error", { detail: { error }, bubbles: true, composed: true })
170
+ );
171
+ },
172
+ onChatToggle: (isOpen) => {
173
+ this.dispatchEvent(
174
+ new CustomEvent("daba-chat-toggle", { detail: { isOpen }, bubbles: true, composed: true })
175
+ );
176
+ },
177
+ // Cards arrive once per reply that carried structured items, so a
178
+ // host page can render them in its own layout instead of (or as well
179
+ // as) the panel's — a listing site putting event cards on the page.
180
+ onCards: (cards) => {
181
+ this.dispatchEvent(
182
+ new CustomEvent("daba-cards", { detail: { cards }, bubbles: true, composed: true })
183
+ );
184
+ }
185
+ });
186
+ }
187
+ disconnectedCallback() {
188
+ if (this.agent) {
189
+ this.agent.destroy();
190
+ this.agent = null;
191
+ }
192
+ }
193
+ get dabaAgent() {
194
+ return this.agent;
195
+ }
196
+ sendText(text) {
197
+ return this.agent?.sendText(text);
198
+ }
199
+ openChat() {
200
+ this.agent?.openChat();
201
+ }
202
+ closeChat() {
203
+ this.agent?.closeChat();
204
+ }
205
+ toggleChat() {
206
+ this.agent?.toggleChat();
207
+ }
208
+ };
209
+ }
210
+ exports.DabaAgentElement = void 0;
211
+ function defineDabaAgentElement(tagName = "daba-agent") {
212
+ if (typeof window === "undefined" || typeof customElements === "undefined") return;
213
+ if (customElements.get(tagName)) return;
214
+ const ctor = buildElementClass();
215
+ customElements.define(tagName, ctor);
216
+ exports.DabaAgentElement ?? (exports.DabaAgentElement = ctor);
217
+ }
218
+ defineDabaAgentElement();
219
+
220
+ exports.defineDabaAgentElement = defineDabaAgentElement;
221
+ //# sourceMappingURL=chunk-3BQ6LE6X.cjs.map
222
+ //# sourceMappingURL=chunk-3BQ6LE6X.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/custom-element.ts"],"names":["cssLength","DabaAgent","DabaAgentElement"],"mappings":";;;;;AAeA,IAAM,eAAA,GAAgD;AAAA,EACpD,cAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA;AACA,IAAM,WAAA,GAAwC,CAAC,OAAA,EAAS,MAAA,EAAQ,QAAQ,CAAA;AACxE,IAAM,gBAAA,GAA6C,CAAC,MAAA,EAAQ,KAAA,EAAO,KAAK,CAAA;AACxE,IAAM,YAAA,GAA+C,CAAC,MAAA,EAAQ,OAAA,EAAS,MAAM,CAAA;AAC7E,IAAM,qBAAA,GAAsD,CAAC,SAAA,EAAW,QAAA,EAAU,MAAM,CAAA;AACxF,IAAM,iBAAA,GAAoB,CAAC,OAAA,EAAS,OAAA,EAAS,MAAM,CAAA;AAKnD,IAAM,gBAAA,GAAmB,GAAA;AAezB,SAAS,QAAA,CAAS,IAAiB,IAAA,EAA2D;AAC5F,EAAA,KAAA,MAAW,QAAQ,CAAC,IAAA,EAAM,CAAA,KAAA,EAAQ,IAAI,EAAE,CAAA,EAAG;AACzC,IAAA,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,CAAa,IAAI,CAAA;AAChC,IAAA,IAAI,QAAQ,IAAA,EAAM;AAClB,IAAA,MAAM,KAAA,GAAQ,IAAI,IAAA,EAAK;AACvB,IAAA,IAAI,UAAU,EAAA,EAAI;AAClB,IAAA,OAAO,EAAE,MAAM,KAAA,EAAM;AAAA,EACvB;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,UAAA,CAAW,IAAiB,IAAA,EAAkC;AACrE,EAAA,OAAO,QAAA,CAAS,EAAA,EAAI,IAAI,CAAA,EAAG,KAAA;AAC7B;AAKA,SAAS,QAAA,CACP,EAAA,EACA,IAAA,EACA,OAAA,EACe;AACf,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,EAAA,EAAI,IAAI,CAAA;AAC/B,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,IAAK,QAA8B,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA,SAAU,KAAA,CAAM,KAAA;AACvE,EAAA,OAAA,CAAQ,KAAA;AAAA,IACN,uBAAuB,KAAA,CAAM,IAAI,KAAK,KAAA,CAAM,KAAK,sCAAsC,OAAA,CAAQ,IAAA;AAAA,MAC7F;AAAA,KACD,CAAA,oBAAA,CAAA;AAAA,IACD;AAAA,GACF;AACA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,QAAA,CAAS,IAAiB,IAAA,EAAmC;AACpE,EAAA,KAAA,MAAW,QAAQ,CAAC,IAAA,EAAM,CAAA,KAAA,EAAQ,IAAI,EAAE,CAAA,EAAG;AACzC,IAAA,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,CAAa,IAAI,CAAA;AAChC,IAAA,IAAI,QAAQ,IAAA,EAAM;AAClB,IAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,IAAA,EAAK,CAAE,WAAA,EAAY;AACrC,IAAA,OAAO,KAAA,KAAU,OAAA,IAAW,KAAA,KAAU,GAAA,IAAO,KAAA,KAAU,IAAA;AAAA,EACzD;AACA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,WAAA,CAAY,IAAiB,IAAA,EAAoC;AACxE,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,EAAA,EAAI,IAAI,CAAA;AAC/B,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,MAAM,UAAU,KAAA,CAAM,KAAA,CACnB,KAAA,CAAM,gBAAgB,EACtB,GAAA,CAAI,CAAC,MAAA,KAAW,MAAA,CAAO,MAAM,CAAA,CAC7B,OAAO,CAAC,MAAA,KAAW,WAAW,EAAE,CAAA;AACnC,EAAA,OAAO,OAAA,CAAQ,MAAA,GAAS,CAAA,GAAI,OAAA,GAAU,MAAA;AACxC;AAOA,SAAS,UAAA,CAAW,IAAiB,IAAA,EAAkC;AACrE,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,EAAA,EAAI,IAAI,CAAA;AAC/B,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,MAAM,MAAA,GAASA,2BAAA,CAAU,KAAA,CAAM,KAAA,EAAO,KAAK,CAAA;AAC3C,EAAA,IAAI,QAAQ,OAAO,MAAA;AACnB,EAAA,OAAA,CAAQ,KAAA;AAAA,IACN,CAAA,oBAAA,EAAuB,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,MAAM,KAAK,CAAA,2EAAA,CAAA;AAAA,IACjD;AAAA,GACF;AACA,EAAA,OAAO,MAAA;AACT;AAIA,SAAS,MAAwB,MAAA,EAA0B;AACzD,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA,CAAK,CAAC,KAAA,KAAU,KAAA,KAAU,MAAS,CAAA,GAAI,MAAA,GAAS,MAAA;AAC/E;AA8BA,SAAS,iBAAA,GAAiD;AACxD,EAAA,OAAO,MAAM,yBAAyB,WAAA,CAAY;AAAA,IAA3C,WAAA,GAAA;AAAA,MAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AAEL,MAAA,IAAA,CAAQ,KAAA,GAA0B,IAAA;AAAA,IAAA;AAAA,IAElC,iBAAA,GAA0B;AACxB,MAAA,IAAI,KAAK,KAAA,EAAO;AAEhB,MAAA,MAAM,SAAA,GAAY,UAAA,CAAW,IAAA,EAAM,YAAY,CAAA;AAC/C,MAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,EAAM,SAAS,CAAA;AAEzC,MAAA,IAAI,CAAC,SAAA,IAAa,CAAC,MAAA,EAAQ;AACzB,QAAA,OAAA,CAAQ,KAAA;AAAA,UACN,qFAAA;AAAA,UACA;AAAA,SACF;AACA,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GAAW,QAAA,CAAS,IAAA,EAAM,UAAA,EAAY,eAAe,CAAA;AAC3D,MAAA,MAAM,WAAA,GAAc,UAAA,CAAW,IAAA,EAAM,cAAc,CAAA;AACnD,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,EAAM,MAAA,EAAQ,WAAW,CAAA;AAC/C,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,EAAM,OAAO,CAAA;AACtC,MAAA,MAAM,WAAA,GAAc,UAAA,CAAW,IAAA,EAAM,aAAa,CAAA;AAClD,MAAA,MAAM,WAAA,GAAc,QAAA,CAAS,IAAA,EAAM,cAAc,CAAA;AACjD,MAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,EAAM,QAAQ,CAAA;AACxC,MAAA,MAAM,UAAA,GAAa,UAAA,CAAW,IAAA,EAAM,aAAa,CAAA;AAIjD,MAAA,MAAM,GAAA,GAAM,UAAA,CAAW,IAAA,EAAM,KAAK,CAAA;AAMlC,MAAA,MAAM,QAAQ,KAAA,CAAiB;AAAA,QAC7B,WAAA;AAAA,QACA,cAAA,EAAgB,UAAA,CAAW,IAAA,EAAM,iBAAiB,CAAA;AAAA,QAClD,YAAA,EAAc,UAAA,CAAW,IAAA,EAAM,eAAe,CAAA;AAAA,QAC9C,SAAA,EAAW,UAAA,CAAW,IAAA,EAAM,YAAY,CAAA;AAAA,QACxC,MAAA,EAAQ,UAAA,CAAW,IAAA,EAAM,QAAQ,CAAA;AAAA,QACjC,UAAA,EAAY,UAAA,CAAW,IAAA,EAAM,aAAa,CAAA;AAAA,QAC1C,KAAA,EAAO,QAAA,CAAS,IAAA,EAAM,OAAA,EAAS,YAAY;AAAA,OAC5C,CAAA;AAKD,MAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,IAAA,EAAM,gBAAgB,CAAA;AACrD,MAAA,MAAM,QAAQ,KAAA,CAAiB;AAAA,QAC7B,OAAA,EAAS,aAAA,KAAkB,MAAA,GAAY,MAAA,GAAY,CAAC,aAAA;AAAA,QACpD,QAAA,EAAU,UAAA,CAAW,IAAA,EAAM,gBAAgB,CAAA;AAAA,QAC3C,WAAA,EAAa,UAAA,CAAW,IAAA,EAAM,mBAAmB,CAAA;AAAA,QACjD,QAAA,EAAU,UAAA,CAAW,IAAA,EAAM,iBAAiB,CAAA;AAAA,QAC5C,SAAA,EAAW,QAAA,CAAS,IAAA,EAAM,kBAAA,EAAoB,iBAAiB,CAAA;AAAA,QAC/D,gBAAA,EAAkB,WAAA,CAAY,IAAA,EAAM,mBAAmB;AAAA,OACxD,CAAA;AAED,MAAA,MAAM,WAAW,KAAA,CAAoB;AAAA,QACnC,KAAA,EAAO,QAAA,CAAS,IAAA,EAAM,gBAAA,EAAkB,qBAAqB,CAAA;AAAA,QAC7D,OAAA,EAAS,UAAA,CAAW,IAAA,EAAM,mBAAmB,CAAA;AAAA,QAC7C,OAAA,EAAS,UAAA,CAAW,IAAA,EAAM,mBAAmB,CAAA;AAAA,QAC7C,QAAA,EAAU,UAAA,CAAW,IAAA,EAAM,oBAAoB,CAAA;AAAA,QAC/C,KAAA,EAAO,UAAA,CAAW,IAAA,EAAM,gBAAgB,CAAA;AAAA,QACxC,IAAA,EAAM,UAAA,CAAW,IAAA,EAAM,eAAe,CAAA;AAAA,QACtC,QAAA,EAAU,UAAA,CAAW,IAAA,EAAM,oBAAoB;AAAA,OAChD,CAAA;AAED,MAAA,MAAM,QAAQ,KAAA,CAAiB;AAAA,QAC7B,KAAA,EAAO,UAAA,CAAW,IAAA,EAAM,aAAa,CAAA;AAAA,QACrC,MAAA,EAAQ,UAAA,CAAW,IAAA,EAAM,cAAc;AAAA,OACxC,CAAA;AAED,MAAA,IAAA,CAAK,KAAA,GAAQ,IAAIC,2BAAA,CAAU;AAAA,QACzB,SAAA,EAAW,IAAA;AAAA,QACX,SAAA;AAAA,QACA,MAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA,IAAA;AAAA,QACA,KAAA;AAAA,QACA,WAAA;AAAA,QACA,WAAA;AAAA,QACA,cAAA,EAAgB,QAAA,CAAS,IAAA,EAAM,iBAAiB,CAAA;AAAA,QAChD,MAAA;AAAA,QACA,UAAA;AAAA,QACA,GAAA;AAAA,QACA,KAAA;AAAA,QACA,KAAA;AAAA,QACA,QAAA;AAAA,QACA,KAAA;AAAA,QACA,OAAA,EAAS,UAAA,CAAW,IAAA,EAAM,UAAU,CAAA;AAAA,QACpC,OAAA,EAAS,UAAA,CAAW,IAAA,EAAM,UAAU,CAAA;AAAA,QACpC,mBAAA,EAAqB,UAAA,CAAW,IAAA,EAAM,uBAAuB,CAAA;AAAA,QAC7D,aAAA,EAAe,UAAA,CAAW,IAAA,EAAM,iBAAiB,CAAA;AAAA,QACjD,UAAA,EAAY,UAAA,CAAW,IAAA,EAAM,aAAa,CAAA;AAAA,QAC1C,SAAA,EAAW,QAAA,CAAS,IAAA,EAAM,WAAA,EAAa,gBAAgB,CAAA;AAAA,QACvD,cAAA,EAAgB,CAAC,MAAA,KAAW;AAC1B,UAAA,IAAA,CAAK,aAAA;AAAA,YACH,IAAI,WAAA,CAAY,oBAAA,EAAsB,EAAE,MAAA,EAAQ,EAAE,MAAA,EAAO,EAAG,OAAA,EAAS,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM;AAAA,WAC7F;AAAA,QACF,CAAA;AAAA,QACA,YAAA,EAAc,CAAC,IAAA,EAAM,IAAA,EAAM,OAAA,KAAY;AACrC,UAAA,IAAA,CAAK,aAAA;AAAA,YACH,IAAI,YAAY,iBAAA,EAAmB;AAAA,cACjC,MAAA,EAAQ,EAAE,IAAA,EAAM,IAAA,EAAM,OAAA,EAAQ;AAAA,cAC9B,OAAA,EAAS,IAAA;AAAA,cACT,QAAA,EAAU;AAAA,aACX;AAAA,WACH;AAAA,QACF,CAAA;AAAA,QACA,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,UAAA,IAAA,CAAK,aAAA;AAAA,YACH,IAAI,WAAA,CAAY,YAAA,EAAc,EAAE,MAAA,EAAQ,EAAE,KAAA,EAAM,EAAG,OAAA,EAAS,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM;AAAA,WACpF;AAAA,QACF,CAAA;AAAA,QACA,YAAA,EAAc,CAAC,MAAA,KAAW;AACxB,UAAA,IAAA,CAAK,aAAA;AAAA,YACH,IAAI,WAAA,CAAY,kBAAA,EAAoB,EAAE,MAAA,EAAQ,EAAE,MAAA,EAAO,EAAG,OAAA,EAAS,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM;AAAA,WAC3F;AAAA,QACF,CAAA;AAAA;AAAA;AAAA;AAAA,QAIA,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,UAAA,IAAA,CAAK,aAAA;AAAA,YACH,IAAI,WAAA,CAAY,YAAA,EAAc,EAAE,MAAA,EAAQ,EAAE,KAAA,EAAM,EAAG,OAAA,EAAS,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM;AAAA,WACpF;AAAA,QACF;AAAA,OACD,CAAA;AAAA,IACH;AAAA,IAEA,oBAAA,GAA6B;AAC3B,MAAA,IAAI,KAAK,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,MAAM,OAAA,EAAQ;AACnB,QAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,MACf;AAAA,IACF;AAAA,IAEA,IAAW,SAAA,GAA8B;AACvC,MAAA,OAAO,IAAA,CAAK,KAAA;AAAA,IACd;AAAA,IAEO,SAAS,IAAA,EAAyC;AACvD,MAAA,OAAO,IAAA,CAAK,KAAA,EAAO,QAAA,CAAS,IAAI,CAAA;AAAA,IAClC;AAAA,IAEO,QAAA,GAAiB;AACtB,MAAA,IAAA,CAAK,OAAO,QAAA,EAAS;AAAA,IACvB;AAAA,IAEO,SAAA,GAAkB;AACvB,MAAA,IAAA,CAAK,OAAO,SAAA,EAAU;AAAA,IACxB;AAAA,IAEO,UAAA,GAAmB;AACxB,MAAA,IAAA,CAAK,OAAO,UAAA,EAAW;AAAA,IACzB;AAAA,GACF;AACF;AAEWC;AAEJ,SAAS,sBAAA,CAAuB,UAAU,YAAA,EAAoB;AACnE,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,mBAAmB,WAAA,EAAa;AAC5E,EAAA,IAAI,cAAA,CAAe,GAAA,CAAI,OAAO,CAAA,EAAG;AACjC,EAAA,MAAM,OAAO,iBAAA,EAAkB;AAC/B,EAAA,cAAA,CAAe,MAAA,CAAO,SAAS,IAAI,CAAA;AAGnC,EAAAA,wBAAA,KAAAA,wBAAA,GAAqB,IAAA,CAAA;AACvB;AAEA,sBAAA,EAAuB","file":"chunk-3BQ6LE6X.cjs","sourcesContent":["import { DabaAgent } from \"../agent\";\nimport { cssLength } from \"../utils/css-length\";\nimport type {\n DabaAgentMode,\n DabaAgentOptions,\n DabaAgentPosition,\n DabaDirection,\n DabaIntro,\n DabaLauncher,\n DabaLauncherShape,\n DabaPanel,\n DabaTheme,\n DabaThemePreference,\n} from \"../types\";\n\nconst VALID_POSITIONS: readonly DabaAgentPosition[] = [\n \"bottom-right\",\n \"bottom-left\",\n \"top-right\",\n \"top-left\",\n];\nconst VALID_MODES: readonly DabaAgentMode[] = [\"voice\", \"chat\", \"hybrid\"];\nconst VALID_DIRECTIONS: readonly DabaDirection[] = [\"auto\", \"ltr\", \"rtl\"];\nconst VALID_THEMES: readonly DabaThemePreference[] = [\"auto\", \"light\", \"dark\"];\nconst VALID_LAUNCHER_SHAPES: readonly DabaLauncherShape[] = [\"rounded\", \"circle\", \"pill\"];\nconst VALID_MEDIA_TYPES = [\"video\", \"image\", \"none\"] as const;\n\n/** Same separator as the script-tag embed's data-daba-suggested-prompts —\n * a pipe, because starter prompts are sentences and sentences contain\n * commas. See src/auto-init.ts for the reasoning. */\nconst PROMPT_SEPARATOR = \"|\";\n\n/**\n * Reads `<name>`, then the `data-<name>` alias this element has always\n * accepted, and reports which spelling was found so a warning can quote\n * what the integrator actually typed.\n *\n * Absent AND blank both read as \"not set\", because an option left\n * `undefined` is what tells the agent to use the project's dashboard\n * configuration. A framework binding that renders `radius=\"\"` must leave\n * the served radius alone rather than override it with nothing.\n *\n * These readers deliberately mirror src/auto-init.ts: the two embeds spell\n * their attributes differently but must accept exactly the same values.\n */\nfunction readAttr(el: HTMLElement, name: string): { attr: string; value: string } | undefined {\n for (const attr of [name, `data-${name}`]) {\n const raw = el.getAttribute(attr);\n if (raw === null) continue;\n const value = raw.trim();\n if (value === \"\") continue;\n return { attr, value };\n }\n return undefined;\n}\n\nfunction stringAttr(el: HTMLElement, name: string): string | undefined {\n return readAttr(el, name)?.value;\n}\n\n/** A value outside the allowed set is dropped rather than forwarded, which\n * leaves the option `undefined` and so degrades a typo to the project's own\n * setting instead of letting garbage reach the DOM. */\nfunction enumAttr<T extends string>(\n el: HTMLElement,\n name: string,\n allowed: readonly T[],\n): T | undefined {\n const found = readAttr(el, name);\n if (!found) return undefined;\n if ((allowed as readonly string[]).includes(found.value)) return found.value as T;\n console.error(\n `daba-agent: invalid ${found.attr} \"${found.value}\" on <daba-agent>. Expected one of ${allowed.join(\n \", \",\n )} — ignoring it.`,\n el,\n );\n return undefined;\n}\n\n/** Present with no value is true, the way HTML spells a boolean, but an\n * explicit \"false\" still means false so a bound attribute\n * (`:intro-disabled=\"hideIntro\"`) does not disable the intro everywhere. */\nfunction flagAttr(el: HTMLElement, name: string): boolean | undefined {\n for (const attr of [name, `data-${name}`]) {\n const raw = el.getAttribute(attr);\n if (raw === null) continue;\n const value = raw.trim().toLowerCase();\n return value !== \"false\" && value !== \"0\" && value !== \"no\";\n }\n return undefined;\n}\n\n/** A list that separates into nothing is unset, not empty — far likelier a\n * binding that rendered nothing than a deliberate clearing of the\n * project's prompts. */\nfunction promptsAttr(el: HTMLElement, name: string): string[] | undefined {\n const found = readAttr(el, name);\n if (!found) return undefined;\n const prompts = found.value\n .split(PROMPT_SEPARATOR)\n .map((prompt) => prompt.trim())\n .filter((prompt) => prompt !== \"\");\n return prompts.length > 0 ? prompts : undefined;\n}\n\n/** Mirrors enumAttr: a value that is not a length is dropped and named,\n * rather than forwarded to become an invalid `width` that would collapse\n * the element it was meant to size. Functions are refused on the attribute\n * surfaces — the value usually comes from a template, where a half-written\n * calc() is far likelier than a deliberate one. */\nfunction lengthAttr(el: HTMLElement, name: string): string | undefined {\n const found = readAttr(el, name);\n if (!found) return undefined;\n const length = cssLength(found.value, false);\n if (length) return length;\n console.error(\n `daba-agent: invalid ${found.attr} \"${found.value}\" on <daba-agent>. Expected a CSS length such as \"400px\", \"28rem\" or \"90%\".`,\n el,\n );\n return undefined;\n}\n\n/** Grouped options exist only when one of their fields was configured;\n * an empty group would read downstream as an intentional override. */\nfunction group<T extends object>(fields: T): T | undefined {\n return Object.values(fields).some((value) => value !== undefined) ? fields : undefined;\n}\n\n/**\n * The element's public shape.\n *\n * A type, not a class: `class ... extends HTMLElement` evaluates its\n * extends clause the moment the module does, and on a server there is no\n * HTMLElement — which is why importing the package root from a Next.js\n * layout threw \"HTMLElement is not defined\" and forced every integrator\n * into a dynamic import inside an effect. The real class is built by\n * defineDabaAgentElement(), which only ever runs in a browser.\n */\nexport interface DabaAgentElement extends HTMLElement {\n readonly dabaAgent: DabaAgent | null;\n sendText(text: string): Promise<void> | undefined;\n openChat(): void;\n closeChat(): void;\n toggleChat(): void;\n}\n\nexport type DabaAgentElementConstructor = new () => DabaAgentElement;\n\n/**\n * The constructor, once a browser has been seen. `undefined` on a server.\n *\n * A fresh subclass per tag name: customElements.define() rejects a\n * constructor that is already registered under another name with a\n * NotSupportedError, so a caller passing their own tag would otherwise\n * break the moment the default one had been defined.\n */\nfunction buildElementClass(): DabaAgentElementConstructor {\n return class DabaAgentElement extends HTMLElement {\n\n private agent: DabaAgent | null = null;\n\n connectedCallback(): void {\n if (this.agent) return;\n\n const projectId = stringAttr(this, \"project-id\");\n const apiKey = stringAttr(this, \"api-key\");\n\n if (!projectId || !apiKey) {\n console.error(\n \"daba-agent: <daba-agent> custom element requires project-id and api-key attributes.\",\n this,\n );\n return;\n }\n\n const position = enumAttr(this, \"position\", VALID_POSITIONS);\n const accentColor = stringAttr(this, \"accent-color\");\n const mode = enumAttr(this, \"mode\", VALID_MODES);\n const title = stringAttr(this, \"title\");\n const placeholder = stringAttr(this, \"placeholder\");\n const initialOpen = flagAttr(this, \"initial-open\");\n const hotkey = stringAttr(this, \"hotkey\");\n const gatewayUrl = stringAttr(this, \"gateway-url\");\n // env=\"staging\" points the element at the staging gateway, the same\n // way data-daba-env does for the script-tag embed. Absent means\n // production — see environment.ts.\n const env = stringAttr(this, \"env\") as DabaAgentOptions[\"env\"];\n\n // The accent is offered under both names it has on the option surface:\n // the flat `accentColor` the badge already reads, and the grouped\n // `theme.accentColor` that sits with the rest of the appearance\n // overrides. Same value either way.\n const theme = group<DabaTheme>({\n accentColor,\n accentContrast: stringAttr(this, \"accent-contrast\"),\n surfaceColor: stringAttr(this, \"surface-color\"),\n textColor: stringAttr(this, \"text-color\"),\n radius: stringAttr(this, \"radius\"),\n fontFamily: stringAttr(this, \"font-family\"),\n theme: enumAttr(this, \"theme\", VALID_THEMES),\n });\n\n // The attribute names the state an integrator wants to force — an\n // intro is on unless switched off — while the option carries the state\n // itself, so the flag is inverted here rather than in the agent.\n const introDisabled = flagAttr(this, \"intro-disabled\");\n const intro = group<DabaIntro>({\n enabled: introDisabled === undefined ? undefined : !introDisabled,\n headline: stringAttr(this, \"intro-headline\"),\n subheadline: stringAttr(this, \"intro-subheadline\"),\n mediaUrl: stringAttr(this, \"intro-media-url\"),\n mediaType: enumAttr(this, \"intro-media-type\", VALID_MEDIA_TYPES),\n suggestedPrompts: promptsAttr(this, \"suggested-prompts\"),\n });\n\n const launcher = group<DabaLauncher>({\n shape: enumAttr(this, \"launcher-shape\", VALID_LAUNCHER_SHAPES),\n iconUrl: stringAttr(this, \"launcher-icon-url\"),\n iconSvg: stringAttr(this, \"launcher-icon-svg\"),\n iconText: stringAttr(this, \"launcher-icon-text\"),\n label: stringAttr(this, \"launcher-label\"),\n size: lengthAttr(this, \"launcher-size\"),\n iconSize: lengthAttr(this, \"launcher-icon-size\"),\n });\n\n const panel = group<DabaPanel>({\n width: lengthAttr(this, \"panel-width\"),\n height: lengthAttr(this, \"panel-height\"),\n });\n\n this.agent = new DabaAgent({\n container: this,\n projectId,\n apiKey,\n position,\n accentColor,\n mode,\n title,\n placeholder,\n initialOpen,\n historyEnabled: flagAttr(this, \"history-enabled\"),\n hotkey,\n gatewayUrl,\n env,\n theme,\n intro,\n launcher,\n panel,\n logoUrl: stringAttr(this, \"logo-url\"),\n logoSvg: stringAttr(this, \"logo-svg\"),\n iconBackgroundColor: stringAttr(this, \"icon-background-color\"),\n iconMarkColor: stringAttr(this, \"icon-mark-color\"),\n uiLanguage: stringAttr(this, \"ui-language\"),\n direction: enumAttr(this, \"direction\", VALID_DIRECTIONS),\n onStatusChange: (status) => {\n this.dispatchEvent(\n new CustomEvent(\"daba-status-change\", { detail: { status }, bubbles: true, composed: true }),\n );\n },\n onTranscript: (role, text, isFinal) => {\n this.dispatchEvent(\n new CustomEvent(\"daba-transcript\", {\n detail: { role, text, isFinal },\n bubbles: true,\n composed: true,\n }),\n );\n },\n onError: (error) => {\n this.dispatchEvent(\n new CustomEvent(\"daba-error\", { detail: { error }, bubbles: true, composed: true }),\n );\n },\n onChatToggle: (isOpen) => {\n this.dispatchEvent(\n new CustomEvent(\"daba-chat-toggle\", { detail: { isOpen }, bubbles: true, composed: true }),\n );\n },\n // Cards arrive once per reply that carried structured items, so a\n // host page can render them in its own layout instead of (or as well\n // as) the panel's — a listing site putting event cards on the page.\n onCards: (cards) => {\n this.dispatchEvent(\n new CustomEvent(\"daba-cards\", { detail: { cards }, bubbles: true, composed: true }),\n );\n },\n });\n }\n\n disconnectedCallback(): void {\n if (this.agent) {\n this.agent.destroy();\n this.agent = null;\n }\n }\n\n public get dabaAgent(): DabaAgent | null {\n return this.agent;\n }\n\n public sendText(text: string): Promise<void> | undefined {\n return this.agent?.sendText(text);\n }\n\n public openChat(): void {\n this.agent?.openChat();\n }\n\n public closeChat(): void {\n this.agent?.closeChat();\n }\n\n public toggleChat(): void {\n this.agent?.toggleChat();\n }\n } as unknown as DabaAgentElementConstructor;\n}\n\nexport let DabaAgentElement: DabaAgentElementConstructor | undefined;\n\nexport function defineDabaAgentElement(tagName = \"daba-agent\"): void {\n if (typeof window === \"undefined\" || typeof customElements === \"undefined\") return;\n if (customElements.get(tagName)) return;\n const ctor = buildElementClass();\n customElements.define(tagName, ctor);\n // The exported binding names the default element. A host registering an\n // extra tag gets its own class and leaves this one pointing at the first.\n DabaAgentElement ??= ctor;\n}\n\ndefineDabaAgentElement();\n"]}