@noodleseed/assistant 1.20.0 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -2
- package/dist/{chunk-DLUINP4W.js → chunk-6TT3R555.js} +101 -42
- package/dist/chunk-6TT3R555.js.map +1 -0
- package/dist/{chunk-52XT7BLR.js → chunk-ZPZHPXIQ.js} +129 -82
- package/dist/chunk-ZPZHPXIQ.js.map +1 -0
- package/dist/{client-7o7n2nqw.d.cts → client-BZ7xPwfW.d.cts} +14 -5
- package/dist/{client-CysBQBdd.d.ts → client-BkJlpN5N.d.ts} +14 -5
- package/dist/client.cjs +127 -80
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/embed.global.js +68 -67
- package/dist/index.cjs +226 -120
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/react/client.cjs +127 -80
- package/dist/react/client.cjs.map +1 -1
- package/dist/react/client.d.cts +1 -1
- package/dist/react/client.d.ts +1 -1
- package/dist/react/client.js +1 -1
- package/dist/react.cjs +227 -120
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +8 -1
- package/dist/react.d.ts +8 -1
- package/dist/react.js +3 -2
- package/dist/react.js.map +1 -1
- package/dist/server.cjs +1 -0
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +15 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.js +1 -0
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-52XT7BLR.js.map +0 -1
- package/dist/chunk-DLUINP4W.js.map +0 -1
package/README.md
CHANGED
|
@@ -222,7 +222,10 @@ instead of `sessionEndpoint` — the two are mutually exclusive, and a public em
|
|
|
222
222
|
```
|
|
223
223
|
|
|
224
224
|
A public embed opens its session on **first open**, never on mount — every mount would otherwise spend
|
|
225
|
-
one of the surface's daily admission budget.
|
|
225
|
+
one of the surface's daily admission budget. While that first session is resolving, the launcher remains as
|
|
226
|
+
a loading affordance and the panel stays hidden. The panel's first visible frame therefore already carries
|
|
227
|
+
the deployment's compiled name, labels, presentation, and light/dark brand tokens instead of flashing the
|
|
228
|
+
built-in defaults. Add `signIn: true` to the surface and it becomes **mixed**:
|
|
226
229
|
anonymous visitors start immediately, and identity-dependent capabilities raise the sign-in flow below.
|
|
227
230
|
Before shipping, preflight the host with `noodle assistant embed --check --surface public` (or `mixed`) —
|
|
228
231
|
it verifies `script-src` too, the one CSP directive whose failure runs no widget code at all.
|
|
@@ -246,7 +249,14 @@ const session = await createAssistantSession({
|
|
|
246
249
|
});
|
|
247
250
|
```
|
|
248
251
|
|
|
249
|
-
The visitor keeps the same conversation with a new token; the anonymous token dies at that moment
|
|
252
|
+
The visitor keeps the same conversation with a new token; the anonymous token dies at that moment —
|
|
253
|
+
and by default **the assistant answers the pending question itself**: the service re-attempts the
|
|
254
|
+
intercepted tool under the signed-in principal and streams the result as the session's first turn,
|
|
255
|
+
so the panel's first content after sign-in is the answer the visitor asked for. It is one-shot
|
|
256
|
+
(consumed by that turn, or mooted the moment the visitor types first), confirm-gated tools stop at
|
|
257
|
+
their normal confirmation card — sign-in is never implicit consent for a write — and the turn counts
|
|
258
|
+
against the surface's daily budget like any other. Pass `resume: false` beside the ticket if your
|
|
259
|
+
application provides its own post-login affordance.
|
|
250
260
|
`signInTicket` and `context` are mutually exclusive — an elevation continues an existing session.
|
|
251
261
|
`routing` IS accepted here, and this is the moment to send it: elevation is the first authenticated
|
|
252
262
|
exchange, so it is the only chance a routed connector's session gets its backend-verified customer
|
|
@@ -494,6 +504,21 @@ element.addEventListener("assistant-view-available", (event) => {
|
|
|
494
504
|
});
|
|
495
505
|
```
|
|
496
506
|
|
|
507
|
+
#### Readiness and call ordering
|
|
508
|
+
|
|
509
|
+
`assistant-ready` fires **once per element lifetime**, when the element's shadow DOM is rendered and its
|
|
510
|
+
imperative API (`sendMessage`, `confirmTool`, …) is callable. It does **not** mean a session exists — that
|
|
511
|
+
is the `assistant-event` with `event: 'session_started'`. A DOM move (router reparent, portal) re-runs the
|
|
512
|
+
element's connection lifecycle but never re-fires the event. The React wrapper's `onReady` mirrors this:
|
|
513
|
+
at most once per component instance, whether the element upgraded before or after the component mounted;
|
|
514
|
+
the first callback identity wins, and a `console.debug('[noodle-assistant] ready')` breadcrumb marks the
|
|
515
|
+
moment for field diagnosis.
|
|
516
|
+
|
|
517
|
+
`sendMessage` awaits an in-flight eager session exchange and never opens a second session — a message sent
|
|
518
|
+
while the panel is still connecting is delivered on the session that exchange produces. It does **not**
|
|
519
|
+
queue: a `sendMessage` issued while another send or response is in flight rejects with a retryable
|
|
520
|
+
`request_in_progress` error before touching the transcript.
|
|
521
|
+
|
|
497
522
|
Assistant text renders as provider deltas arrive. If a turn finds an expired session, the component calls
|
|
498
523
|
the same authenticated session endpoint and retries that unprocessed message once. Confirmations never
|
|
499
524
|
replay across sessions. React applications may observe recovery and structured failures:
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
copyAssistantPageContext,
|
|
5
5
|
createAssistantClient,
|
|
6
6
|
sessionSourceKey
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ZPZHPXIQ.js";
|
|
8
8
|
import {
|
|
9
9
|
_enum,
|
|
10
10
|
_null,
|
|
@@ -6824,6 +6824,11 @@ var AssistantElementEventController = class {
|
|
|
6824
6824
|
this.#completedTool = void 0;
|
|
6825
6825
|
return;
|
|
6826
6826
|
}
|
|
6827
|
+
if (name === "resume_started") {
|
|
6828
|
+
this.#startStream("message");
|
|
6829
|
+
this.#host.element.dispatchEvent(new CustomEvent("assistant-message-started"));
|
|
6830
|
+
return;
|
|
6831
|
+
}
|
|
6827
6832
|
if (name === "interaction_completed") {
|
|
6828
6833
|
if (this.#streamKind !== "interaction") return;
|
|
6829
6834
|
this.#finishInteraction(String(data.id ?? ""), String(data.action ?? "accept"));
|
|
@@ -7042,6 +7047,36 @@ function queryRequired(root, selector) {
|
|
|
7042
7047
|
if (!element) throw new Error(`assistant renderer is missing ${selector}`);
|
|
7043
7048
|
return element;
|
|
7044
7049
|
}
|
|
7050
|
+
function assistantElementMarkup(appearance, open, styles) {
|
|
7051
|
+
return `${styles}
|
|
7052
|
+
<button class="launcher" type="button" aria-label="${escapeAttribute(appearance.labels.open)}" aria-controls="assistant-panel" aria-expanded="${String(open)}"><slot name="launcher-icon"></slot><span class="visually-hidden" data-session-status aria-live="polite" hidden></span></button>
|
|
7053
|
+
<section class="panel" id="assistant-panel" role="dialog" aria-label="${escapeAttribute(appearance.brand.name)}">
|
|
7054
|
+
<header><slot name="header-leading"></slot><img class="brand-logo" alt=""><strong></strong><slot name="header-actions"></slot><button class="close" type="button" aria-label="${escapeAttribute(appearance.labels.close)}"></button></header>
|
|
7055
|
+
<div class="welcome"><slot name="empty-state"></slot></div>
|
|
7056
|
+
<div class="suggested-prompts"></div>
|
|
7057
|
+
<div class="messages-region">
|
|
7058
|
+
<div class="messages" aria-live="polite"></div>
|
|
7059
|
+
<button class="new-messages" type="button" aria-label="${escapeAttribute(appearance.labels.newMessages)}" hidden></button>
|
|
7060
|
+
</div>
|
|
7061
|
+
<form><slot name="composer-leading"></slot><textarea rows="1"></textarea><button class="send" type="submit"></button><slot name="composer-trailing"></slot></form>
|
|
7062
|
+
<nav class="legal" aria-label="Legal"></nav>
|
|
7063
|
+
<slot name="conversation-footer"></slot>
|
|
7064
|
+
</section>`;
|
|
7065
|
+
}
|
|
7066
|
+
function appendLegalLinks(legal, appearance) {
|
|
7067
|
+
for (const [label, href] of [
|
|
7068
|
+
["Privacy", appearance.privacyUrl],
|
|
7069
|
+
["Terms", appearance.termsUrl]
|
|
7070
|
+
]) {
|
|
7071
|
+
if (!href) continue;
|
|
7072
|
+
const link = document.createElement("a");
|
|
7073
|
+
link.href = href;
|
|
7074
|
+
link.target = "_blank";
|
|
7075
|
+
link.rel = "noopener noreferrer";
|
|
7076
|
+
link.textContent = label;
|
|
7077
|
+
legal.append(link);
|
|
7078
|
+
}
|
|
7079
|
+
}
|
|
7045
7080
|
|
|
7046
7081
|
// src/element-page-context-controller.ts
|
|
7047
7082
|
var AssistantElementPageContextController = class {
|
|
@@ -7083,6 +7118,33 @@ var AssistantElementPageContextController = class {
|
|
|
7083
7118
|
}
|
|
7084
7119
|
};
|
|
7085
7120
|
|
|
7121
|
+
// src/element-presentation-gate.ts
|
|
7122
|
+
var AssistantElementPresentationGate = class {
|
|
7123
|
+
#host;
|
|
7124
|
+
#primeSession;
|
|
7125
|
+
#focusComposer;
|
|
7126
|
+
constructor(host, primeSession, focusComposer) {
|
|
7127
|
+
this.#host = host;
|
|
7128
|
+
this.#primeSession = primeSession;
|
|
7129
|
+
this.#focusComposer = focusComposer;
|
|
7130
|
+
}
|
|
7131
|
+
syncOpenState() {
|
|
7132
|
+
const open = this.#host.hasAttribute("open");
|
|
7133
|
+
const presentationReady = this.#host.hasAttribute("data-presentation-ready");
|
|
7134
|
+
const launcher = this.#host.shadowRoot?.querySelector(".launcher");
|
|
7135
|
+
launcher?.setAttribute("aria-expanded", String(open && presentationReady));
|
|
7136
|
+
launcher?.setAttribute("aria-busy", String(open && !presentationReady));
|
|
7137
|
+
if (launcher) launcher.disabled = open && !presentationReady;
|
|
7138
|
+
if (open && this.#host.isConnected) this.#primeSession();
|
|
7139
|
+
}
|
|
7140
|
+
reveal() {
|
|
7141
|
+
if (this.#host.hasAttribute("data-presentation-ready")) return;
|
|
7142
|
+
this.#host.setAttribute("data-presentation-ready", "");
|
|
7143
|
+
this.syncOpenState();
|
|
7144
|
+
if (this.#host.hasAttribute("open")) queueMicrotask(this.#focusComposer);
|
|
7145
|
+
}
|
|
7146
|
+
};
|
|
7147
|
+
|
|
7086
7148
|
// src/element-scroll-controller.ts
|
|
7087
7149
|
var AssistantElementScrollController = class {
|
|
7088
7150
|
#region;
|
|
@@ -7198,9 +7260,10 @@ var ASSISTANT_ELEMENT_STYLES = `<style>
|
|
|
7198
7260
|
.launcher:hover { transform: translateY(-2px) scale(1.03); box-shadow: 0 8px 26px rgba(0,0,0,.16); }
|
|
7199
7261
|
.launcher img { width: 28px; height: 28px; border-radius: 50%; object-fit: contain; }
|
|
7200
7262
|
.panel { display: none; flex-direction: column; width: min(var(--ns-assistant-panel-width, var(--ns-assistant-default-panel-width)), calc(100vw - 40px)); min-height: var(--ns-assistant-min-height, var(--ns-assistant-default-min-height)); max-height: min(var(--ns-assistant-max-height, var(--ns-assistant-default-max-height)), calc(100vh - 40px)); overflow: hidden; color: var(--ns-assistant-panel-text, var(--ns-assistant-text, var(--ns-assistant-default-text))); background: var(--ns-assistant-panel, var(--ns-assistant-default-panel)); border: 1px solid var(--ns-assistant-panel-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))); border-radius: var(--ns-assistant-panel-radius, var(--ns-assistant-default-panel-radius)); box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-default-shadow)); transform-origin: bottom right; isolation: isolate; animation: halo-panel-in .28s cubic-bezier(.23,1,.32,1) both; }
|
|
7201
|
-
:host([open]) .panel { display: flex; }
|
|
7263
|
+
:host([open][data-presentation-ready]) .panel { display: flex; }
|
|
7202
7264
|
.panel { position: relative; }
|
|
7203
|
-
:host([open]) .launcher { display: none; }
|
|
7265
|
+
:host([open][data-presentation-ready]) .launcher { display: none; }
|
|
7266
|
+
:host([open]:not([data-presentation-ready])) .launcher { cursor: progress; opacity: .72; transform: none; }
|
|
7204
7267
|
header { display: flex; flex: 0 0 auto; gap: 10px; align-items: center; min-height: 64px; padding: 12px 18px; color: var(--ns-assistant-header-text, inherit); background: var(--ns-assistant-header, transparent); border-bottom: 1px solid color-mix(in srgb, var(--ns-assistant-header-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))) 78%, transparent); }
|
|
7205
7268
|
header strong { flex: 1; font-size: 16px; font-weight: 600; letter-spacing: 0; }
|
|
7206
7269
|
.brand-logo { display: block; max-width: 120px; max-height: 28px; object-fit: contain; }
|
|
@@ -7826,9 +7889,16 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7826
7889
|
#automaticPageContext = new AssistantElementPageContextController(
|
|
7827
7890
|
() => !this.#pageContext
|
|
7828
7891
|
);
|
|
7892
|
+
#presentationGate = new AssistantElementPresentationGate(
|
|
7893
|
+
this,
|
|
7894
|
+
() => this.#primeSession(),
|
|
7895
|
+
() => this.focusComposer()
|
|
7896
|
+
);
|
|
7829
7897
|
#pendingUserEcho;
|
|
7830
7898
|
#sessionState = "idle";
|
|
7831
7899
|
#startOpenApplied = false;
|
|
7900
|
+
#readyDispatched = false;
|
|
7901
|
+
#turnInFlight = false;
|
|
7832
7902
|
#hostAppearance;
|
|
7833
7903
|
#appearanceWarningKeys = /* @__PURE__ */ new Set();
|
|
7834
7904
|
#appearanceStyleSnapshot = /* @__PURE__ */ new Map();
|
|
@@ -7894,20 +7964,24 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7894
7964
|
if (!this.sessionEndpoint) this.sessionEndpoint = this.getAttribute("session-endpoint") ?? "";
|
|
7895
7965
|
if (!this.embedId) this.embedId = this.getAttribute("embed-id") ?? "";
|
|
7896
7966
|
if (!this.serviceUrl) this.serviceUrl = this.getAttribute("service-url") ?? "";
|
|
7967
|
+
if (!this.sessionEndpoint && !this.embedId) this.#presentationGate.reveal();
|
|
7897
7968
|
this.#media = globalThis.matchMedia?.("(prefers-color-scheme: dark)");
|
|
7898
7969
|
this.#media?.addEventListener("change", this.#handleSystemTheme);
|
|
7899
7970
|
document.addEventListener("keydown", this.#handleDocumentKeydown);
|
|
7900
7971
|
document.addEventListener("pointerdown", this.#handleDocumentPointerDown);
|
|
7901
7972
|
if (this.#appearance.behavior.startOpen) this.#applyStartOpenPolicy();
|
|
7902
7973
|
this.#render();
|
|
7903
|
-
|
|
7974
|
+
if (!this.#readyDispatched) {
|
|
7975
|
+
this.#readyDispatched = true;
|
|
7976
|
+
this.dispatchEvent(new CustomEvent("assistant-ready"));
|
|
7977
|
+
}
|
|
7904
7978
|
if (this.hasAttribute("start-open")) {
|
|
7905
7979
|
this.setAttribute("open", "");
|
|
7906
7980
|
this.#startOpenApplied = true;
|
|
7907
7981
|
} else if (!this.embedId) {
|
|
7908
7982
|
this.#primeSession();
|
|
7909
7983
|
}
|
|
7910
|
-
this.#syncOpenState();
|
|
7984
|
+
this.#presentationGate.syncOpenState();
|
|
7911
7985
|
}
|
|
7912
7986
|
disconnectedCallback() {
|
|
7913
7987
|
this.#conversationGeneration += 1;
|
|
@@ -7925,7 +7999,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7925
7999
|
}
|
|
7926
8000
|
attributeChangedCallback(name) {
|
|
7927
8001
|
if (name === "theme") this.#applyTheme();
|
|
7928
|
-
if (name === "open") this.#syncOpenState();
|
|
8002
|
+
if (name === "open") this.#presentationGate.syncOpenState();
|
|
7929
8003
|
}
|
|
7930
8004
|
open() {
|
|
7931
8005
|
this.setAttribute("open", "");
|
|
@@ -8014,7 +8088,14 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
8014
8088
|
async sendMessage(text2) {
|
|
8015
8089
|
const message = text2.trim();
|
|
8016
8090
|
if (!message) return;
|
|
8091
|
+
if (this.#turnInFlight) {
|
|
8092
|
+
throw new AssistantClientError(
|
|
8093
|
+
{ code: "request_in_progress", retryable: true },
|
|
8094
|
+
"an assistant request is already in progress"
|
|
8095
|
+
);
|
|
8096
|
+
}
|
|
8017
8097
|
const generation = this.#conversationGeneration;
|
|
8098
|
+
this.#turnInFlight = true;
|
|
8018
8099
|
this.#pendingUserEcho = message;
|
|
8019
8100
|
this.#appendMessage("user", message);
|
|
8020
8101
|
this.#setBusy(true);
|
|
@@ -8031,6 +8112,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
8031
8112
|
this.#dispatchClientError(error, "turn_failed");
|
|
8032
8113
|
throw error;
|
|
8033
8114
|
} finally {
|
|
8115
|
+
this.#turnInFlight = false;
|
|
8034
8116
|
if (this.#pendingUserEcho === message) this.#pendingUserEcho = void 0;
|
|
8035
8117
|
if (generation === this.#conversationGeneration) this.#setBusy(false);
|
|
8036
8118
|
}
|
|
@@ -8099,6 +8181,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
8099
8181
|
#primeSession() {
|
|
8100
8182
|
if (!this.sessionEndpoint && !this.embedId) return;
|
|
8101
8183
|
if (this.#sessionBootstrap || this.#client?.hasSession()) return;
|
|
8184
|
+
if (this.#client?.isBusy?.() === true) return;
|
|
8102
8185
|
if (this.embedId && !this.#pageContext) void this.#automaticPageContext.refresh();
|
|
8103
8186
|
const client = this.#ensureClient();
|
|
8104
8187
|
const generation = this.#conversationGeneration;
|
|
@@ -8106,6 +8189,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
8106
8189
|
const bootstrap = client.connect().catch((error) => {
|
|
8107
8190
|
if (generation !== this.#conversationGeneration || this.#client !== client) return;
|
|
8108
8191
|
this.#dispatchClientError(error, "session_failed");
|
|
8192
|
+
this.#presentationGate.reveal();
|
|
8109
8193
|
}).finally(() => {
|
|
8110
8194
|
if (this.#sessionBootstrap === bootstrap) this.#sessionBootstrap = void 0;
|
|
8111
8195
|
});
|
|
@@ -8115,6 +8199,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
8115
8199
|
this.dispatchEvent(new CustomEvent("assistant-event", { detail: event }));
|
|
8116
8200
|
this.#events.handle(event);
|
|
8117
8201
|
if (event.event === "session_started") {
|
|
8202
|
+
this.#presentationGate.reveal();
|
|
8118
8203
|
this.#setSessionState("ready");
|
|
8119
8204
|
this.#messages?.querySelector(".conversation-error")?.remove();
|
|
8120
8205
|
}
|
|
@@ -8128,6 +8213,8 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
8128
8213
|
if (event.event === "content" || event.event === "message_completed" || event.event === "interaction_completed" || event.event === "error") {
|
|
8129
8214
|
this.#removeThinking();
|
|
8130
8215
|
}
|
|
8216
|
+
if (event.event === "resume_started") this.#setBusy(true);
|
|
8217
|
+
if (event.event === "message_completed" || event.event === "error") this.#setBusy(false);
|
|
8131
8218
|
}
|
|
8132
8219
|
#setBusy(busy) {
|
|
8133
8220
|
this.toggleAttribute("busy", busy);
|
|
@@ -8282,11 +8369,6 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
8282
8369
|
this.#sessionState = state;
|
|
8283
8370
|
syncAssistantSessionVisualState(this, this.shadowRoot, state, this.#appearance);
|
|
8284
8371
|
}
|
|
8285
|
-
#syncOpenState() {
|
|
8286
|
-
const open = this.hasAttribute("open");
|
|
8287
|
-
this.shadowRoot?.querySelector(".launcher")?.setAttribute("aria-expanded", String(open));
|
|
8288
|
-
if (open && this.isConnected) this.#primeSession();
|
|
8289
|
-
}
|
|
8290
8372
|
#closeAndRestoreFocus() {
|
|
8291
8373
|
this.close();
|
|
8292
8374
|
this.shadowRoot?.querySelector(".launcher")?.focus();
|
|
@@ -8336,7 +8418,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
8336
8418
|
queryRequired(this.shadowRoot, "header").hidden = !appearance.behavior.showHeader;
|
|
8337
8419
|
const legal = queryRequired(this.shadowRoot, ".legal");
|
|
8338
8420
|
legal.replaceChildren();
|
|
8339
|
-
|
|
8421
|
+
appendLegalLinks(legal, this.#appearance);
|
|
8340
8422
|
this.#applyTheme();
|
|
8341
8423
|
}
|
|
8342
8424
|
#render() {
|
|
@@ -8352,20 +8434,11 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
8352
8434
|
this.dataset.position = appearance.layout.position;
|
|
8353
8435
|
this.dataset.density = appearance.layout.density;
|
|
8354
8436
|
this.toggleAttribute("mobile-fullscreen", appearance.layout.mobileFullscreen);
|
|
8355
|
-
this.shadowRoot.innerHTML =
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
<div class="suggested-prompts"></div>
|
|
8361
|
-
<div class="messages-region">
|
|
8362
|
-
<div class="messages" aria-live="polite"></div>
|
|
8363
|
-
<button class="new-messages" type="button" aria-label="${escapeAttribute(appearance.labels.newMessages)}" hidden></button>
|
|
8364
|
-
</div>
|
|
8365
|
-
<form><slot name="composer-leading"></slot><textarea rows="1"></textarea><button class="send" type="submit"></button><slot name="composer-trailing"></slot></form>
|
|
8366
|
-
<nav class="legal" aria-label="Legal"></nav>
|
|
8367
|
-
<slot name="conversation-footer"></slot>
|
|
8368
|
-
</section>`;
|
|
8437
|
+
this.shadowRoot.innerHTML = assistantElementMarkup(
|
|
8438
|
+
appearance,
|
|
8439
|
+
this.hasAttribute("open"),
|
|
8440
|
+
`${ASSISTANT_ELEMENT_STYLES}${presentationStyles}`
|
|
8441
|
+
);
|
|
8369
8442
|
queryRequired(this.shadowRoot, "strong").textContent = appearance.brand.name;
|
|
8370
8443
|
const logo = queryRequired(this.shadowRoot, ".brand-logo");
|
|
8371
8444
|
const logoUrl = appearance.brand.logo[this.#resolvedMode()];
|
|
@@ -8392,7 +8465,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
8392
8465
|
if (!appearance.behavior.showHeader)
|
|
8393
8466
|
queryRequired(this.shadowRoot, "header").hidden = true;
|
|
8394
8467
|
const legal = queryRequired(this.shadowRoot, ".legal");
|
|
8395
|
-
|
|
8468
|
+
appendLegalLinks(legal, this.#appearance);
|
|
8396
8469
|
this.#messages = this.shadowRoot.querySelector(".messages") ?? void 0;
|
|
8397
8470
|
this.#messages?.append(...conversation);
|
|
8398
8471
|
this.#thinking = this.#messages?.querySelector(".thinking") ?? void 0;
|
|
@@ -8431,20 +8504,6 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
8431
8504
|
});
|
|
8432
8505
|
this.#applyTheme();
|
|
8433
8506
|
}
|
|
8434
|
-
#appendLegalLinks(legal) {
|
|
8435
|
-
for (const [label, href] of [
|
|
8436
|
-
["Privacy", this.#appearance.privacyUrl],
|
|
8437
|
-
["Terms", this.#appearance.termsUrl]
|
|
8438
|
-
]) {
|
|
8439
|
-
if (!href) continue;
|
|
8440
|
-
const link = document.createElement("a");
|
|
8441
|
-
link.href = href;
|
|
8442
|
-
link.target = "_blank";
|
|
8443
|
-
link.rel = "noopener noreferrer";
|
|
8444
|
-
link.textContent = label;
|
|
8445
|
-
legal.append(link);
|
|
8446
|
-
}
|
|
8447
|
-
}
|
|
8448
8507
|
};
|
|
8449
8508
|
function registerNoodleAssistant() {
|
|
8450
8509
|
if (globalThis.customElements && !customElements.get(ASSISTANT_TAG_NAME)) {
|
|
@@ -8465,4 +8524,4 @@ export {
|
|
|
8465
8524
|
dompurify/dist/purify.es.mjs:
|
|
8466
8525
|
(*! @license DOMPurify 3.4.11 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.11/LICENSE *)
|
|
8467
8526
|
*/
|
|
8468
|
-
//# sourceMappingURL=chunk-
|
|
8527
|
+
//# sourceMappingURL=chunk-6TT3R555.js.map
|