@pluno/product-agent-web 0.1.159 → 0.1.160

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/index.d.ts CHANGED
@@ -294,6 +294,7 @@ export declare class PlunoProductAgent {
294
294
  private send;
295
295
  private getUploadToken;
296
296
  private sendNow;
297
+ private reportHealthSignal;
297
298
  private requestTransientStarterPrompts;
298
299
  private startStarterPromptUrlWatcher;
299
300
  private handleStarterPromptUrlChange;
@@ -133,7 +133,7 @@ function ms(t, e, s, n) {
133
133
  }
134
134
  const be = "pluno.productAgent.transportId", ys = "pluno.productAgent.transportIdentity", Ce = "pluno.productAgent.transportIdentity.event", Is = 50, Ts = globalThis.setTimeout.bind(globalThis);
135
135
  let z = null;
136
- const le = /* @__PURE__ */ new Set(), ke = /* @__PURE__ */ new Map();
136
+ const le = /* @__PURE__ */ new Set(), _e = /* @__PURE__ */ new Map();
137
137
  async function ws(t = Pt()) {
138
138
  const e = t.randomUUID(), s = t.storage.getItem(be);
139
139
  let n = s ?? t.randomUUID(), r = !1, i = !1;
@@ -206,13 +206,13 @@ function As() {
206
206
  return {
207
207
  getItem: (t) => {
208
208
  try {
209
- return window.sessionStorage?.getItem(t) ?? ke.get(t) ?? null;
209
+ return window.sessionStorage?.getItem(t) ?? _e.get(t) ?? null;
210
210
  } catch {
211
- return ke.get(t) ?? null;
211
+ return _e.get(t) ?? null;
212
212
  }
213
213
  },
214
214
  setItem: (t, e) => {
215
- ke.set(t, e);
215
+ _e.set(t, e);
216
216
  try {
217
217
  window.sessionStorage?.setItem(t, e);
218
218
  } catch {
@@ -269,7 +269,7 @@ function bs(t) {
269
269
  const s = e;
270
270
  return s.ok !== !0 || s.toolName !== Dt || typeof s.dueAt != "string" || Number.isNaN(Date.parse(s.dueAt)) ? null : s.dueAt;
271
271
  }
272
- const Cs = globalThis.fetch.bind(globalThis), Le = '.pluno-pa-widget-host[data-pluno-product-agent-ui="widget"]', ks = '.pluno-pa-widget[data-pluno-product-agent-ui-root="widget"]', _s = ".pluno-pa-widget__panel", Us = ".pluno-pa-widget__timeline", ut = `${Le}[data-pluno-sdk-preview-channel]`;
272
+ const Cs = globalThis.fetch.bind(globalThis), Le = '.pluno-pa-widget-host[data-pluno-product-agent-ui="widget"]', _s = '.pluno-pa-widget[data-pluno-product-agent-ui-root="widget"]', ks = ".pluno-pa-widget__panel", Us = ".pluno-pa-widget__timeline", ut = `${Le}[data-pluno-sdk-preview-channel]`;
273
273
  let Ps = 0;
274
274
  function dt(t) {
275
275
  const e = {};
@@ -308,7 +308,7 @@ function dt(t) {
308
308
  }
309
309
  return e;
310
310
  }
311
- function _e(t, e, s) {
311
+ function ke(t, e, s) {
312
312
  if (typeof window > "u")
313
313
  return;
314
314
  const n = window.__PLUNO_PRODUCT_AGENT_TRACE_ID__;
@@ -327,13 +327,13 @@ function _e(t, e, s) {
327
327
  };
328
328
  window.dispatchEvent(new CustomEvent("product-agent:trace", { detail: r }));
329
329
  }
330
- const Ds = "https://app.pluno.ai", vs = "gpt-5.6-terra", Ns = 2e4, Os = 1e4, xs = 1e4, Ls = 1e4, qs = 1e4, Bs = 1e3, ht = 3e4, pt = 0.2, gt = 6e4, Hs = 15e3, K = 8, Ws = "Pluno could not finish this message. Try it again.", js = "Browser connection was interrupted.", ft = 15e3, Fs = "Pluno could not send this message. Try it again.", mt = 2e3, $s = 1e3, zs = 100, yt = 8e3, It = 3, Ks = [300, 1e3], vt = 50 * 1024 * 1024, Gs = /* @__PURE__ */ new Set([
330
+ const Ds = "https://app.pluno.ai", vs = "gpt-5.6-terra", Os = 2e4, Ns = 1e4, xs = 1e4, Ls = 1e4, qs = 1e4, Bs = 1e3, ht = 3e4, pt = 0.2, gt = 6e4, Hs = 15e3, K = 8, Ws = "Pluno could not finish this message. Try it again.", js = "Browser connection was interrupted.", ft = 15e3, Fs = "Pluno could not send this message. Try it again.", mt = 2e3, $s = 1e3, zs = 100, yt = 8e3, It = 3, Ks = [300, 1e3], vt = 50 * 1024 * 1024, Gs = /* @__PURE__ */ new Set([
331
331
  ".jpeg:image/jpeg",
332
332
  ".jpg:image/jpeg",
333
333
  ".pdf:application/pdf",
334
334
  ".png:image/png",
335
335
  ".webp:image/webp"
336
- ]), oi = ".pdf,.png,.jpg,.jpeg,.webp", Je = 64e3, Ue = 4e3, Ve = 30, Xs = 2e3, Js = 1e3, Nt = "Image is too large for model vision input.", Vs = 100, Ot = "pluno.productAgent.state.", qe = "pluno.productAgent.pendingEvents.", pe = "pluno.productAgent.activeToolCalls.", Ys = 100;
336
+ ]), oi = ".pdf,.png,.jpg,.jpeg,.webp", Je = 64e3, Ue = 4e3, Ve = 30, Xs = 2e3, Js = 1e3, Ot = "Image is too large for model vision input.", Vs = 100, Nt = "pluno.productAgent.state.", qe = "pluno.productAgent.pendingEvents.", pe = "pluno.productAgent.activeToolCalls.", Ys = 100;
337
337
  function G(t, e = 0) {
338
338
  const s = t === 0 ? 0 : Math.min(3e4, 1e3 * 2 ** (t - 1));
339
339
  return Math.max(e, s);
@@ -361,7 +361,7 @@ class xt {
361
361
  constructor(e, s) {
362
362
  this.options = e, this.transportIdentity = s, this.state = {
363
363
  ...this.state,
364
- starterPrompts: Nn(e.initialStarterPrompts)
364
+ starterPrompts: On(e.initialStarterPrompts)
365
365
  };
366
366
  const n = e.restorePersistedState === !1 ? null : Rr(e.clientId, e.expectedPersistedSessionId);
367
367
  n && (this.state = {
@@ -380,7 +380,7 @@ class xt {
380
380
  lastError: null
381
381
  }), this.queuedClientEvents = Pr(
382
382
  br(e.clientId),
383
- kr(e.clientId)
383
+ _r(e.clientId)
384
384
  );
385
385
  const r = [...this.queuedClientEvents].reverse().find(
386
386
  (i) => i.type === "chat.user_message" && typeof i.clientMessageId == "string"
@@ -897,7 +897,7 @@ class xt {
897
897
  });
898
898
  }
899
899
  send(e) {
900
- this.sendNow(_(e)) || (e.type === "chat.user_message" && typeof e.clientMessageId == "string" && this.queuedClientEvents.some(
900
+ this.sendNow(k(e)) || (e.type === "chat.user_message" && typeof e.clientMessageId == "string" && this.queuedClientEvents.some(
901
901
  (r) => r.type === "chat.user_message" && r.clientMessageId === e.clientMessageId
902
902
  ) || this.queuedClientEvents.push(e), L(this.options.clientId, this.queuedClientEvents), this.setState({
903
903
  status: "reconnecting",
@@ -915,7 +915,7 @@ class xt {
915
915
  return !1;
916
916
  const s = this.socket;
917
917
  try {
918
- return s.send(JSON.stringify(e)), _e("client_event", e.type, dt(e)), !0;
918
+ return s.send(JSON.stringify(e)), ke("client_event", e.type, dt(e)), !0;
919
919
  } catch (n) {
920
920
  return M("web-sdk.agent", "Pluno socket send failed; scheduling reconnect", {
921
921
  message: n instanceof Error ? n.message : String(n),
@@ -924,13 +924,36 @@ class xt {
924
924
  }), this.socket === s && (this.clearSocketPhaseTimers(), this.stopHeartbeat(), this.socket = null, this.setReconnectingState(), this.scheduleReconnect()), s.readyState !== WebSocket.CLOSED && s.readyState !== WebSocket.CLOSING && s.close(), !1;
925
925
  }
926
926
  }
927
+ reportHealthSignal(e, s = {}) {
928
+ if (!(!this.socket || this.socket.readyState !== WebSocket.OPEN))
929
+ try {
930
+ this.socket.send(JSON.stringify({
931
+ type: "runtime.health",
932
+ signal: {
933
+ id: crypto.randomUUID(),
934
+ name: e,
935
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
936
+ source: "web_sdk",
937
+ entrySurface: this.options.entrySurface,
938
+ ...this.state.sessionId ? { sessionId: this.state.sessionId } : {},
939
+ ...this.activeResponseRunId ? { runId: this.activeResponseRunId } : {},
940
+ ...s
941
+ }
942
+ }));
943
+ } catch (n) {
944
+ M("web-sdk.agent", "Pluno health signal send failed", {
945
+ name: e,
946
+ message: n instanceof Error ? n.message : String(n)
947
+ });
948
+ }
949
+ }
927
950
  requestTransientStarterPrompts() {
928
951
  if (this.state.starterPromptsLoading || this.transientStarterPromptsRequestInFlight || this.transientStarterPromptsRequestAttempted)
929
952
  return;
930
953
  this.transientStarterPromptsRequestInFlight = !0, this.transientStarterPromptsRequestAttempted = !0, this.setState({ starterPromptsLoading: !0 });
931
954
  const e = Rn();
932
955
  this.sendNow(
933
- _({
956
+ k({
934
957
  type: "starter_prompts.page_context",
935
958
  pageUrl: e.pageUrl,
936
959
  pageTitle: e.pageTitle,
@@ -963,7 +986,7 @@ class xt {
963
986
  L(this.options.clientId, this.queuedClientEvents);
964
987
  for (let s = 0; s < e.length; s += 1) {
965
988
  const n = e[s];
966
- if (!this.sendNow(_(n))) {
989
+ if (!this.sendNow(k(n))) {
967
990
  this.queuedClientEvents.unshift(n, ...e.slice(s + 1)), L(this.options.clientId, this.queuedClientEvents);
968
991
  return;
969
992
  }
@@ -974,7 +997,7 @@ class xt {
974
997
  !this.pendingWarmupEvent || !this.sendNow(this.pendingWarmupEvent) || (this.pendingWarmupEvent = null);
975
998
  }
976
999
  handleServerEvent(e) {
977
- if (_e("server_event", e.type, dt(e)), e.type === "run.ack") {
1000
+ if (ke("server_event", e.type, dt(e)), e.type === "run.ack") {
978
1001
  const s = De(e), n = typeof e.clientMessageId == "string" ? e.clientMessageId : null;
979
1002
  s && n && this.backgroundClientMessageIds.delete(n) ? (this.backgroundSessionIds.add(s), this.deferredSessionUpdatedSessionIds.delete(s)) : s && (n === this.activeClientMessageId || n === this.pendingClientMessageId) && this.deferredSessionUpdatedSessionIds.delete(s) && this.state.sessionId === null && this.setState({ sessionId: s }), this.handleRunAck(e);
980
1003
  return;
@@ -997,7 +1020,7 @@ class xt {
997
1020
  }
998
1021
  if (sn(e) && this.markThinkingProgress(), e.type === "auth.ok") {
999
1022
  this.clearSocketAuthTimer(), this.reconnectAttempts = 0, this.flushQueuedClientEvents(), this.pendingClientMessageId && (this.setState({ pendingMessageStatus: "sending" }), this.schedulePendingDeliveryAck(this.pendingClientMessageId)), this.flushPendingWarmupEvent(), this.startHeartbeat();
1000
- const s = On(e), n = Object.prototype.hasOwnProperty.call(e, "appearance");
1023
+ const s = Nn(e), n = Object.prototype.hasOwnProperty.call(e, "appearance");
1001
1024
  M("web-sdk.agent", "Received auth.ok appearance", {
1002
1025
  hasAppearance: n,
1003
1026
  rawAppearance: e.appearance,
@@ -1131,7 +1154,7 @@ class xt {
1131
1154
  const s = H(e.item);
1132
1155
  if (We(s)) {
1133
1156
  typeof s?.runId == "string" && this.retryableFailureRunIdsAwaitingDone.add(s.runId);
1134
- const r = E(e.item, "sessionId") ?? this.state.sessionId, i = s ? O(s) : null, o = i ? this.clientMessageIdsByUserMessageItemId.get(i) : null, a = typeof s?.clientMessageId == "string" ? s.clientMessageId : o ?? (i ? null : this.activeClientMessageId ?? this.latestRecoverableClientMessageId);
1157
+ const r = E(e.item, "sessionId") ?? this.state.sessionId, i = s ? N(s) : null, o = i ? this.clientMessageIdsByUserMessageItemId.get(i) : null, a = typeof s?.clientMessageId == "string" ? s.clientMessageId : o ?? (i ? null : this.activeClientMessageId ?? this.latestRecoverableClientMessageId);
1135
1158
  if (r && a) {
1136
1159
  this.retryAfterInterruptedRun(r, a);
1137
1160
  return;
@@ -1371,7 +1394,11 @@ class xt {
1371
1394
  return;
1372
1395
  const n = this.retryAttemptsByClientMessageId[s] ?? 0;
1373
1396
  if (n >= K) {
1374
- this.retryableClientMessageId = s, this.setState({
1397
+ this.reportHealthSignal("run_recovery_exhausted", {
1398
+ clientMessageId: s,
1399
+ retryAttempts: n,
1400
+ reason: "retry_budget_exhausted"
1401
+ }), this.retryableClientMessageId = s, this.setState({
1375
1402
  messages: oe(
1376
1403
  this.state.messages,
1377
1404
  s,
@@ -1491,7 +1518,7 @@ class xt {
1491
1518
  this.failPendingDelivery(e);
1492
1519
  return;
1493
1520
  }
1494
- this.retryAttemptsByClientMessageId[e] = s + 1, this.setState({ pendingMessageStatus: "reconnecting" }), this.pendingDeliveryRetryTimer = window.setTimeout(() => {
1521
+ s === 0 && this.reportHealthSignal("run_ack_missed", { clientMessageId: e }), this.retryAttemptsByClientMessageId[e] = s + 1, this.setState({ pendingMessageStatus: "reconnecting" }), this.pendingDeliveryRetryTimer = window.setTimeout(() => {
1495
1522
  this.pendingDeliveryRetryTimer = null, !(this.pendingClientMessageId !== e || !this.pendingUserMessageEvent) && (this.send(this.pendingUserMessageEvent), this.setState({ pendingMessageStatus: "sending" }), this.schedulePendingDeliveryAck(e));
1496
1523
  }, G(s, mt));
1497
1524
  }
@@ -1532,7 +1559,7 @@ class xt {
1532
1559
  !this.state.isThinking || this.state.status === "closed" || this.activeClientMessageId !== e || (M("web-sdk.agent", "Pluno run ack missed; resyncing session", {
1533
1560
  sessionId: this.state.sessionId,
1534
1561
  clientMessageId: e
1535
- }), this.resyncThinkingSession(), this.scheduleRunAckResyncRetry(e));
1562
+ }), this.reportHealthSignal("run_ack_missed", { clientMessageId: e }), this.resyncThinkingSession(), this.scheduleRunAckResyncRetry(e));
1536
1563
  }
1537
1564
  scheduleRunAckResyncRetry(e) {
1538
1565
  this.clearRunAckResyncRetryTimer();
@@ -1566,6 +1593,8 @@ class xt {
1566
1593
  if (!e) {
1567
1594
  M("web-sdk.agent", "Pluno thinking watchdog stopped without a recoverable message id", {
1568
1595
  sessionId: this.state.sessionId
1596
+ }), this.reportHealthSignal("run_recovery_exhausted", {
1597
+ reason: "missing_client_message_id"
1569
1598
  }), this.setState({
1570
1599
  isThinking: !1,
1571
1600
  lastError: this.getRunRecoveryExhaustedErrorMessage(null),
@@ -1578,6 +1607,10 @@ class xt {
1578
1607
  M("web-sdk.agent", "Pluno run recovery retry exhausted", {
1579
1608
  sessionId: this.state.sessionId,
1580
1609
  clientMessageId: e
1610
+ }), this.reportHealthSignal("run_recovery_exhausted", {
1611
+ clientMessageId: e,
1612
+ retryAttempts: n,
1613
+ reason: "retry_budget_exhausted"
1581
1614
  }), this.retryableClientMessageId = e, this.setState({
1582
1615
  messages: oe(
1583
1616
  this.state.messages,
@@ -1637,8 +1670,8 @@ class xt {
1637
1670
  callId: n,
1638
1671
  toolName: r,
1639
1672
  summary: i,
1640
- rawInput: _(o),
1641
- rawOutput: _({
1673
+ rawInput: k(o),
1674
+ rawOutput: k({
1642
1675
  ok: !1,
1643
1676
  toolName: r,
1644
1677
  error: `Unsupported browser tool: ${r}`
@@ -1653,7 +1686,7 @@ class xt {
1653
1686
  callId: n,
1654
1687
  toolName: r,
1655
1688
  summary: i,
1656
- rawInput: _(o),
1689
+ rawInput: k(o),
1657
1690
  rawOutput: {
1658
1691
  ok: !1,
1659
1692
  toolName: r,
@@ -1669,7 +1702,7 @@ class xt {
1669
1702
  callId: n,
1670
1703
  toolName: r,
1671
1704
  summary: i,
1672
- rawInput: _(o),
1705
+ rawInput: k(o),
1673
1706
  rawOutput: null
1674
1707
  },
1675
1708
  startedAtMs: Date.now(),
@@ -1691,8 +1724,8 @@ class xt {
1691
1724
  callId: n,
1692
1725
  toolName: r,
1693
1726
  summary: o.summary,
1694
- rawInput: _(o),
1695
- rawOutput: _(Ln(h, c))
1727
+ rawInput: k(o),
1728
+ rawOutput: k(Ln(h, c))
1696
1729
  }), Cr(this.options.clientId, this.activeBrowserToolCalls.values());
1697
1730
  }
1698
1731
  setToolMessageLoading(e, s) {
@@ -1763,8 +1796,8 @@ class xt {
1763
1796
  const e = this.socket;
1764
1797
  !e || !this.sendNow({ type: "runtime.ping" }) || (this.clearHeartbeatAckTimer(), this.heartbeatAckTimer = window.setTimeout(() => {
1765
1798
  this.socket === e && (M("web-sdk.agent", "Pluno heartbeat acknowledgement timed out; reconnecting"), this.replaceTimedOutSocket(e));
1766
- }, Os));
1767
- }, Ns);
1799
+ }, Ns));
1800
+ }, Os);
1768
1801
  }
1769
1802
  stopHeartbeat() {
1770
1803
  this.heartbeatTimer !== null && (window.clearInterval(this.heartbeatTimer), this.heartbeatTimer = null), this.clearHeartbeatAckTimer();
@@ -1790,7 +1823,7 @@ class xt {
1790
1823
  ...e,
1791
1824
  ...e.lastError === null && e.lastErrorCode === void 0 ? { lastErrorCode: null } : {},
1792
1825
  ...e.lastError !== void 0 && e.lastErrorSecuritySettingsUrl === void 0 ? { lastErrorSecuritySettingsUrl: null } : {}
1793
- }, Er(this.options.clientId, this.state), this.emit("state", this.getState()), _e("state", this.state.status, {
1826
+ }, Er(this.options.clientId, this.state), this.emit("state", this.getState()), ke("state", this.state.status, {
1794
1827
  status: this.state.status,
1795
1828
  sessionId: this.state.sessionId,
1796
1829
  messageCount: this.state.messages.length,
@@ -1843,11 +1876,11 @@ function tn() {
1843
1876
  const m = y instanceof Request ? y : null, T = Br(y, m), f = Yt(u?.headers ?? m?.headers);
1844
1877
  if (!q(T, f, u?.body)) {
1845
1878
  const F = {
1846
- requestId: Oe("fetch"),
1879
+ requestId: Ne("fetch"),
1847
1880
  url: P(T, Ue),
1848
1881
  method: (u?.method ?? m?.method ?? "GET").toUpperCase(),
1849
1882
  requestHeaders: f,
1850
- requestBody: kt(u?.body),
1883
+ requestBody: _t(u?.body),
1851
1884
  resourceType: "fetch",
1852
1885
  startedAt: new Date(d).toISOString()
1853
1886
  };
@@ -1876,7 +1909,7 @@ function tn() {
1876
1909
  }, a = function(y, u, d, g, m) {
1877
1910
  const T = n.call(this, y, u, d ?? !0, g ?? void 0, m ?? void 0), f = typeof u == "string" ? u : u.toString();
1878
1911
  return Pe.set(this, {
1879
- requestId: Oe("xhr"),
1912
+ requestId: Ne("xhr"),
1880
1913
  method: String(y ?? "GET").toUpperCase(),
1881
1914
  url: P(f, Ue),
1882
1915
  requestHeaders: {},
@@ -1890,7 +1923,7 @@ function tn() {
1890
1923
  }, c = function(y) {
1891
1924
  try {
1892
1925
  const u = Pe.get(this);
1893
- u && (u.excluded = u.excluded || q(u.url, u.requestHeaders, y), u.requestBody = kt(y), u.excluded || this.addEventListener(
1926
+ u && (u.excluded = u.excluded || q(u.url, u.requestHeaders, y), u.requestBody = _t(y), u.excluded || this.addEventListener(
1894
1927
  "loadend",
1895
1928
  () => {
1896
1929
  queueMicrotask(() => {
@@ -1946,7 +1979,7 @@ function tn() {
1946
1979
  continue;
1947
1980
  const d = performance.timeOrigin + u.startTime;
1948
1981
  e({
1949
- requestId: Oe("resource"),
1982
+ requestId: Ne("resource"),
1950
1983
  url: P(u.name, Ue),
1951
1984
  method: "GET",
1952
1985
  resourceType: "resource",
@@ -2046,7 +2079,7 @@ async function un(t, e = {}) {
2046
2079
  return n.ok ? n.sizeBytes > 8 * 1024 * 1024 ? {
2047
2080
  type: "pluno.pageImages.inspectImage",
2048
2081
  imageAttached: !1,
2049
- imageAttachmentError: Nt
2082
+ imageAttachmentError: Ot
2050
2083
  } : {
2051
2084
  type: "pluno.pageImages.inspectImage",
2052
2085
  imageAttached: !0,
@@ -2061,7 +2094,7 @@ async function un(t, e = {}) {
2061
2094
  };
2062
2095
  }
2063
2096
  async function dn(t) {
2064
- return t instanceof Blob ? t.type.startsWith("image/") ? t.size === 0 ? { ok: !1, error: "Page image is empty." } : t.size > 8 * 1024 * 1024 ? { ok: !1, error: Nt } : {
2097
+ return t instanceof Blob ? t.type.startsWith("image/") ? t.size === 0 ? { ok: !1, error: "Page image is empty." } : t.size > 8 * 1024 * 1024 ? { ok: !1, error: Ot } : {
2065
2098
  ok: !0,
2066
2099
  mimeType: t.type,
2067
2100
  sizeBytes: t.size,
@@ -2303,7 +2336,7 @@ function Ye() {
2303
2336
  const a = t.map(([d, g]) => `${d}:
2304
2337
  ${g}`).join(`
2305
2338
 
2306
- `).trim().slice(0, 12e3), l = kn(r, i).trim(), c = `Simplified DOM outline:
2339
+ `).trim().slice(0, 12e3), l = _n(r, i).trim(), c = `Simplified DOM outline:
2307
2340
  `, h = `
2308
2341
 
2309
2342
  Visible page text:
@@ -2334,7 +2367,7 @@ function Lt(t) {
2334
2367
  function Cn() {
2335
2368
  return Array.from(document.querySelectorAll("main, [role='main'], article")).filter(Lt).sort((t, e) => J(e).length - J(t).length)[0] ?? null;
2336
2369
  }
2337
- function kn(t, e) {
2370
+ function _n(t, e) {
2338
2371
  const s = /* @__PURE__ */ new Set([
2339
2372
  "main",
2340
2373
  "nav",
@@ -2414,7 +2447,7 @@ function kn(t, e) {
2414
2447
  "data-test",
2415
2448
  "data-qa",
2416
2449
  "data-cy"
2417
- ], c = ["aria-label", "placeholder", "data-testid", "data-test", "data-qa", "data-cy"], { priorityElements: h, priorityTargets: p } = _n(), w = new Set(t);
2450
+ ], c = ["aria-label", "placeholder", "data-testid", "data-test", "data-qa", "data-cy"], { priorityElements: h, priorityTargets: p } = kn(), w = new Set(t);
2418
2451
  e && w.add(e);
2419
2452
  let y = 0;
2420
2453
  const u = (f) => {
@@ -2512,7 +2545,7 @@ function qt(t, e, s, n) {
2512
2545
  t.hasAttribute(a) && (i += `[${a}]`);
2513
2546
  return `${i}${n ? ` ${JSON.stringify(n)}` : ""}`;
2514
2547
  }
2515
- function _n() {
2548
+ function kn() {
2516
2549
  const t = /* @__PURE__ */ new Set(), e = /* @__PURE__ */ new Map(), s = (a, l) => {
2517
2550
  if (!a)
2518
2551
  return;
@@ -2610,12 +2643,12 @@ function Ht() {
2610
2643
  },
2611
2644
  {
2612
2645
  name: "widget_root",
2613
- selector: ks,
2646
+ selector: _s,
2614
2647
  description: "Finds Pluno's widget root inside the widget host shadow root."
2615
2648
  },
2616
2649
  {
2617
2650
  name: "widget_panel",
2618
- selector: _s,
2651
+ selector: ks,
2619
2652
  description: "Finds Pluno's open chat panel inside the widget host shadow root."
2620
2653
  },
2621
2654
  {
@@ -2650,10 +2683,10 @@ function Mt(t, e) {
2650
2683
  const s = t[e];
2651
2684
  return Array.isArray(s) ? s.filter((n) => typeof n == "string" && n.trim().length > 0) : [];
2652
2685
  }
2653
- function Nn(t) {
2686
+ function On(t) {
2654
2687
  return Array.isArray(t) ? t.filter((e) => typeof e == "string" && e.trim().length > 0) : [];
2655
2688
  }
2656
- function On(t) {
2689
+ function Nn(t) {
2657
2690
  if (!t || typeof t != "object")
2658
2691
  return null;
2659
2692
  const e = t, s = e.appearance, n = s && typeof s == "object" ? s : e, r = typeof n.accentColor == "string" ? n.accentColor : null, i = n.colorScheme === "dark" ? "dark" : n.colorScheme === "light" ? "light" : null, o = typeof n.fontFamily == "string" && n.fontFamily.trim() ? n.fontFamily : null, a = typeof n.scribbleStyle == "boolean" ? n.scribbleStyle : null;
@@ -2752,9 +2785,9 @@ function Wt(t, e) {
2752
2785
  e
2753
2786
  ),
2754
2787
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
2755
- ...N(r) !== null ? { causalSequence: N(r) } : {},
2756
- respondsToUserMessageId: O(r) ?? void 0,
2757
- ...k(r) ? { runId: k(r) } : {},
2788
+ ...O(r) !== null ? { causalSequence: O(r) } : {},
2789
+ respondsToUserMessageId: N(r) ?? void 0,
2790
+ ..._(r) ? { runId: _(r) } : {},
2758
2791
  attachments: Xt(r.attachments, e)
2759
2792
  };
2760
2793
  return i === "assistant" && typeof r.id == "string" && Object.defineProperty(o, "assistantDraftItemId", {
@@ -2773,11 +2806,11 @@ function Wt(t, e) {
2773
2806
  role: "tool",
2774
2807
  content: "",
2775
2808
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
2776
- respondsToUserMessageId: O(r) ?? void 0,
2777
- ...k(r) ? { runId: k(r) } : {},
2809
+ respondsToUserMessageId: N(r) ?? void 0,
2810
+ ..._(r) ? { runId: _(r) } : {},
2778
2811
  dataType: "scheduled_check_in",
2779
2812
  toolName: Dt,
2780
- callId: Ne(r) ?? void 0,
2813
+ callId: Oe(r) ?? void 0,
2781
2814
  scheduledCheckInAt: i
2782
2815
  };
2783
2816
  const o = $n(r.output);
@@ -2786,12 +2819,12 @@ function Wt(t, e) {
2786
2819
  role: "tool",
2787
2820
  content: `Connect ${o.appName} to continue`,
2788
2821
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
2789
- ...N(r) !== null ? { causalSequence: N(r) } : {},
2790
- respondsToUserMessageId: O(r) ?? void 0,
2791
- ...k(r) ? { runId: k(r) } : {},
2822
+ ...O(r) !== null ? { causalSequence: O(r) } : {},
2823
+ respondsToUserMessageId: N(r) ?? void 0,
2824
+ ..._(r) ? { runId: _(r) } : {},
2792
2825
  dataType: "function_call_output",
2793
2826
  toolName: "authenticate_pipedream_app",
2794
- callId: Ne(r) ?? void 0,
2827
+ callId: Oe(r) ?? void 0,
2795
2828
  integrationAuthRequest: o
2796
2829
  } : null;
2797
2830
  }
@@ -2800,21 +2833,21 @@ function Wt(t, e) {
2800
2833
  role: "tool",
2801
2834
  content: r.type === "mcp_call" ? Fn(r) : Kn(r),
2802
2835
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
2803
- ...N(r) !== null ? { causalSequence: N(r) } : {},
2804
- respondsToUserMessageId: O(r) ?? void 0,
2805
- ...k(r) ? { runId: k(r) } : {},
2836
+ ...O(r) !== null ? { causalSequence: O(r) } : {},
2837
+ respondsToUserMessageId: N(r) ?? void 0,
2838
+ ..._(r) ? { runId: _(r) } : {},
2806
2839
  dataType: String(r.type),
2807
2840
  toolName: r.type === "tab_lifecycle_decision" ? "tab_lifecycle_decision" : typeof r.name == "string" ? r.name : void 0,
2808
- callId: Ne(r) ?? void 0,
2841
+ callId: Oe(r) ?? void 0,
2809
2842
  loading: r.localExecutionStatus === "queued" || r.localExecutionStatus === "running" ? !0 : typeof r.localExecutionStatus == "string" ? !1 : void 0
2810
2843
  } : r.type === "run_status" || r.type === "run_error" ? r.type === "run_error" && r.stage === "tool_execution" ? null : {
2811
2844
  id: String(s.id ?? crypto.randomUUID()),
2812
2845
  role: "system",
2813
2846
  content: zn(r),
2814
2847
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
2815
- ...N(r) !== null ? { causalSequence: N(r) } : {},
2816
- respondsToUserMessageId: O(r) ?? void 0,
2817
- ...k(r) ? { runId: k(r) } : {},
2848
+ ...O(r) !== null ? { causalSequence: O(r) } : {},
2849
+ respondsToUserMessageId: N(r) ?? void 0,
2850
+ ..._(r) ? { runId: _(r) } : {},
2818
2851
  dataType: String(r.type),
2819
2852
  loading: r.type === "run_status" && (r.status === "running" || r.status === "retrying"),
2820
2853
  ...r.type === "run_status" && r.status === "steered" ? { steered: !0 } : {},
@@ -2892,11 +2925,11 @@ function Xn(t) {
2892
2925
  runId: typeof e.runId == "string" ? e.runId : null
2893
2926
  };
2894
2927
  }
2895
- function Ne(t) {
2928
+ function Oe(t) {
2896
2929
  const e = t.callId ?? t.call_id;
2897
2930
  return typeof e == "string" && e ? e : null;
2898
2931
  }
2899
- function N(t) {
2932
+ function O(t) {
2900
2933
  return typeof t.causalSequence == "number" && Number.isSafeInteger(t.causalSequence) ? t.causalSequence : null;
2901
2934
  }
2902
2935
  function Jn(t) {
@@ -3199,7 +3232,7 @@ function ur(t) {
3199
3232
  function Fe(t, e) {
3200
3233
  if (typeof e.clientMessageId == "string")
3201
3234
  return e.clientMessageId;
3202
- const s = O(e);
3235
+ const s = N(e);
3203
3236
  if (!s)
3204
3237
  return null;
3205
3238
  const n = t.find((i) => E(i, "id") === s), r = H(n);
@@ -3222,7 +3255,7 @@ function Et(t, e, s, n, r) {
3222
3255
  if (!e || !hr(t))
3223
3256
  return !1;
3224
3257
  const i = t;
3225
- return !(We(i) || s !== null && typeof i.id == "string" && i.id !== s || (n !== null ? O(i) !== n : r !== null && k(i) !== r));
3258
+ return !(We(i) || s !== null && typeof i.id == "string" && i.id !== s || (n !== null ? N(i) !== n : r !== null && _(i) !== r));
3226
3259
  }
3227
3260
  function hr(t) {
3228
3261
  if (!t || typeof t != "object")
@@ -3357,7 +3390,7 @@ function E(t, e) {
3357
3390
  }
3358
3391
  function Rr(t, e) {
3359
3392
  try {
3360
- const s = window.localStorage.getItem(`${Ot}${t}`);
3393
+ const s = window.localStorage.getItem(`${Nt}${t}`);
3361
3394
  if (!s)
3362
3395
  return null;
3363
3396
  const n = JSON.parse(s), r = typeof n.sessionId == "string" ? n.sessionId : null;
@@ -3375,7 +3408,7 @@ function Rr(t, e) {
3375
3408
  function Er(t, e) {
3376
3409
  try {
3377
3410
  window.localStorage.setItem(
3378
- `${Ot}${t}`,
3411
+ `${Nt}${t}`,
3379
3412
  JSON.stringify({
3380
3413
  sessionId: e.sessionId,
3381
3414
  messages: e.messages.slice(-Vs).map(Lr)
@@ -3436,7 +3469,7 @@ function Cr(t, e) {
3436
3469
  }
3437
3470
  Gt(t, e);
3438
3471
  }
3439
- function kr(t) {
3472
+ function _r(t) {
3440
3473
  try {
3441
3474
  const e = `${pe}${t}`, s = window.sessionStorage.getItem(e);
3442
3475
  if (window.sessionStorage.removeItem(e), !s)
@@ -3448,7 +3481,7 @@ function kr(t) {
3448
3481
  rawOutput: {
3449
3482
  pageContextRestarted: !0,
3450
3483
  outcome: "unknown",
3451
- message: _r(location.href),
3484
+ message: kr(location.href),
3452
3485
  currentUrl: location.href,
3453
3486
  console: [],
3454
3487
  metadata: {
@@ -3465,7 +3498,7 @@ function kr(t) {
3465
3498
  return [];
3466
3499
  }
3467
3500
  }
3468
- function _r(t) {
3501
+ function kr(t) {
3469
3502
  return `The page context restarted. This is expected when the action included page navigation. Otherwise, it's unknown whether the action completed.
3470
3503
  Current URL: ${t}`;
3471
3504
  }
@@ -3521,7 +3554,7 @@ function Jt(t, e) {
3521
3554
  } : t;
3522
3555
  }
3523
3556
  function ze(t) {
3524
- return t.type || Or(t.name) || "application/octet-stream";
3557
+ return t.type || Nr(t.name) || "application/octet-stream";
3525
3558
  }
3526
3559
  function vr(t) {
3527
3560
  Vt({
@@ -3531,17 +3564,17 @@ function vr(t) {
3531
3564
  });
3532
3565
  }
3533
3566
  function Vt(t) {
3534
- const e = Nr(t.name), s = t.mimeType.trim().toLowerCase();
3567
+ const e = Or(t.name), s = t.mimeType.trim().toLowerCase();
3535
3568
  if (!Gs.has(`${e}:${s}`))
3536
3569
  throw new Error("This attachment type is not supported by the embedded model provider");
3537
3570
  if (t.sizeBytes <= 0 || t.sizeBytes >= vt)
3538
3571
  throw new Error("Embedded attachments must be between 1 byte and less than 50 MB");
3539
3572
  }
3540
- function Nr(t) {
3573
+ function Or(t) {
3541
3574
  const e = t.trim().toLowerCase(), s = e.lastIndexOf(".");
3542
3575
  return s >= 0 ? e.slice(s) : "";
3543
3576
  }
3544
- function Or(t) {
3577
+ function Nr(t) {
3545
3578
  const e = t.toLowerCase();
3546
3579
  return e.endsWith(".png") ? "image/png" : e.endsWith(".jpg") || e.endsWith(".jpeg") ? "image/jpeg" : e.endsWith(".webp") ? "image/webp" : e.endsWith(".gif") ? "image/gif" : e.endsWith(".pdf") ? "application/pdf" : null;
3547
3580
  }
@@ -3581,11 +3614,11 @@ function Ze(t) {
3581
3614
  } = t;
3582
3615
  return r;
3583
3616
  }
3584
- function O(t) {
3617
+ function N(t) {
3585
3618
  const e = t.respondsToUserMessageId;
3586
3619
  return typeof e == "string" && e ? e : null;
3587
3620
  }
3588
- function k(t) {
3621
+ function _(t) {
3589
3622
  const e = t.runId;
3590
3623
  return typeof e == "string" && e ? e : null;
3591
3624
  }
@@ -3660,25 +3693,25 @@ function jr(t, e) {
3660
3693
  return;
3661
3694
  }
3662
3695
  }
3663
- function kt(t) {
3696
+ function _t(t) {
3664
3697
  if (typeof t == "string")
3665
3698
  return P(t);
3666
3699
  }
3667
3700
  function Fr(t) {
3668
- return _({
3701
+ return k({
3669
3702
  ...t,
3670
- requestBody: _t(t.requestBody),
3671
- responseBody: _t(t.responseBody)
3703
+ requestBody: kt(t.requestBody),
3704
+ responseBody: kt(t.responseBody)
3672
3705
  });
3673
3706
  }
3674
- function _t(t) {
3707
+ function kt(t) {
3675
3708
  if (typeof t != "string")
3676
3709
  return t;
3677
3710
  const e = t.trim();
3678
3711
  if (!e.startsWith("{") && !e.startsWith("["))
3679
3712
  return he(t);
3680
3713
  try {
3681
- return JSON.stringify(_(JSON.parse(t)));
3714
+ return JSON.stringify(k(JSON.parse(t)));
3682
3715
  } catch {
3683
3716
  return he(t);
3684
3717
  }
@@ -3734,7 +3767,7 @@ function Kr(t) {
3734
3767
  function P(t, e = Je) {
3735
3768
  return t.length <= e ? t : `${t.slice(0, e)}... [truncated ${t.length - e} chars]`;
3736
3769
  }
3737
- function Oe(t) {
3770
+ function Ne(t) {
3738
3771
  return `${t}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
3739
3772
  }
3740
3773
  class ue extends Error {
@@ -3770,7 +3803,7 @@ function Vr(t) {
3770
3803
  return t === 401 || t === 403;
3771
3804
  }
3772
3805
  const fe = "[REDACTED_SECRET]", D = "[REDACTED_TOKEN]", Yr = "[REDACTED_SIGNED_URL]", Qr = 20, Zr = /^(access_token|accessToken|refresh_token|refreshToken|id_token|idToken|authToken|token|api_key|apiKey|apikey|key|secret|signature|sig|password|passwd|pwd|code|state|session|jwt|csrf|csrfToken|xsrf|xsrfToken)$/i, Zt = /\bBearer\s+[A-Za-z0-9._~+/=-]{12,}/gi, es = /\bBasic\s+[A-Za-z0-9+/=-]{12,}/gi, ts = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, ss = /\b(access_token|accessToken|refresh_token|refreshToken|id_token|idToken|authToken|api_key|apiKey|apikey|client_secret|clientSecret|password|secret|token|jwt|csrf|csrfToken|xsrf|xsrfToken)\b\s*[:=]\s*["']?[^"',&\s}]+/gi, ei = /\bhttps?:\/\/[^\s"'<>]+(?:X-Amz-Signature|X-Goog-Signature|Signature|sig=)[^\s"'<>]*/gi, ti = /\bhttps?:\/\/[^\s"'<>]+/gi, si = /[),.;\]]+$/;
3773
- function _(t) {
3806
+ function k(t) {
3774
3807
  return de(t, 0, /* @__PURE__ */ new WeakSet());
3775
3808
  }
3776
3809
  function de(t, e, s) {
@@ -3819,8 +3852,8 @@ function ii(t) {
3819
3852
  export {
3820
3853
  ut as PLUNO_PRODUCT_AGENT_SDK_PREVIEW_HOST_SELECTOR,
3821
3854
  Le as PLUNO_PRODUCT_AGENT_WIDGET_HOST_SELECTOR,
3822
- _s as PLUNO_PRODUCT_AGENT_WIDGET_PANEL_SELECTOR,
3823
- ks as PLUNO_PRODUCT_AGENT_WIDGET_ROOT_SELECTOR,
3855
+ ks as PLUNO_PRODUCT_AGENT_WIDGET_PANEL_SELECTOR,
3856
+ _s as PLUNO_PRODUCT_AGENT_WIDGET_ROOT_SELECTOR,
3824
3857
  Us as PLUNO_PRODUCT_AGENT_WIDGET_TIMELINE_SELECTOR,
3825
3858
  oi as PRODUCT_AGENT_PROVIDER_INPUT_ATTACHMENT_ACCEPT,
3826
3859
  xt as PlunoProductAgent,
@@ -595,7 +595,7 @@ class ko {
595
595
  }, n);
596
596
  try {
597
597
  $a().catch((o) => {
598
- J("web-sdk.attachments", "Failed to delete stale Product Agent attachments", {
598
+ X("web-sdk.attachments", "Failed to delete stale Product Agent attachments", {
599
599
  message: o instanceof Error ? o.message : String(o)
600
600
  });
601
601
  }), e.disableNetworkCapture || i.enableNetworkCapture(), i.startPageLifecycleRecovery(), i.startStarterPromptUrlWatcher(), e.autoConnect !== !1 && await i.connect();
@@ -631,9 +631,9 @@ class ko {
631
631
  throw new Error("Pluno requires a token or tokenProvider");
632
632
  const n = dp(this.options.backendUrl), i = this.options.webSocketFactory?.(n) ?? new WebSocket(n);
633
633
  this.socket = i, this.socketConnectTimer = window.setTimeout(() => {
634
- this.socket === i && i.readyState === WebSocket.CONNECTING && (J("web-sdk.agent", "Pluno socket opening timed out; reconnecting"), this.replaceTimedOutSocket(i));
634
+ this.socket === i && i.readyState === WebSocket.CONNECTING && (X("web-sdk.agent", "Pluno socket opening timed out; reconnecting"), this.replaceTimedOutSocket(i));
635
635
  }, El), i.addEventListener("open", () => {
636
- this.socket !== i || (this.clearSocketConnectTimer(), J("web-sdk.agent", "Pluno socket opened", {
636
+ this.socket !== i || (this.clearSocketConnectTimer(), X("web-sdk.agent", "Pluno socket opened", {
637
637
  queuedClientEventCount: this.queuedClientEvents.length,
638
638
  isThinking: this.state.isThinking
639
639
  }), !(this.token ? this.sendNow({
@@ -643,7 +643,7 @@ class ko {
643
643
  transportId: this.transportIdentity.transportId,
644
644
  pageUrl: location.href
645
645
  }) : !0)) || (this.socketAuthTimer = window.setTimeout(() => {
646
- this.socket === i && (J("web-sdk.agent", "Pluno socket authentication timed out; reconnecting"), this.replaceTimedOutSocket(i));
646
+ this.socket === i && (X("web-sdk.agent", "Pluno socket authentication timed out; reconnecting"), this.replaceTimedOutSocket(i));
647
647
  }, Cl));
648
648
  }), i.addEventListener("message", (o) => {
649
649
  this.socket === i && this.handleServerEvent(_p(o.data));
@@ -655,7 +655,7 @@ class ko {
655
655
  (r) => r.type === "chat.user_message" && r.clientMessageId === s.clientMessageId
656
656
  ) && (this.queuedClientEvents.push(s), Lt(this.options.clientId, this.queuedClientEvents), this.setState({ pendingMessageStatus: "reconnecting" })), this.clearSocketPhaseTimers(), this.stopHeartbeat(), this.socket = null, this.setReconnectingState(), this.scheduleReconnect(), i.readyState !== WebSocket.CLOSED && i.readyState !== WebSocket.CLOSING && i.close();
657
657
  }), i.addEventListener("close", (o) => {
658
- this.socket === i && (this.clearSocketPhaseTimers(), this.stopHeartbeat(), this.socket = null, this.state.status !== "closed" && (this.rememberBrowserConnectionInterruptionForActiveRun(), J("web-sdk.agent", "Pluno socket closed; scheduling reconnect", {
658
+ this.socket === i && (this.clearSocketPhaseTimers(), this.stopHeartbeat(), this.socket = null, this.state.status !== "closed" && (this.rememberBrowserConnectionInterruptionForActiveRun(), X("web-sdk.agent", "Pluno socket closed; scheduling reconnect", {
659
659
  code: typeof o?.code == "number" ? o.code : null,
660
660
  reason: typeof o?.reason == "string" ? o.reason : "",
661
661
  wasClean: typeof o?.wasClean == "boolean" ? o.wasClean : null,
@@ -663,7 +663,7 @@ class ko {
663
663
  isThinking: this.state.isThinking
664
664
  }), this.setReconnectingState(), this.scheduleReconnect()));
665
665
  }), i.addEventListener("error", () => {
666
- this.socket !== i || this.state.status === "closed" || (J("web-sdk.agent", "Pluno socket error; scheduling reconnect", {
666
+ this.socket !== i || this.state.status === "closed" || (X("web-sdk.agent", "Pluno socket error; scheduling reconnect", {
667
667
  queuedClientEventCount: this.queuedClientEvents.length,
668
668
  isThinking: this.state.isThinking
669
669
  }), this.clearSocketPhaseTimers(), this.stopHeartbeat(), this.socket = null, this.rememberBrowserConnectionInterruptionForActiveRun(), this.setReconnectingState(), this.scheduleReconnect(), i.readyState !== WebSocket.CLOSED && i.readyState !== WebSocket.CLOSING && i.close());
@@ -813,7 +813,7 @@ class ko {
813
813
  createdAt: o,
814
814
  lastUsedAt: o
815
815
  }).catch((s) => {
816
- J("web-sdk.attachments", "Failed to store Product Agent attachment", {
816
+ X("web-sdk.attachments", "Failed to store Product Agent attachment", {
817
817
  attachmentId: n,
818
818
  name: i.name,
819
819
  message: s instanceof Error ? s.message : String(s)
@@ -875,7 +875,7 @@ class ko {
875
875
  storageKey: l.storageKey,
876
876
  lastUsedAt: Date.now()
877
877
  }).catch((p) => {
878
- J("web-sdk.attachments", "Failed to update persisted Product Agent attachment", {
878
+ X("web-sdk.attachments", "Failed to update persisted Product Agent attachment", {
879
879
  attachmentId: n.id,
880
880
  name: l.name,
881
881
  message: p instanceof Error ? p.message : String(p)
@@ -1035,13 +1035,36 @@ class ko {
1035
1035
  try {
1036
1036
  return n.send(JSON.stringify(e)), Oi("client_event", e.type, ws(e)), !0;
1037
1037
  } catch (i) {
1038
- return J("web-sdk.agent", "Pluno socket send failed; scheduling reconnect", {
1038
+ return X("web-sdk.agent", "Pluno socket send failed; scheduling reconnect", {
1039
1039
  message: i instanceof Error ? i.message : String(i),
1040
1040
  queuedClientEventCount: this.queuedClientEvents.length,
1041
1041
  isThinking: this.state.isThinking
1042
1042
  }), this.socket === n && (this.clearSocketPhaseTimers(), this.stopHeartbeat(), this.socket = null, this.setReconnectingState(), this.scheduleReconnect()), n.readyState !== WebSocket.CLOSED && n.readyState !== WebSocket.CLOSING && n.close(), !1;
1043
1043
  }
1044
1044
  }
1045
+ reportHealthSignal(e, n = {}) {
1046
+ if (!(!this.socket || this.socket.readyState !== WebSocket.OPEN))
1047
+ try {
1048
+ this.socket.send(JSON.stringify({
1049
+ type: "runtime.health",
1050
+ signal: {
1051
+ id: crypto.randomUUID(),
1052
+ name: e,
1053
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
1054
+ source: "web_sdk",
1055
+ entrySurface: this.options.entrySurface,
1056
+ ...this.state.sessionId ? { sessionId: this.state.sessionId } : {},
1057
+ ...this.activeResponseRunId ? { runId: this.activeResponseRunId } : {},
1058
+ ...n
1059
+ }
1060
+ }));
1061
+ } catch (i) {
1062
+ X("web-sdk.agent", "Pluno health signal send failed", {
1063
+ name: e,
1064
+ message: i instanceof Error ? i.message : String(i)
1065
+ });
1066
+ }
1067
+ }
1045
1068
  requestTransientStarterPrompts() {
1046
1069
  if (this.state.starterPromptsLoading || this.transientStarterPromptsRequestInFlight || this.transientStarterPromptsRequestAttempted)
1047
1070
  return;
@@ -1116,7 +1139,7 @@ class ko {
1116
1139
  if (Gl(e) && this.markThinkingProgress(), e.type === "auth.ok") {
1117
1140
  this.clearSocketAuthTimer(), this.reconnectAttempts = 0, this.flushQueuedClientEvents(), this.pendingClientMessageId && (this.setState({ pendingMessageStatus: "sending" }), this.schedulePendingDeliveryAck(this.pendingClientMessageId)), this.flushPendingWarmupEvent(), this.startHeartbeat();
1118
1141
  const n = Sp(e), i = Object.prototype.hasOwnProperty.call(e, "appearance");
1119
- J("web-sdk.agent", "Received auth.ok appearance", {
1142
+ X("web-sdk.agent", "Received auth.ok appearance", {
1120
1143
  hasAppearance: i,
1121
1144
  rawAppearance: e.appearance,
1122
1145
  normalizedAppearance: n
@@ -1489,7 +1512,11 @@ class ko {
1489
1512
  return;
1490
1513
  const i = this.retryAttemptsByClientMessageId[n] ?? 0;
1491
1514
  if (i >= tn) {
1492
- this.retryableClientMessageId = n, this.setState({
1515
+ this.reportHealthSignal("run_recovery_exhausted", {
1516
+ clientMessageId: n,
1517
+ retryAttempts: i,
1518
+ reason: "retry_budget_exhausted"
1519
+ }), this.retryableClientMessageId = n, this.setState({
1493
1520
  messages: Fn(
1494
1521
  this.state.messages,
1495
1522
  n,
@@ -1609,7 +1636,7 @@ class ko {
1609
1636
  this.failPendingDelivery(e);
1610
1637
  return;
1611
1638
  }
1612
- this.retryAttemptsByClientMessageId[e] = n + 1, this.setState({ pendingMessageStatus: "reconnecting" }), this.pendingDeliveryRetryTimer = window.setTimeout(() => {
1639
+ n === 0 && this.reportHealthSignal("run_ack_missed", { clientMessageId: e }), this.retryAttemptsByClientMessageId[e] = n + 1, this.setState({ pendingMessageStatus: "reconnecting" }), this.pendingDeliveryRetryTimer = window.setTimeout(() => {
1613
1640
  this.pendingDeliveryRetryTimer = null, !(this.pendingClientMessageId !== e || !this.pendingUserMessageEvent) && (this.send(this.pendingUserMessageEvent), this.setState({ pendingMessageStatus: "sending" }), this.schedulePendingDeliveryAck(e));
1614
1641
  }, nn(n, vs));
1615
1642
  }
@@ -1647,10 +1674,10 @@ class ko {
1647
1674
  }, xs);
1648
1675
  }
1649
1676
  recoverMissedRunAck(e) {
1650
- !this.state.isThinking || this.state.status === "closed" || this.activeClientMessageId !== e || (J("web-sdk.agent", "Pluno run ack missed; resyncing session", {
1677
+ !this.state.isThinking || this.state.status === "closed" || this.activeClientMessageId !== e || (X("web-sdk.agent", "Pluno run ack missed; resyncing session", {
1651
1678
  sessionId: this.state.sessionId,
1652
1679
  clientMessageId: e
1653
- }), this.resyncThinkingSession(), this.scheduleRunAckResyncRetry(e));
1680
+ }), this.reportHealthSignal("run_ack_missed", { clientMessageId: e }), this.resyncThinkingSession(), this.scheduleRunAckResyncRetry(e));
1654
1681
  }
1655
1682
  scheduleRunAckResyncRetry(e) {
1656
1683
  this.clearRunAckResyncRetryTimer();
@@ -1660,7 +1687,7 @@ class ko {
1660
1687
  status: this.state.status === "reconnecting" ? "reconnecting" : "connected",
1661
1688
  isThinking: !0,
1662
1689
  lastError: null
1663
- }), J("web-sdk.agent", "Pluno run ack recovery retrying last user message", {
1690
+ }), X("web-sdk.agent", "Pluno run ack recovery retrying last user message", {
1664
1691
  sessionId: this.state.sessionId,
1665
1692
  clientMessageId: e
1666
1693
  }), this.state.sessionId ? this.send({
@@ -1682,8 +1709,10 @@ class ko {
1682
1709
  return;
1683
1710
  const e = this.activeClientMessageId;
1684
1711
  if (!e) {
1685
- J("web-sdk.agent", "Pluno thinking watchdog stopped without a recoverable message id", {
1712
+ X("web-sdk.agent", "Pluno thinking watchdog stopped without a recoverable message id", {
1686
1713
  sessionId: this.state.sessionId
1714
+ }), this.reportHealthSignal("run_recovery_exhausted", {
1715
+ reason: "missing_client_message_id"
1687
1716
  }), this.setState({
1688
1717
  isThinking: !1,
1689
1718
  lastError: this.getRunRecoveryExhaustedErrorMessage(null),
@@ -1693,9 +1722,13 @@ class ko {
1693
1722
  }
1694
1723
  const n = this.thinkingWatchdogResyncAttemptsByClientMessageId[e] ?? 0, i = this.retryAttemptsByClientMessageId[e] ?? 0;
1695
1724
  if (i >= tn) {
1696
- J("web-sdk.agent", "Pluno run recovery retry exhausted", {
1725
+ X("web-sdk.agent", "Pluno run recovery retry exhausted", {
1697
1726
  sessionId: this.state.sessionId,
1698
1727
  clientMessageId: e
1728
+ }), this.reportHealthSignal("run_recovery_exhausted", {
1729
+ clientMessageId: e,
1730
+ retryAttempts: i,
1731
+ reason: "retry_budget_exhausted"
1699
1732
  }), this.retryableClientMessageId = e, this.setState({
1700
1733
  messages: Fn(
1701
1734
  this.state.messages,
@@ -1709,7 +1742,7 @@ class ko {
1709
1742
  return;
1710
1743
  }
1711
1744
  if (n < 1) {
1712
- this.thinkingWatchdogResyncAttemptsByClientMessageId[e] = n + 1, J("web-sdk.agent", "Pluno thinking watchdog resyncing session", {
1745
+ this.thinkingWatchdogResyncAttemptsByClientMessageId[e] = n + 1, X("web-sdk.agent", "Pluno thinking watchdog resyncing session", {
1713
1746
  sessionId: this.state.sessionId,
1714
1747
  clientMessageId: e,
1715
1748
  resyncAttempts: n + 1
@@ -1720,7 +1753,7 @@ class ko {
1720
1753
  status: this.state.status === "reconnecting" ? "reconnecting" : "connected",
1721
1754
  isThinking: !0,
1722
1755
  lastError: null
1723
- }), J("web-sdk.agent", "Pluno thinking watchdog scheduling retry for last user message", {
1756
+ }), X("web-sdk.agent", "Pluno thinking watchdog scheduling retry for last user message", {
1724
1757
  sessionId: this.state.sessionId,
1725
1758
  clientMessageId: e,
1726
1759
  retryAttempts: i + 1
@@ -1868,7 +1901,7 @@ class ko {
1868
1901
  const e = Wl(this.reconnectAttempts);
1869
1902
  this.reconnectAttempts += 1, this.reconnectTimer = window.setTimeout(() => {
1870
1903
  this.reconnectTimer = null, this.connect().catch((n) => {
1871
- J("web-sdk.agent", "Pluno reconnect failed; retrying", {
1904
+ X("web-sdk.agent", "Pluno reconnect failed; retrying", {
1872
1905
  message: n instanceof Error ? n.message : String(n),
1873
1906
  queuedClientEventCount: this.queuedClientEvents.length,
1874
1907
  isThinking: this.state.isThinking
@@ -1880,7 +1913,7 @@ class ko {
1880
1913
  this.stopHeartbeat(), this.heartbeatTimer = window.setInterval(() => {
1881
1914
  const e = this.socket;
1882
1915
  !e || !this.sendNow({ type: "runtime.ping" }) || (this.clearHeartbeatAckTimer(), this.heartbeatAckTimer = window.setTimeout(() => {
1883
- this.socket === e && (J("web-sdk.agent", "Pluno heartbeat acknowledgement timed out; reconnecting"), this.replaceTimedOutSocket(e));
1916
+ this.socket === e && (X("web-sdk.agent", "Pluno heartbeat acknowledgement timed out; reconnecting"), this.replaceTimedOutSocket(e));
1884
1917
  }, Il));
1885
1918
  }, Sl);
1886
1919
  }
@@ -2104,7 +2137,7 @@ function jl() {
2104
2137
  };
2105
2138
  return window.__plunoProductAgentNetworkCapture = c, c;
2106
2139
  }
2107
- function J(t, e, n) {
2140
+ function X(t, e, n) {
2108
2141
  if (typeof window > "u")
2109
2142
  return;
2110
2143
  const i = window, o = {
@@ -4591,7 +4624,7 @@ async function Qd(t = {}) {
4591
4624
  const gi = new Set(p.openToolGroupKeys), gt = new Set(
4592
4625
  p.seenShareCandidateIds
4593
4626
  ), Wt = new Set(gt);
4594
- let hi = p.sharePromptsDisabled || await zg(e), Ie = null, it = null, X = !1, bn = !(e.loginRequired || e.signupRequired), ot = !1, ht = {
4627
+ let hi = p.sharePromptsDisabled || await zg(e), Ie = null, it = null, J = !1, bn = !(e.loginRequired || e.signupRequired), ot = !1, ht = {
4595
4628
  enabled: !0
4596
4629
  }, ft = 0, fi = null, mt = null, wt = null, yn = null, $o = "", de = !1, fe = !1, Oe = [], Ht = null, bt = null, _n = !1, yt = 0, me = null, jo = location.origin, Go = E.getState().sessionId, Ko = E.getState().user?.id ?? null, mi = E.getState().status;
4597
4630
  const Te = (a, u) => {
@@ -4639,11 +4672,11 @@ async function Qd(t = {}) {
4639
4672
  fe = !0, bt = null, Ce();
4640
4673
  try {
4641
4674
  const y = await E.listSessions({ cursor: a, limit: 20 });
4642
- if (u !== yt || X)
4675
+ if (u !== yt || J)
4643
4676
  return;
4644
4677
  Oe = a ? [...Oe, ...y.sessions] : y.sessions, Ht = y.nextCursor, a || (_n = !0);
4645
4678
  } catch (y) {
4646
- if (u !== yt || X)
4679
+ if (u !== yt || J)
4647
4680
  return;
4648
4681
  ue(
4649
4682
  "web-sdk.widget",
@@ -4653,7 +4686,7 @@ async function Qd(t = {}) {
4653
4686
  }
4654
4687
  ), bt = Od;
4655
4688
  } finally {
4656
- if (u !== yt || X)
4689
+ if (u !== yt || J)
4657
4690
  return;
4658
4691
  fe = !1, Ce();
4659
4692
  }
@@ -4662,12 +4695,12 @@ async function Qd(t = {}) {
4662
4695
  me !== null && (window.clearTimeout(me), me = null), yt += 1, fe = !1, Oe = [], Ht = null, bt = null, _n = !1, Ce(), !(e.layout === "page" || e.loginRequired || e.signupRequired) && Vo(null, yt);
4663
4696
  }, vn = () => {
4664
4697
  me === null && (me = window.setTimeout(() => {
4665
- me = null, !(X || !r.classList.contains("pluno-pa-widget--open")) && Yo();
4698
+ me = null, !(J || !r.classList.contains("pluno-pa-widget--open")) && Yo();
4666
4699
  }, 0));
4667
4700
  }, Ia = () => {
4668
4701
  !Ht || fe || ee.scrollHeight - ee.scrollTop - ee.clientHeight <= 24 && Vo(Ht);
4669
4702
  }, Xo = () => {
4670
- X || typeof document > "u" || (cr(s, e.accentColor), o.isConnected || (e.mountTarget?.isConnected ? e.mountTarget.appendChild(o) : e.mountTarget || f.body?.appendChild(o)));
4703
+ J || typeof document > "u" || (cr(s, e.accentColor), o.isConnected || (e.mountTarget?.isConnected ? e.mountTarget.appendChild(o) : e.mountTarget || f.body?.appendChild(o)));
4671
4704
  }, Jo = new MutationObserver(Xo);
4672
4705
  Jo.observe(f.documentElement, {
4673
4706
  childList: !0,
@@ -4886,7 +4919,7 @@ async function Qd(t = {}) {
4886
4919
  bi = !0;
4887
4920
  try {
4888
4921
  const a = await e.billingStatusLoader();
4889
- if (X)
4922
+ if (J)
4890
4923
  return;
4891
4924
  sr(
4892
4925
  e.billingStatus,
@@ -5131,12 +5164,12 @@ async function Qd(t = {}) {
5131
5164
  };
5132
5165
  Ii();
5133
5166
  const Ti = () => {
5134
- Yt() || X || (bn = !0, Tt(), le(), E.connect().then(
5167
+ Yt() || J || (bn = !0, Tt(), le(), E.connect().then(
5135
5168
  () => {
5136
- X || (bn = !1, Tt(), le());
5169
+ J || (bn = !1, Tt(), le());
5137
5170
  },
5138
5171
  (a) => {
5139
- X || (bn = !1, Tt(), le(), ue(
5172
+ J || (bn = !1, Tt(), le(), ue(
5140
5173
  "web-sdk.widget",
5141
5174
  "Failed to connect Product Agent widget",
5142
5175
  {
@@ -5318,7 +5351,7 @@ async function Qd(t = {}) {
5318
5351
  const a = E.getState();
5319
5352
  return a.assistantDraft.trim().length > 0 && a.assistantDraftPhase !== "commentary";
5320
5353
  }, Ua = async () => {
5321
- if (!Qt || !C || kt || X || !E.getState().isThinking || Pn())
5354
+ if (!Qt || !C || kt || J || !E.getState().isThinking || Pn())
5322
5355
  return;
5323
5356
  let a;
5324
5357
  try {
@@ -5326,7 +5359,7 @@ async function Qd(t = {}) {
5326
5359
  } catch {
5327
5360
  return;
5328
5361
  }
5329
- a.enabled || a.neverSuggest || !E.getState().isThinking || Pn() || kt || X || (C.hidden = !1);
5362
+ a.enabled || a.neverSuggest || !E.getState().isThinking || Pn() || kt || J || (C.hidden = !1);
5330
5363
  };
5331
5364
  k?.addEventListener("click", () => {
5332
5365
  kt = !0, Rn(), Qt?.enable().catch(() => {
@@ -5340,10 +5373,10 @@ async function Qd(t = {}) {
5340
5373
  const Ln = e.tabGroups;
5341
5374
  let At = !1;
5342
5375
  const Dn = async () => {
5343
- if (!Ln || !V || At || X)
5376
+ if (!Ln || !V || At || J)
5344
5377
  return;
5345
5378
  const a = await Ln.getState().catch(() => null);
5346
- !a || At || X || (V.hidden = !a.permissionNeeded);
5379
+ !a || At || J || (V.hidden = !a.permissionNeeded);
5347
5380
  };
5348
5381
  T?.addEventListener("click", () => {
5349
5382
  At = !0, V && (V.hidden = !0), Ln?.enable().catch(() => {
@@ -5516,7 +5549,7 @@ async function Qd(t = {}) {
5516
5549
  const R = a.isThinking ? null : a.messages.map((D) => D.scheduledCheckInAt).filter((D) => !!D).filter((D) => Jn(D) !== null).sort((D, Pt) => Date.parse(D) - Date.parse(Pt))[0] ?? null, j = R ? fl(R) : null;
5517
5550
  j !== null && (it = window.setTimeout(
5518
5551
  () => {
5519
- it = null, X || G(E.getState());
5552
+ it = null, J || G(E.getState());
5520
5553
  },
5521
5554
  Math.min(j, 2147483647)
5522
5555
  )), S ? (ft = z.scrollTop, Ee()) : y && _u(a) && va();
@@ -5550,14 +5583,14 @@ async function Qd(t = {}) {
5550
5583
  } finally {
5551
5584
  Nn.delete(y.authRequestId);
5552
5585
  }
5553
- X || G(E.getState());
5586
+ J || G(E.getState());
5554
5587
  }
5555
5588
  })
5556
5589
  );
5557
5590
  };
5558
5591
  return ls = ld(
5559
5592
  (a) => {
5560
- Mt = a, !X && Qi(E.getState(), Ri()) && G(E.getState());
5593
+ Mt = a, !J && Qi(E.getState(), Ri()) && G(E.getState());
5561
5594
  },
5562
5595
  {
5563
5596
  backendUrl: e.backendUrl,
@@ -5622,7 +5655,7 @@ async function Qd(t = {}) {
5622
5655
  a && (Fe = null, ie = "idle", he && (he.value = "")), e.proactiveSuggestion = a ?? null, tt();
5623
5656
  },
5624
5657
  destroy: () => {
5625
- X || (Y(), X = !0, Jo.disconnect(), f.removeEventListener(
5658
+ J || (Y(), J = !0, Jo.disconnect(), f.removeEventListener(
5626
5659
  "selectionchange",
5627
5660
  cs
5628
5661
  ), rs?.disconnect(), Ra(), f.defaultView?.removeEventListener(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluno/product-agent-web",
3
- "version": "0.1.159",
3
+ "version": "0.1.160",
4
4
  "description": "Browser SDK and default widget for embedding Pluno Product Agent into customer web apps.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",