@noodleseed/assistant 1.13.0 → 1.15.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.
@@ -1,8 +1,9 @@
1
1
  import {
2
2
  AssistantClientError,
3
3
  copyAssistantModelContext,
4
- createAssistantClient
5
- } from "./chunk-KRB2SXFD.js";
4
+ createAssistantClient,
5
+ sessionSourceKey
6
+ } from "./chunk-RRJIK473.js";
6
7
  import {
7
8
  _enum,
8
9
  _null,
@@ -3142,7 +3143,7 @@ function mountAssistantApp(detail, actions, options = {}) {
3142
3143
  const current = options.getDetail?.() ?? detail;
3143
3144
  void bridge.sendSandboxResourceReady({
3144
3145
  html: current.html,
3145
- sandbox: "allow-scripts allow-forms",
3146
+ sandbox: "allow-scripts",
3146
3147
  ...current.resourceMeta ?? {}
3147
3148
  });
3148
3149
  };
@@ -6706,7 +6707,6 @@ var AssistantElementEventController = class {
6706
6707
  return;
6707
6708
  }
6708
6709
  if (name === "tool_proposed" || name === "interaction_proposed") {
6709
- if (!this.#streamKind) return;
6710
6710
  this.#appendToolProposal(
6711
6711
  String(data.id ?? ""),
6712
6712
  String(data.tool ?? "action"),
@@ -6718,7 +6718,6 @@ var AssistantElementEventController = class {
6718
6718
  return;
6719
6719
  }
6720
6720
  if (name === "input_requested" && isRecord(data.requestedSchema)) {
6721
- if (!this.#streamKind) return;
6722
6721
  this.#appendInputRequest(
6723
6722
  String(data.id ?? ""),
6724
6723
  String(data.message ?? "More information is required"),
@@ -7622,6 +7621,10 @@ var NoodleAssistantElement = class extends HTMLElementBase {
7622
7621
  #appearanceStyleSnapshot = /* @__PURE__ */ new Map();
7623
7622
  #scroll = new AssistantElementScrollController();
7624
7623
  sessionEndpoint = "";
7624
+ /** Public mount: the non-secret embed id `noodle deploy` printed. Mutually exclusive with the above. */
7625
+ embedId = "";
7626
+ /** Only for a dev or self-hosted service; the published snippet needs no origin. */
7627
+ serviceUrl = "";
7625
7628
  get appearance() {
7626
7629
  return this.#hostAppearance;
7627
7630
  }
@@ -7676,6 +7679,8 @@ var NoodleAssistantElement = class extends HTMLElementBase {
7676
7679
  connectedCallback() {
7677
7680
  if (!this.shadowRoot) this.attachShadow({ mode: "open" });
7678
7681
  if (!this.sessionEndpoint) this.sessionEndpoint = this.getAttribute("session-endpoint") ?? "";
7682
+ if (!this.embedId) this.embedId = this.getAttribute("embed-id") ?? "";
7683
+ if (!this.serviceUrl) this.serviceUrl = this.getAttribute("service-url") ?? "";
7679
7684
  this.#media = globalThis.matchMedia?.("(prefers-color-scheme: dark)");
7680
7685
  this.#media?.addEventListener("change", this.#handleSystemTheme);
7681
7686
  document.addEventListener("keydown", this.#handleDocumentKeydown);
@@ -7847,26 +7852,31 @@ var NoodleAssistantElement = class extends HTMLElementBase {
7847
7852
  }
7848
7853
  };
7849
7854
  #ensureClient() {
7850
- if (this.#client && this.#clientEndpoint === this.sessionEndpoint) return this.#client;
7855
+ const key = sessionSourceKey(this);
7856
+ if (this.#client && this.#clientEndpoint === key) return this.#client;
7851
7857
  this.#client?.abort();
7852
7858
  this.#unsubscribeClient?.();
7853
7859
  this.#sessionBootstrap = void 0;
7854
- const client = createAssistantClient({
7855
- sessionEndpoint: this.sessionEndpoint,
7860
+ const behavior = {
7856
7861
  ...this.#context ? { context: this.#context } : {},
7857
7862
  clientContext: browserClientContext,
7858
7863
  ...this.#pageContext ? { pageContext: this.#pageContext } : {},
7859
7864
  ...this.#modelContext ? { modelContext: this.#modelContext } : {}
7860
- });
7865
+ };
7866
+ const client = this.embedId ? createAssistantClient({
7867
+ embedId: this.embedId,
7868
+ ...this.serviceUrl ? { serviceUrl: this.serviceUrl } : {},
7869
+ ...behavior
7870
+ }) : createAssistantClient({ sessionEndpoint: this.sessionEndpoint, ...behavior });
7861
7871
  this.#client = client;
7862
- this.#clientEndpoint = this.sessionEndpoint;
7872
+ this.#clientEndpoint = key;
7863
7873
  this.#unsubscribeClient = client.subscribe((event) => {
7864
7874
  if (this.#client === client) this.#handleClientEvent(event);
7865
7875
  });
7866
7876
  return client;
7867
7877
  }
7868
7878
  #primeSession() {
7869
- if (!this.sessionEndpoint) return;
7879
+ if (!this.sessionEndpoint && !this.embedId) return;
7870
7880
  const client = this.#ensureClient();
7871
7881
  const generation = this.#conversationGeneration;
7872
7882
  this.#setSessionState("loading");
@@ -7990,23 +8000,30 @@ var NoodleAssistantElement = class extends HTMLElementBase {
7990
8000
  }
7991
8001
  const detail = error instanceof AssistantClientError ? error.detail : { code: fallbackCode, retryable: false };
7992
8002
  this.#appendRecoveryError(
7993
- detail.code === "session_expired" ? this.#appearance.labels.sessionExpired : this.#appearance.labels.unavailable
8003
+ detail.code === "session_expired" ? this.#appearance.labels.sessionExpired : this.#appearance.labels.unavailable,
8004
+ // A spent or switched-off daily budget offers no retry. Reconnecting cannot succeed, and every
8005
+ // open tab trying is exactly the load the cap was set to refuse — so the button goes, not just
8006
+ // the alarming words. A spent *session* keeps it: reconnect mints a fresh one, which is the fix.
8007
+ detail.retryable !== false || detail.serviceCode === void 0
7994
8008
  );
7995
8009
  this.#dispatchError(detail);
7996
8010
  }
7997
- #appendRecoveryError(message) {
8011
+ #appendRecoveryError(message, offerRetry = true) {
7998
8012
  if (!this.#messages) return;
7999
8013
  this.#messages.querySelector(".conversation-error")?.remove();
8000
8014
  const error = document.createElement("section");
8001
8015
  error.className = "conversation-error";
8002
- error.setAttribute("role", "alert");
8016
+ error.setAttribute("role", offerRetry ? "alert" : "status");
8003
8017
  const text2 = document.createElement("p");
8004
8018
  text2.textContent = message;
8005
- const retry = document.createElement("button");
8006
- retry.type = "button";
8007
- retry.textContent = this.#appearance.labels.reconnect;
8008
- retry.addEventListener("click", () => this.reconnect());
8009
- error.append(text2, retry);
8019
+ error.append(text2);
8020
+ if (offerRetry) {
8021
+ const retry = document.createElement("button");
8022
+ retry.type = "button";
8023
+ retry.textContent = this.#appearance.labels.reconnect;
8024
+ retry.addEventListener("click", () => this.reconnect());
8025
+ error.append(retry);
8026
+ }
8010
8027
  this.#messages.append(error);
8011
8028
  this.#revealLatest();
8012
8029
  }
@@ -8223,4 +8240,4 @@ export {
8223
8240
  dompurify/dist/purify.es.mjs:
8224
8241
  (*! @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 *)
8225
8242
  */
8226
- //# sourceMappingURL=chunk-ZPELSHUP.js.map
8243
+ //# sourceMappingURL=chunk-SUHNNWKP.js.map