@pluno/product-agent-web 0.1.67 → 0.1.69

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,11 +1,11 @@
1
- const Ut = "pluno-product-agent-attachments";
2
- const W = "files";
3
- async function at(e) {
4
- const t = await D();
5
- await lt(t, "readwrite", (s) => s.put(e));
6
- }
7
- async function bt(e) {
8
- const t = await D(), s = await lt(
1
+ const Xt = "pluno-product-agent-attachments";
2
+ const Y = "files";
3
+ async function kt(e) {
4
+ const t = await H();
5
+ await Rt(t, "readwrite", (s) => s.put(e));
6
+ }
7
+ async function Kt(e) {
8
+ const t = await H(), s = await Rt(
9
9
  t,
10
10
  "readonly",
11
11
  (r) => r.get(e)
@@ -13,12 +13,12 @@ async function bt(e) {
13
13
  if (!s)
14
14
  return null;
15
15
  const n = Date.now();
16
- return await ct(e, { lastUsedAt: n }), { ...s, lastUsedAt: n };
16
+ return await Et(e, { lastUsedAt: n }), { ...s, lastUsedAt: n };
17
17
  }
18
- async function ct(e, t) {
19
- const s = await D();
20
- await $(s, "readwrite", async (n) => {
21
- const r = await z(
18
+ async function Et(e, t) {
19
+ const s = await H();
20
+ await st(s, "readwrite", async (n) => {
21
+ const r = await nt(
22
22
  n.get(e)
23
23
  );
24
24
  r && n.put({
@@ -27,40 +27,40 @@ async function ct(e, t) {
27
27
  });
28
28
  });
29
29
  }
30
- async function Ct(e = 864e5) {
31
- const t = await D(), s = Date.now() - e;
32
- await $(t, "readwrite", async (n) => {
30
+ async function Jt(e = 864e5) {
31
+ const t = await H(), s = Date.now() - e;
32
+ await st(t, "readwrite", async (n) => {
33
33
  const r = n.index("lastUsedAt");
34
- (await z(r.getAllKeys(IDBKeyRange.upperBound(s)))).forEach((o) => n.delete(o));
34
+ (await nt(r.getAllKeys(IDBKeyRange.upperBound(s)))).forEach((o) => n.delete(o));
35
35
  });
36
36
  }
37
- function D() {
37
+ function H() {
38
38
  return typeof indexedDB > "u" ? Promise.reject(new Error("Product Agent attachment storage is unavailable")) : new Promise((e, t) => {
39
- const s = indexedDB.open(Ut, 1);
39
+ const s = indexedDB.open(Xt, 1);
40
40
  s.onupgradeneeded = () => {
41
- const r = s.result.createObjectStore(W, { keyPath: "attachmentId" });
41
+ const r = s.result.createObjectStore(Y, { keyPath: "attachmentId" });
42
42
  r.createIndex("lastUsedAt", "lastUsedAt", { unique: !1 }), r.createIndex("sessionId", "sessionId", { unique: !1 }), r.createIndex("origin", "origin", { unique: !1 });
43
43
  }, s.onsuccess = () => e(s.result), s.onerror = () => t(s.error ?? new Error("Failed to open Product Agent attachment storage"));
44
44
  });
45
45
  }
46
- async function lt(e, t, s) {
47
- return await $(e, t, async (n) => await z(s(n)));
46
+ async function Rt(e, t, s) {
47
+ return await st(e, t, async (n) => await nt(s(n)));
48
48
  }
49
- function $(e, t, s) {
49
+ function st(e, t, s) {
50
50
  return new Promise((n, r) => {
51
- const i = e.transaction(W, t), o = i.objectStore(W);
52
- let c, a = !1;
53
- s(o).then((d) => {
54
- c = d;
55
- }).catch((d) => {
51
+ const i = e.transaction(Y, t), o = i.objectStore(Y);
52
+ let d, a = !1;
53
+ s(o).then((h) => {
54
+ d = h;
55
+ }).catch((h) => {
56
56
  a = !0;
57
57
  try {
58
58
  i.abort();
59
59
  } catch {
60
60
  }
61
- r(d);
61
+ r(h);
62
62
  }), i.oncomplete = () => {
63
- a || n(c);
63
+ a || n(d);
64
64
  }, i.onerror = () => {
65
65
  a || (a = !0, r(i.error ?? new Error("Product Agent attachment storage transaction failed")));
66
66
  }, i.onabort = () => {
@@ -68,23 +68,146 @@ function $(e, t, s) {
68
68
  };
69
69
  });
70
70
  }
71
- function z(e) {
71
+ function nt(e) {
72
72
  return new Promise((t, s) => {
73
73
  e.onsuccess = () => t(e.result), e.onerror = () => s(e.error ?? new Error("Product Agent attachment storage request failed"));
74
74
  });
75
75
  }
76
- const B = '.pluno-pa-widget-host[data-pluno-product-agent-ui="widget"]', Mt = '.pluno-pa-widget[data-pluno-product-agent-ui-root="widget"]', Dt = ".pluno-pa-widget__panel", Nt = ".pluno-pa-widget__timeline", J = `${B}[data-pluno-sdk-preview-channel]`, qt = "https://app.pluno.ai", Ot = "gpt-5.4", Ft = 2e4, Lt = 2e3, E = 6e4, Ht = 15e3, V = 2, Wt = 15e3, Bt = 5e3, vt = 1e3, xt = 8e3, jt = 15e3, Y = 3, $t = [300, 1e3], F = 1e5, zt = 200 * 1024 * 1024, Gt = "Image is too large for model vision input.", Xt = 100, ut = "pluno.productAgent.state.", v = "pluno.productAgent.pendingEvents.", Z = "pluno.productAgent.transportId", Kt = 100, b = /* @__PURE__ */ new Set();
77
- let R = null;
78
- class dt {
79
- constructor(t) {
80
- this.options = t, this.transportId = ye(), this.state = {
76
+ const $ = "pluno.productAgent.transportId", Vt = "pluno.productAgent.transportIdentity", z = "pluno.productAgent.transportIdentity.event", Yt = 50, Zt = globalThis.setTimeout.bind(globalThis);
77
+ let b = null;
78
+ const O = /* @__PURE__ */ new Set();
79
+ async function Qt(e = _t()) {
80
+ const t = e.randomUUID(), s = e.storage.getItem($);
81
+ let n = s ?? e.randomUUID(), r = !1, i = !1;
82
+ const o = e.channel.subscribe((a) => {
83
+ if (!(a.senderId === t || a.transportId !== n)) {
84
+ if (a.type === "probe") {
85
+ e.channel.postMessage({
86
+ type: "contender",
87
+ transportId: n,
88
+ senderId: t,
89
+ targetId: a.senderId,
90
+ established: r
91
+ }), !r && t > a.senderId && (i = !0);
92
+ return;
93
+ }
94
+ a.targetId === t && (a.established || t > a.senderId) && (i = !0);
95
+ }
96
+ });
97
+ if (!s)
98
+ e.storage.setItem($, n), r = !0;
99
+ else
100
+ for (; ; ) {
101
+ if (i = !1, e.channel.postMessage({ type: "probe", transportId: n, senderId: t }), await e.settle(), !i) {
102
+ r = !0;
103
+ break;
104
+ }
105
+ n = e.randomUUID(), e.storage.setItem($, n);
106
+ }
107
+ let d = !1;
108
+ return {
109
+ transportId: n,
110
+ release: () => {
111
+ d || (d = !0, o(), e.channel.close());
112
+ }
113
+ };
114
+ }
115
+ async function te() {
116
+ b || (b = Qt(_t()), b.then((n) => {
117
+ const r = (i) => {
118
+ i.persisted || (n.release(), b = null, O.clear(), window.removeEventListener("pagehide", r));
119
+ };
120
+ window.addEventListener("pagehide", r);
121
+ }));
122
+ const e = await b, t = ee();
123
+ O.add(t);
124
+ let s = !1;
125
+ return {
126
+ // A stable per-tab base keeps reload routing intact, while slots isolate multiple live SDK instances in one tab.
127
+ transportId: t === 0 ? e.transportId : `${e.transportId}.${t}`,
128
+ release: () => {
129
+ s || (s = !0, O.delete(t));
130
+ }
131
+ };
132
+ }
133
+ function ee() {
134
+ let e = 0;
135
+ for (; O.has(e); )
136
+ e += 1;
137
+ return e;
138
+ }
139
+ function _t() {
140
+ return {
141
+ storage: window.sessionStorage,
142
+ channel: se(),
143
+ randomUUID: () => crypto.randomUUID(),
144
+ settle: () => new Promise((e) => Zt(e, Yt))
145
+ };
146
+ }
147
+ function se() {
148
+ if (typeof BroadcastChannel < "u") {
149
+ const e = new BroadcastChannel(Vt);
150
+ return {
151
+ postMessage: (t) => e.postMessage(t),
152
+ subscribe: (t) => {
153
+ const s = (n) => t(n.data);
154
+ return e.addEventListener("message", s), () => e.removeEventListener("message", s);
155
+ },
156
+ close: () => e.close()
157
+ };
158
+ }
159
+ return ne();
160
+ }
161
+ function ne() {
162
+ const e = /* @__PURE__ */ new Set(), t = (s) => {
163
+ if (s.key !== z || !s.newValue)
164
+ return;
165
+ const n = JSON.parse(s.newValue);
166
+ for (const r of e)
167
+ r(n);
168
+ };
169
+ return window.addEventListener("storage", t), {
170
+ postMessage: (s) => {
171
+ window.localStorage.setItem(
172
+ z,
173
+ JSON.stringify({ ...s, eventId: crypto.randomUUID() })
174
+ ), window.localStorage.removeItem(z);
175
+ },
176
+ subscribe: (s) => (e.add(s), () => e.delete(s)),
177
+ close: () => {
178
+ e.clear(), window.removeEventListener("storage", t);
179
+ }
180
+ };
181
+ }
182
+ const Z = '.pluno-pa-widget-host[data-pluno-product-agent-ui="widget"]', re = '.pluno-pa-widget[data-pluno-product-agent-ui-root="widget"]', ie = ".pluno-pa-widget__panel", oe = ".pluno-pa-widget__timeline", lt = `${Z}[data-pluno-sdk-preview-channel]`, ae = "https://app.pluno.ai", ce = "gpt-5.4", le = 2e4, ue = 1e4, de = 1e4, he = 1e4, pe = 1e4, ge = 1e3, ut = 3e4, dt = 0.2, U = 6e4, fe = 15e3, ht = 2, me = 15e3, ye = 5e3, we = 1e3, Te = 100, Ae = 8e3, Ie = 15e3, pt = 3, Se = [300, 1e3], rt = 64e3, G = 4e3, it = 30, ke = 2e3, Ee = 1e3, Re = 200 * 1024 * 1024, _e = "Image is too large for model vision input.", Ce = 100, Ct = "pluno.productAgent.state.", Q = "pluno.productAgent.pendingEvents.", F = "pluno.productAgent.activeToolCalls.", Pe = 100, v = /* @__PURE__ */ new Set();
183
+ let D = null;
184
+ function be(e, t = Math.random) {
185
+ const s = Math.min(ut, ge * 2 ** e), n = 1 - dt + t() * dt * 2;
186
+ return Math.min(ut, Math.round(s * n));
187
+ }
188
+ function Ue(e, t, s) {
189
+ return new Promise((n, r) => {
190
+ const i = setTimeout(() => r(new Error(s)), t);
191
+ e.then(
192
+ (o) => {
193
+ clearTimeout(i), n(o);
194
+ },
195
+ (o) => {
196
+ clearTimeout(i), r(o);
197
+ }
198
+ );
199
+ });
200
+ }
201
+ class Pt {
202
+ constructor(t, s) {
203
+ this.options = t, this.transportIdentity = s, this.state = {
81
204
  ...this.state,
82
- starterPrompts: de(t.initialStarterPrompts)
205
+ starterPrompts: Je(t.initialStarterPrompts)
83
206
  };
84
- const s = t.restorePersistedState === !1 ? null : Be(t.clientId, t.expectedPersistedSessionId);
85
- s && (this.state = {
207
+ const n = t.restorePersistedState === !1 ? null : ks(t.clientId, t.expectedPersistedSessionId);
208
+ n && (this.state = {
86
209
  ...this.state,
87
- ...s,
210
+ ...n,
88
211
  status: "idle",
89
212
  user: null,
90
213
  assistantDraft: "",
@@ -92,20 +215,29 @@ class dt {
92
215
  assistantDraftRunId: null,
93
216
  isThinking: !1,
94
217
  lastError: null
95
- }), this.queuedClientEvents = xe(t.clientId);
218
+ }), this.queuedClientEvents = bs(
219
+ Rs(t.clientId),
220
+ Cs(t.clientId)
221
+ ), M(t.clientId, this.queuedClientEvents);
96
222
  }
97
223
  options;
98
224
  listeners = {};
99
225
  socket = null;
100
226
  reconnectTimer = null;
101
227
  heartbeatTimer = null;
228
+ heartbeatAckTimer = null;
229
+ socketConnectTimer = null;
230
+ socketAuthTimer = null;
231
+ reconnectAttempts = 0;
232
+ connectionAttemptId = 0;
233
+ connectionInProgress = !1;
102
234
  token = null;
103
235
  networkCaptureCleanup = null;
104
236
  networkBatchTimer = null;
105
237
  queuedNetworkEvents = [];
106
238
  queuedClientEvents = [];
107
239
  pendingSessionHistoryRequests = /* @__PURE__ */ new Map();
108
- transportId;
240
+ transportIdentity;
109
241
  retryAttemptsByClientMessageId = {};
110
242
  retryTimersByClientMessageId = {};
111
243
  thinkingWatchdogTimer = null;
@@ -121,6 +253,8 @@ class dt {
121
253
  attachmentFiles = /* @__PURE__ */ new Map();
122
254
  attachmentBlobCache = /* @__PURE__ */ new Map();
123
255
  sessionUserFilesApiCleanup = null;
256
+ activeBrowserToolCalls = /* @__PURE__ */ new Map();
257
+ pageLifecycleCleanup = null;
124
258
  transientStarterPromptsRequestInFlight = !1;
125
259
  transientStarterPromptsRequestAttempted = !1;
126
260
  locationChangeCleanup = null;
@@ -142,22 +276,22 @@ class dt {
142
276
  lastErrorCode: null
143
277
  };
144
278
  static async init(t) {
145
- const s = new dt({
279
+ const s = await te(), n = new Pt({
146
280
  ...t,
147
- backendUrl: se(t.backendUrl ?? qt),
148
- clientId: t.clientId ?? me(),
149
- model: t.model ?? Ot
150
- });
281
+ backendUrl: Fe(t.backendUrl ?? ae),
282
+ clientId: t.clientId ?? ts(),
283
+ model: t.model ?? ce
284
+ }, s);
151
285
  try {
152
- Ct().catch((n) => {
153
- g("web-sdk.attachments", "Failed to delete stale Product Agent attachments", {
154
- message: n instanceof Error ? n.message : String(n)
286
+ Jt().catch((r) => {
287
+ f("web-sdk.attachments", "Failed to delete stale Product Agent attachments", {
288
+ message: r instanceof Error ? r.message : String(r)
155
289
  });
156
- }), s.enableNetworkCapture(), s.startStarterPromptUrlWatcher(), t.autoConnect !== !1 && await s.connect();
157
- } catch (n) {
158
- throw s.destroy(), n;
290
+ }), t.disableNetworkCapture || n.enableNetworkCapture(), n.startPageLifecycleRecovery(), n.startStarterPromptUrlWatcher(), t.autoConnect !== !1 && await n.connect();
291
+ } catch (r) {
292
+ throw n.destroy(), r;
159
293
  }
160
- return s;
294
+ return n;
161
295
  }
162
296
  on(t, s) {
163
297
  const n = this.listeners[t] ?? /* @__PURE__ */ new Set();
@@ -172,53 +306,70 @@ class dt {
172
306
  };
173
307
  }
174
308
  async connect() {
175
- if (this.socket?.readyState === WebSocket.OPEN || this.socket?.readyState === WebSocket.CONNECTING)
309
+ if (this.connectionInProgress || this.socket?.readyState === WebSocket.OPEN || this.socket?.readyState === WebSocket.CONNECTING)
310
+ return;
311
+ this.connectionInProgress = !0;
312
+ const t = ++this.connectionAttemptId;
313
+ this.setState({
314
+ status: this.state.status === "reconnecting" ? "reconnecting" : "connecting",
315
+ lastError: null
316
+ });
317
+ try {
318
+ this.token = this.options.token ?? (this.options.tokenProvider ? await Ue(this.options.tokenProvider(), de, "Pluno token provider timed out") : null);
319
+ } finally {
320
+ this.connectionInProgress = !1;
321
+ }
322
+ if (t !== this.connectionAttemptId || this.state.status === "closed")
176
323
  return;
177
- if (this.setState({ status: (this.state.status === "closed", "connecting"), lastError: null }), this.token = this.options.token ?? await this.options.tokenProvider?.() ?? null, !this.token && !this.options.webSocketFactory)
324
+ if (!this.token && !this.options.webSocketFactory)
178
325
  throw new Error("Pluno requires a token or tokenProvider");
179
- const t = re(this.options.backendUrl), s = this.options.webSocketFactory?.(t) ?? new WebSocket(t);
180
- this.socket = s, s.addEventListener("open", () => {
181
- this.socket === s && (g("web-sdk.agent", "Pluno socket opened", {
326
+ const s = xe(this.options.backendUrl), n = this.options.webSocketFactory?.(s) ?? new WebSocket(s);
327
+ this.socket = n, this.socketConnectTimer = window.setTimeout(() => {
328
+ this.socket !== n || n.readyState !== WebSocket.CONNECTING || (f("web-sdk.agent", "Pluno socket opening timed out; reconnecting"), this.replaceTimedOutSocket(n));
329
+ }, he), n.addEventListener("open", () => {
330
+ this.socket !== n || (this.clearSocketConnectTimer(), f("web-sdk.agent", "Pluno socket opened", {
182
331
  queuedClientEventCount: this.queuedClientEvents.length,
183
332
  isThinking: this.state.isThinking
184
- }), this.token && this.sendNow({
333
+ }), !(this.token ? this.sendNow({
185
334
  type: "auth.session",
186
335
  token: this.token,
187
336
  clientId: this.options.clientId,
188
- transportId: this.transportId,
337
+ transportId: this.transportIdentity.transportId,
189
338
  pageUrl: location.href
190
- }), this.flushQueuedClientEvents(), this.startHeartbeat(), this.setState({ status: "connected", lastError: null }));
191
- }), s.addEventListener("message", (n) => {
192
- this.socket === s && this.handleServerEvent(ue(n.data));
193
- }), s.addEventListener("close", (n) => {
194
- this.socket === s && (this.stopHeartbeat(), this.socket = null, this.state.status !== "closed" && (g("web-sdk.agent", "Pluno socket closed; scheduling reconnect", {
195
- code: typeof n?.code == "number" ? n.code : null,
196
- reason: typeof n?.reason == "string" ? n.reason : "",
197
- wasClean: typeof n?.wasClean == "boolean" ? n.wasClean : null,
339
+ }) : !0)) || (this.socketAuthTimer = window.setTimeout(() => {
340
+ this.socket === n && (f("web-sdk.agent", "Pluno socket authentication timed out; reconnecting"), this.replaceTimedOutSocket(n));
341
+ }, pe));
342
+ }), n.addEventListener("message", (r) => {
343
+ this.socket === n && this.handleServerEvent(Ke(r.data));
344
+ }), n.addEventListener("close", (r) => {
345
+ this.socket === n && (this.clearSocketPhaseTimers(), this.stopHeartbeat(), this.socket = null, this.state.status !== "closed" && (f("web-sdk.agent", "Pluno socket closed; scheduling reconnect", {
346
+ code: typeof r?.code == "number" ? r.code : null,
347
+ reason: typeof r?.reason == "string" ? r.reason : "",
348
+ wasClean: typeof r?.wasClean == "boolean" ? r.wasClean : null,
198
349
  queuedClientEventCount: this.queuedClientEvents.length,
199
350
  isThinking: this.state.isThinking
200
351
  }), this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect()));
201
- }), s.addEventListener("error", () => {
202
- this.socket !== s || this.state.status === "closed" || (g("web-sdk.agent", "Pluno socket error; scheduling reconnect", {
352
+ }), n.addEventListener("error", () => {
353
+ this.socket !== n || this.state.status === "closed" || (f("web-sdk.agent", "Pluno socket error; scheduling reconnect", {
203
354
  queuedClientEventCount: this.queuedClientEvents.length,
204
355
  isThinking: this.state.isThinking
205
- }), this.stopHeartbeat(), this.socket = null, this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect(), s.readyState !== WebSocket.CLOSED && s.readyState !== WebSocket.CLOSING && s.close());
356
+ }), this.clearSocketPhaseTimers(), this.stopHeartbeat(), this.socket = null, this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect(), n.readyState !== WebSocket.CLOSED && n.readyState !== WebSocket.CLOSING && n.close());
206
357
  });
207
358
  }
208
359
  disconnect() {
209
- this.setState({ status: "closed", isThinking: !1 }), this.stopHeartbeat(), this.clearStarterPromptUrlRefreshTimer(), this.clearRetryTimers(), this.clearThinkingWatchdog(), this.rejectPendingSessionHistoryRequests("Pluno disconnected."), this.reconnectTimer !== null && (window.clearTimeout(this.reconnectTimer), this.reconnectTimer = null), this.queuedClientEvents = [], this.socket?.close(), this.socket = null;
360
+ this.connectionAttemptId += 1, this.setState({ status: "closed", isThinking: !1 }), this.clearSocketPhaseTimers(), this.stopHeartbeat(), this.clearStarterPromptUrlRefreshTimer(), this.clearRetryTimers(), this.clearThinkingWatchdog(), this.rejectPendingSessionHistoryRequests("Pluno disconnected."), this.reconnectTimer !== null && (window.clearTimeout(this.reconnectTimer), this.reconnectTimer = null), this.queuedClientEvents = [], this.socket?.close(), this.socket = null;
210
361
  }
211
362
  destroy() {
212
- this.disconnect(), this.locationChangeCleanup?.(), this.locationChangeCleanup = null, this.cleanupSessionUserFilesApi(), this.networkCaptureCleanup?.(), this.networkCaptureCleanup = null;
363
+ this.disconnect(), this.locationChangeCleanup?.(), this.locationChangeCleanup = null, this.cleanupSessionUserFilesApi(), this.pageLifecycleCleanup?.(), this.pageLifecycleCleanup = null, this.activeBrowserToolCalls.clear(), Us(this.options.clientId), this.transportIdentity.release(), this.networkCaptureCleanup?.(), this.networkCaptureCleanup = null, this.networkBatchTimer !== null && (window.clearTimeout(this.networkBatchTimer), this.networkBatchTimer = null), this.queuedNetworkEvents = [];
213
364
  for (const t of Object.values(this.listeners))
214
365
  t?.clear();
215
366
  }
216
367
  sendMessage(t, s = {}) {
217
- const n = t.trim(), r = s.attachments ?? [], i = r.map(G);
368
+ const n = t.trim(), r = s.attachments ?? [], i = r.map(at);
218
369
  if (!n && i.length === 0)
219
370
  return null;
220
- const o = y(), c = _(), a = {
221
- id: `local-${c}`,
371
+ const o = I(), d = N(), a = {
372
+ id: `local-${d}`,
222
373
  role: "user",
223
374
  content: n,
224
375
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -234,39 +385,39 @@ class dt {
234
385
  isThinking: !0,
235
386
  lastError: null
236
387
  }), this.emit("message", a);
237
- const d = {
388
+ const h = {
238
389
  type: "chat.user_message",
239
390
  sessionId: this.state.sessionId ?? void 0,
240
- clientMessageId: c,
391
+ clientMessageId: d,
241
392
  content: n,
242
393
  attachments: i.length > 0 ? i : void 0,
243
394
  page: o,
244
395
  model: this.options.model,
245
- metadata: Q(this.options.metadata)
396
+ metadata: gt(this.options.metadata)
246
397
  };
247
- return this.activeClientMessageId = c, this.activeUserMessageEvent = d, this.markThinkingProgress(), this.send(d), this.startBackgroundAttachmentUploads(c, i), c;
398
+ return this.activeClientMessageId = d, this.activeUserMessageEvent = h, this.markThinkingProgress(), this.send(h), this.startBackgroundAttachmentUploads(d, i), d;
248
399
  }
249
400
  createLocalAttachment(t) {
250
- const s = _(), n = {
401
+ const s = N(), n = {
251
402
  id: s,
252
403
  name: t.name || "attachment",
253
- mimeType: it(t),
404
+ mimeType: At(t),
254
405
  sizeBytes: t.size
255
406
  };
256
407
  this.attachmentFiles.set(s, t), this.attachmentBlobCache.set(s, t);
257
408
  const r = Date.now();
258
- return at({
409
+ return kt({
259
410
  attachmentId: s,
260
411
  name: n.name,
261
412
  mimeType: n.mimeType,
262
413
  sizeBytes: n.sizeBytes,
263
414
  blob: t,
264
- origin: y().origin,
415
+ origin: I().origin,
265
416
  sessionId: this.state.sessionId ?? void 0,
266
417
  createdAt: r,
267
418
  lastUsedAt: r
268
419
  }).catch((i) => {
269
- g("web-sdk.attachments", "Failed to store Product Agent attachment", {
420
+ f("web-sdk.attachments", "Failed to store Product Agent attachment", {
270
421
  attachmentId: s,
271
422
  name: n.name,
272
423
  message: i instanceof Error ? i.message : String(i)
@@ -278,7 +429,7 @@ class dt {
278
429
  return await this.uploadAttachmentForMessage({
279
430
  file: t,
280
431
  attachment: s,
281
- clientMessageId: _(),
432
+ clientMessageId: N(),
282
433
  waitForSession: !1,
283
434
  notifyCompletion: !1
284
435
  });
@@ -295,7 +446,7 @@ class dt {
295
446
  waitForSession: !0,
296
447
  notifyCompletion: !0
297
448
  }).catch((i) => {
298
- g("web-sdk.agent", "Attachment background upload failed", {
449
+ f("web-sdk.agent", "Attachment background upload failed", {
299
450
  attachmentId: n.id,
300
451
  name: n.name,
301
452
  message: i instanceof Error ? i.message : String(i)
@@ -310,55 +461,55 @@ class dt {
310
461
  waitForSession: r,
311
462
  notifyCompletion: i
312
463
  }) {
313
- const o = r ? await this.waitForSessionId() : this.state.sessionId, c = it(t), a = {
464
+ const o = r ? await this.waitForSessionId() : this.state.sessionId, d = At(t), a = {
314
465
  sessionId: o ?? void 0,
315
466
  attachmentId: s.id,
316
467
  clientId: this.options.clientId,
317
- transportId: this.transportId,
468
+ transportId: this.transportIdentity.transportId,
318
469
  name: t.name || "attachment",
319
- mimeType: c,
470
+ mimeType: d,
320
471
  sizeBytes: t.size,
321
- page: y(),
472
+ page: I(),
322
473
  model: this.options.model,
323
- metadata: Q(this.options.metadata)
324
- }, d = this.options.prepareAttachmentUpload ? await H(
474
+ metadata: gt(this.options.metadata)
475
+ }, h = this.options.prepareAttachmentUpload ? await V(
325
476
  () => this.options.prepareAttachmentUpload(a),
326
477
  "Failed to prepare attachment upload"
327
478
  ) : await this.prepareEmbedAttachmentUpload(a);
328
- await H(async () => {
329
- const l = await fetch(d.uploadUrl, {
330
- method: d.uploadMethod,
331
- headers: d.uploadHeaders,
479
+ await V(async () => {
480
+ const u = await fetch(h.uploadUrl, {
481
+ method: h.uploadMethod,
482
+ headers: h.uploadHeaders,
332
483
  body: t
333
484
  });
334
- if (!l.ok)
335
- throw new C("Failed to upload attachment", l.status);
336
- return l;
337
- }, "Failed to upload attachment"), this.setState({ sessionId: d.sessionId });
338
- const h = It(d.attachment, this.options.backendUrl);
339
- return this.updateAttachmentInState(s.id, h), s.id && ct(s.id, {
340
- sessionId: d.sessionId,
341
- fileUrl: h.fileUrl,
342
- gcsPath: h.gcsPath,
485
+ if (!u.ok)
486
+ throw new L("Failed to upload attachment", u.status);
487
+ return u;
488
+ }, "Failed to upload attachment"), this.setState({ sessionId: h.sessionId });
489
+ const g = Bt(h.attachment, this.options.backendUrl);
490
+ return this.updateAttachmentInState(s.id, g), s.id && Et(s.id, {
491
+ sessionId: h.sessionId,
492
+ fileUrl: g.fileUrl,
493
+ gcsPath: g.gcsPath,
343
494
  lastUsedAt: Date.now()
344
- }).catch((l) => {
345
- g("web-sdk.attachments", "Failed to update persisted Product Agent attachment", {
495
+ }).catch((u) => {
496
+ f("web-sdk.attachments", "Failed to update persisted Product Agent attachment", {
346
497
  attachmentId: s.id,
347
- name: h.name,
348
- message: l instanceof Error ? l.message : String(l)
498
+ name: g.name,
499
+ message: u instanceof Error ? u.message : String(u)
349
500
  });
350
- }), i && h.gcsPath && this.send({
501
+ }), i && g.gcsPath && this.send({
351
502
  type: "attachment.upload_completed",
352
- sessionId: d.sessionId,
503
+ sessionId: h.sessionId,
353
504
  clientMessageId: n,
354
- attachment: h
355
- }), h;
505
+ attachment: g
506
+ }), g;
356
507
  }
357
508
  waitForSessionId() {
358
509
  return this.state.sessionId ? Promise.resolve(this.state.sessionId) : new Promise((t, s) => {
359
510
  const n = window.setTimeout(() => {
360
511
  r(), s(new Error("Timed out waiting for Pluno session before persisting attachment"));
361
- }, jt), r = this.on("state", (i) => {
512
+ }, Ie), r = this.on("state", (i) => {
362
513
  i.sessionId && (window.clearTimeout(n), r(), t(i.sessionId));
363
514
  });
364
515
  });
@@ -376,18 +527,18 @@ class dt {
376
527
  }
377
528
  async prepareEmbedAttachmentUpload(t) {
378
529
  let s = !1;
379
- return await H(async () => {
530
+ return await V(async () => {
380
531
  const n = await this.fetchEmbedAttachmentUpload(t);
381
532
  if (n.ok)
382
533
  return await n.json();
383
- if (ss(n.status) && this.options.tokenProvider && !s) {
534
+ if (Ks(n.status) && this.options.tokenProvider && !s) {
384
535
  s = !0;
385
536
  const r = await this.fetchEmbedAttachmentUpload(t);
386
537
  if (r.ok)
387
538
  return await r.json();
388
- throw new C("Failed to prepare attachment upload", r.status);
539
+ throw new L("Failed to prepare attachment upload", r.status);
389
540
  }
390
- throw new C("Failed to prepare attachment upload", n.status);
541
+ throw new L("Failed to prepare attachment upload", n.status);
391
542
  }, "Failed to prepare attachment upload");
392
543
  }
393
544
  async fetchEmbedAttachmentUpload(t) {
@@ -404,11 +555,12 @@ class dt {
404
555
  stop() {
405
556
  this.state.sessionId && (this.send({ type: "run.stop", sessionId: this.state.sessionId }), this.setState({ isThinking: !1 }), this.clearThinkingWatchdog());
406
557
  }
407
- startNewSession() {
408
- this.state.sessionId && this.state.isThinking && this.sendNow({ type: "run.stop", sessionId: this.state.sessionId }), this.cleanupSessionUserFilesApi(), this.queuedClientEvents = this.queuedClientEvents.filter((t) => t.type !== "chat.user_message"), this.clearThinkingWatchdog(), this.send({
558
+ startNewSession(t = {}) {
559
+ const s = t.notifyTransport !== !1;
560
+ s && this.state.sessionId && this.state.isThinking && this.sendNow({ type: "run.stop", sessionId: this.state.sessionId }), this.cleanupSessionUserFilesApi(), this.queuedClientEvents = this.queuedClientEvents.filter((n) => n.type !== "chat.user_message"), this.clearThinkingWatchdog(), s && this.send({
409
561
  type: "session.reset",
410
562
  sessionId: this.state.sessionId ?? void 0,
411
- page: y()
563
+ page: I()
412
564
  }), this.setState({
413
565
  sessionId: null,
414
566
  starterPrompts: [...this.state.starterPrompts],
@@ -421,15 +573,15 @@ class dt {
421
573
  });
422
574
  }
423
575
  listSessions(t = {}) {
424
- const s = _(), n = new Promise((i, o) => {
425
- const c = window.setTimeout(() => {
576
+ const s = N(), n = new Promise((i, o) => {
577
+ const d = window.setTimeout(() => {
426
578
  this.pendingSessionHistoryRequests.delete(s), o(new Error("Session history did not respond in time"));
427
- }, xt);
428
- this.pendingSessionHistoryRequests.set(s, { resolve: i, reject: o, timeout: c });
579
+ }, Ae);
580
+ this.pendingSessionHistoryRequests.set(s, { resolve: i, reject: o, timeout: d });
429
581
  }), r = {
430
582
  type: "sessions.list",
431
583
  requestId: s,
432
- page: y(),
584
+ page: I(),
433
585
  ...t.cursor ? { cursor: t.cursor } : {},
434
586
  ...t.limit ? { limit: t.limit } : {}
435
587
  };
@@ -451,11 +603,11 @@ class dt {
451
603
  }), this.send({
452
604
  type: "session.load",
453
605
  sessionId: t,
454
- page: y()
606
+ page: I()
455
607
  });
456
608
  }
457
609
  send(t) {
458
- this.sendNow(T(t)) || (this.queuedClientEvents.push(t), P(this.options.clientId, this.queuedClientEvents), this.setState({ status: "reconnecting" }), this.scheduleReconnect());
610
+ this.sendNow(A(t)) || (this.queuedClientEvents.push(t), M(this.options.clientId, this.queuedClientEvents), this.setState({ status: "reconnecting" }), this.scheduleReconnect());
459
611
  }
460
612
  async getUploadToken() {
461
613
  const t = this.options.token ?? await this.options.tokenProvider?.() ?? this.token ?? null;
@@ -470,20 +622,20 @@ class dt {
470
622
  try {
471
623
  return s.send(JSON.stringify(t)), !0;
472
624
  } catch (n) {
473
- return g("web-sdk.agent", "Pluno socket send failed; scheduling reconnect", {
625
+ return f("web-sdk.agent", "Pluno socket send failed; scheduling reconnect", {
474
626
  message: n instanceof Error ? n.message : String(n),
475
627
  queuedClientEventCount: this.queuedClientEvents.length,
476
628
  isThinking: this.state.isThinking
477
- }), this.socket === s && (this.stopHeartbeat(), this.socket = null, this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect()), s.readyState !== WebSocket.CLOSED && s.readyState !== WebSocket.CLOSING && s.close(), !1;
629
+ }), this.socket === s && (this.clearSocketPhaseTimers(), this.stopHeartbeat(), this.socket = null, this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect()), s.readyState !== WebSocket.CLOSED && s.readyState !== WebSocket.CLOSING && s.close(), !1;
478
630
  }
479
631
  }
480
632
  requestTransientStarterPrompts() {
481
633
  if (this.state.starterPromptsLoading || this.transientStarterPromptsRequestInFlight || this.transientStarterPromptsRequestAttempted)
482
634
  return;
483
635
  this.transientStarterPromptsRequestInFlight = !0, this.transientStarterPromptsRequestAttempted = !0, this.setState({ starterPromptsLoading: !0 });
484
- const t = ie();
636
+ const t = je();
485
637
  this.sendNow(
486
- T({
638
+ A({
487
639
  type: "starter_prompts.page_context",
488
640
  pageUrl: t.pageUrl,
489
641
  pageTitle: t.pageTitle,
@@ -492,13 +644,13 @@ class dt {
492
644
  ) || (this.transientStarterPromptsRequestInFlight = !1, this.transientStarterPromptsRequestAttempted = !1, this.setState({ starterPromptsLoading: !1 }));
493
645
  }
494
646
  startStarterPromptUrlWatcher() {
495
- this.locationChangeCleanup || (this.locationChangeCleanup = oe(() => this.handleStarterPromptUrlChange()));
647
+ this.locationChangeCleanup || (this.locationChangeCleanup = $e(() => this.handleStarterPromptUrlChange()));
496
648
  }
497
649
  handleStarterPromptUrlChange() {
498
650
  const t = location.href;
499
651
  t !== this.lastStarterPromptPageUrl && (this.lastStarterPromptPageUrl = t, this.clearStarterPromptUrlRefreshTimer(), this.starterPromptUrlRefreshTimer = window.setTimeout(() => {
500
652
  this.starterPromptUrlRefreshTimer = null, this.refreshStarterPromptsForCurrentUrl();
501
- }, Kt));
653
+ }, Pe));
502
654
  }
503
655
  refreshStarterPromptsForCurrentUrl() {
504
656
  this.socket?.readyState !== WebSocket.OPEN || this.state.status === "closed" || (this.setState({ starterPromptsLoading: this.state.messages.length === 0 }), this.sendNow({
@@ -513,14 +665,14 @@ class dt {
513
665
  if (this.socket?.readyState !== WebSocket.OPEN || this.queuedClientEvents.length === 0)
514
666
  return;
515
667
  const t = this.queuedClientEvents.splice(0, this.queuedClientEvents.length);
516
- P(this.options.clientId, this.queuedClientEvents);
668
+ M(this.options.clientId, this.queuedClientEvents);
517
669
  for (let s = 0; s < t.length; s += 1) {
518
670
  const n = t[s];
519
- if (!this.sendNow(T(n))) {
520
- this.queuedClientEvents.unshift(n, ...t.slice(s + 1)), P(this.options.clientId, this.queuedClientEvents);
671
+ if (!this.sendNow(A(n))) {
672
+ this.queuedClientEvents.unshift(n, ...t.slice(s + 1)), M(this.options.clientId, this.queuedClientEvents);
521
673
  return;
522
674
  }
523
- P(this.options.clientId, this.queuedClientEvents);
675
+ M(this.options.clientId, this.queuedClientEvents);
524
676
  }
525
677
  }
526
678
  handleServerEvent(t) {
@@ -528,42 +680,47 @@ class dt {
528
680
  this.handleRunAck(t);
529
681
  return;
530
682
  }
531
- if (Jt(t) && this.markThinkingProgress(), t.type === "auth.ok") {
532
- const s = he(t), n = Object.prototype.hasOwnProperty.call(t, "appearance");
533
- g("web-sdk.agent", "Received auth.ok appearance", {
683
+ if (t.type === "runtime.pong") {
684
+ this.clearHeartbeatAckTimer();
685
+ return;
686
+ }
687
+ if (Ne(t) && this.markThinkingProgress(), t.type === "auth.ok") {
688
+ this.clearSocketAuthTimer(), this.reconnectAttempts = 0, this.flushQueuedClientEvents(), this.startHeartbeat();
689
+ const s = Ve(t), n = Object.prototype.hasOwnProperty.call(t, "appearance");
690
+ f("web-sdk.agent", "Received auth.ok appearance", {
534
691
  hasAppearance: n,
535
692
  rawAppearance: t.appearance,
536
693
  normalizedAppearance: s
537
- }), this.runtimeHelperJavascript = pe(t.runtimeHelpers)?.javascript ?? null;
538
- const r = st(t, "starterPrompts"), i = Object.prototype.hasOwnProperty.call(t, "starterPrompts"), o = t.starterPromptsLoading === !0, c = {
539
- user: we(t.user),
694
+ }), this.runtimeHelperJavascript = Ye(t.runtimeHelpers)?.javascript ?? null;
695
+ const r = yt(t, "starterPrompts"), i = Object.prototype.hasOwnProperty.call(t, "starterPrompts"), o = t.starterPromptsLoading === !0, d = {
696
+ user: es(t.user),
540
697
  status: "connected"
541
698
  };
542
- (i || this.state.starterPrompts.length === 0) && (c.starterPrompts = r, c.starterPromptsLoading = r.length > 0 ? !1 : o), i && r.length > 0 && (this.transientStarterPromptsRequestInFlight = !1, this.transientStarterPromptsRequestAttempted = !0), (n || s) && (c.appearance = s), this.setState(c), i && r.length === 0 && !o && !ce() && this.requestTransientStarterPrompts(), this.state.sessionId && this.send({
699
+ (i || this.state.starterPrompts.length === 0) && (d.starterPrompts = r, d.starterPromptsLoading = r.length > 0 ? !1 : o), i && r.length > 0 && (this.transientStarterPromptsRequestInFlight = !1, this.transientStarterPromptsRequestAttempted = !0), (n || s) && (d.appearance = s), this.setState(d), i && r.length === 0 && !o && !Ge() && this.requestTransientStarterPrompts(), this.state.sessionId && this.send({
543
700
  type: "page.upsert",
544
701
  sessionId: this.state.sessionId,
545
- page: y(),
702
+ page: I(),
546
703
  model: this.options.model
547
704
  });
548
705
  return;
549
706
  }
550
707
  if (t.type === "starterPrompts.updated") {
551
708
  this.transientStarterPromptsRequestInFlight = !1, this.transientStarterPromptsRequestAttempted = !0, this.setState({
552
- starterPrompts: st(t, "starterPrompts"),
709
+ starterPrompts: yt(t, "starterPrompts"),
553
710
  starterPromptsLoading: !1
554
711
  });
555
712
  return;
556
713
  }
557
714
  if (t.type === "conversation.state") {
558
- const s = Array.isArray(t.items) ? t.items : [], n = Pe(
715
+ const s = Array.isArray(t.items) ? t.items : [], n = us(
559
716
  this.state.messages,
560
- Te(s, this.options.backendUrl)
561
- ), r = nt(n);
562
- if (!r && De(this.state.messages, s))
717
+ ss(s, this.options.backendUrl)
718
+ ), r = wt(n);
719
+ if (!r && fs(this.state.messages, s))
563
720
  return;
564
- const i = r ? null : Ne(s);
565
- this.latestRecoverableClientMessageId = i, Me(n) && this.clearRetryTimers(), this.setState({
566
- sessionId: A(t.session, "id") ?? this.state.sessionId,
721
+ const i = r ? null : ms(s);
722
+ this.latestRecoverableClientMessageId = i, gs(n) && this.clearRetryTimers(), this.setState({
723
+ sessionId: E(t.session, "id") ?? this.state.sessionId,
567
724
  messages: n,
568
725
  ...r ? { assistantDraft: "", assistantDraftRespondsToUserMessageId: null, assistantDraftRunId: null, isThinking: !1 } : i ? {
569
726
  assistantDraft: "",
@@ -578,22 +735,22 @@ class dt {
578
735
  if (t.type === "sessions.page") {
579
736
  const s = typeof t.requestId == "string" ? t.requestId : null, n = s ? this.pendingSessionHistoryRequests.get(s) : null;
580
737
  s && n && (window.clearTimeout(n.timeout), this.pendingSessionHistoryRequests.delete(s), n.resolve({
581
- sessions: Ae(t.sessions),
738
+ sessions: ns(t.sessions),
582
739
  nextCursor: typeof t.nextCursor == "string" ? t.nextCursor : null
583
740
  }));
584
741
  return;
585
742
  }
586
743
  if (t.type === "session.updated") {
587
- this.clearRunAckResyncRetryTimer(), this.setState({ sessionId: A(t.session, "id") ?? this.state.sessionId });
744
+ this.clearRunAckResyncRetryTimer(), this.setState({ sessionId: E(t.session, "id") ?? this.state.sessionId });
588
745
  return;
589
746
  }
590
747
  if (t.type === "session.item") {
591
- const s = pt(t.item, this.options.backendUrl);
748
+ const s = Ut(t.item, this.options.backendUrl);
592
749
  if (s) {
593
750
  s.role === "assistant" && (this.clearRetryTimers(), this.clearRunAckResyncRetryTimer());
594
751
  const n = t.item.data;
595
- qe(n) && this.clearRunAckResyncRetryTimer();
596
- const r = _e(this.state.messages, s), i = nt(r);
752
+ ys(n) && this.clearRunAckResyncRetryTimer();
753
+ const r = ls(this.state.messages, s), i = wt(r);
597
754
  this.setState({
598
755
  messages: r,
599
756
  assistantDraft: s.role === "assistant" ? "" : this.state.assistantDraft,
@@ -638,7 +795,7 @@ class dt {
638
795
  }
639
796
  if (this.retryAfterRetryableError(t))
640
797
  return;
641
- const r = new Error(typeof t.message == "string" ? t.message.replace(/Product Agent/g, "Pluno") : "Pluno error"), i = ne(r.message);
798
+ const r = new Error(typeof t.message == "string" ? t.message.replace(/Product Agent/g, "Pluno") : "Pluno error"), i = We(r.message);
642
799
  i && console.error(i), this.setState({
643
800
  status: "error",
644
801
  isThinking: !1,
@@ -675,7 +832,7 @@ class dt {
675
832
  this.pendingSessionHistoryRequests.clear();
676
833
  }
677
834
  markThinkingProgress() {
678
- !this.state.isThinking || this.state.status === "closed" || (this.scheduleThinkingWatchdog(E), this.activeClientMessageId && this.scheduleRunAckWatchdog(this.activeClientMessageId));
835
+ !this.state.isThinking || this.state.status === "closed" || (this.scheduleThinkingWatchdog(U), this.activeClientMessageId && this.scheduleRunAckWatchdog(this.activeClientMessageId));
679
836
  }
680
837
  scheduleThinkingWatchdog(t) {
681
838
  this.thinkingWatchdogTimer !== null && window.clearTimeout(this.thinkingWatchdogTimer), this.thinkingWatchdogTimer = window.setTimeout(() => {
@@ -692,29 +849,29 @@ class dt {
692
849
  scheduleRunAckWatchdog(t) {
693
850
  this.runAckWatchdogTimer !== null && window.clearTimeout(this.runAckWatchdogTimer), this.runAckWatchdogTimer = window.setTimeout(() => {
694
851
  this.runAckWatchdogTimer = null, this.recoverMissedRunAck(t);
695
- }, Wt);
852
+ }, me);
696
853
  }
697
854
  recoverMissedRunAck(t) {
698
- !this.state.isThinking || this.state.status === "closed" || this.activeClientMessageId !== t || (g("web-sdk.agent", "Pluno run ack missed; resyncing session", {
855
+ !this.state.isThinking || this.state.status === "closed" || this.activeClientMessageId !== t || (f("web-sdk.agent", "Pluno run ack missed; resyncing session", {
699
856
  sessionId: this.state.sessionId,
700
857
  clientMessageId: t
701
858
  }), this.resyncThinkingSession(), this.scheduleRunAckResyncRetry(t));
702
859
  }
703
860
  scheduleRunAckResyncRetry(t) {
704
861
  this.clearRunAckResyncRetryTimer(), this.runAckResyncRetryTimer = window.setTimeout(() => {
705
- this.runAckResyncRetryTimer = null, !((this.runAckRecoveryRetryAttemptsByClientMessageId[t] ?? 0) >= 1) && (!this.state.isThinking || this.state.status === "closed" || this.activeClientMessageId !== t || this.latestRecoverableClientMessageId !== t || (this.runAckRecoveryRetryAttemptsByClientMessageId[t] = 1, this.thinkingWatchdogRetryAttemptsByClientMessageId[t] = V, this.setState({
862
+ this.runAckResyncRetryTimer = null, !((this.runAckRecoveryRetryAttemptsByClientMessageId[t] ?? 0) >= 1) && (!this.state.isThinking || this.state.status === "closed" || this.activeClientMessageId !== t || this.latestRecoverableClientMessageId !== t || (this.runAckRecoveryRetryAttemptsByClientMessageId[t] = 1, this.thinkingWatchdogRetryAttemptsByClientMessageId[t] = ht, this.setState({
706
863
  status: this.state.status === "reconnecting" ? "reconnecting" : "connected",
707
864
  isThinking: !0,
708
865
  lastError: null
709
- }), g("web-sdk.agent", "Pluno run ack recovery retrying last user message", {
866
+ }), f("web-sdk.agent", "Pluno run ack recovery retrying last user message", {
710
867
  sessionId: this.state.sessionId,
711
868
  clientMessageId: t
712
869
  }), this.state.sessionId ? this.send({
713
870
  type: "chat.retry_last_user_message",
714
871
  sessionId: this.state.sessionId,
715
872
  clientMessageId: t
716
- }) : this.activeUserMessageEvent && this.send(this.activeUserMessageEvent), this.scheduleThinkingWatchdog(E)));
717
- }, Bt);
873
+ }) : this.activeUserMessageEvent && this.send(this.activeUserMessageEvent), this.scheduleThinkingWatchdog(U)));
874
+ }, ye);
718
875
  }
719
876
  clearRunAckResyncRetryTimer() {
720
877
  this.runAckResyncRetryTimer !== null && (window.clearTimeout(this.runAckResyncRetryTimer), this.runAckResyncRetryTimer = null);
@@ -727,33 +884,33 @@ class dt {
727
884
  return;
728
885
  const t = this.activeClientMessageId;
729
886
  if (!t) {
730
- g("web-sdk.agent", "Pluno thinking watchdog resyncing without active message id", {
887
+ f("web-sdk.agent", "Pluno thinking watchdog resyncing without active message id", {
731
888
  sessionId: this.state.sessionId
732
- }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(E);
889
+ }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(U);
733
890
  return;
734
891
  }
735
892
  const s = this.thinkingWatchdogResyncAttemptsByClientMessageId[t] ?? 0, n = this.thinkingWatchdogRetryAttemptsByClientMessageId[t] ?? 0;
736
893
  if (s <= n) {
737
- this.thinkingWatchdogResyncAttemptsByClientMessageId[t] = s + 1, g("web-sdk.agent", "Pluno thinking watchdog resyncing session", {
894
+ this.thinkingWatchdogResyncAttemptsByClientMessageId[t] = s + 1, f("web-sdk.agent", "Pluno thinking watchdog resyncing session", {
738
895
  sessionId: this.state.sessionId,
739
896
  clientMessageId: t,
740
897
  resyncAttempts: s + 1
741
- }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(Ht);
898
+ }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(fe);
742
899
  return;
743
900
  }
744
- if (n >= V) {
745
- g("web-sdk.agent", "Pluno thinking watchdog retry limit reached; continuing resync", {
901
+ if (n >= ht) {
902
+ f("web-sdk.agent", "Pluno thinking watchdog retry limit reached; continuing resync", {
746
903
  sessionId: this.state.sessionId,
747
904
  clientMessageId: t,
748
905
  retryAttempts: n
749
- }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(E);
906
+ }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(U);
750
907
  return;
751
908
  }
752
909
  this.thinkingWatchdogRetryAttemptsByClientMessageId[t] = n + 1, this.setState({
753
910
  status: this.state.status === "reconnecting" ? "reconnecting" : "connected",
754
911
  isThinking: !0,
755
912
  lastError: null
756
- }), g("web-sdk.agent", "Pluno thinking watchdog retrying last user message", {
913
+ }), f("web-sdk.agent", "Pluno thinking watchdog retrying last user message", {
757
914
  sessionId: this.state.sessionId,
758
915
  clientMessageId: t,
759
916
  retryAttempts: n + 1
@@ -761,13 +918,13 @@ class dt {
761
918
  type: "chat.retry_last_user_message",
762
919
  sessionId: this.state.sessionId,
763
920
  clientMessageId: t
764
- }) : this.activeUserMessageEvent && this.send(this.activeUserMessageEvent), this.scheduleThinkingWatchdog(E);
921
+ }) : this.activeUserMessageEvent && this.send(this.activeUserMessageEvent), this.scheduleThinkingWatchdog(U);
765
922
  }
766
923
  resyncThinkingSession() {
767
924
  this.state.sessionId ? this.send({
768
925
  type: "page.upsert",
769
926
  sessionId: this.state.sessionId,
770
- page: y(),
927
+ page: I(),
771
928
  model: this.options.model
772
929
  }) : (!this.socket || this.socket.readyState !== WebSocket.OPEN) && (this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect());
773
930
  }
@@ -775,15 +932,15 @@ class dt {
775
932
  const s = typeof t.sessionId == "string" ? t.sessionId : null, n = typeof t.callId == "string" ? t.callId : null, r = typeof t.toolName == "string" ? t.toolName : null, i = typeof t.summary == "string" ? t.summary : "Running browser tool", o = t.rawInput;
776
933
  if (!s || !n || !r)
777
934
  return;
778
- if (r !== "execute_code" || !Ke(o)) {
935
+ if (r !== "execute_code" || !Ls(o)) {
779
936
  this.send({
780
937
  type: "tool.result",
781
938
  sessionId: s,
782
939
  callId: n,
783
940
  toolName: r,
784
941
  summary: i,
785
- rawInput: T(o),
786
- rawOutput: T({
942
+ rawInput: A(o),
943
+ rawOutput: A({
787
944
  ok: !1,
788
945
  toolName: r,
789
946
  error: `Unsupported browser tool: ${r}`
@@ -791,164 +948,300 @@ class dt {
791
948
  });
792
949
  return;
793
950
  }
794
- const c = Yt(this.state.messages);
795
- this.installSessionUserFilesApi(c);
796
- let a = null, d;
797
- a = await this.executeRuntimeHelper(), d = await et(o).catch((h) => ({
951
+ const d = ve(this.state.messages);
952
+ this.activeBrowserToolCalls.set(n, {
953
+ event: {
954
+ type: "tool.result",
955
+ sessionId: s,
956
+ callId: n,
957
+ toolName: r,
958
+ summary: o.summary,
959
+ rawInput: A(o),
960
+ rawOutput: null
961
+ },
962
+ startedAtMs: Date.now(),
963
+ startedAtUrl: location.href,
964
+ startedAtOrigin: location.origin
965
+ }), this.installSessionUserFilesApi(d);
966
+ let a = null, h;
967
+ a = await this.executeRuntimeHelper(), h = await mt(o).catch((g) => ({
798
968
  ok: !1,
799
969
  exception: {
800
- message: h instanceof Error ? h.message : String(h)
970
+ message: g instanceof Error ? g.message : String(g)
801
971
  }
802
- })), this.send({
972
+ })), this.activeBrowserToolCalls.delete(n), this.send({
803
973
  type: "tool.result",
804
974
  sessionId: s,
805
975
  callId: n,
806
976
  toolName: r,
807
977
  summary: o.summary,
808
- rawInput: T(o),
809
- rawOutput: T(ge(d, a))
810
- });
978
+ rawInput: A(o),
979
+ rawOutput: A(Ze(h, a))
980
+ }), _s(this.options.clientId, this.activeBrowserToolCalls.values());
981
+ }
982
+ startPageLifecycleRecovery() {
983
+ if (this.pageLifecycleCleanup)
984
+ return;
985
+ const t = () => {
986
+ Lt(this.options.clientId, this.activeBrowserToolCalls.values());
987
+ };
988
+ window.addEventListener("pagehide", t), window.addEventListener("beforeunload", t), this.pageLifecycleCleanup = () => {
989
+ window.removeEventListener("pagehide", t), window.removeEventListener("beforeunload", t);
990
+ };
811
991
  }
812
992
  installSessionUserFilesApi(t) {
813
- this.cleanupSessionUserFilesApi(), this.sessionUserFilesApiCleanup = Zt(t, this.attachmentFiles, this.attachmentBlobCache);
993
+ this.cleanupSessionUserFilesApi(), this.sessionUserFilesApiCleanup = Le(t, this.attachmentFiles, this.attachmentBlobCache);
814
994
  }
815
995
  cleanupSessionUserFilesApi() {
816
- this.sessionUserFilesApiCleanup && (Qt(this.sessionUserFilesApiCleanup), this.sessionUserFilesApiCleanup = null);
996
+ this.sessionUserFilesApiCleanup && (qe(this.sessionUserFilesApiCleanup), this.sessionUserFilesApiCleanup = null);
817
997
  }
818
998
  async executeRuntimeHelper() {
819
999
  if (!this.runtimeHelperJavascript?.trim())
820
1000
  return null;
821
- const t = await et({
1001
+ const t = await mt({
822
1002
  javascript: this.runtimeHelperJavascript
823
1003
  });
824
- return t.ok === !1 ? fe(t) : null;
1004
+ return t.ok === !1 ? Qe(t) : null;
825
1005
  }
826
1006
  enableNetworkCapture() {
827
- if (this.networkCaptureCleanup)
828
- return;
829
- const t = window.fetch.bind(window), s = XMLHttpRequest.prototype.open, n = XMLHttpRequest.prototype.setRequestHeader, r = XMLHttpRequest.prototype.send;
830
- window.fetch = async (i, o) => {
831
- const c = Date.now(), a = new Date(c).toISOString(), d = i instanceof Request ? i : null, h = typeof i == "string" ? i : i instanceof URL ? i.toString() : d?.url ?? "", l = (o?.method ?? d?.method ?? "GET").toUpperCase(), u = ot(new Headers(o?.headers ?? d?.headers ?? void 0)), f = await Je(d, o);
832
- try {
833
- const p = await t(i, o);
834
- return this.enqueueNetworkEvent({
835
- requestId: U("fetch"),
836
- url: h,
837
- method: l,
838
- requestHeaders: u,
839
- requestBody: f,
840
- resourceType: "fetch",
841
- responseStatus: p.status,
842
- responseHeaders: ot(p.headers),
843
- responseBody: await Ve(p),
844
- startedAt: a,
845
- durationMs: Date.now() - c
846
- }), p;
847
- } catch (p) {
848
- throw this.enqueueNetworkEvent({
849
- requestId: U("fetch"),
850
- url: h,
851
- method: l,
852
- requestHeaders: u,
853
- requestBody: f,
854
- resourceType: "fetch",
855
- errorText: p instanceof Error ? p.message : String(p),
856
- startedAt: a,
857
- durationMs: Date.now() - c
858
- }), p;
859
- }
860
- }, XMLHttpRequest.prototype.open = function(o, c, a, d, h) {
861
- return this.__plunoMeta = {
862
- requestId: U("xhr"),
863
- method: String(o ?? "GET").toUpperCase(),
864
- url: typeof c == "string" ? c : c.toString(),
865
- requestHeaders: {},
866
- startedAtMs: Date.now(),
867
- startedAt: (/* @__PURE__ */ new Date()).toISOString()
868
- }, s.call(this, o, c, a ?? !0, d ?? void 0, h ?? void 0);
869
- }, XMLHttpRequest.prototype.setRequestHeader = function(o, c) {
870
- const a = this.__plunoMeta;
871
- if (a) {
872
- const d = a.requestHeaders ?? {};
873
- d[o] = c, a.requestHeaders = d;
874
- }
875
- return n.call(this, o, c);
876
- }, XMLHttpRequest.prototype.send = function(o) {
877
- const c = window.__plunoProductAgentInstance, a = this.__plunoMeta ?? {
878
- requestId: U("xhr"),
879
- method: "GET",
880
- url: "",
881
- requestHeaders: {},
882
- startedAtMs: Date.now(),
883
- startedAt: (/* @__PURE__ */ new Date()).toISOString()
884
- };
885
- return a.requestBody = St(o), this.__plunoMeta = a, this.addEventListener(
886
- "loadend",
887
- function() {
888
- !c || !this.__plunoMeta || c.enqueueNetworkEvent({
889
- requestId: String(this.__plunoMeta.requestId),
890
- url: String(this.__plunoMeta.url ?? ""),
891
- method: String(this.__plunoMeta.method ?? "GET"),
892
- requestHeaders: this.__plunoMeta.requestHeaders ?? {},
893
- requestBody: typeof this.__plunoMeta.requestBody == "string" ? this.__plunoMeta.requestBody : void 0,
894
- resourceType: "xhr",
895
- responseStatus: this.status,
896
- responseHeaders: Ze(this.getAllResponseHeaders()),
897
- responseBody: Ye(this),
898
- errorText: this.status === 0 ? "XHR request failed or was aborted" : void 0,
899
- startedAt: String(this.__plunoMeta.startedAt),
900
- durationMs: Date.now() - Number(this.__plunoMeta.startedAtMs ?? Date.now())
901
- });
902
- },
903
- { once: !0 }
904
- ), r.call(this, o ?? null);
905
- }, window.__plunoProductAgentInstance = this, this.networkCaptureCleanup = () => {
906
- window.fetch = t, XMLHttpRequest.prototype.open = s, XMLHttpRequest.prototype.setRequestHeader = n, XMLHttpRequest.prototype.send = r, window.__plunoProductAgentInstance === this && delete window.__plunoProductAgentInstance;
907
- };
1007
+ this.networkCaptureCleanup || (this.networkCaptureCleanup = Me((t) => {
1008
+ xs(t.url, this.options.backendUrl) || this.enqueueNetworkEvent(t);
1009
+ }));
908
1010
  }
909
1011
  enqueueNetworkEvent(t) {
910
- this.queuedNetworkEvents.push(T(t)), this.networkBatchTimer === null && (this.networkBatchTimer = window.setTimeout(() => {
1012
+ this.queuedNetworkEvents.length >= Te || (this.queuedNetworkEvents.push(Ws(t)), this.networkBatchTimer === null && (this.networkBatchTimer = window.setTimeout(() => {
911
1013
  this.networkBatchTimer = null;
912
1014
  const s = this.queuedNetworkEvents.splice(0, this.queuedNetworkEvents.length);
913
1015
  s.length === 0 || this.socket?.readyState !== WebSocket.OPEN || this.sendNow({
914
1016
  type: "network.batch",
915
1017
  sessionId: this.state.sessionId ?? void 0,
916
- page: y(),
1018
+ page: I(),
917
1019
  events: s
918
1020
  });
919
- }, vt));
1021
+ }, we)));
920
1022
  }
921
1023
  scheduleReconnect() {
922
- this.reconnectTimer !== null || this.state.status === "closed" || (this.reconnectTimer = window.setTimeout(() => {
923
- this.reconnectTimer = null, this.connect().catch((t) => {
924
- g("web-sdk.agent", "Pluno reconnect failed; retrying", {
925
- message: t instanceof Error ? t.message : String(t),
1024
+ if (this.reconnectTimer !== null || this.state.status === "closed")
1025
+ return;
1026
+ const t = be(this.reconnectAttempts);
1027
+ this.reconnectAttempts += 1, this.reconnectTimer = window.setTimeout(() => {
1028
+ this.reconnectTimer = null, this.connect().catch((s) => {
1029
+ f("web-sdk.agent", "Pluno reconnect failed; retrying", {
1030
+ message: s instanceof Error ? s.message : String(s),
926
1031
  queuedClientEventCount: this.queuedClientEvents.length,
927
1032
  isThinking: this.state.isThinking
928
1033
  }), this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect();
929
1034
  });
930
- }, Lt));
1035
+ }, t);
931
1036
  }
932
1037
  startHeartbeat() {
933
1038
  this.stopHeartbeat(), this.heartbeatTimer = window.setInterval(() => {
934
- this.sendNow({ type: "runtime.ping" });
935
- }, Ft);
1039
+ const t = this.socket;
1040
+ !t || !this.sendNow({ type: "runtime.ping" }) || (this.clearHeartbeatAckTimer(), this.heartbeatAckTimer = window.setTimeout(() => {
1041
+ this.socket === t && (f("web-sdk.agent", "Pluno heartbeat acknowledgement timed out; reconnecting"), this.replaceTimedOutSocket(t));
1042
+ }, ue));
1043
+ }, le);
936
1044
  }
937
1045
  stopHeartbeat() {
938
- this.heartbeatTimer !== null && (window.clearInterval(this.heartbeatTimer), this.heartbeatTimer = null);
1046
+ this.heartbeatTimer !== null && (window.clearInterval(this.heartbeatTimer), this.heartbeatTimer = null), this.clearHeartbeatAckTimer();
1047
+ }
1048
+ clearHeartbeatAckTimer() {
1049
+ this.heartbeatAckTimer !== null && (window.clearTimeout(this.heartbeatAckTimer), this.heartbeatAckTimer = null);
1050
+ }
1051
+ clearSocketConnectTimer() {
1052
+ this.socketConnectTimer !== null && (window.clearTimeout(this.socketConnectTimer), this.socketConnectTimer = null);
1053
+ }
1054
+ clearSocketAuthTimer() {
1055
+ this.socketAuthTimer !== null && (window.clearTimeout(this.socketAuthTimer), this.socketAuthTimer = null);
1056
+ }
1057
+ clearSocketPhaseTimers() {
1058
+ this.clearSocketConnectTimer(), this.clearSocketAuthTimer();
1059
+ }
1060
+ replaceTimedOutSocket(t) {
1061
+ this.socket !== t || this.state.status === "closed" || (this.clearSocketPhaseTimers(), this.stopHeartbeat(), this.socket = null, this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect(), t.readyState !== WebSocket.CLOSED && t.readyState !== WebSocket.CLOSING && t.close());
939
1062
  }
940
1063
  setState(t) {
941
1064
  this.state = {
942
1065
  ...this.state,
943
1066
  ...t,
944
1067
  ...t.lastError === null && t.lastErrorCode === void 0 ? { lastErrorCode: null } : {}
945
- }, ve(this.options.clientId, this.state), this.emit("state", this.getState());
1068
+ }, Es(this.options.clientId, this.state), this.emit("state", this.getState());
946
1069
  }
947
1070
  emit(t, s) {
948
1071
  this.listeners[t]?.forEach((r) => r(s));
949
1072
  }
950
1073
  }
951
- function g(e, t, s) {
1074
+ const X = /* @__PURE__ */ new WeakMap();
1075
+ function Me(e) {
1076
+ const t = window.__plunoProductAgentNetworkCapture ?? De();
1077
+ return t.subscribers.add(e), () => {
1078
+ t.subscribers.delete(e), !(t.subscribers.size > 0) && (t.destroy(), window.__plunoProductAgentNetworkCapture === t && delete window.__plunoProductAgentNetworkCapture);
1079
+ };
1080
+ }
1081
+ function De() {
1082
+ const e = /* @__PURE__ */ new Set(), t = (c) => {
1083
+ e.forEach((p) => {
1084
+ try {
1085
+ p(c);
1086
+ } catch {
1087
+ }
1088
+ });
1089
+ }, s = window.fetch, n = XMLHttpRequest.prototype.open, r = XMLHttpRequest.prototype.setRequestHeader, i = XMLHttpRequest.prototype.send, o = function(p, l) {
1090
+ const m = Date.now();
1091
+ let y;
1092
+ try {
1093
+ y = s.call(this, p, l);
1094
+ } catch (T) {
1095
+ throw T;
1096
+ }
1097
+ try {
1098
+ const T = p instanceof Request ? p : null, R = qs(p, T), w = Ht(l?.headers ?? T?.headers);
1099
+ if (!P(R, w, l?.body)) {
1100
+ const j = {
1101
+ requestId: J("fetch"),
1102
+ url: S(R, G),
1103
+ method: (l?.method ?? T?.method ?? "GET").toUpperCase(),
1104
+ requestHeaders: w,
1105
+ requestBody: It(l?.body),
1106
+ resourceType: "fetch",
1107
+ startedAt: new Date(m).toISOString()
1108
+ };
1109
+ y.then(
1110
+ (_) => {
1111
+ Bs(_, j, m, t).catch(() => {
1112
+ t({
1113
+ ...j,
1114
+ responseStatus: _.status,
1115
+ durationMs: Date.now() - m
1116
+ });
1117
+ });
1118
+ },
1119
+ (_) => {
1120
+ t({
1121
+ ...j,
1122
+ errorText: S(_ instanceof Error ? _.message : String(_)),
1123
+ durationMs: Date.now() - m
1124
+ });
1125
+ }
1126
+ );
1127
+ }
1128
+ } catch {
1129
+ }
1130
+ return y;
1131
+ }, d = function(p, l, m, y, T) {
1132
+ const R = n.call(this, p, l, m ?? !0, y ?? void 0, T ?? void 0), w = typeof l == "string" ? l : l.toString();
1133
+ return X.set(this, {
1134
+ requestId: J("xhr"),
1135
+ method: String(p ?? "GET").toUpperCase(),
1136
+ url: S(w, G),
1137
+ requestHeaders: {},
1138
+ startedAtMs: Date.now(),
1139
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
1140
+ excluded: P(w)
1141
+ }), R;
1142
+ }, a = function(p, l) {
1143
+ const m = r.call(this, p, l), y = X.get(this);
1144
+ return y && Object.keys(y.requestHeaders).length < it && (y.requestHeaders[p] = ct(p, l), y.excluded = y.excluded || P(y.url, y.requestHeaders)), m;
1145
+ }, h = function(p) {
1146
+ try {
1147
+ const l = X.get(this);
1148
+ l && (l.excluded = l.excluded || P(l.url, l.requestHeaders, p), l.requestBody = It(p), l.excluded || this.addEventListener(
1149
+ "loadend",
1150
+ () => {
1151
+ queueMicrotask(() => {
1152
+ try {
1153
+ const m = $s(this.getAllResponseHeaders());
1154
+ t({
1155
+ requestId: l.requestId,
1156
+ url: l.url,
1157
+ method: l.method,
1158
+ requestHeaders: l.requestHeaders,
1159
+ requestBody: l.requestBody,
1160
+ resourceType: "xhr",
1161
+ responseStatus: this.status,
1162
+ responseHeaders: m,
1163
+ responseBody: Fs(this, m),
1164
+ errorText: this.status === 0 ? "XHR request failed or was aborted" : void 0,
1165
+ startedAt: l.startedAt,
1166
+ durationMs: Date.now() - l.startedAtMs
1167
+ });
1168
+ } catch {
1169
+ return;
1170
+ }
1171
+ });
1172
+ },
1173
+ { once: !0 }
1174
+ ));
1175
+ } catch {
1176
+ }
1177
+ return i.call(this, p ?? null);
1178
+ };
1179
+ try {
1180
+ window.fetch = o;
1181
+ } catch {
1182
+ }
1183
+ try {
1184
+ XMLHttpRequest.prototype.open = d;
1185
+ } catch {
1186
+ }
1187
+ try {
1188
+ XMLHttpRequest.prototype.setRequestHeader = a;
1189
+ } catch {
1190
+ }
1191
+ try {
1192
+ XMLHttpRequest.prototype.send = h;
1193
+ } catch {
1194
+ }
1195
+ let g = null;
1196
+ if (typeof PerformanceObserver < "u") {
1197
+ g = new PerformanceObserver((c) => {
1198
+ for (const p of c.getEntries()) {
1199
+ const l = p;
1200
+ if (l.initiatorType === "fetch" || l.initiatorType === "xmlhttprequest" || P(l.name))
1201
+ continue;
1202
+ const m = performance.timeOrigin + l.startTime;
1203
+ t({
1204
+ requestId: J("resource"),
1205
+ url: S(l.name, G),
1206
+ method: "GET",
1207
+ resourceType: "resource",
1208
+ responseStatus: l.responseStatus,
1209
+ startedAt: new Date(m).toISOString(),
1210
+ durationMs: l.duration
1211
+ });
1212
+ }
1213
+ });
1214
+ try {
1215
+ g.observe({ type: "resource", buffered: !0 });
1216
+ } catch {
1217
+ g.disconnect(), g = null;
1218
+ }
1219
+ }
1220
+ const u = {
1221
+ subscribers: e,
1222
+ destroy: () => {
1223
+ g?.disconnect();
1224
+ try {
1225
+ window.fetch === o && (window.fetch = s);
1226
+ } catch {
1227
+ }
1228
+ try {
1229
+ XMLHttpRequest.prototype.open === d && (XMLHttpRequest.prototype.open = n);
1230
+ } catch {
1231
+ }
1232
+ try {
1233
+ XMLHttpRequest.prototype.setRequestHeader === a && (XMLHttpRequest.prototype.setRequestHeader = r);
1234
+ } catch {
1235
+ }
1236
+ try {
1237
+ XMLHttpRequest.prototype.send === h && (XMLHttpRequest.prototype.send = i);
1238
+ } catch {
1239
+ }
1240
+ }
1241
+ };
1242
+ return window.__plunoProductAgentNetworkCapture = u, u;
1243
+ }
1244
+ function f(e, t, s) {
952
1245
  if (typeof window > "u")
953
1246
  return;
954
1247
  const n = window, r = {
@@ -959,15 +1252,15 @@ function g(e, t, s) {
959
1252
  }, i = n.__plunoProductAgentDiagnostics__ ?? [];
960
1253
  i.push(r), i.length > 120 && i.splice(0, i.length - 120), n.__plunoProductAgentDiagnostics__ = i, n.__PLUNO_PRODUCT_AGENT_DIAGNOSTICS__ = () => [...i], window.dispatchEvent(new CustomEvent("product-agent:preview-diagnostic", { detail: r }));
961
1254
  }
962
- function Q(e) {
1255
+ function gt(e) {
963
1256
  const t = typeof e == "function" ? e() : e;
964
1257
  return t && Object.keys(t).length > 0 ? t : void 0;
965
1258
  }
966
- function Jt(e) {
1259
+ function Ne(e) {
967
1260
  return e.type === "conversation.state" || e.type === "session.updated" || e.type === "session.item" || e.type === "chat.assistant_delta" || e.type === "chat.assistant_done" || e.type === "tool.call";
968
1261
  }
969
- const Vt = 5e3;
970
- function Yt(e) {
1262
+ const Oe = 5e3;
1263
+ function ve(e) {
971
1264
  const t = [];
972
1265
  for (const s of e)
973
1266
  s.role !== "user" || !s.attachments?.length || s.attachments.forEach((n, r) => {
@@ -978,118 +1271,118 @@ function Yt(e) {
978
1271
  });
979
1272
  return t;
980
1273
  }
981
- function Zt(e, t = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map()) {
982
- const n = new Map(e.map((l) => [l.id, l])), r = (l) => ({
983
- id: l.id,
984
- name: l.name,
985
- mimeType: l.mimeType,
986
- sizeBytes: l.sizeBytes,
987
- type: l.mimeType,
988
- size: l.sizeBytes
989
- }), i = (l) => {
990
- const u = n.get(l);
991
- if (!u)
992
- throw new Error(`Unknown Pluno user file: ${l}`);
993
- return u;
994
- }, o = async (l) => {
995
- const u = i(l), f = t.get(u.id);
996
- if (f)
997
- return f;
998
- const p = s.get(u.id);
1274
+ function Le(e, t = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map()) {
1275
+ const n = new Map(e.map((u) => [u.id, u])), r = (u) => ({
1276
+ id: u.id,
1277
+ name: u.name,
1278
+ mimeType: u.mimeType,
1279
+ sizeBytes: u.sizeBytes,
1280
+ type: u.mimeType,
1281
+ size: u.sizeBytes
1282
+ }), i = (u) => {
1283
+ const c = n.get(u);
1284
+ if (!c)
1285
+ throw new Error(`Unknown Pluno user file: ${u}`);
1286
+ return c;
1287
+ }, o = async (u) => {
1288
+ const c = i(u), p = t.get(c.id);
999
1289
  if (p)
1000
1290
  return p;
1001
- const S = await bt(u.id).then((m) => m?.blob ?? null).catch((m) => (g("web-sdk.attachments", "Failed to load Product Agent attachment from IndexedDB", {
1002
- attachmentId: u.id,
1003
- name: u.name,
1004
- message: m instanceof Error ? m.message : String(m)
1291
+ const l = s.get(c.id);
1292
+ if (l)
1293
+ return l;
1294
+ const m = await Kt(c.id).then((w) => w?.blob ?? null).catch((w) => (f("web-sdk.attachments", "Failed to load Product Agent attachment from IndexedDB", {
1295
+ attachmentId: c.id,
1296
+ name: c.name,
1297
+ message: w instanceof Error ? w.message : String(w)
1005
1298
  }), null));
1006
- if (S)
1007
- return s.set(u.id, S), S;
1008
- if (!u.fileUrl)
1009
- throw new Error(`Pluno user file is missing content: ${l}`);
1010
- const q = await fetch(u.fileUrl, je(u.fileUrl));
1011
- if (!q.ok)
1012
- throw new Error(`Failed to load Pluno user file: ${l}`);
1013
- const O = await q.blob();
1014
- s.set(u.id, O);
1015
- const K = Date.now();
1016
- return at({
1017
- attachmentId: u.id,
1018
- name: u.name,
1019
- mimeType: u.mimeType,
1020
- sizeBytes: u.sizeBytes,
1021
- blob: O,
1022
- fileUrl: u.fileUrl,
1023
- gcsPath: u.gcsPath,
1024
- createdAt: K,
1025
- lastUsedAt: K
1026
- }).catch((m) => {
1027
- g("web-sdk.attachments", "Failed to cache Product Agent attachment from fileUrl", {
1028
- attachmentId: u.id,
1029
- name: u.name,
1030
- message: m instanceof Error ? m.message : String(m)
1299
+ if (m)
1300
+ return s.set(c.id, m), m;
1301
+ if (!c.fileUrl)
1302
+ throw new Error(`Pluno user file is missing content: ${u}`);
1303
+ const y = await fetch(c.fileUrl, Ms(c.fileUrl));
1304
+ if (!y.ok)
1305
+ throw new Error(`Failed to load Pluno user file: ${u}`);
1306
+ const T = await y.blob();
1307
+ s.set(c.id, T);
1308
+ const R = Date.now();
1309
+ return kt({
1310
+ attachmentId: c.id,
1311
+ name: c.name,
1312
+ mimeType: c.mimeType,
1313
+ sizeBytes: c.sizeBytes,
1314
+ blob: T,
1315
+ fileUrl: c.fileUrl,
1316
+ gcsPath: c.gcsPath,
1317
+ createdAt: R,
1318
+ lastUsedAt: R
1319
+ }).catch((w) => {
1320
+ f("web-sdk.attachments", "Failed to cache Product Agent attachment from fileUrl", {
1321
+ attachmentId: c.id,
1322
+ name: c.name,
1323
+ message: w instanceof Error ? w.message : String(w)
1031
1324
  });
1032
- }), O;
1033
- }, c = async (l) => {
1034
- const u = i(l), f = await o(l), p = u.mimeType.startsWith("image/") ? u.mimeType : f.type || u.mimeType;
1035
- if (!p.startsWith("image/"))
1036
- throw new Error(`Pluno user file is not an image: ${l}`);
1037
- const S = f.type === p ? f : new Blob([f], { type: p });
1038
- return te(p, S.size) > zt ? {
1325
+ }), T;
1326
+ }, d = async (u) => {
1327
+ const c = i(u), p = await o(u), l = c.mimeType.startsWith("image/") ? c.mimeType : p.type || c.mimeType;
1328
+ if (!l.startsWith("image/"))
1329
+ throw new Error(`Pluno user file is not an image: ${u}`);
1330
+ const m = p.type === l ? p : new Blob([p], { type: l });
1331
+ return Be(l, m.size) > Re ? {
1039
1332
  type: "pluno.userFiles.inspectImage",
1040
- id: u.id,
1041
- name: u.name,
1042
- mimeType: p,
1043
- sizeBytes: u.sizeBytes,
1333
+ id: c.id,
1334
+ name: c.name,
1335
+ mimeType: l,
1336
+ sizeBytes: c.sizeBytes,
1044
1337
  imageAttached: !1,
1045
- imageAttachmentError: Gt
1338
+ imageAttachmentError: _e
1046
1339
  } : {
1047
1340
  type: "pluno.userFiles.inspectImage",
1048
- id: u.id,
1049
- name: u.name,
1050
- mimeType: p,
1051
- sizeBytes: u.sizeBytes,
1341
+ id: c.id,
1342
+ name: c.name,
1343
+ mimeType: l,
1344
+ sizeBytes: c.sizeBytes,
1052
1345
  imageAttached: !0,
1053
- dataUrl: await tt(S)
1346
+ dataUrl: await ft(m)
1054
1347
  };
1055
- }, a = globalThis, d = a.pluno?.userFiles, h = Object.prototype.hasOwnProperty.call(a.pluno ?? {}, "userFiles");
1348
+ }, a = globalThis, h = a.pluno?.userFiles, g = Object.prototype.hasOwnProperty.call(a.pluno ?? {}, "userFiles");
1056
1349
  return a.pluno = {
1057
1350
  ...a.pluno ?? {},
1058
1351
  userFiles: {
1059
1352
  list: () => e.map(r),
1060
- get: (l) => {
1061
- const u = n.get(l);
1062
- return u ? r(u) : null;
1353
+ get: (u) => {
1354
+ const c = n.get(u);
1355
+ return c ? r(c) : null;
1063
1356
  },
1064
- inspectImage: c,
1065
- getDataUrl: async (l) => (i(l), await tt(await o(l))),
1357
+ inspectImage: d,
1358
+ getDataUrl: async (u) => (i(u), await ft(await o(u))),
1066
1359
  getBlob: o,
1067
- getArrayBuffer: async (l) => await (await o(l)).arrayBuffer(),
1068
- getFile: async (l) => {
1069
- const u = i(l);
1070
- return new File([await o(l)], u.name, { type: u.mimeType });
1360
+ getArrayBuffer: async (u) => await (await o(u)).arrayBuffer(),
1361
+ getFile: async (u) => {
1362
+ const c = i(u);
1363
+ return new File([await o(u)], c.name, { type: c.mimeType });
1071
1364
  }
1072
1365
  }
1073
1366
  }, () => {
1074
- const l = a.pluno ?? {};
1075
- if (h) {
1367
+ const u = a.pluno ?? {};
1368
+ if (g) {
1076
1369
  a.pluno = {
1077
- ...l,
1078
- userFiles: d
1370
+ ...u,
1371
+ userFiles: h
1079
1372
  };
1080
1373
  return;
1081
1374
  }
1082
- const { userFiles: u, ...f } = l;
1083
- a.pluno = f;
1375
+ const { userFiles: c, ...p } = u;
1376
+ a.pluno = p;
1084
1377
  };
1085
1378
  }
1086
- function Qt(e) {
1379
+ function qe(e) {
1087
1380
  try {
1088
1381
  e();
1089
1382
  } catch {
1090
1383
  }
1091
1384
  }
1092
- function tt(e) {
1385
+ function ft(e) {
1093
1386
  return new Promise((t, s) => {
1094
1387
  const n = new FileReader();
1095
1388
  n.onload = () => {
@@ -1101,32 +1394,32 @@ function tt(e) {
1101
1394
  }, n.onerror = () => s(n.error ?? new Error("Failed to read Pluno user file")), n.readAsDataURL(e);
1102
1395
  });
1103
1396
  }
1104
- function te(e, t) {
1397
+ function Be(e, t) {
1105
1398
  return `data:${e};base64,`.length + Math.ceil(t / 3) * 4;
1106
1399
  }
1107
- async function et(e) {
1400
+ async function mt(e) {
1108
1401
  const t = Object.getPrototypeOf(async function() {
1109
- }).constructor, s = e.timeoutMs ?? Vt, n = Date.now(), r = [];
1402
+ }).constructor, s = e.timeoutMs ?? Oe, n = Date.now(), r = [];
1110
1403
  let i;
1111
1404
  const o = {
1112
1405
  log: console.log,
1113
1406
  info: console.info,
1114
1407
  warn: console.warn,
1115
1408
  error: console.error
1116
- }, c = (a) => (...d) => {
1117
- r.push({ level: a, args: d }), o[a](...d);
1409
+ }, d = (a) => (...h) => {
1410
+ r.push({ level: a, args: h }), o[a](...h);
1118
1411
  };
1119
- console.log = c("log"), console.info = c("info"), console.warn = c("warn"), console.error = c("error");
1412
+ console.log = d("log"), console.info = d("info"), console.warn = d("warn"), console.error = d("error");
1120
1413
  try {
1121
- const a = /* @__PURE__ */ Symbol("execute_code_timeout"), d = await Promise.race([
1414
+ const a = /* @__PURE__ */ Symbol("execute_code_timeout"), h = await Promise.race([
1122
1415
  new t(e.javascript)(),
1123
- new Promise((h) => {
1124
- i = window.setTimeout(() => h(a), s);
1416
+ new Promise((g) => {
1417
+ i = window.setTimeout(() => g(a), s);
1125
1418
  })
1126
1419
  ]);
1127
- return d === a ? ee(s) : {
1420
+ return h === a ? He(s) : {
1128
1421
  ok: !0,
1129
- result: d,
1422
+ result: h,
1130
1423
  console: r,
1131
1424
  metadata: {
1132
1425
  durationMs: Date.now() - n,
@@ -1153,7 +1446,7 @@ async function et(e) {
1153
1446
  i !== void 0 && window.clearTimeout(i), console.log = o.log, console.info = o.info, console.warn = o.warn, console.error = o.error;
1154
1447
  }
1155
1448
  }
1156
- function ee(e) {
1449
+ function He(e) {
1157
1450
  return {
1158
1451
  ok: !1,
1159
1452
  exception: {
@@ -1167,18 +1460,18 @@ function ee(e) {
1167
1460
  }
1168
1461
  };
1169
1462
  }
1170
- function se(e) {
1463
+ function Fe(e) {
1171
1464
  return e.replace(/\/+$/, "");
1172
1465
  }
1173
- function ne(e, t = location.origin) {
1466
+ function We(e, t = location.origin) {
1174
1467
  return /origin (?:is not allowed|does not match browser origin)/i.test(e) ? `Pluno widget blocked on ${t}: this domain is not allowed. Add ${t} in Pluno under Integration > Domains.` : null;
1175
1468
  }
1176
- function re(e) {
1469
+ function xe(e) {
1177
1470
  const t = new URL("/api/product-agent/embed/ws", e);
1178
1471
  return t.protocol = t.protocol === "https:" ? "wss:" : "ws:", t.toString();
1179
1472
  }
1180
- function y() {
1181
- const e = ht();
1473
+ function I() {
1474
+ const e = bt();
1182
1475
  return {
1183
1476
  url: location.href,
1184
1477
  title: document.title,
@@ -1186,21 +1479,21 @@ function y() {
1186
1479
  ...e ? { plunoProductAgentUi: e } : {}
1187
1480
  };
1188
1481
  }
1189
- function ie() {
1482
+ function je() {
1190
1483
  return {
1191
1484
  pageUrl: location.href,
1192
1485
  pageTitle: document.title,
1193
- htmlContent: le()
1486
+ htmlContent: Xe()
1194
1487
  };
1195
1488
  }
1196
- function oe(e) {
1197
- return b.add(e), R || (R = ae()), () => {
1198
- b.delete(e), b.size === 0 && (R?.(), R = null);
1489
+ function $e(e) {
1490
+ return v.add(e), D || (D = ze()), () => {
1491
+ v.delete(e), v.size === 0 && (D?.(), D = null);
1199
1492
  };
1200
1493
  }
1201
- function ae() {
1494
+ function ze() {
1202
1495
  const e = () => {
1203
- for (const i of Array.from(b))
1496
+ for (const i of Array.from(v))
1204
1497
  i();
1205
1498
  }, t = window.history.pushState.bind(window.history), s = window.history.replaceState.bind(window.history), n = ((...i) => {
1206
1499
  const o = t(...i);
@@ -1213,10 +1506,10 @@ function ae() {
1213
1506
  window.history.pushState === n && (window.history.pushState = t), window.history.replaceState === r && (window.history.replaceState = s), window.removeEventListener("popstate", e), window.removeEventListener("hashchange", e);
1214
1507
  };
1215
1508
  }
1216
- function ce() {
1217
- return ht()?.surface === "browser_extension_sdk_preview";
1509
+ function Ge() {
1510
+ return bt()?.surface === "browser_extension_sdk_preview";
1218
1511
  }
1219
- function le() {
1512
+ function Xe() {
1220
1513
  const e = document.body?.cloneNode(!0);
1221
1514
  return e instanceof HTMLElement ? (e.querySelectorAll(
1222
1515
  [
@@ -1240,9 +1533,9 @@ function le() {
1240
1533
  s.name === "href" || s.name === "aria-label" || s.name === "role" || t.removeAttribute(s.name);
1241
1534
  }), e.textContent?.replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, "[email]").replace(/\b(?:\d[ -]*?){13,19}\b/g, "[number]").replace(/\b(?:sk|pk|tok|key|secret|token)_[A-Za-z0-9_-]{8,}\b/gi, "[secret]").replace(/\s+/g, " ").trim().slice(0, 12e3) ?? "") : "";
1242
1535
  }
1243
- function ht() {
1244
- const e = document.querySelector(J);
1245
- if (!(e ?? document.querySelector(B)))
1536
+ function bt() {
1537
+ const e = document.querySelector(lt);
1538
+ if (!(e ?? document.querySelector(Z)))
1246
1539
  return;
1247
1540
  const s = e ? "browser_extension_sdk_preview" : "embedded_widget";
1248
1541
  return {
@@ -1251,28 +1544,28 @@ function ht() {
1251
1544
  selectors: [
1252
1545
  {
1253
1546
  name: "widget_host",
1254
- selector: s === "browser_extension_sdk_preview" ? J : B,
1547
+ selector: s === "browser_extension_sdk_preview" ? lt : Z,
1255
1548
  description: "Finds Pluno's shadow-host element in the host page DOM."
1256
1549
  },
1257
1550
  {
1258
1551
  name: "widget_root",
1259
- selector: Mt,
1552
+ selector: re,
1260
1553
  description: "Finds Pluno's widget root inside the widget host shadow root."
1261
1554
  },
1262
1555
  {
1263
1556
  name: "widget_panel",
1264
- selector: Dt,
1557
+ selector: ie,
1265
1558
  description: "Finds Pluno's open chat panel inside the widget host shadow root."
1266
1559
  },
1267
1560
  {
1268
1561
  name: "widget_timeline",
1269
- selector: Nt,
1562
+ selector: oe,
1270
1563
  description: "Finds Pluno's chat timeline inside the widget host shadow root."
1271
1564
  }
1272
1565
  ]
1273
1566
  };
1274
1567
  }
1275
- function ue(e) {
1568
+ function Ke(e) {
1276
1569
  try {
1277
1570
  const t = JSON.parse(e);
1278
1571
  return t && typeof t == "object" ? t : { type: "error", message: "Invalid server event" };
@@ -1280,33 +1573,33 @@ function ue(e) {
1280
1573
  return { type: "error", message: "Invalid server event" };
1281
1574
  }
1282
1575
  }
1283
- function st(e, t) {
1576
+ function yt(e, t) {
1284
1577
  if (!e || typeof e != "object")
1285
1578
  return [];
1286
1579
  const s = e[t];
1287
1580
  return Array.isArray(s) ? s.filter((n) => typeof n == "string" && n.trim().length > 0) : [];
1288
1581
  }
1289
- function de(e) {
1582
+ function Je(e) {
1290
1583
  return Array.isArray(e) ? e.filter((t) => typeof t == "string" && t.trim().length > 0) : [];
1291
1584
  }
1292
- function he(e) {
1585
+ function Ve(e) {
1293
1586
  if (!e || typeof e != "object")
1294
1587
  return null;
1295
- const t = e, s = t.appearance, n = s && typeof s == "object" ? s : t, 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, c = typeof n.scribbleStyle == "boolean" ? n.scribbleStyle : null;
1296
- return !r && !i && !o && c === null ? null : {
1588
+ const t = e, s = t.appearance, n = s && typeof s == "object" ? s : t, 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, d = typeof n.scribbleStyle == "boolean" ? n.scribbleStyle : null;
1589
+ return !r && !i && !o && d === null ? null : {
1297
1590
  ...r ? { accentColor: r } : {},
1298
1591
  ...i ? { colorScheme: i } : {},
1299
1592
  ...o ? { fontFamily: o } : {},
1300
- ...c !== null ? { scribbleStyle: c } : {}
1593
+ ...d !== null ? { scribbleStyle: d } : {}
1301
1594
  };
1302
1595
  }
1303
- function pe(e) {
1596
+ function Ye(e) {
1304
1597
  if (!e || typeof e != "object")
1305
1598
  return null;
1306
1599
  const t = e.javascript;
1307
1600
  return typeof t != "string" || !t.trim() ? null : { javascript: t };
1308
1601
  }
1309
- function ge(e, t) {
1602
+ function Ze(e, t) {
1310
1603
  return t ? e && typeof e == "object" ? {
1311
1604
  ...e,
1312
1605
  helperError: t
@@ -1316,30 +1609,23 @@ function ge(e, t) {
1316
1609
  helperError: t
1317
1610
  } : e;
1318
1611
  }
1319
- function fe(e) {
1612
+ function Qe(e) {
1320
1613
  if (!e || typeof e != "object")
1321
1614
  return e;
1322
1615
  const t = e;
1323
1616
  return typeof t.exception?.message == "string" ? t.exception.message : typeof t.error == "string" ? t.error : e;
1324
1617
  }
1325
- function me() {
1618
+ function ts() {
1326
1619
  const e = "pluno.productAgent.clientId", t = window.localStorage.getItem(e);
1327
1620
  if (t)
1328
1621
  return t;
1329
1622
  const s = crypto.randomUUID();
1330
1623
  return window.localStorage.setItem(e, s), s;
1331
1624
  }
1332
- function ye() {
1333
- const e = window.sessionStorage.getItem(Z);
1334
- if (e)
1335
- return e;
1336
- const t = crypto.randomUUID();
1337
- return window.sessionStorage.setItem(Z, t), t;
1338
- }
1339
- function _() {
1625
+ function N() {
1340
1626
  return crypto.randomUUID();
1341
1627
  }
1342
- function we(e) {
1628
+ function es(e) {
1343
1629
  if (!e || typeof e != "object")
1344
1630
  return null;
1345
1631
  const t = e, s = typeof t.id == "string" ? t.id : null;
@@ -1350,23 +1636,23 @@ function we(e) {
1350
1636
  avatarUrl: typeof t.avatarUrl == "string" ? t.avatarUrl : null
1351
1637
  } : null;
1352
1638
  }
1353
- function Te(e, t) {
1354
- return Array.isArray(e) ? x(
1355
- j(
1356
- e.map((s) => pt(s, t)).filter((s) => s !== null)
1639
+ function ss(e, t) {
1640
+ return Array.isArray(e) ? tt(
1641
+ et(
1642
+ e.map((s) => Ut(s, t)).filter((s) => s !== null)
1357
1643
  )
1358
1644
  ) : [];
1359
1645
  }
1360
- function Ae(e) {
1646
+ function ns(e) {
1361
1647
  return Array.isArray(e) ? e.flatMap((t) => {
1362
1648
  if (!t || typeof t != "object")
1363
1649
  return [];
1364
- const s = t, n = A(s, "id"), r = A(s, "createdAt"), i = A(s, "updatedAt"), o = A(s, "lastActiveAt");
1650
+ const s = t, n = E(s, "id"), r = E(s, "createdAt"), i = E(s, "updatedAt"), o = E(s, "lastActiveAt");
1365
1651
  return !n || !r || !i || !o ? [] : [
1366
1652
  {
1367
1653
  id: n,
1368
- title: A(s, "title"),
1369
- firstUserMessage: A(s, "firstUserMessage"),
1654
+ title: E(s, "title"),
1655
+ firstUserMessage: E(s, "firstUserMessage"),
1370
1656
  currentPage: s.currentPage ?? null,
1371
1657
  createdAt: r,
1372
1658
  updatedAt: i,
@@ -1375,7 +1661,7 @@ function Ae(e) {
1375
1661
  ];
1376
1662
  }) : [];
1377
1663
  }
1378
- function pt(e, t) {
1664
+ function Ut(e, t) {
1379
1665
  if (!e || typeof e != "object")
1380
1666
  return null;
1381
1667
  const s = e, n = s.data;
@@ -1387,39 +1673,39 @@ function pt(e, t) {
1387
1673
  return {
1388
1674
  id: String(s.id ?? crypto.randomUUID()),
1389
1675
  role: i,
1390
- content: Re(r.content),
1676
+ content: cs(r.content),
1391
1677
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
1392
- respondsToUserMessageId: L(r) ?? void 0,
1393
- ...k(r) ? { runId: k(r) } : {},
1394
- attachments: At(r.attachments, t)
1678
+ respondsToUserMessageId: K(r) ?? void 0,
1679
+ ...C(r) ? { runId: C(r) } : {},
1680
+ attachments: qt(r.attachments, t)
1395
1681
  };
1396
1682
  }
1397
1683
  return r.type === "function_call" || r.type === "tool_call" || r.type === "web_search_call" ? {
1398
1684
  id: String(s.id ?? crypto.randomUUID()),
1399
1685
  role: "tool",
1400
- content: Se(r),
1686
+ content: is(r),
1401
1687
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
1402
- respondsToUserMessageId: L(r) ?? void 0,
1403
- ...k(r) ? { runId: k(r) } : {},
1688
+ respondsToUserMessageId: K(r) ?? void 0,
1689
+ ...C(r) ? { runId: C(r) } : {},
1404
1690
  dataType: String(r.type),
1405
1691
  toolName: typeof r.name == "string" ? r.name : void 0,
1406
- callId: Ee(r) ?? void 0,
1692
+ callId: as(r) ?? void 0,
1407
1693
  loading: r.localExecutionStatus === "running"
1408
1694
  } : r.type === "run_status" || r.type === "run_error" ? r.type === "run_error" && r.stage === "tool_execution" ? null : {
1409
1695
  id: String(s.id ?? crypto.randomUUID()),
1410
1696
  role: "system",
1411
- content: Ie(r),
1697
+ content: rs(r),
1412
1698
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
1413
- respondsToUserMessageId: L(r) ?? void 0,
1414
- ...k(r) ? { runId: k(r) } : {},
1699
+ respondsToUserMessageId: K(r) ?? void 0,
1700
+ ...C(r) ? { runId: C(r) } : {},
1415
1701
  dataType: String(r.type),
1416
1702
  loading: r.type === "run_status" && (r.status === "running" || r.status === "retrying")
1417
1703
  } : null;
1418
1704
  }
1419
- function Ie(e) {
1705
+ function rs(e) {
1420
1706
  return typeof e.message == "string" && e.message.trim().length > 0 ? e.message.replace(/Product Agent/g, "Pluno") : e.type === "run_status" && e.status === "interrupted" ? "Pluno was interrupted before it could finish this message." : e.type === "run_status" && e.status === "stopped" ? "Pluno stopped." : "Pluno run status changed.";
1421
1707
  }
1422
- function Se(e) {
1708
+ function is(e) {
1423
1709
  if (e.type === "web_search_call") {
1424
1710
  const t = e.action;
1425
1711
  if (t && typeof t == "object") {
@@ -1431,9 +1717,9 @@ function Se(e) {
1431
1717
  }
1432
1718
  return "Searching the web";
1433
1719
  }
1434
- return ke(e);
1720
+ return os(e);
1435
1721
  }
1436
- function ke(e) {
1722
+ function os(e) {
1437
1723
  if (typeof e.summary == "string" && e.summary.trim().length > 0)
1438
1724
  return e.summary;
1439
1725
  if (typeof e.arguments == "string")
@@ -1446,11 +1732,11 @@ function ke(e) {
1446
1732
  }
1447
1733
  return typeof e.name == "string" && e.name.trim().length > 0 ? e.name : "Run tool";
1448
1734
  }
1449
- function Ee(e) {
1735
+ function as(e) {
1450
1736
  const t = e.callId ?? e.call_id;
1451
1737
  return typeof t == "string" && t ? t : null;
1452
1738
  }
1453
- function Re(e) {
1739
+ function cs(e) {
1454
1740
  return typeof e == "string" ? e : Array.isArray(e) ? e.map((t) => {
1455
1741
  if (!t || typeof t != "object")
1456
1742
  return "";
@@ -1458,19 +1744,19 @@ function Re(e) {
1458
1744
  return typeof s.text == "string" ? s.text : typeof s.content == "string" ? s.content : "";
1459
1745
  }).filter(Boolean).join("") : "";
1460
1746
  }
1461
- function _e(e, t) {
1462
- const s = gt(e, t), n = Ce(e, t), r = n.findIndex((o) => o.id === s.id);
1747
+ function ls(e, t) {
1748
+ const s = Mt(e, t), n = ps(e, t), r = n.findIndex((o) => o.id === s.id);
1463
1749
  if (r === -1)
1464
- return x(
1465
- j([...n, s])
1750
+ return tt(
1751
+ et([...n, s])
1466
1752
  );
1467
1753
  const i = [...n];
1468
- return i[r] = s, x(j(i));
1754
+ return i[r] = s, tt(et(i));
1469
1755
  }
1470
- function Pe(e, t) {
1471
- return t.map((s) => gt(e, s));
1756
+ function us(e, t) {
1757
+ return t.map((s) => Mt(e, s));
1472
1758
  }
1473
- function gt(e, t) {
1759
+ function Mt(e, t) {
1474
1760
  if (t.role !== "user" || !t.attachments?.length)
1475
1761
  return t;
1476
1762
  const s = e.find(
@@ -1479,19 +1765,19 @@ function gt(e, t) {
1479
1765
  if (!s?.attachments?.length)
1480
1766
  return t;
1481
1767
  const n = t.attachments.map((r) => {
1482
- const i = Ue(s.attachments ?? [], r);
1483
- return i ? be(r, i) : r;
1768
+ const i = ds(s.attachments ?? [], r);
1769
+ return i ? hs(r, i) : r;
1484
1770
  });
1485
1771
  return { ...t, attachments: n };
1486
1772
  }
1487
- function Ue(e, t) {
1773
+ function ds(e, t) {
1488
1774
  return t.id ? e.find((s) => s.id === t.id) ?? null : null;
1489
1775
  }
1490
- function be(e, t) {
1776
+ function hs(e, t) {
1491
1777
  const { previewUrl: s } = t;
1492
1778
  return s ? { ...e, previewUrl: s } : e;
1493
1779
  }
1494
- function Ce(e, t) {
1780
+ function ps(e, t) {
1495
1781
  if (t.role !== "user")
1496
1782
  return e;
1497
1783
  const s = e.findIndex(
@@ -1502,24 +1788,24 @@ function Ce(e, t) {
1502
1788
  const n = [...e];
1503
1789
  return n.splice(s, 1), n;
1504
1790
  }
1505
- function nt(e) {
1506
- const t = ft(e);
1507
- return t === null ? !1 : e.slice(t + 1).some(mt);
1791
+ function wt(e) {
1792
+ const t = Dt(e);
1793
+ return t === null ? !1 : e.slice(t + 1).some(Nt);
1508
1794
  }
1509
- function Me(e) {
1510
- const t = ft(e);
1795
+ function gs(e) {
1796
+ const t = Dt(e);
1511
1797
  return t === null ? e.some((s) => s.role === "assistant") : e.slice(t + 1).some((s) => s.role === "assistant");
1512
1798
  }
1513
- function ft(e) {
1799
+ function Dt(e) {
1514
1800
  for (let t = e.length - 1; t >= 0; t -= 1)
1515
1801
  if (e[t].role === "user")
1516
1802
  return t;
1517
1803
  return null;
1518
1804
  }
1519
- function mt(e) {
1805
+ function Nt(e) {
1520
1806
  return e.role === "assistant" ? !0 : e.role !== "system" ? !1 : e.dataType === "run_error" ? !0 : e.dataType === "run_status" && e.loading !== !0;
1521
1807
  }
1522
- function yt(e) {
1808
+ function Ot(e) {
1523
1809
  for (let t = e.length - 1; t >= 0; t -= 1) {
1524
1810
  const s = e[t];
1525
1811
  if (!s || typeof s != "object")
@@ -1533,18 +1819,18 @@ function yt(e) {
1533
1819
  }
1534
1820
  return null;
1535
1821
  }
1536
- function De(e, t) {
1537
- const s = yt(t);
1822
+ function fs(e, t) {
1823
+ const s = Ot(t);
1538
1824
  if (s === null)
1539
1825
  return !1;
1540
1826
  const n = t[s], r = n && typeof n == "object" ? n.id : null;
1541
1827
  if (typeof r != "string" || !r)
1542
1828
  return !1;
1543
1829
  const i = e.findIndex((o) => o.role === "user" && o.id === r);
1544
- return i === -1 ? !1 : e.slice(i + 1).some(mt);
1830
+ return i === -1 ? !1 : e.slice(i + 1).some(Nt);
1545
1831
  }
1546
- function Ne(e) {
1547
- const t = yt(e);
1832
+ function ms(e) {
1833
+ const t = Ot(e);
1548
1834
  if (t === null)
1549
1835
  return null;
1550
1836
  const s = e[t];
@@ -1556,22 +1842,22 @@ function Ne(e) {
1556
1842
  const r = n.clientMessageId;
1557
1843
  return typeof r == "string" ? r : null;
1558
1844
  }
1559
- function qe(e) {
1845
+ function ys(e) {
1560
1846
  if (!e || typeof e != "object")
1561
1847
  return !1;
1562
1848
  const t = e;
1563
1849
  return t.type === "message" && t.role === "user" ? !1 : t.type === "message" || t.type === "function_call" || t.type === "function_call_output" || t.type === "run_error" || t.type === "run_status";
1564
1850
  }
1565
- function x(e) {
1566
- return e.filter((t, s) => wt(t) ? !We(e, s) && !Le(e, s) && !He(e, s) : Oe(t) ? !Fe(e, s) : !0);
1851
+ function tt(e) {
1852
+ return e.filter((t, s) => vt(t) ? !Ss(e, s) && !As(e, s) && !Is(e, s) : ws(t) ? !Ts(e, s) : !0);
1567
1853
  }
1568
- function Oe(e) {
1854
+ function ws(e) {
1569
1855
  return e.role === "system" && (e.dataType === "run_status" || e.dataType === "run_error");
1570
1856
  }
1571
- function wt(e) {
1857
+ function vt(e) {
1572
1858
  return e.role === "system" && e.dataType === "run_status" && e.loading === !0;
1573
1859
  }
1574
- function j(e) {
1860
+ function et(e) {
1575
1861
  const t = new Set(e.filter((i) => i.role === "user").map((i) => i.id)), s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Set();
1576
1862
  for (const i of e) {
1577
1863
  if (i.role === "user" || !i.respondsToUserMessageId || !t.has(i.respondsToUserMessageId))
@@ -1587,53 +1873,53 @@ function j(e) {
1587
1873
  n.has(i.id) || (r.push(i), i.role === "user" && r.push(...s.get(i.id) ?? []));
1588
1874
  return r;
1589
1875
  }
1590
- function Fe(e, t) {
1876
+ function Ts(e, t) {
1591
1877
  const s = e[t];
1592
1878
  for (let n = t + 1; n < e.length; n += 1) {
1593
1879
  const r = e[n];
1594
1880
  if (r.role === "user")
1595
1881
  return !1;
1596
- if (r.role === "assistant" && N(s, r))
1882
+ if (r.role === "assistant" && W(s, r))
1597
1883
  return !0;
1598
1884
  }
1599
1885
  return !1;
1600
1886
  }
1601
- function Le(e, t) {
1887
+ function As(e, t) {
1602
1888
  const s = e[t];
1603
1889
  for (let n = t + 1; n < e.length; n += 1)
1604
- if (e[n].role === "assistant" && N(s, e[n]))
1890
+ if (e[n].role === "assistant" && W(s, e[n]))
1605
1891
  return !0;
1606
1892
  return !1;
1607
1893
  }
1608
- function He(e, t) {
1894
+ function Is(e, t) {
1609
1895
  const s = e[t];
1610
1896
  for (let n = t + 1; n < e.length; n += 1)
1611
- if (e[n].role === "tool" && N(s, e[n]))
1897
+ if (e[n].role === "tool" && W(s, e[n]))
1612
1898
  return !0;
1613
1899
  return !1;
1614
1900
  }
1615
- function We(e, t) {
1901
+ function Ss(e, t) {
1616
1902
  const s = e[t];
1617
1903
  for (let n = t + 1; n < e.length; n += 1)
1618
- if (wt(e[n]) && N(s, e[n]))
1904
+ if (vt(e[n]) && W(s, e[n]))
1619
1905
  return !0;
1620
1906
  return !1;
1621
1907
  }
1622
- function N(e, t) {
1908
+ function W(e, t) {
1623
1909
  return !e.runId || !t.runId ? !0 : e.runId === t.runId;
1624
1910
  }
1625
- function A(e, t) {
1911
+ function E(e, t) {
1626
1912
  return e && typeof e == "object" && typeof e[t] == "string" ? e[t] : null;
1627
1913
  }
1628
- function Be(e, t) {
1914
+ function ks(e, t) {
1629
1915
  try {
1630
- const s = window.localStorage.getItem(`${ut}${e}`);
1916
+ const s = window.localStorage.getItem(`${Ct}${e}`);
1631
1917
  if (!s)
1632
1918
  return null;
1633
1919
  const n = JSON.parse(s), r = typeof n.sessionId == "string" ? n.sessionId : null;
1634
1920
  if (t !== void 0 && r !== t)
1635
1921
  return null;
1636
- const i = Array.isArray(n.messages) ? n.messages.map(Ge).filter((o) => !!o) : [];
1922
+ const i = Array.isArray(n.messages) ? n.messages.map(Os).filter((o) => !!o) : [];
1637
1923
  return {
1638
1924
  sessionId: r,
1639
1925
  messages: i
@@ -1642,58 +1928,135 @@ function Be(e, t) {
1642
1928
  return null;
1643
1929
  }
1644
1930
  }
1645
- function ve(e, t) {
1931
+ function Es(e, t) {
1646
1932
  try {
1647
1933
  window.localStorage.setItem(
1648
- `${ut}${e}`,
1934
+ `${Ct}${e}`,
1649
1935
  JSON.stringify({
1650
1936
  sessionId: t.sessionId,
1651
- messages: t.messages.slice(-Xt).map(Xe)
1937
+ messages: t.messages.slice(-Ce).map(vs)
1652
1938
  })
1653
1939
  );
1654
1940
  } catch {
1655
1941
  return;
1656
1942
  }
1657
1943
  }
1658
- function xe(e) {
1944
+ function Rs(e) {
1659
1945
  try {
1660
- const t = window.localStorage.getItem(`${v}${e}`);
1946
+ const t = window.localStorage.getItem(`${Q}${e}`);
1661
1947
  if (!t)
1662
1948
  return [];
1663
1949
  const s = JSON.parse(t);
1664
- return Array.isArray(s) ? s.filter(Tt) : [];
1950
+ return Array.isArray(s) ? s.filter(ot) : [];
1665
1951
  } catch {
1666
1952
  return [];
1667
1953
  }
1668
1954
  }
1669
- function P(e, t) {
1955
+ function M(e, t) {
1670
1956
  try {
1671
- const s = t.filter(Tt);
1957
+ const s = t.filter(ot);
1672
1958
  if (s.length === 0) {
1673
- window.localStorage.removeItem(`${v}${e}`);
1959
+ window.localStorage.removeItem(`${Q}${e}`);
1674
1960
  return;
1675
1961
  }
1676
1962
  window.localStorage.setItem(
1677
- `${v}${e}`,
1963
+ `${Q}${e}`,
1678
1964
  JSON.stringify(s.slice(-25))
1679
1965
  );
1680
1966
  } catch {
1681
1967
  return;
1682
1968
  }
1683
1969
  }
1684
- function Tt(e) {
1970
+ function Lt(e, t) {
1971
+ try {
1972
+ const s = `${F}${e}`, n = location.href, r = location.origin, i = Array.from(t, (o) => ({
1973
+ ...o,
1974
+ storedAt: Date.now(),
1975
+ unloadUrl: n,
1976
+ unloadOrigin: r
1977
+ }));
1978
+ if (i.length === 0) {
1979
+ window.sessionStorage.removeItem(s);
1980
+ return;
1981
+ }
1982
+ window.sessionStorage.setItem(s, JSON.stringify(i));
1983
+ } catch {
1984
+ }
1985
+ }
1986
+ function _s(e, t) {
1987
+ try {
1988
+ if (window.sessionStorage.getItem(`${F}${e}`) === null)
1989
+ return;
1990
+ } catch {
1991
+ return;
1992
+ }
1993
+ Lt(e, t);
1994
+ }
1995
+ function Cs(e) {
1996
+ try {
1997
+ const t = `${F}${e}`, s = window.sessionStorage.getItem(t);
1998
+ if (window.sessionStorage.removeItem(t), !s)
1999
+ return [];
2000
+ const n = JSON.parse(s);
2001
+ return Array.isArray(n) ? n.flatMap((r) => Ps(r) ? [{
2002
+ ...r.event,
2003
+ rawOutput: {
2004
+ ok: !0,
2005
+ result: {
2006
+ navigated: !0,
2007
+ url: location.href,
2008
+ title: document.title
2009
+ },
2010
+ console: [],
2011
+ metadata: {
2012
+ durationMs: Math.max(0, Date.now() - r.startedAtMs),
2013
+ url: location.href,
2014
+ origin: location.origin,
2015
+ previousUrl: r.startedAtUrl,
2016
+ unloadUrl: r.unloadUrl,
2017
+ recoveredAfterNavigation: !0
2018
+ }
2019
+ }
2020
+ }] : []) : [];
2021
+ } catch {
2022
+ return [];
2023
+ }
2024
+ }
2025
+ function Ps(e) {
2026
+ if (!e || typeof e != "object")
2027
+ return !1;
2028
+ const t = e, s = t.event;
2029
+ return typeof t.startedAtMs == "number" && typeof t.startedAtUrl == "string" && t.startedAtOrigin === location.origin && t.unloadOrigin === location.origin && typeof t.unloadUrl == "string" && ot(s) && s.type === "tool.result";
2030
+ }
2031
+ function bs(e, t) {
2032
+ const s = new Set(
2033
+ e.flatMap((n) => n.type === "tool.result" ? [n.callId] : [])
2034
+ );
2035
+ return [
2036
+ ...e,
2037
+ ...t.filter((n) => !s.has(n.callId))
2038
+ ];
2039
+ }
2040
+ function Us(e) {
2041
+ try {
2042
+ window.sessionStorage.removeItem(`${F}${e}`);
2043
+ } catch {
2044
+ return;
2045
+ }
2046
+ }
2047
+ function ot(e) {
1685
2048
  if (!e || typeof e != "object")
1686
2049
  return !1;
1687
2050
  const t = e;
1688
- return t.type === "chat.user_message" ? typeof t.content == "string" && rt(t.page) : t.type === "page.upsert" || t.type === "session.reset" || t.type === "network.batch" ? rt(t.page) : t.type === "tool.result" ? typeof t.sessionId == "string" && typeof t.callId == "string" && t.toolName === "execute_code" : t.type === "chat.retry_last_user_message" ? typeof t.sessionId == "string" && typeof t.clientMessageId == "string" : t.type === "run.stop" ? typeof t.sessionId == "string" : !1;
2051
+ return t.type === "chat.user_message" ? typeof t.content == "string" && Tt(t.page) : t.type === "page.upsert" || t.type === "session.reset" || t.type === "network.batch" ? Tt(t.page) : t.type === "tool.result" ? typeof t.sessionId == "string" && typeof t.callId == "string" && t.toolName === "execute_code" : t.type === "chat.retry_last_user_message" ? typeof t.sessionId == "string" && typeof t.clientMessageId == "string" : t.type === "run.stop" ? typeof t.sessionId == "string" : !1;
1689
2052
  }
1690
- function rt(e) {
2053
+ function Tt(e) {
1691
2054
  if (!e || typeof e != "object")
1692
2055
  return !1;
1693
2056
  const t = e;
1694
2057
  return typeof t.url == "string" && typeof t.title == "string" && typeof t.origin == "string";
1695
2058
  }
1696
- function At(e, t) {
2059
+ function qt(e, t) {
1697
2060
  if (!Array.isArray(e))
1698
2061
  return;
1699
2062
  const s = e.filter((r) => {
@@ -1701,24 +2064,24 @@ function At(e, t) {
1701
2064
  return !1;
1702
2065
  const i = r;
1703
2066
  return typeof i.name == "string" && typeof i.mimeType == "string" && typeof i.sizeBytes == "number";
1704
- }), n = t ? s.map((r) => It(r, t)) : s;
2067
+ }), n = t ? s.map((r) => Bt(r, t)) : s;
1705
2068
  return n.length > 0 ? n : void 0;
1706
2069
  }
1707
- function It(e, t) {
2070
+ function Bt(e, t) {
1708
2071
  return e.fileUrl?.startsWith("/") ? {
1709
2072
  ...e,
1710
2073
  fileUrl: new URL(e.fileUrl, t).toString()
1711
2074
  } : e;
1712
2075
  }
1713
- function je(e) {
1714
- if ($e(e))
2076
+ function Ms(e) {
2077
+ if (Ds(e))
1715
2078
  return {
1716
2079
  headers: {
1717
2080
  "ngrok-skip-browser-warning": "true"
1718
2081
  }
1719
2082
  };
1720
2083
  }
1721
- function $e(e) {
2084
+ function Ds(e) {
1722
2085
  try {
1723
2086
  const t = new URL(e).hostname;
1724
2087
  return t.endsWith(".ngrok-free.dev") || t.endsWith(".ngrok-free.app") || t.endsWith(".ngrok.app") || t.endsWith(".ngrok.io");
@@ -1726,14 +2089,14 @@ function $e(e) {
1726
2089
  return !1;
1727
2090
  }
1728
2091
  }
1729
- function it(e) {
1730
- return e.type || ze(e.name) || "application/octet-stream";
2092
+ function At(e) {
2093
+ return e.type || Ns(e.name) || "application/octet-stream";
1731
2094
  }
1732
- function ze(e) {
2095
+ function Ns(e) {
1733
2096
  const t = e.toLowerCase();
1734
2097
  return t.endsWith(".png") ? "image/png" : t.endsWith(".jpg") || t.endsWith(".jpeg") ? "image/jpeg" : t.endsWith(".webp") ? "image/webp" : t.endsWith(".gif") ? "image/gif" : t.endsWith(".pdf") ? "application/pdf" : null;
1735
2098
  }
1736
- function Ge(e) {
2099
+ function Os(e) {
1737
2100
  if (!e || typeof e != "object")
1738
2101
  return null;
1739
2102
  const t = e;
@@ -1745,17 +2108,17 @@ function Ge(e) {
1745
2108
  respondsToUserMessageId: typeof t.respondsToUserMessageId == "string" ? t.respondsToUserMessageId : void 0,
1746
2109
  ...typeof t.runId == "string" ? { runId: t.runId } : {},
1747
2110
  dataType: typeof t.dataType == "string" ? t.dataType : void 0,
1748
- attachments: At(t.attachments)?.map(G),
2111
+ attachments: qt(t.attachments)?.map(at),
1749
2112
  loading: typeof t.loading == "boolean" ? t.loading : void 0
1750
2113
  };
1751
2114
  }
1752
- function Xe(e) {
2115
+ function vs(e) {
1753
2116
  return e.attachments?.length ? {
1754
2117
  ...e,
1755
- attachments: e.attachments.map(G)
2118
+ attachments: e.attachments.map(at)
1756
2119
  } : e;
1757
2120
  }
1758
- function G(e) {
2121
+ function at(e) {
1759
2122
  const {
1760
2123
  dataUrl: t,
1761
2124
  objectUrl: s,
@@ -1764,166 +2127,248 @@ function G(e) {
1764
2127
  } = e;
1765
2128
  return r;
1766
2129
  }
1767
- function L(e) {
2130
+ function K(e) {
1768
2131
  const t = e.respondsToUserMessageId;
1769
2132
  return typeof t == "string" && t ? t : null;
1770
2133
  }
1771
- function k(e) {
2134
+ function C(e) {
1772
2135
  const t = e.runId;
1773
2136
  return typeof t == "string" && t ? t : null;
1774
2137
  }
1775
- function Ke(e) {
2138
+ function Ls(e) {
1776
2139
  return !!e && typeof e == "object" && typeof e.summary == "string" && typeof e.javascript == "string";
1777
2140
  }
1778
- function ot(e) {
2141
+ function Ht(e) {
1779
2142
  const t = {};
1780
- return e?.forEach((s, n) => {
1781
- t[n] = s;
1782
- }), t;
1783
- }
1784
- async function Je(e, t) {
1785
- if (typeof t?.body < "u")
1786
- return St(t.body);
1787
- if (e)
2143
+ try {
2144
+ new Headers(e).forEach((s, n) => {
2145
+ Object.keys(t).length < it && (t[n] = ct(n, s));
2146
+ });
2147
+ } catch {
2148
+ return {};
2149
+ }
2150
+ return t;
2151
+ }
2152
+ function ct(e, t) {
2153
+ return zt(e) ? x : S(B(t), ke);
2154
+ }
2155
+ function qs(e, t) {
2156
+ return typeof e == "string" ? e : e instanceof URL ? e.toString() : t?.url ?? "";
2157
+ }
2158
+ async function Bs(e, t, s, n) {
2159
+ const r = Ht(e.headers);
2160
+ n({
2161
+ ...t,
2162
+ responseStatus: e.status,
2163
+ responseHeaders: r,
2164
+ responseBody: await Hs(e),
2165
+ durationMs: Date.now() - s
2166
+ });
2167
+ }
2168
+ async function Hs(e) {
2169
+ if (!Ft(e.headers))
2170
+ return;
2171
+ let t = null, s = null;
2172
+ try {
2173
+ if (t = e.clone().body?.getReader() ?? null, !t)
2174
+ return;
2175
+ const n = new Promise((d) => {
2176
+ s = window.setTimeout(() => {
2177
+ t?.cancel(), d("timeout");
2178
+ }, Ee);
2179
+ }), r = new TextDecoder();
2180
+ let i = "", o = 0;
2181
+ for (; ; ) {
2182
+ const d = await Promise.race([t.read(), n]);
2183
+ if (d === "timeout")
2184
+ return;
2185
+ const { done: a, value: h } = d;
2186
+ if (a)
2187
+ return S(i + r.decode());
2188
+ const g = rt - o;
2189
+ if (h.byteLength > g)
2190
+ return i += r.decode(h.subarray(0, Math.max(g, 0)), { stream: !0 }), t.cancel(), `${S(i)}... [truncated]`;
2191
+ o += h.byteLength, i += r.decode(h, { stream: !0 });
2192
+ }
2193
+ } catch {
2194
+ t?.cancel();
2195
+ return;
2196
+ } finally {
2197
+ s !== null && window.clearTimeout(s);
2198
+ }
2199
+ }
2200
+ function Fs(e, t) {
2201
+ if (Ft(new Headers(t)))
1788
2202
  try {
1789
- return I(await e.clone().text());
2203
+ return e.responseType === "" || e.responseType === "text" ? S(e.responseText ?? "") : void 0;
1790
2204
  } catch {
1791
2205
  return;
1792
2206
  }
1793
2207
  }
1794
- async function Ve(e) {
2208
+ function It(e) {
2209
+ if (typeof e == "string")
2210
+ return S(e);
2211
+ }
2212
+ function Ws(e) {
2213
+ return A({
2214
+ ...e,
2215
+ requestBody: St(e.requestBody),
2216
+ responseBody: St(e.responseBody)
2217
+ });
2218
+ }
2219
+ function St(e) {
2220
+ if (typeof e != "string")
2221
+ return e;
2222
+ const t = e.trim();
2223
+ if (!t.startsWith("{") && !t.startsWith("["))
2224
+ return B(e);
1795
2225
  try {
1796
- return I(await e.clone().text());
1797
- } catch (t) {
1798
- return { error: t instanceof Error ? t.message : "unavailable" };
2226
+ return JSON.stringify(A(JSON.parse(e)));
2227
+ } catch {
2228
+ return B(e);
1799
2229
  }
1800
2230
  }
1801
- function Ye(e) {
2231
+ function Ft(e) {
2232
+ if (!e)
2233
+ return !1;
2234
+ const t = e.get("content-type")?.toLowerCase() ?? "", s = e.get("content-length"), n = Number(s);
2235
+ return s !== null && Number.isInteger(n) && n >= 0 && n <= rt && (t.startsWith("text/") || t.includes("json") || t.includes("javascript"));
2236
+ }
2237
+ function P(e, t = {}, s) {
2238
+ if (js(s))
2239
+ return !0;
2240
+ const n = Object.entries(t).find(([r]) => r.toLowerCase() === "content-type")?.[1]?.toLowerCase();
2241
+ if (n?.includes("multipart/form-data") || n?.includes("application/octet-stream"))
2242
+ return !0;
1802
2243
  try {
1803
- return e.responseType === "" || e.responseType === "text" ? I(e.responseText ?? "") : e.responseType === "json" ? I(JSON.stringify(e.response)) : `[unsupported xhr responseType: ${e.responseType || "unknown"}]`;
1804
- } catch (t) {
1805
- return { error: t instanceof Error ? t.message : "unavailable" };
2244
+ const r = new URL(e, location.href);
2245
+ if (r.protocol !== "http:" && r.protocol !== "https:")
2246
+ return !0;
2247
+ const i = r.hostname.toLowerCase(), o = r.pathname.toLowerCase();
2248
+ return i === "pluno.ai" || i.endsWith(".pluno.ai") || o === "/api/product-agent" || o.startsWith("/api/product-agent/") || /(^|\/)(auth|oauth|login|logout)(\/|$)/.test(o) || /(^|\/)[^/]*token[^/]*(\/|$)/.test(o) || /(^|\/)(upload|uploads|attachments)(\/|$)/.test(o) || [...r.searchParams.keys()].some((d) => /^(x-amz-signature|x-goog-signature|signature|sig)$/i.test(d));
2249
+ } catch {
2250
+ return !0;
1806
2251
  }
1807
2252
  }
1808
- function St(e) {
1809
- if (!(e === null || typeof e > "u")) {
1810
- if (typeof e == "string")
1811
- return I(e);
1812
- if (e instanceof URLSearchParams)
1813
- return I(e.toString());
1814
- if (e instanceof FormData) {
1815
- const t = [];
1816
- return e.forEach((s, n) => t.push([n, s instanceof File ? `[file:${s.name}]` : String(s)])), I(JSON.stringify(t));
1817
- }
1818
- if (e instanceof Blob)
1819
- return `[blob:${e.type || "application/octet-stream"}:${e.size}]`;
1820
- try {
1821
- return I(JSON.stringify(e));
1822
- } catch {
1823
- return `[unserializable body: ${Object.prototype.toString.call(e)}]`;
1824
- }
2253
+ function xs(e, t) {
2254
+ if (P(e))
2255
+ return !0;
2256
+ try {
2257
+ const s = new URL(e, location.href), n = new URL(t);
2258
+ return s.origin === n.origin && s.pathname.startsWith("/api/product-agent/");
2259
+ } catch {
2260
+ return !0;
1825
2261
  }
1826
2262
  }
1827
- function Ze(e) {
2263
+ function js(e) {
2264
+ return e instanceof FormData || e instanceof Blob || e instanceof ArrayBuffer || ArrayBuffer.isView(e) || typeof ReadableStream < "u" && e instanceof ReadableStream;
2265
+ }
2266
+ function $s(e) {
1828
2267
  const t = {};
1829
2268
  for (const s of e.trim().split(/[\r\n]+/)) {
1830
2269
  const n = s.indexOf(":");
1831
- n <= 0 || (t[s.slice(0, n).trim()] = s.slice(n + 1).trim());
2270
+ if (n <= 0)
2271
+ continue;
2272
+ if (Object.keys(t).length >= it)
2273
+ break;
2274
+ const r = s.slice(0, n).trim();
2275
+ t[r] = ct(r, s.slice(n + 1).trim());
1832
2276
  }
1833
2277
  return t;
1834
2278
  }
1835
- function I(e) {
1836
- return e.length <= F ? e : `${e.slice(0, F)}... [truncated ${e.length - F} chars]`;
2279
+ function S(e, t = rt) {
2280
+ return e.length <= t ? e : `${e.slice(0, t)}... [truncated ${e.length - t} chars]`;
1837
2281
  }
1838
- function U(e) {
2282
+ function J(e) {
1839
2283
  return `${e}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
1840
2284
  }
1841
- class C extends Error {
2285
+ class L extends Error {
1842
2286
  constructor(t, s) {
1843
2287
  super(`${t} (${s})`), this.status = s, this.name = "AttachmentUploadHttpError";
1844
2288
  }
1845
2289
  status;
1846
2290
  }
1847
- async function H(e, t) {
2291
+ async function V(e, t) {
1848
2292
  let s = null;
1849
- for (let n = 0; n < Y; n += 1)
2293
+ for (let n = 0; n < pt; n += 1)
1850
2294
  try {
1851
2295
  return await e();
1852
2296
  } catch (r) {
1853
- if (s = r, n >= Y - 1 || !ts(r))
2297
+ if (s = r, n >= pt - 1 || !Gs(r))
1854
2298
  throw r;
1855
- await Qe(n);
2299
+ await zs(n);
1856
2300
  }
1857
2301
  throw s instanceof Error ? s : new Error(t);
1858
2302
  }
1859
- function Qe(e) {
2303
+ function zs(e) {
1860
2304
  return new Promise((t) => {
1861
- window.setTimeout(t, $t[e] ?? 0);
2305
+ window.setTimeout(t, Se[e] ?? 0);
1862
2306
  });
1863
2307
  }
1864
- function ts(e) {
1865
- return e instanceof C ? es(e.status) : e instanceof TypeError;
2308
+ function Gs(e) {
2309
+ return e instanceof L ? Xs(e.status) : e instanceof TypeError;
1866
2310
  }
1867
- function es(e) {
2311
+ function Xs(e) {
1868
2312
  return e === 408 || e === 409 || e === 429 || e >= 500;
1869
2313
  }
1870
- function ss(e) {
2314
+ function Ks(e) {
1871
2315
  return e === 401 || e === 403;
1872
2316
  }
1873
- const X = "[REDACTED_SECRET]", w = "[REDACTED_TOKEN]", ns = "[REDACTED_SIGNED_URL]", rs = 20, is = /^(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, kt = /\bBearer\s+[A-Za-z0-9._~+/=-]{12,}/gi, Et = /\bBasic\s+[A-Za-z0-9+/=-]{12,}/gi, Rt = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, _t = /\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, os = /\bhttps?:\/\/[^\s"'<>]+(?:X-Amz-Signature|X-Goog-Signature|Signature|sig=)[^\s"'<>]*/gi, as = /\bhttps?:\/\/[^\s"'<>]+/gi, cs = /[),.;\]]+$/;
1874
- function T(e) {
1875
- return M(e, 0, /* @__PURE__ */ new WeakSet());
2317
+ const x = "[REDACTED_SECRET]", k = "[REDACTED_TOKEN]", Js = "[REDACTED_SIGNED_URL]", Vs = 20, Ys = /^(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, Wt = /\bBearer\s+[A-Za-z0-9._~+/=-]{12,}/gi, xt = /\bBasic\s+[A-Za-z0-9+/=-]{12,}/gi, jt = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, $t = /\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, Zs = /\bhttps?:\/\/[^\s"'<>]+(?:X-Amz-Signature|X-Goog-Signature|Signature|sig=)[^\s"'<>]*/gi, Qs = /\bhttps?:\/\/[^\s"'<>]+/gi, tn = /[),.;\]]+$/;
2318
+ function A(e) {
2319
+ return q(e, 0, /* @__PURE__ */ new WeakSet());
1876
2320
  }
1877
- function M(e, t, s) {
2321
+ function q(e, t, s) {
1878
2322
  if (typeof e == "string")
1879
- return e.startsWith("data:image/") || e.startsWith("data:application/pdf;") ? e : ds(e);
2323
+ return e.startsWith("data:image/") || e.startsWith("data:application/pdf;") ? e : B(e);
1880
2324
  if (e === null || typeof e != "object")
1881
2325
  return e;
1882
- if (t >= rs)
2326
+ if (t >= Vs)
1883
2327
  return "[REDACTED_MAX_DEPTH]";
1884
2328
  if (s.has(e))
1885
2329
  return "[REDACTED_CIRCULAR]";
1886
2330
  if (s.add(e), Array.isArray(e))
1887
- return e.map((r) => M(r, t + 1, s));
2331
+ return e.map((r) => q(r, t + 1, s));
1888
2332
  const n = {};
1889
2333
  for (const [r, i] of Object.entries(e))
1890
- ls(r) ? n[r] = X : n[r] = r.toLowerCase() === "url" ? us(i) : M(i, t + 1, s);
2334
+ zt(r) ? n[r] = x : n[r] = r.toLowerCase() === "url" ? en(i) : q(i, t + 1, s);
1891
2335
  return n;
1892
2336
  }
1893
- function ls(e) {
2337
+ function zt(e) {
1894
2338
  const t = e.replace(/[^a-z0-9]/gi, "").toLowerCase();
1895
2339
  return t.includes("authorization") || t.includes("cookie") || t.includes("password") || t.includes("passwd") || t === "pwd" || t.includes("secret") || t === "token" || t.endsWith("token") || t.includes("apikey") || t.includes("csrf") || t.includes("xsrf") || t === "jwt" || t === "session" || t === "signature" || t.includes("privatekey");
1896
2340
  }
1897
- function us(e) {
1898
- return typeof e == "string" ? Pt(e) : M(e, 0, /* @__PURE__ */ new WeakSet());
2341
+ function en(e) {
2342
+ return typeof e == "string" ? Gt(e) : q(e, 0, /* @__PURE__ */ new WeakSet());
1899
2343
  }
1900
- function Pt(e) {
2344
+ function Gt(e) {
1901
2345
  try {
1902
2346
  const t = new URL(e, location.href);
1903
2347
  for (const s of Array.from(t.searchParams.keys()))
1904
- is.test(s) && t.searchParams.set(s, w);
1905
- return t.username && (t.username = w), t.password && (t.password = w), t.toString();
2348
+ Ys.test(s) && t.searchParams.set(s, k);
2349
+ return t.username && (t.username = k), t.password && (t.password = k), t.toString();
1906
2350
  } catch {
1907
- return hs(e);
2351
+ return sn(e);
1908
2352
  }
1909
2353
  }
1910
- function ds(e) {
1911
- return e.replace(os, ns).replace(as, ps).replace(kt, `Bearer ${w}`).replace(Et, `Basic ${w}`).replace(Rt, w).replace(_t, (t, s) => `${s}: ${X}`);
2354
+ function B(e) {
2355
+ return e.replace(Zs, Js).replace(Qs, nn).replace(Wt, `Bearer ${k}`).replace(xt, `Basic ${k}`).replace(jt, k).replace($t, (t, s) => `${s}: ${x}`);
1912
2356
  }
1913
- function hs(e) {
1914
- return e.replace(kt, `Bearer ${w}`).replace(Et, `Basic ${w}`).replace(Rt, w).replace(_t, (t, s) => `${s}: ${X}`);
2357
+ function sn(e) {
2358
+ return e.replace(Wt, `Bearer ${k}`).replace(xt, `Basic ${k}`).replace(jt, k).replace($t, (t, s) => `${s}: ${x}`);
1915
2359
  }
1916
- function ps(e) {
1917
- const t = e.match(cs)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
1918
- return `${Pt(s)}${t}`;
2360
+ function nn(e) {
2361
+ const t = e.match(tn)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
2362
+ return `${Gt(s)}${t}`;
1919
2363
  }
1920
2364
  export {
1921
- J as PLUNO_PRODUCT_AGENT_SDK_PREVIEW_HOST_SELECTOR,
1922
- B as PLUNO_PRODUCT_AGENT_WIDGET_HOST_SELECTOR,
1923
- Dt as PLUNO_PRODUCT_AGENT_WIDGET_PANEL_SELECTOR,
1924
- Mt as PLUNO_PRODUCT_AGENT_WIDGET_ROOT_SELECTOR,
1925
- Nt as PLUNO_PRODUCT_AGENT_WIDGET_TIMELINE_SELECTOR,
1926
- dt as PlunoProductAgent,
1927
- dt as default,
1928
- ne as getProductAgentOriginAccessErrorMessage
2365
+ lt as PLUNO_PRODUCT_AGENT_SDK_PREVIEW_HOST_SELECTOR,
2366
+ Z as PLUNO_PRODUCT_AGENT_WIDGET_HOST_SELECTOR,
2367
+ ie as PLUNO_PRODUCT_AGENT_WIDGET_PANEL_SELECTOR,
2368
+ re as PLUNO_PRODUCT_AGENT_WIDGET_ROOT_SELECTOR,
2369
+ oe as PLUNO_PRODUCT_AGENT_WIDGET_TIMELINE_SELECTOR,
2370
+ Pt as PlunoProductAgent,
2371
+ be as calculateReconnectDelay,
2372
+ Pt as default,
2373
+ We as getProductAgentOriginAccessErrorMessage
1929
2374
  };