@pluno/product-agent-web 0.1.66 → 0.1.68

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) {
@@ -408,7 +559,7 @@ class dt {
408
559
  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({
409
560
  type: "session.reset",
410
561
  sessionId: this.state.sessionId ?? void 0,
411
- page: y()
562
+ page: I()
412
563
  }), this.setState({
413
564
  sessionId: null,
414
565
  starterPrompts: [...this.state.starterPrompts],
@@ -421,15 +572,15 @@ class dt {
421
572
  });
422
573
  }
423
574
  listSessions(t = {}) {
424
- const s = _(), n = new Promise((i, o) => {
425
- const c = window.setTimeout(() => {
575
+ const s = N(), n = new Promise((i, o) => {
576
+ const d = window.setTimeout(() => {
426
577
  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 });
578
+ }, Ae);
579
+ this.pendingSessionHistoryRequests.set(s, { resolve: i, reject: o, timeout: d });
429
580
  }), r = {
430
581
  type: "sessions.list",
431
582
  requestId: s,
432
- page: y(),
583
+ page: I(),
433
584
  ...t.cursor ? { cursor: t.cursor } : {},
434
585
  ...t.limit ? { limit: t.limit } : {}
435
586
  };
@@ -451,11 +602,11 @@ class dt {
451
602
  }), this.send({
452
603
  type: "session.load",
453
604
  sessionId: t,
454
- page: y()
605
+ page: I()
455
606
  });
456
607
  }
457
608
  send(t) {
458
- this.sendNow(T(t)) || (this.queuedClientEvents.push(t), P(this.options.clientId, this.queuedClientEvents), this.setState({ status: "reconnecting" }), this.scheduleReconnect());
609
+ this.sendNow(A(t)) || (this.queuedClientEvents.push(t), M(this.options.clientId, this.queuedClientEvents), this.setState({ status: "reconnecting" }), this.scheduleReconnect());
459
610
  }
460
611
  async getUploadToken() {
461
612
  const t = this.options.token ?? await this.options.tokenProvider?.() ?? this.token ?? null;
@@ -470,20 +621,20 @@ class dt {
470
621
  try {
471
622
  return s.send(JSON.stringify(t)), !0;
472
623
  } catch (n) {
473
- return g("web-sdk.agent", "Pluno socket send failed; scheduling reconnect", {
624
+ return f("web-sdk.agent", "Pluno socket send failed; scheduling reconnect", {
474
625
  message: n instanceof Error ? n.message : String(n),
475
626
  queuedClientEventCount: this.queuedClientEvents.length,
476
627
  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;
628
+ }), 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
629
  }
479
630
  }
480
631
  requestTransientStarterPrompts() {
481
632
  if (this.state.starterPromptsLoading || this.transientStarterPromptsRequestInFlight || this.transientStarterPromptsRequestAttempted)
482
633
  return;
483
634
  this.transientStarterPromptsRequestInFlight = !0, this.transientStarterPromptsRequestAttempted = !0, this.setState({ starterPromptsLoading: !0 });
484
- const t = ie();
635
+ const t = je();
485
636
  this.sendNow(
486
- T({
637
+ A({
487
638
  type: "starter_prompts.page_context",
488
639
  pageUrl: t.pageUrl,
489
640
  pageTitle: t.pageTitle,
@@ -492,13 +643,13 @@ class dt {
492
643
  ) || (this.transientStarterPromptsRequestInFlight = !1, this.transientStarterPromptsRequestAttempted = !1, this.setState({ starterPromptsLoading: !1 }));
493
644
  }
494
645
  startStarterPromptUrlWatcher() {
495
- this.locationChangeCleanup || (this.locationChangeCleanup = oe(() => this.handleStarterPromptUrlChange()));
646
+ this.locationChangeCleanup || (this.locationChangeCleanup = $e(() => this.handleStarterPromptUrlChange()));
496
647
  }
497
648
  handleStarterPromptUrlChange() {
498
649
  const t = location.href;
499
650
  t !== this.lastStarterPromptPageUrl && (this.lastStarterPromptPageUrl = t, this.clearStarterPromptUrlRefreshTimer(), this.starterPromptUrlRefreshTimer = window.setTimeout(() => {
500
651
  this.starterPromptUrlRefreshTimer = null, this.refreshStarterPromptsForCurrentUrl();
501
- }, Kt));
652
+ }, Pe));
502
653
  }
503
654
  refreshStarterPromptsForCurrentUrl() {
504
655
  this.socket?.readyState !== WebSocket.OPEN || this.state.status === "closed" || (this.setState({ starterPromptsLoading: this.state.messages.length === 0 }), this.sendNow({
@@ -513,14 +664,14 @@ class dt {
513
664
  if (this.socket?.readyState !== WebSocket.OPEN || this.queuedClientEvents.length === 0)
514
665
  return;
515
666
  const t = this.queuedClientEvents.splice(0, this.queuedClientEvents.length);
516
- P(this.options.clientId, this.queuedClientEvents);
667
+ M(this.options.clientId, this.queuedClientEvents);
517
668
  for (let s = 0; s < t.length; s += 1) {
518
669
  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);
670
+ if (!this.sendNow(A(n))) {
671
+ this.queuedClientEvents.unshift(n, ...t.slice(s + 1)), M(this.options.clientId, this.queuedClientEvents);
521
672
  return;
522
673
  }
523
- P(this.options.clientId, this.queuedClientEvents);
674
+ M(this.options.clientId, this.queuedClientEvents);
524
675
  }
525
676
  }
526
677
  handleServerEvent(t) {
@@ -528,42 +679,47 @@ class dt {
528
679
  this.handleRunAck(t);
529
680
  return;
530
681
  }
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", {
682
+ if (t.type === "runtime.pong") {
683
+ this.clearHeartbeatAckTimer();
684
+ return;
685
+ }
686
+ if (Ne(t) && this.markThinkingProgress(), t.type === "auth.ok") {
687
+ this.clearSocketAuthTimer(), this.reconnectAttempts = 0, this.flushQueuedClientEvents(), this.startHeartbeat();
688
+ const s = Ve(t), n = Object.prototype.hasOwnProperty.call(t, "appearance");
689
+ f("web-sdk.agent", "Received auth.ok appearance", {
534
690
  hasAppearance: n,
535
691
  rawAppearance: t.appearance,
536
692
  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),
693
+ }), this.runtimeHelperJavascript = Ye(t.runtimeHelpers)?.javascript ?? null;
694
+ const r = yt(t, "starterPrompts"), i = Object.prototype.hasOwnProperty.call(t, "starterPrompts"), o = t.starterPromptsLoading === !0, d = {
695
+ user: es(t.user),
540
696
  status: "connected"
541
697
  };
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({
698
+ (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
699
  type: "page.upsert",
544
700
  sessionId: this.state.sessionId,
545
- page: y(),
701
+ page: I(),
546
702
  model: this.options.model
547
703
  });
548
704
  return;
549
705
  }
550
706
  if (t.type === "starterPrompts.updated") {
551
707
  this.transientStarterPromptsRequestInFlight = !1, this.transientStarterPromptsRequestAttempted = !0, this.setState({
552
- starterPrompts: st(t, "starterPrompts"),
708
+ starterPrompts: yt(t, "starterPrompts"),
553
709
  starterPromptsLoading: !1
554
710
  });
555
711
  return;
556
712
  }
557
713
  if (t.type === "conversation.state") {
558
- const s = Array.isArray(t.items) ? t.items : [], n = Pe(
714
+ const s = Array.isArray(t.items) ? t.items : [], n = us(
559
715
  this.state.messages,
560
- Te(s, this.options.backendUrl)
561
- ), r = nt(n);
562
- if (!r && De(this.state.messages, s))
716
+ ss(s, this.options.backendUrl)
717
+ ), r = wt(n);
718
+ if (!r && fs(this.state.messages, s))
563
719
  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,
720
+ const i = r ? null : ms(s);
721
+ this.latestRecoverableClientMessageId = i, gs(n) && this.clearRetryTimers(), this.setState({
722
+ sessionId: E(t.session, "id") ?? this.state.sessionId,
567
723
  messages: n,
568
724
  ...r ? { assistantDraft: "", assistantDraftRespondsToUserMessageId: null, assistantDraftRunId: null, isThinking: !1 } : i ? {
569
725
  assistantDraft: "",
@@ -578,22 +734,22 @@ class dt {
578
734
  if (t.type === "sessions.page") {
579
735
  const s = typeof t.requestId == "string" ? t.requestId : null, n = s ? this.pendingSessionHistoryRequests.get(s) : null;
580
736
  s && n && (window.clearTimeout(n.timeout), this.pendingSessionHistoryRequests.delete(s), n.resolve({
581
- sessions: Ae(t.sessions),
737
+ sessions: ns(t.sessions),
582
738
  nextCursor: typeof t.nextCursor == "string" ? t.nextCursor : null
583
739
  }));
584
740
  return;
585
741
  }
586
742
  if (t.type === "session.updated") {
587
- this.clearRunAckResyncRetryTimer(), this.setState({ sessionId: A(t.session, "id") ?? this.state.sessionId });
743
+ this.clearRunAckResyncRetryTimer(), this.setState({ sessionId: E(t.session, "id") ?? this.state.sessionId });
588
744
  return;
589
745
  }
590
746
  if (t.type === "session.item") {
591
- const s = pt(t.item, this.options.backendUrl);
747
+ const s = Ut(t.item, this.options.backendUrl);
592
748
  if (s) {
593
749
  s.role === "assistant" && (this.clearRetryTimers(), this.clearRunAckResyncRetryTimer());
594
750
  const n = t.item.data;
595
- qe(n) && this.clearRunAckResyncRetryTimer();
596
- const r = _e(this.state.messages, s), i = nt(r);
751
+ ys(n) && this.clearRunAckResyncRetryTimer();
752
+ const r = ls(this.state.messages, s), i = wt(r);
597
753
  this.setState({
598
754
  messages: r,
599
755
  assistantDraft: s.role === "assistant" ? "" : this.state.assistantDraft,
@@ -638,7 +794,7 @@ class dt {
638
794
  }
639
795
  if (this.retryAfterRetryableError(t))
640
796
  return;
641
- const r = new Error(typeof t.message == "string" ? t.message.replace(/Product Agent/g, "Pluno") : "Pluno error"), i = ne(r.message);
797
+ const r = new Error(typeof t.message == "string" ? t.message.replace(/Product Agent/g, "Pluno") : "Pluno error"), i = We(r.message);
642
798
  i && console.error(i), this.setState({
643
799
  status: "error",
644
800
  isThinking: !1,
@@ -675,7 +831,7 @@ class dt {
675
831
  this.pendingSessionHistoryRequests.clear();
676
832
  }
677
833
  markThinkingProgress() {
678
- !this.state.isThinking || this.state.status === "closed" || (this.scheduleThinkingWatchdog(E), this.activeClientMessageId && this.scheduleRunAckWatchdog(this.activeClientMessageId));
834
+ !this.state.isThinking || this.state.status === "closed" || (this.scheduleThinkingWatchdog(U), this.activeClientMessageId && this.scheduleRunAckWatchdog(this.activeClientMessageId));
679
835
  }
680
836
  scheduleThinkingWatchdog(t) {
681
837
  this.thinkingWatchdogTimer !== null && window.clearTimeout(this.thinkingWatchdogTimer), this.thinkingWatchdogTimer = window.setTimeout(() => {
@@ -692,29 +848,29 @@ class dt {
692
848
  scheduleRunAckWatchdog(t) {
693
849
  this.runAckWatchdogTimer !== null && window.clearTimeout(this.runAckWatchdogTimer), this.runAckWatchdogTimer = window.setTimeout(() => {
694
850
  this.runAckWatchdogTimer = null, this.recoverMissedRunAck(t);
695
- }, Wt);
851
+ }, me);
696
852
  }
697
853
  recoverMissedRunAck(t) {
698
- !this.state.isThinking || this.state.status === "closed" || this.activeClientMessageId !== t || (g("web-sdk.agent", "Pluno run ack missed; resyncing session", {
854
+ !this.state.isThinking || this.state.status === "closed" || this.activeClientMessageId !== t || (f("web-sdk.agent", "Pluno run ack missed; resyncing session", {
699
855
  sessionId: this.state.sessionId,
700
856
  clientMessageId: t
701
857
  }), this.resyncThinkingSession(), this.scheduleRunAckResyncRetry(t));
702
858
  }
703
859
  scheduleRunAckResyncRetry(t) {
704
860
  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({
861
+ 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
862
  status: this.state.status === "reconnecting" ? "reconnecting" : "connected",
707
863
  isThinking: !0,
708
864
  lastError: null
709
- }), g("web-sdk.agent", "Pluno run ack recovery retrying last user message", {
865
+ }), f("web-sdk.agent", "Pluno run ack recovery retrying last user message", {
710
866
  sessionId: this.state.sessionId,
711
867
  clientMessageId: t
712
868
  }), this.state.sessionId ? this.send({
713
869
  type: "chat.retry_last_user_message",
714
870
  sessionId: this.state.sessionId,
715
871
  clientMessageId: t
716
- }) : this.activeUserMessageEvent && this.send(this.activeUserMessageEvent), this.scheduleThinkingWatchdog(E)));
717
- }, Bt);
872
+ }) : this.activeUserMessageEvent && this.send(this.activeUserMessageEvent), this.scheduleThinkingWatchdog(U)));
873
+ }, ye);
718
874
  }
719
875
  clearRunAckResyncRetryTimer() {
720
876
  this.runAckResyncRetryTimer !== null && (window.clearTimeout(this.runAckResyncRetryTimer), this.runAckResyncRetryTimer = null);
@@ -727,33 +883,33 @@ class dt {
727
883
  return;
728
884
  const t = this.activeClientMessageId;
729
885
  if (!t) {
730
- g("web-sdk.agent", "Pluno thinking watchdog resyncing without active message id", {
886
+ f("web-sdk.agent", "Pluno thinking watchdog resyncing without active message id", {
731
887
  sessionId: this.state.sessionId
732
- }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(E);
888
+ }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(U);
733
889
  return;
734
890
  }
735
891
  const s = this.thinkingWatchdogResyncAttemptsByClientMessageId[t] ?? 0, n = this.thinkingWatchdogRetryAttemptsByClientMessageId[t] ?? 0;
736
892
  if (s <= n) {
737
- this.thinkingWatchdogResyncAttemptsByClientMessageId[t] = s + 1, g("web-sdk.agent", "Pluno thinking watchdog resyncing session", {
893
+ this.thinkingWatchdogResyncAttemptsByClientMessageId[t] = s + 1, f("web-sdk.agent", "Pluno thinking watchdog resyncing session", {
738
894
  sessionId: this.state.sessionId,
739
895
  clientMessageId: t,
740
896
  resyncAttempts: s + 1
741
- }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(Ht);
897
+ }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(fe);
742
898
  return;
743
899
  }
744
- if (n >= V) {
745
- g("web-sdk.agent", "Pluno thinking watchdog retry limit reached; continuing resync", {
900
+ if (n >= ht) {
901
+ f("web-sdk.agent", "Pluno thinking watchdog retry limit reached; continuing resync", {
746
902
  sessionId: this.state.sessionId,
747
903
  clientMessageId: t,
748
904
  retryAttempts: n
749
- }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(E);
905
+ }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(U);
750
906
  return;
751
907
  }
752
908
  this.thinkingWatchdogRetryAttemptsByClientMessageId[t] = n + 1, this.setState({
753
909
  status: this.state.status === "reconnecting" ? "reconnecting" : "connected",
754
910
  isThinking: !0,
755
911
  lastError: null
756
- }), g("web-sdk.agent", "Pluno thinking watchdog retrying last user message", {
912
+ }), f("web-sdk.agent", "Pluno thinking watchdog retrying last user message", {
757
913
  sessionId: this.state.sessionId,
758
914
  clientMessageId: t,
759
915
  retryAttempts: n + 1
@@ -761,13 +917,13 @@ class dt {
761
917
  type: "chat.retry_last_user_message",
762
918
  sessionId: this.state.sessionId,
763
919
  clientMessageId: t
764
- }) : this.activeUserMessageEvent && this.send(this.activeUserMessageEvent), this.scheduleThinkingWatchdog(E);
920
+ }) : this.activeUserMessageEvent && this.send(this.activeUserMessageEvent), this.scheduleThinkingWatchdog(U);
765
921
  }
766
922
  resyncThinkingSession() {
767
923
  this.state.sessionId ? this.send({
768
924
  type: "page.upsert",
769
925
  sessionId: this.state.sessionId,
770
- page: y(),
926
+ page: I(),
771
927
  model: this.options.model
772
928
  }) : (!this.socket || this.socket.readyState !== WebSocket.OPEN) && (this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect());
773
929
  }
@@ -775,15 +931,15 @@ class dt {
775
931
  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
932
  if (!s || !n || !r)
777
933
  return;
778
- if (r !== "execute_code" || !Ke(o)) {
934
+ if (r !== "execute_code" || !Ls(o)) {
779
935
  this.send({
780
936
  type: "tool.result",
781
937
  sessionId: s,
782
938
  callId: n,
783
939
  toolName: r,
784
940
  summary: i,
785
- rawInput: T(o),
786
- rawOutput: T({
941
+ rawInput: A(o),
942
+ rawOutput: A({
787
943
  ok: !1,
788
944
  toolName: r,
789
945
  error: `Unsupported browser tool: ${r}`
@@ -791,164 +947,300 @@ class dt {
791
947
  });
792
948
  return;
793
949
  }
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) => ({
950
+ const d = ve(this.state.messages);
951
+ this.activeBrowserToolCalls.set(n, {
952
+ event: {
953
+ type: "tool.result",
954
+ sessionId: s,
955
+ callId: n,
956
+ toolName: r,
957
+ summary: o.summary,
958
+ rawInput: A(o),
959
+ rawOutput: null
960
+ },
961
+ startedAtMs: Date.now(),
962
+ startedAtUrl: location.href,
963
+ startedAtOrigin: location.origin
964
+ }), this.installSessionUserFilesApi(d);
965
+ let a = null, h;
966
+ a = await this.executeRuntimeHelper(), h = await mt(o).catch((g) => ({
798
967
  ok: !1,
799
968
  exception: {
800
- message: h instanceof Error ? h.message : String(h)
969
+ message: g instanceof Error ? g.message : String(g)
801
970
  }
802
- })), this.send({
971
+ })), this.activeBrowserToolCalls.delete(n), this.send({
803
972
  type: "tool.result",
804
973
  sessionId: s,
805
974
  callId: n,
806
975
  toolName: r,
807
976
  summary: o.summary,
808
- rawInput: T(o),
809
- rawOutput: T(ge(d, a))
810
- });
977
+ rawInput: A(o),
978
+ rawOutput: A(Ze(h, a))
979
+ }), _s(this.options.clientId, this.activeBrowserToolCalls.values());
980
+ }
981
+ startPageLifecycleRecovery() {
982
+ if (this.pageLifecycleCleanup)
983
+ return;
984
+ const t = () => {
985
+ Lt(this.options.clientId, this.activeBrowserToolCalls.values());
986
+ };
987
+ window.addEventListener("pagehide", t), window.addEventListener("beforeunload", t), this.pageLifecycleCleanup = () => {
988
+ window.removeEventListener("pagehide", t), window.removeEventListener("beforeunload", t);
989
+ };
811
990
  }
812
991
  installSessionUserFilesApi(t) {
813
- this.cleanupSessionUserFilesApi(), this.sessionUserFilesApiCleanup = Zt(t, this.attachmentFiles, this.attachmentBlobCache);
992
+ this.cleanupSessionUserFilesApi(), this.sessionUserFilesApiCleanup = Le(t, this.attachmentFiles, this.attachmentBlobCache);
814
993
  }
815
994
  cleanupSessionUserFilesApi() {
816
- this.sessionUserFilesApiCleanup && (Qt(this.sessionUserFilesApiCleanup), this.sessionUserFilesApiCleanup = null);
995
+ this.sessionUserFilesApiCleanup && (qe(this.sessionUserFilesApiCleanup), this.sessionUserFilesApiCleanup = null);
817
996
  }
818
997
  async executeRuntimeHelper() {
819
998
  if (!this.runtimeHelperJavascript?.trim())
820
999
  return null;
821
- const t = await et({
1000
+ const t = await mt({
822
1001
  javascript: this.runtimeHelperJavascript
823
1002
  });
824
- return t.ok === !1 ? fe(t) : null;
1003
+ return t.ok === !1 ? Qe(t) : null;
825
1004
  }
826
1005
  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
- };
1006
+ this.networkCaptureCleanup || (this.networkCaptureCleanup = Me((t) => {
1007
+ xs(t.url, this.options.backendUrl) || this.enqueueNetworkEvent(t);
1008
+ }));
908
1009
  }
909
1010
  enqueueNetworkEvent(t) {
910
- this.queuedNetworkEvents.push(T(t)), this.networkBatchTimer === null && (this.networkBatchTimer = window.setTimeout(() => {
1011
+ this.queuedNetworkEvents.length >= Te || (this.queuedNetworkEvents.push(Ws(t)), this.networkBatchTimer === null && (this.networkBatchTimer = window.setTimeout(() => {
911
1012
  this.networkBatchTimer = null;
912
1013
  const s = this.queuedNetworkEvents.splice(0, this.queuedNetworkEvents.length);
913
1014
  s.length === 0 || this.socket?.readyState !== WebSocket.OPEN || this.sendNow({
914
1015
  type: "network.batch",
915
1016
  sessionId: this.state.sessionId ?? void 0,
916
- page: y(),
1017
+ page: I(),
917
1018
  events: s
918
1019
  });
919
- }, vt));
1020
+ }, we)));
920
1021
  }
921
1022
  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),
1023
+ if (this.reconnectTimer !== null || this.state.status === "closed")
1024
+ return;
1025
+ const t = be(this.reconnectAttempts);
1026
+ this.reconnectAttempts += 1, this.reconnectTimer = window.setTimeout(() => {
1027
+ this.reconnectTimer = null, this.connect().catch((s) => {
1028
+ f("web-sdk.agent", "Pluno reconnect failed; retrying", {
1029
+ message: s instanceof Error ? s.message : String(s),
926
1030
  queuedClientEventCount: this.queuedClientEvents.length,
927
1031
  isThinking: this.state.isThinking
928
1032
  }), this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect();
929
1033
  });
930
- }, Lt));
1034
+ }, t);
931
1035
  }
932
1036
  startHeartbeat() {
933
1037
  this.stopHeartbeat(), this.heartbeatTimer = window.setInterval(() => {
934
- this.sendNow({ type: "runtime.ping" });
935
- }, Ft);
1038
+ const t = this.socket;
1039
+ !t || !this.sendNow({ type: "runtime.ping" }) || (this.clearHeartbeatAckTimer(), this.heartbeatAckTimer = window.setTimeout(() => {
1040
+ this.socket === t && (f("web-sdk.agent", "Pluno heartbeat acknowledgement timed out; reconnecting"), this.replaceTimedOutSocket(t));
1041
+ }, ue));
1042
+ }, le);
936
1043
  }
937
1044
  stopHeartbeat() {
938
- this.heartbeatTimer !== null && (window.clearInterval(this.heartbeatTimer), this.heartbeatTimer = null);
1045
+ this.heartbeatTimer !== null && (window.clearInterval(this.heartbeatTimer), this.heartbeatTimer = null), this.clearHeartbeatAckTimer();
1046
+ }
1047
+ clearHeartbeatAckTimer() {
1048
+ this.heartbeatAckTimer !== null && (window.clearTimeout(this.heartbeatAckTimer), this.heartbeatAckTimer = null);
1049
+ }
1050
+ clearSocketConnectTimer() {
1051
+ this.socketConnectTimer !== null && (window.clearTimeout(this.socketConnectTimer), this.socketConnectTimer = null);
1052
+ }
1053
+ clearSocketAuthTimer() {
1054
+ this.socketAuthTimer !== null && (window.clearTimeout(this.socketAuthTimer), this.socketAuthTimer = null);
1055
+ }
1056
+ clearSocketPhaseTimers() {
1057
+ this.clearSocketConnectTimer(), this.clearSocketAuthTimer();
1058
+ }
1059
+ replaceTimedOutSocket(t) {
1060
+ 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
1061
  }
940
1062
  setState(t) {
941
1063
  this.state = {
942
1064
  ...this.state,
943
1065
  ...t,
944
1066
  ...t.lastError === null && t.lastErrorCode === void 0 ? { lastErrorCode: null } : {}
945
- }, ve(this.options.clientId, this.state), this.emit("state", this.getState());
1067
+ }, Es(this.options.clientId, this.state), this.emit("state", this.getState());
946
1068
  }
947
1069
  emit(t, s) {
948
1070
  this.listeners[t]?.forEach((r) => r(s));
949
1071
  }
950
1072
  }
951
- function g(e, t, s) {
1073
+ const X = /* @__PURE__ */ new WeakMap();
1074
+ function Me(e) {
1075
+ const t = window.__plunoProductAgentNetworkCapture ?? De();
1076
+ return t.subscribers.add(e), () => {
1077
+ t.subscribers.delete(e), !(t.subscribers.size > 0) && (t.destroy(), window.__plunoProductAgentNetworkCapture === t && delete window.__plunoProductAgentNetworkCapture);
1078
+ };
1079
+ }
1080
+ function De() {
1081
+ const e = /* @__PURE__ */ new Set(), t = (c) => {
1082
+ e.forEach((p) => {
1083
+ try {
1084
+ p(c);
1085
+ } catch {
1086
+ }
1087
+ });
1088
+ }, s = window.fetch, n = XMLHttpRequest.prototype.open, r = XMLHttpRequest.prototype.setRequestHeader, i = XMLHttpRequest.prototype.send, o = function(p, l) {
1089
+ const m = Date.now();
1090
+ let y;
1091
+ try {
1092
+ y = s.call(this, p, l);
1093
+ } catch (T) {
1094
+ throw T;
1095
+ }
1096
+ try {
1097
+ const T = p instanceof Request ? p : null, R = qs(p, T), w = Ht(l?.headers ?? T?.headers);
1098
+ if (!P(R, w, l?.body)) {
1099
+ const j = {
1100
+ requestId: J("fetch"),
1101
+ url: S(R, G),
1102
+ method: (l?.method ?? T?.method ?? "GET").toUpperCase(),
1103
+ requestHeaders: w,
1104
+ requestBody: It(l?.body),
1105
+ resourceType: "fetch",
1106
+ startedAt: new Date(m).toISOString()
1107
+ };
1108
+ y.then(
1109
+ (_) => {
1110
+ Bs(_, j, m, t).catch(() => {
1111
+ t({
1112
+ ...j,
1113
+ responseStatus: _.status,
1114
+ durationMs: Date.now() - m
1115
+ });
1116
+ });
1117
+ },
1118
+ (_) => {
1119
+ t({
1120
+ ...j,
1121
+ errorText: S(_ instanceof Error ? _.message : String(_)),
1122
+ durationMs: Date.now() - m
1123
+ });
1124
+ }
1125
+ );
1126
+ }
1127
+ } catch {
1128
+ }
1129
+ return y;
1130
+ }, d = function(p, l, m, y, T) {
1131
+ const R = n.call(this, p, l, m ?? !0, y ?? void 0, T ?? void 0), w = typeof l == "string" ? l : l.toString();
1132
+ return X.set(this, {
1133
+ requestId: J("xhr"),
1134
+ method: String(p ?? "GET").toUpperCase(),
1135
+ url: S(w, G),
1136
+ requestHeaders: {},
1137
+ startedAtMs: Date.now(),
1138
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
1139
+ excluded: P(w)
1140
+ }), R;
1141
+ }, a = function(p, l) {
1142
+ const m = r.call(this, p, l), y = X.get(this);
1143
+ return y && Object.keys(y.requestHeaders).length < it && (y.requestHeaders[p] = ct(p, l), y.excluded = y.excluded || P(y.url, y.requestHeaders)), m;
1144
+ }, h = function(p) {
1145
+ try {
1146
+ const l = X.get(this);
1147
+ l && (l.excluded = l.excluded || P(l.url, l.requestHeaders, p), l.requestBody = It(p), l.excluded || this.addEventListener(
1148
+ "loadend",
1149
+ () => {
1150
+ queueMicrotask(() => {
1151
+ try {
1152
+ const m = $s(this.getAllResponseHeaders());
1153
+ t({
1154
+ requestId: l.requestId,
1155
+ url: l.url,
1156
+ method: l.method,
1157
+ requestHeaders: l.requestHeaders,
1158
+ requestBody: l.requestBody,
1159
+ resourceType: "xhr",
1160
+ responseStatus: this.status,
1161
+ responseHeaders: m,
1162
+ responseBody: Fs(this, m),
1163
+ errorText: this.status === 0 ? "XHR request failed or was aborted" : void 0,
1164
+ startedAt: l.startedAt,
1165
+ durationMs: Date.now() - l.startedAtMs
1166
+ });
1167
+ } catch {
1168
+ return;
1169
+ }
1170
+ });
1171
+ },
1172
+ { once: !0 }
1173
+ ));
1174
+ } catch {
1175
+ }
1176
+ return i.call(this, p ?? null);
1177
+ };
1178
+ try {
1179
+ window.fetch = o;
1180
+ } catch {
1181
+ }
1182
+ try {
1183
+ XMLHttpRequest.prototype.open = d;
1184
+ } catch {
1185
+ }
1186
+ try {
1187
+ XMLHttpRequest.prototype.setRequestHeader = a;
1188
+ } catch {
1189
+ }
1190
+ try {
1191
+ XMLHttpRequest.prototype.send = h;
1192
+ } catch {
1193
+ }
1194
+ let g = null;
1195
+ if (typeof PerformanceObserver < "u") {
1196
+ g = new PerformanceObserver((c) => {
1197
+ for (const p of c.getEntries()) {
1198
+ const l = p;
1199
+ if (l.initiatorType === "fetch" || l.initiatorType === "xmlhttprequest" || P(l.name))
1200
+ continue;
1201
+ const m = performance.timeOrigin + l.startTime;
1202
+ t({
1203
+ requestId: J("resource"),
1204
+ url: S(l.name, G),
1205
+ method: "GET",
1206
+ resourceType: "resource",
1207
+ responseStatus: l.responseStatus,
1208
+ startedAt: new Date(m).toISOString(),
1209
+ durationMs: l.duration
1210
+ });
1211
+ }
1212
+ });
1213
+ try {
1214
+ g.observe({ type: "resource", buffered: !0 });
1215
+ } catch {
1216
+ g.disconnect(), g = null;
1217
+ }
1218
+ }
1219
+ const u = {
1220
+ subscribers: e,
1221
+ destroy: () => {
1222
+ g?.disconnect();
1223
+ try {
1224
+ window.fetch === o && (window.fetch = s);
1225
+ } catch {
1226
+ }
1227
+ try {
1228
+ XMLHttpRequest.prototype.open === d && (XMLHttpRequest.prototype.open = n);
1229
+ } catch {
1230
+ }
1231
+ try {
1232
+ XMLHttpRequest.prototype.setRequestHeader === a && (XMLHttpRequest.prototype.setRequestHeader = r);
1233
+ } catch {
1234
+ }
1235
+ try {
1236
+ XMLHttpRequest.prototype.send === h && (XMLHttpRequest.prototype.send = i);
1237
+ } catch {
1238
+ }
1239
+ }
1240
+ };
1241
+ return window.__plunoProductAgentNetworkCapture = u, u;
1242
+ }
1243
+ function f(e, t, s) {
952
1244
  if (typeof window > "u")
953
1245
  return;
954
1246
  const n = window, r = {
@@ -959,15 +1251,15 @@ function g(e, t, s) {
959
1251
  }, i = n.__plunoProductAgentDiagnostics__ ?? [];
960
1252
  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
1253
  }
962
- function Q(e) {
1254
+ function gt(e) {
963
1255
  const t = typeof e == "function" ? e() : e;
964
1256
  return t && Object.keys(t).length > 0 ? t : void 0;
965
1257
  }
966
- function Jt(e) {
1258
+ function Ne(e) {
967
1259
  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
1260
  }
969
- const Vt = 5e3;
970
- function Yt(e) {
1261
+ const Oe = 5e3;
1262
+ function ve(e) {
971
1263
  const t = [];
972
1264
  for (const s of e)
973
1265
  s.role !== "user" || !s.attachments?.length || s.attachments.forEach((n, r) => {
@@ -978,118 +1270,118 @@ function Yt(e) {
978
1270
  });
979
1271
  return t;
980
1272
  }
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);
1273
+ function Le(e, t = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map()) {
1274
+ const n = new Map(e.map((u) => [u.id, u])), r = (u) => ({
1275
+ id: u.id,
1276
+ name: u.name,
1277
+ mimeType: u.mimeType,
1278
+ sizeBytes: u.sizeBytes,
1279
+ type: u.mimeType,
1280
+ size: u.sizeBytes
1281
+ }), i = (u) => {
1282
+ const c = n.get(u);
1283
+ if (!c)
1284
+ throw new Error(`Unknown Pluno user file: ${u}`);
1285
+ return c;
1286
+ }, o = async (u) => {
1287
+ const c = i(u), p = t.get(c.id);
999
1288
  if (p)
1000
1289
  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)
1290
+ const l = s.get(c.id);
1291
+ if (l)
1292
+ return l;
1293
+ 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", {
1294
+ attachmentId: c.id,
1295
+ name: c.name,
1296
+ message: w instanceof Error ? w.message : String(w)
1005
1297
  }), 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)
1298
+ if (m)
1299
+ return s.set(c.id, m), m;
1300
+ if (!c.fileUrl)
1301
+ throw new Error(`Pluno user file is missing content: ${u}`);
1302
+ const y = await fetch(c.fileUrl, Ms(c.fileUrl));
1303
+ if (!y.ok)
1304
+ throw new Error(`Failed to load Pluno user file: ${u}`);
1305
+ const T = await y.blob();
1306
+ s.set(c.id, T);
1307
+ const R = Date.now();
1308
+ return kt({
1309
+ attachmentId: c.id,
1310
+ name: c.name,
1311
+ mimeType: c.mimeType,
1312
+ sizeBytes: c.sizeBytes,
1313
+ blob: T,
1314
+ fileUrl: c.fileUrl,
1315
+ gcsPath: c.gcsPath,
1316
+ createdAt: R,
1317
+ lastUsedAt: R
1318
+ }).catch((w) => {
1319
+ f("web-sdk.attachments", "Failed to cache Product Agent attachment from fileUrl", {
1320
+ attachmentId: c.id,
1321
+ name: c.name,
1322
+ message: w instanceof Error ? w.message : String(w)
1031
1323
  });
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 ? {
1324
+ }), T;
1325
+ }, d = async (u) => {
1326
+ const c = i(u), p = await o(u), l = c.mimeType.startsWith("image/") ? c.mimeType : p.type || c.mimeType;
1327
+ if (!l.startsWith("image/"))
1328
+ throw new Error(`Pluno user file is not an image: ${u}`);
1329
+ const m = p.type === l ? p : new Blob([p], { type: l });
1330
+ return Be(l, m.size) > Re ? {
1039
1331
  type: "pluno.userFiles.inspectImage",
1040
- id: u.id,
1041
- name: u.name,
1042
- mimeType: p,
1043
- sizeBytes: u.sizeBytes,
1332
+ id: c.id,
1333
+ name: c.name,
1334
+ mimeType: l,
1335
+ sizeBytes: c.sizeBytes,
1044
1336
  imageAttached: !1,
1045
- imageAttachmentError: Gt
1337
+ imageAttachmentError: _e
1046
1338
  } : {
1047
1339
  type: "pluno.userFiles.inspectImage",
1048
- id: u.id,
1049
- name: u.name,
1050
- mimeType: p,
1051
- sizeBytes: u.sizeBytes,
1340
+ id: c.id,
1341
+ name: c.name,
1342
+ mimeType: l,
1343
+ sizeBytes: c.sizeBytes,
1052
1344
  imageAttached: !0,
1053
- dataUrl: await tt(S)
1345
+ dataUrl: await ft(m)
1054
1346
  };
1055
- }, a = globalThis, d = a.pluno?.userFiles, h = Object.prototype.hasOwnProperty.call(a.pluno ?? {}, "userFiles");
1347
+ }, a = globalThis, h = a.pluno?.userFiles, g = Object.prototype.hasOwnProperty.call(a.pluno ?? {}, "userFiles");
1056
1348
  return a.pluno = {
1057
1349
  ...a.pluno ?? {},
1058
1350
  userFiles: {
1059
1351
  list: () => e.map(r),
1060
- get: (l) => {
1061
- const u = n.get(l);
1062
- return u ? r(u) : null;
1352
+ get: (u) => {
1353
+ const c = n.get(u);
1354
+ return c ? r(c) : null;
1063
1355
  },
1064
- inspectImage: c,
1065
- getDataUrl: async (l) => (i(l), await tt(await o(l))),
1356
+ inspectImage: d,
1357
+ getDataUrl: async (u) => (i(u), await ft(await o(u))),
1066
1358
  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 });
1359
+ getArrayBuffer: async (u) => await (await o(u)).arrayBuffer(),
1360
+ getFile: async (u) => {
1361
+ const c = i(u);
1362
+ return new File([await o(u)], c.name, { type: c.mimeType });
1071
1363
  }
1072
1364
  }
1073
1365
  }, () => {
1074
- const l = a.pluno ?? {};
1075
- if (h) {
1366
+ const u = a.pluno ?? {};
1367
+ if (g) {
1076
1368
  a.pluno = {
1077
- ...l,
1078
- userFiles: d
1369
+ ...u,
1370
+ userFiles: h
1079
1371
  };
1080
1372
  return;
1081
1373
  }
1082
- const { userFiles: u, ...f } = l;
1083
- a.pluno = f;
1374
+ const { userFiles: c, ...p } = u;
1375
+ a.pluno = p;
1084
1376
  };
1085
1377
  }
1086
- function Qt(e) {
1378
+ function qe(e) {
1087
1379
  try {
1088
1380
  e();
1089
1381
  } catch {
1090
1382
  }
1091
1383
  }
1092
- function tt(e) {
1384
+ function ft(e) {
1093
1385
  return new Promise((t, s) => {
1094
1386
  const n = new FileReader();
1095
1387
  n.onload = () => {
@@ -1101,32 +1393,32 @@ function tt(e) {
1101
1393
  }, n.onerror = () => s(n.error ?? new Error("Failed to read Pluno user file")), n.readAsDataURL(e);
1102
1394
  });
1103
1395
  }
1104
- function te(e, t) {
1396
+ function Be(e, t) {
1105
1397
  return `data:${e};base64,`.length + Math.ceil(t / 3) * 4;
1106
1398
  }
1107
- async function et(e) {
1399
+ async function mt(e) {
1108
1400
  const t = Object.getPrototypeOf(async function() {
1109
- }).constructor, s = e.timeoutMs ?? Vt, n = Date.now(), r = [];
1401
+ }).constructor, s = e.timeoutMs ?? Oe, n = Date.now(), r = [];
1110
1402
  let i;
1111
1403
  const o = {
1112
1404
  log: console.log,
1113
1405
  info: console.info,
1114
1406
  warn: console.warn,
1115
1407
  error: console.error
1116
- }, c = (a) => (...d) => {
1117
- r.push({ level: a, args: d }), o[a](...d);
1408
+ }, d = (a) => (...h) => {
1409
+ r.push({ level: a, args: h }), o[a](...h);
1118
1410
  };
1119
- console.log = c("log"), console.info = c("info"), console.warn = c("warn"), console.error = c("error");
1411
+ console.log = d("log"), console.info = d("info"), console.warn = d("warn"), console.error = d("error");
1120
1412
  try {
1121
- const a = /* @__PURE__ */ Symbol("execute_code_timeout"), d = await Promise.race([
1413
+ const a = /* @__PURE__ */ Symbol("execute_code_timeout"), h = await Promise.race([
1122
1414
  new t(e.javascript)(),
1123
- new Promise((h) => {
1124
- i = window.setTimeout(() => h(a), s);
1415
+ new Promise((g) => {
1416
+ i = window.setTimeout(() => g(a), s);
1125
1417
  })
1126
1418
  ]);
1127
- return d === a ? ee(s) : {
1419
+ return h === a ? He(s) : {
1128
1420
  ok: !0,
1129
- result: d,
1421
+ result: h,
1130
1422
  console: r,
1131
1423
  metadata: {
1132
1424
  durationMs: Date.now() - n,
@@ -1153,7 +1445,7 @@ async function et(e) {
1153
1445
  i !== void 0 && window.clearTimeout(i), console.log = o.log, console.info = o.info, console.warn = o.warn, console.error = o.error;
1154
1446
  }
1155
1447
  }
1156
- function ee(e) {
1448
+ function He(e) {
1157
1449
  return {
1158
1450
  ok: !1,
1159
1451
  exception: {
@@ -1167,18 +1459,18 @@ function ee(e) {
1167
1459
  }
1168
1460
  };
1169
1461
  }
1170
- function se(e) {
1462
+ function Fe(e) {
1171
1463
  return e.replace(/\/+$/, "");
1172
1464
  }
1173
- function ne(e, t = location.origin) {
1465
+ function We(e, t = location.origin) {
1174
1466
  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
1467
  }
1176
- function re(e) {
1468
+ function xe(e) {
1177
1469
  const t = new URL("/api/product-agent/embed/ws", e);
1178
1470
  return t.protocol = t.protocol === "https:" ? "wss:" : "ws:", t.toString();
1179
1471
  }
1180
- function y() {
1181
- const e = ht();
1472
+ function I() {
1473
+ const e = bt();
1182
1474
  return {
1183
1475
  url: location.href,
1184
1476
  title: document.title,
@@ -1186,21 +1478,21 @@ function y() {
1186
1478
  ...e ? { plunoProductAgentUi: e } : {}
1187
1479
  };
1188
1480
  }
1189
- function ie() {
1481
+ function je() {
1190
1482
  return {
1191
1483
  pageUrl: location.href,
1192
1484
  pageTitle: document.title,
1193
- htmlContent: le()
1485
+ htmlContent: Xe()
1194
1486
  };
1195
1487
  }
1196
- function oe(e) {
1197
- return b.add(e), R || (R = ae()), () => {
1198
- b.delete(e), b.size === 0 && (R?.(), R = null);
1488
+ function $e(e) {
1489
+ return v.add(e), D || (D = ze()), () => {
1490
+ v.delete(e), v.size === 0 && (D?.(), D = null);
1199
1491
  };
1200
1492
  }
1201
- function ae() {
1493
+ function ze() {
1202
1494
  const e = () => {
1203
- for (const i of Array.from(b))
1495
+ for (const i of Array.from(v))
1204
1496
  i();
1205
1497
  }, t = window.history.pushState.bind(window.history), s = window.history.replaceState.bind(window.history), n = ((...i) => {
1206
1498
  const o = t(...i);
@@ -1213,10 +1505,10 @@ function ae() {
1213
1505
  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
1506
  };
1215
1507
  }
1216
- function ce() {
1217
- return ht()?.surface === "browser_extension_sdk_preview";
1508
+ function Ge() {
1509
+ return bt()?.surface === "browser_extension_sdk_preview";
1218
1510
  }
1219
- function le() {
1511
+ function Xe() {
1220
1512
  const e = document.body?.cloneNode(!0);
1221
1513
  return e instanceof HTMLElement ? (e.querySelectorAll(
1222
1514
  [
@@ -1240,9 +1532,9 @@ function le() {
1240
1532
  s.name === "href" || s.name === "aria-label" || s.name === "role" || t.removeAttribute(s.name);
1241
1533
  }), 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
1534
  }
1243
- function ht() {
1244
- const e = document.querySelector(J);
1245
- if (!(e ?? document.querySelector(B)))
1535
+ function bt() {
1536
+ const e = document.querySelector(lt);
1537
+ if (!(e ?? document.querySelector(Z)))
1246
1538
  return;
1247
1539
  const s = e ? "browser_extension_sdk_preview" : "embedded_widget";
1248
1540
  return {
@@ -1251,28 +1543,28 @@ function ht() {
1251
1543
  selectors: [
1252
1544
  {
1253
1545
  name: "widget_host",
1254
- selector: s === "browser_extension_sdk_preview" ? J : B,
1546
+ selector: s === "browser_extension_sdk_preview" ? lt : Z,
1255
1547
  description: "Finds Pluno's shadow-host element in the host page DOM."
1256
1548
  },
1257
1549
  {
1258
1550
  name: "widget_root",
1259
- selector: Mt,
1551
+ selector: re,
1260
1552
  description: "Finds Pluno's widget root inside the widget host shadow root."
1261
1553
  },
1262
1554
  {
1263
1555
  name: "widget_panel",
1264
- selector: Dt,
1556
+ selector: ie,
1265
1557
  description: "Finds Pluno's open chat panel inside the widget host shadow root."
1266
1558
  },
1267
1559
  {
1268
1560
  name: "widget_timeline",
1269
- selector: Nt,
1561
+ selector: oe,
1270
1562
  description: "Finds Pluno's chat timeline inside the widget host shadow root."
1271
1563
  }
1272
1564
  ]
1273
1565
  };
1274
1566
  }
1275
- function ue(e) {
1567
+ function Ke(e) {
1276
1568
  try {
1277
1569
  const t = JSON.parse(e);
1278
1570
  return t && typeof t == "object" ? t : { type: "error", message: "Invalid server event" };
@@ -1280,33 +1572,33 @@ function ue(e) {
1280
1572
  return { type: "error", message: "Invalid server event" };
1281
1573
  }
1282
1574
  }
1283
- function st(e, t) {
1575
+ function yt(e, t) {
1284
1576
  if (!e || typeof e != "object")
1285
1577
  return [];
1286
1578
  const s = e[t];
1287
1579
  return Array.isArray(s) ? s.filter((n) => typeof n == "string" && n.trim().length > 0) : [];
1288
1580
  }
1289
- function de(e) {
1581
+ function Je(e) {
1290
1582
  return Array.isArray(e) ? e.filter((t) => typeof t == "string" && t.trim().length > 0) : [];
1291
1583
  }
1292
- function he(e) {
1584
+ function Ve(e) {
1293
1585
  if (!e || typeof e != "object")
1294
1586
  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 : {
1587
+ 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;
1588
+ return !r && !i && !o && d === null ? null : {
1297
1589
  ...r ? { accentColor: r } : {},
1298
1590
  ...i ? { colorScheme: i } : {},
1299
1591
  ...o ? { fontFamily: o } : {},
1300
- ...c !== null ? { scribbleStyle: c } : {}
1592
+ ...d !== null ? { scribbleStyle: d } : {}
1301
1593
  };
1302
1594
  }
1303
- function pe(e) {
1595
+ function Ye(e) {
1304
1596
  if (!e || typeof e != "object")
1305
1597
  return null;
1306
1598
  const t = e.javascript;
1307
1599
  return typeof t != "string" || !t.trim() ? null : { javascript: t };
1308
1600
  }
1309
- function ge(e, t) {
1601
+ function Ze(e, t) {
1310
1602
  return t ? e && typeof e == "object" ? {
1311
1603
  ...e,
1312
1604
  helperError: t
@@ -1316,30 +1608,23 @@ function ge(e, t) {
1316
1608
  helperError: t
1317
1609
  } : e;
1318
1610
  }
1319
- function fe(e) {
1611
+ function Qe(e) {
1320
1612
  if (!e || typeof e != "object")
1321
1613
  return e;
1322
1614
  const t = e;
1323
1615
  return typeof t.exception?.message == "string" ? t.exception.message : typeof t.error == "string" ? t.error : e;
1324
1616
  }
1325
- function me() {
1617
+ function ts() {
1326
1618
  const e = "pluno.productAgent.clientId", t = window.localStorage.getItem(e);
1327
1619
  if (t)
1328
1620
  return t;
1329
1621
  const s = crypto.randomUUID();
1330
1622
  return window.localStorage.setItem(e, s), s;
1331
1623
  }
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 _() {
1624
+ function N() {
1340
1625
  return crypto.randomUUID();
1341
1626
  }
1342
- function we(e) {
1627
+ function es(e) {
1343
1628
  if (!e || typeof e != "object")
1344
1629
  return null;
1345
1630
  const t = e, s = typeof t.id == "string" ? t.id : null;
@@ -1350,23 +1635,23 @@ function we(e) {
1350
1635
  avatarUrl: typeof t.avatarUrl == "string" ? t.avatarUrl : null
1351
1636
  } : null;
1352
1637
  }
1353
- function Te(e, t) {
1354
- return Array.isArray(e) ? x(
1355
- j(
1356
- e.map((s) => pt(s, t)).filter((s) => s !== null)
1638
+ function ss(e, t) {
1639
+ return Array.isArray(e) ? tt(
1640
+ et(
1641
+ e.map((s) => Ut(s, t)).filter((s) => s !== null)
1357
1642
  )
1358
1643
  ) : [];
1359
1644
  }
1360
- function Ae(e) {
1645
+ function ns(e) {
1361
1646
  return Array.isArray(e) ? e.flatMap((t) => {
1362
1647
  if (!t || typeof t != "object")
1363
1648
  return [];
1364
- const s = t, n = A(s, "id"), r = A(s, "createdAt"), i = A(s, "updatedAt"), o = A(s, "lastActiveAt");
1649
+ const s = t, n = E(s, "id"), r = E(s, "createdAt"), i = E(s, "updatedAt"), o = E(s, "lastActiveAt");
1365
1650
  return !n || !r || !i || !o ? [] : [
1366
1651
  {
1367
1652
  id: n,
1368
- title: A(s, "title"),
1369
- firstUserMessage: A(s, "firstUserMessage"),
1653
+ title: E(s, "title"),
1654
+ firstUserMessage: E(s, "firstUserMessage"),
1370
1655
  currentPage: s.currentPage ?? null,
1371
1656
  createdAt: r,
1372
1657
  updatedAt: i,
@@ -1375,7 +1660,7 @@ function Ae(e) {
1375
1660
  ];
1376
1661
  }) : [];
1377
1662
  }
1378
- function pt(e, t) {
1663
+ function Ut(e, t) {
1379
1664
  if (!e || typeof e != "object")
1380
1665
  return null;
1381
1666
  const s = e, n = s.data;
@@ -1387,39 +1672,39 @@ function pt(e, t) {
1387
1672
  return {
1388
1673
  id: String(s.id ?? crypto.randomUUID()),
1389
1674
  role: i,
1390
- content: Re(r.content),
1675
+ content: cs(r.content),
1391
1676
  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)
1677
+ respondsToUserMessageId: K(r) ?? void 0,
1678
+ ...C(r) ? { runId: C(r) } : {},
1679
+ attachments: qt(r.attachments, t)
1395
1680
  };
1396
1681
  }
1397
1682
  return r.type === "function_call" || r.type === "tool_call" || r.type === "web_search_call" ? {
1398
1683
  id: String(s.id ?? crypto.randomUUID()),
1399
1684
  role: "tool",
1400
- content: Se(r),
1685
+ content: is(r),
1401
1686
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
1402
- respondsToUserMessageId: L(r) ?? void 0,
1403
- ...k(r) ? { runId: k(r) } : {},
1687
+ respondsToUserMessageId: K(r) ?? void 0,
1688
+ ...C(r) ? { runId: C(r) } : {},
1404
1689
  dataType: String(r.type),
1405
1690
  toolName: typeof r.name == "string" ? r.name : void 0,
1406
- callId: Ee(r) ?? void 0,
1691
+ callId: as(r) ?? void 0,
1407
1692
  loading: r.localExecutionStatus === "running"
1408
1693
  } : r.type === "run_status" || r.type === "run_error" ? r.type === "run_error" && r.stage === "tool_execution" ? null : {
1409
1694
  id: String(s.id ?? crypto.randomUUID()),
1410
1695
  role: "system",
1411
- content: Ie(r),
1696
+ content: rs(r),
1412
1697
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
1413
- respondsToUserMessageId: L(r) ?? void 0,
1414
- ...k(r) ? { runId: k(r) } : {},
1698
+ respondsToUserMessageId: K(r) ?? void 0,
1699
+ ...C(r) ? { runId: C(r) } : {},
1415
1700
  dataType: String(r.type),
1416
1701
  loading: r.type === "run_status" && (r.status === "running" || r.status === "retrying")
1417
1702
  } : null;
1418
1703
  }
1419
- function Ie(e) {
1704
+ function rs(e) {
1420
1705
  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
1706
  }
1422
- function Se(e) {
1707
+ function is(e) {
1423
1708
  if (e.type === "web_search_call") {
1424
1709
  const t = e.action;
1425
1710
  if (t && typeof t == "object") {
@@ -1431,9 +1716,9 @@ function Se(e) {
1431
1716
  }
1432
1717
  return "Searching the web";
1433
1718
  }
1434
- return ke(e);
1719
+ return os(e);
1435
1720
  }
1436
- function ke(e) {
1721
+ function os(e) {
1437
1722
  if (typeof e.summary == "string" && e.summary.trim().length > 0)
1438
1723
  return e.summary;
1439
1724
  if (typeof e.arguments == "string")
@@ -1446,11 +1731,11 @@ function ke(e) {
1446
1731
  }
1447
1732
  return typeof e.name == "string" && e.name.trim().length > 0 ? e.name : "Run tool";
1448
1733
  }
1449
- function Ee(e) {
1734
+ function as(e) {
1450
1735
  const t = e.callId ?? e.call_id;
1451
1736
  return typeof t == "string" && t ? t : null;
1452
1737
  }
1453
- function Re(e) {
1738
+ function cs(e) {
1454
1739
  return typeof e == "string" ? e : Array.isArray(e) ? e.map((t) => {
1455
1740
  if (!t || typeof t != "object")
1456
1741
  return "";
@@ -1458,19 +1743,19 @@ function Re(e) {
1458
1743
  return typeof s.text == "string" ? s.text : typeof s.content == "string" ? s.content : "";
1459
1744
  }).filter(Boolean).join("") : "";
1460
1745
  }
1461
- function _e(e, t) {
1462
- const s = gt(e, t), n = Ce(e, t), r = n.findIndex((o) => o.id === s.id);
1746
+ function ls(e, t) {
1747
+ const s = Mt(e, t), n = ps(e, t), r = n.findIndex((o) => o.id === s.id);
1463
1748
  if (r === -1)
1464
- return x(
1465
- j([...n, s])
1749
+ return tt(
1750
+ et([...n, s])
1466
1751
  );
1467
1752
  const i = [...n];
1468
- return i[r] = s, x(j(i));
1753
+ return i[r] = s, tt(et(i));
1469
1754
  }
1470
- function Pe(e, t) {
1471
- return t.map((s) => gt(e, s));
1755
+ function us(e, t) {
1756
+ return t.map((s) => Mt(e, s));
1472
1757
  }
1473
- function gt(e, t) {
1758
+ function Mt(e, t) {
1474
1759
  if (t.role !== "user" || !t.attachments?.length)
1475
1760
  return t;
1476
1761
  const s = e.find(
@@ -1479,19 +1764,19 @@ function gt(e, t) {
1479
1764
  if (!s?.attachments?.length)
1480
1765
  return t;
1481
1766
  const n = t.attachments.map((r) => {
1482
- const i = Ue(s.attachments ?? [], r);
1483
- return i ? be(r, i) : r;
1767
+ const i = ds(s.attachments ?? [], r);
1768
+ return i ? hs(r, i) : r;
1484
1769
  });
1485
1770
  return { ...t, attachments: n };
1486
1771
  }
1487
- function Ue(e, t) {
1772
+ function ds(e, t) {
1488
1773
  return t.id ? e.find((s) => s.id === t.id) ?? null : null;
1489
1774
  }
1490
- function be(e, t) {
1775
+ function hs(e, t) {
1491
1776
  const { previewUrl: s } = t;
1492
1777
  return s ? { ...e, previewUrl: s } : e;
1493
1778
  }
1494
- function Ce(e, t) {
1779
+ function ps(e, t) {
1495
1780
  if (t.role !== "user")
1496
1781
  return e;
1497
1782
  const s = e.findIndex(
@@ -1502,24 +1787,24 @@ function Ce(e, t) {
1502
1787
  const n = [...e];
1503
1788
  return n.splice(s, 1), n;
1504
1789
  }
1505
- function nt(e) {
1506
- const t = ft(e);
1507
- return t === null ? !1 : e.slice(t + 1).some(mt);
1790
+ function wt(e) {
1791
+ const t = Dt(e);
1792
+ return t === null ? !1 : e.slice(t + 1).some(Nt);
1508
1793
  }
1509
- function Me(e) {
1510
- const t = ft(e);
1794
+ function gs(e) {
1795
+ const t = Dt(e);
1511
1796
  return t === null ? e.some((s) => s.role === "assistant") : e.slice(t + 1).some((s) => s.role === "assistant");
1512
1797
  }
1513
- function ft(e) {
1798
+ function Dt(e) {
1514
1799
  for (let t = e.length - 1; t >= 0; t -= 1)
1515
1800
  if (e[t].role === "user")
1516
1801
  return t;
1517
1802
  return null;
1518
1803
  }
1519
- function mt(e) {
1804
+ function Nt(e) {
1520
1805
  return e.role === "assistant" ? !0 : e.role !== "system" ? !1 : e.dataType === "run_error" ? !0 : e.dataType === "run_status" && e.loading !== !0;
1521
1806
  }
1522
- function yt(e) {
1807
+ function Ot(e) {
1523
1808
  for (let t = e.length - 1; t >= 0; t -= 1) {
1524
1809
  const s = e[t];
1525
1810
  if (!s || typeof s != "object")
@@ -1533,18 +1818,18 @@ function yt(e) {
1533
1818
  }
1534
1819
  return null;
1535
1820
  }
1536
- function De(e, t) {
1537
- const s = yt(t);
1821
+ function fs(e, t) {
1822
+ const s = Ot(t);
1538
1823
  if (s === null)
1539
1824
  return !1;
1540
1825
  const n = t[s], r = n && typeof n == "object" ? n.id : null;
1541
1826
  if (typeof r != "string" || !r)
1542
1827
  return !1;
1543
1828
  const i = e.findIndex((o) => o.role === "user" && o.id === r);
1544
- return i === -1 ? !1 : e.slice(i + 1).some(mt);
1829
+ return i === -1 ? !1 : e.slice(i + 1).some(Nt);
1545
1830
  }
1546
- function Ne(e) {
1547
- const t = yt(e);
1831
+ function ms(e) {
1832
+ const t = Ot(e);
1548
1833
  if (t === null)
1549
1834
  return null;
1550
1835
  const s = e[t];
@@ -1556,22 +1841,22 @@ function Ne(e) {
1556
1841
  const r = n.clientMessageId;
1557
1842
  return typeof r == "string" ? r : null;
1558
1843
  }
1559
- function qe(e) {
1844
+ function ys(e) {
1560
1845
  if (!e || typeof e != "object")
1561
1846
  return !1;
1562
1847
  const t = e;
1563
1848
  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
1849
  }
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);
1850
+ function tt(e) {
1851
+ return e.filter((t, s) => vt(t) ? !Ss(e, s) && !As(e, s) && !Is(e, s) : ws(t) ? !Ts(e, s) : !0);
1567
1852
  }
1568
- function Oe(e) {
1853
+ function ws(e) {
1569
1854
  return e.role === "system" && (e.dataType === "run_status" || e.dataType === "run_error");
1570
1855
  }
1571
- function wt(e) {
1856
+ function vt(e) {
1572
1857
  return e.role === "system" && e.dataType === "run_status" && e.loading === !0;
1573
1858
  }
1574
- function j(e) {
1859
+ function et(e) {
1575
1860
  const t = new Set(e.filter((i) => i.role === "user").map((i) => i.id)), s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Set();
1576
1861
  for (const i of e) {
1577
1862
  if (i.role === "user" || !i.respondsToUserMessageId || !t.has(i.respondsToUserMessageId))
@@ -1587,53 +1872,53 @@ function j(e) {
1587
1872
  n.has(i.id) || (r.push(i), i.role === "user" && r.push(...s.get(i.id) ?? []));
1588
1873
  return r;
1589
1874
  }
1590
- function Fe(e, t) {
1875
+ function Ts(e, t) {
1591
1876
  const s = e[t];
1592
1877
  for (let n = t + 1; n < e.length; n += 1) {
1593
1878
  const r = e[n];
1594
1879
  if (r.role === "user")
1595
1880
  return !1;
1596
- if (r.role === "assistant" && N(s, r))
1881
+ if (r.role === "assistant" && W(s, r))
1597
1882
  return !0;
1598
1883
  }
1599
1884
  return !1;
1600
1885
  }
1601
- function Le(e, t) {
1886
+ function As(e, t) {
1602
1887
  const s = e[t];
1603
1888
  for (let n = t + 1; n < e.length; n += 1)
1604
- if (e[n].role === "assistant" && N(s, e[n]))
1889
+ if (e[n].role === "assistant" && W(s, e[n]))
1605
1890
  return !0;
1606
1891
  return !1;
1607
1892
  }
1608
- function He(e, t) {
1893
+ function Is(e, t) {
1609
1894
  const s = e[t];
1610
1895
  for (let n = t + 1; n < e.length; n += 1)
1611
- if (e[n].role === "tool" && N(s, e[n]))
1896
+ if (e[n].role === "tool" && W(s, e[n]))
1612
1897
  return !0;
1613
1898
  return !1;
1614
1899
  }
1615
- function We(e, t) {
1900
+ function Ss(e, t) {
1616
1901
  const s = e[t];
1617
1902
  for (let n = t + 1; n < e.length; n += 1)
1618
- if (wt(e[n]) && N(s, e[n]))
1903
+ if (vt(e[n]) && W(s, e[n]))
1619
1904
  return !0;
1620
1905
  return !1;
1621
1906
  }
1622
- function N(e, t) {
1907
+ function W(e, t) {
1623
1908
  return !e.runId || !t.runId ? !0 : e.runId === t.runId;
1624
1909
  }
1625
- function A(e, t) {
1910
+ function E(e, t) {
1626
1911
  return e && typeof e == "object" && typeof e[t] == "string" ? e[t] : null;
1627
1912
  }
1628
- function Be(e, t) {
1913
+ function ks(e, t) {
1629
1914
  try {
1630
- const s = window.localStorage.getItem(`${ut}${e}`);
1915
+ const s = window.localStorage.getItem(`${Ct}${e}`);
1631
1916
  if (!s)
1632
1917
  return null;
1633
1918
  const n = JSON.parse(s), r = typeof n.sessionId == "string" ? n.sessionId : null;
1634
1919
  if (t !== void 0 && r !== t)
1635
1920
  return null;
1636
- const i = Array.isArray(n.messages) ? n.messages.map(Ge).filter((o) => !!o) : [];
1921
+ const i = Array.isArray(n.messages) ? n.messages.map(Os).filter((o) => !!o) : [];
1637
1922
  return {
1638
1923
  sessionId: r,
1639
1924
  messages: i
@@ -1642,58 +1927,135 @@ function Be(e, t) {
1642
1927
  return null;
1643
1928
  }
1644
1929
  }
1645
- function ve(e, t) {
1930
+ function Es(e, t) {
1646
1931
  try {
1647
1932
  window.localStorage.setItem(
1648
- `${ut}${e}`,
1933
+ `${Ct}${e}`,
1649
1934
  JSON.stringify({
1650
1935
  sessionId: t.sessionId,
1651
- messages: t.messages.slice(-Xt).map(Xe)
1936
+ messages: t.messages.slice(-Ce).map(vs)
1652
1937
  })
1653
1938
  );
1654
1939
  } catch {
1655
1940
  return;
1656
1941
  }
1657
1942
  }
1658
- function xe(e) {
1943
+ function Rs(e) {
1659
1944
  try {
1660
- const t = window.localStorage.getItem(`${v}${e}`);
1945
+ const t = window.localStorage.getItem(`${Q}${e}`);
1661
1946
  if (!t)
1662
1947
  return [];
1663
1948
  const s = JSON.parse(t);
1664
- return Array.isArray(s) ? s.filter(Tt) : [];
1949
+ return Array.isArray(s) ? s.filter(ot) : [];
1665
1950
  } catch {
1666
1951
  return [];
1667
1952
  }
1668
1953
  }
1669
- function P(e, t) {
1954
+ function M(e, t) {
1670
1955
  try {
1671
- const s = t.filter(Tt);
1956
+ const s = t.filter(ot);
1672
1957
  if (s.length === 0) {
1673
- window.localStorage.removeItem(`${v}${e}`);
1958
+ window.localStorage.removeItem(`${Q}${e}`);
1674
1959
  return;
1675
1960
  }
1676
1961
  window.localStorage.setItem(
1677
- `${v}${e}`,
1962
+ `${Q}${e}`,
1678
1963
  JSON.stringify(s.slice(-25))
1679
1964
  );
1680
1965
  } catch {
1681
1966
  return;
1682
1967
  }
1683
1968
  }
1684
- function Tt(e) {
1969
+ function Lt(e, t) {
1970
+ try {
1971
+ const s = `${F}${e}`, n = location.href, r = location.origin, i = Array.from(t, (o) => ({
1972
+ ...o,
1973
+ storedAt: Date.now(),
1974
+ unloadUrl: n,
1975
+ unloadOrigin: r
1976
+ }));
1977
+ if (i.length === 0) {
1978
+ window.sessionStorage.removeItem(s);
1979
+ return;
1980
+ }
1981
+ window.sessionStorage.setItem(s, JSON.stringify(i));
1982
+ } catch {
1983
+ }
1984
+ }
1985
+ function _s(e, t) {
1986
+ try {
1987
+ if (window.sessionStorage.getItem(`${F}${e}`) === null)
1988
+ return;
1989
+ } catch {
1990
+ return;
1991
+ }
1992
+ Lt(e, t);
1993
+ }
1994
+ function Cs(e) {
1995
+ try {
1996
+ const t = `${F}${e}`, s = window.sessionStorage.getItem(t);
1997
+ if (window.sessionStorage.removeItem(t), !s)
1998
+ return [];
1999
+ const n = JSON.parse(s);
2000
+ return Array.isArray(n) ? n.flatMap((r) => Ps(r) ? [{
2001
+ ...r.event,
2002
+ rawOutput: {
2003
+ ok: !0,
2004
+ result: {
2005
+ navigated: !0,
2006
+ url: location.href,
2007
+ title: document.title
2008
+ },
2009
+ console: [],
2010
+ metadata: {
2011
+ durationMs: Math.max(0, Date.now() - r.startedAtMs),
2012
+ url: location.href,
2013
+ origin: location.origin,
2014
+ previousUrl: r.startedAtUrl,
2015
+ unloadUrl: r.unloadUrl,
2016
+ recoveredAfterNavigation: !0
2017
+ }
2018
+ }
2019
+ }] : []) : [];
2020
+ } catch {
2021
+ return [];
2022
+ }
2023
+ }
2024
+ function Ps(e) {
2025
+ if (!e || typeof e != "object")
2026
+ return !1;
2027
+ const t = e, s = t.event;
2028
+ 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";
2029
+ }
2030
+ function bs(e, t) {
2031
+ const s = new Set(
2032
+ e.flatMap((n) => n.type === "tool.result" ? [n.callId] : [])
2033
+ );
2034
+ return [
2035
+ ...e,
2036
+ ...t.filter((n) => !s.has(n.callId))
2037
+ ];
2038
+ }
2039
+ function Us(e) {
2040
+ try {
2041
+ window.sessionStorage.removeItem(`${F}${e}`);
2042
+ } catch {
2043
+ return;
2044
+ }
2045
+ }
2046
+ function ot(e) {
1685
2047
  if (!e || typeof e != "object")
1686
2048
  return !1;
1687
2049
  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;
2050
+ 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
2051
  }
1690
- function rt(e) {
2052
+ function Tt(e) {
1691
2053
  if (!e || typeof e != "object")
1692
2054
  return !1;
1693
2055
  const t = e;
1694
2056
  return typeof t.url == "string" && typeof t.title == "string" && typeof t.origin == "string";
1695
2057
  }
1696
- function At(e, t) {
2058
+ function qt(e, t) {
1697
2059
  if (!Array.isArray(e))
1698
2060
  return;
1699
2061
  const s = e.filter((r) => {
@@ -1701,24 +2063,24 @@ function At(e, t) {
1701
2063
  return !1;
1702
2064
  const i = r;
1703
2065
  return typeof i.name == "string" && typeof i.mimeType == "string" && typeof i.sizeBytes == "number";
1704
- }), n = t ? s.map((r) => It(r, t)) : s;
2066
+ }), n = t ? s.map((r) => Bt(r, t)) : s;
1705
2067
  return n.length > 0 ? n : void 0;
1706
2068
  }
1707
- function It(e, t) {
2069
+ function Bt(e, t) {
1708
2070
  return e.fileUrl?.startsWith("/") ? {
1709
2071
  ...e,
1710
2072
  fileUrl: new URL(e.fileUrl, t).toString()
1711
2073
  } : e;
1712
2074
  }
1713
- function je(e) {
1714
- if ($e(e))
2075
+ function Ms(e) {
2076
+ if (Ds(e))
1715
2077
  return {
1716
2078
  headers: {
1717
2079
  "ngrok-skip-browser-warning": "true"
1718
2080
  }
1719
2081
  };
1720
2082
  }
1721
- function $e(e) {
2083
+ function Ds(e) {
1722
2084
  try {
1723
2085
  const t = new URL(e).hostname;
1724
2086
  return t.endsWith(".ngrok-free.dev") || t.endsWith(".ngrok-free.app") || t.endsWith(".ngrok.app") || t.endsWith(".ngrok.io");
@@ -1726,14 +2088,14 @@ function $e(e) {
1726
2088
  return !1;
1727
2089
  }
1728
2090
  }
1729
- function it(e) {
1730
- return e.type || ze(e.name) || "application/octet-stream";
2091
+ function At(e) {
2092
+ return e.type || Ns(e.name) || "application/octet-stream";
1731
2093
  }
1732
- function ze(e) {
2094
+ function Ns(e) {
1733
2095
  const t = e.toLowerCase();
1734
2096
  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
2097
  }
1736
- function Ge(e) {
2098
+ function Os(e) {
1737
2099
  if (!e || typeof e != "object")
1738
2100
  return null;
1739
2101
  const t = e;
@@ -1745,17 +2107,17 @@ function Ge(e) {
1745
2107
  respondsToUserMessageId: typeof t.respondsToUserMessageId == "string" ? t.respondsToUserMessageId : void 0,
1746
2108
  ...typeof t.runId == "string" ? { runId: t.runId } : {},
1747
2109
  dataType: typeof t.dataType == "string" ? t.dataType : void 0,
1748
- attachments: At(t.attachments)?.map(G),
2110
+ attachments: qt(t.attachments)?.map(at),
1749
2111
  loading: typeof t.loading == "boolean" ? t.loading : void 0
1750
2112
  };
1751
2113
  }
1752
- function Xe(e) {
2114
+ function vs(e) {
1753
2115
  return e.attachments?.length ? {
1754
2116
  ...e,
1755
- attachments: e.attachments.map(G)
2117
+ attachments: e.attachments.map(at)
1756
2118
  } : e;
1757
2119
  }
1758
- function G(e) {
2120
+ function at(e) {
1759
2121
  const {
1760
2122
  dataUrl: t,
1761
2123
  objectUrl: s,
@@ -1764,166 +2126,248 @@ function G(e) {
1764
2126
  } = e;
1765
2127
  return r;
1766
2128
  }
1767
- function L(e) {
2129
+ function K(e) {
1768
2130
  const t = e.respondsToUserMessageId;
1769
2131
  return typeof t == "string" && t ? t : null;
1770
2132
  }
1771
- function k(e) {
2133
+ function C(e) {
1772
2134
  const t = e.runId;
1773
2135
  return typeof t == "string" && t ? t : null;
1774
2136
  }
1775
- function Ke(e) {
2137
+ function Ls(e) {
1776
2138
  return !!e && typeof e == "object" && typeof e.summary == "string" && typeof e.javascript == "string";
1777
2139
  }
1778
- function ot(e) {
2140
+ function Ht(e) {
1779
2141
  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)
2142
+ try {
2143
+ new Headers(e).forEach((s, n) => {
2144
+ Object.keys(t).length < it && (t[n] = ct(n, s));
2145
+ });
2146
+ } catch {
2147
+ return {};
2148
+ }
2149
+ return t;
2150
+ }
2151
+ function ct(e, t) {
2152
+ return zt(e) ? x : S(B(t), ke);
2153
+ }
2154
+ function qs(e, t) {
2155
+ return typeof e == "string" ? e : e instanceof URL ? e.toString() : t?.url ?? "";
2156
+ }
2157
+ async function Bs(e, t, s, n) {
2158
+ const r = Ht(e.headers);
2159
+ n({
2160
+ ...t,
2161
+ responseStatus: e.status,
2162
+ responseHeaders: r,
2163
+ responseBody: await Hs(e),
2164
+ durationMs: Date.now() - s
2165
+ });
2166
+ }
2167
+ async function Hs(e) {
2168
+ if (!Ft(e.headers))
2169
+ return;
2170
+ let t = null, s = null;
2171
+ try {
2172
+ if (t = e.clone().body?.getReader() ?? null, !t)
2173
+ return;
2174
+ const n = new Promise((d) => {
2175
+ s = window.setTimeout(() => {
2176
+ t?.cancel(), d("timeout");
2177
+ }, Ee);
2178
+ }), r = new TextDecoder();
2179
+ let i = "", o = 0;
2180
+ for (; ; ) {
2181
+ const d = await Promise.race([t.read(), n]);
2182
+ if (d === "timeout")
2183
+ return;
2184
+ const { done: a, value: h } = d;
2185
+ if (a)
2186
+ return S(i + r.decode());
2187
+ const g = rt - o;
2188
+ if (h.byteLength > g)
2189
+ return i += r.decode(h.subarray(0, Math.max(g, 0)), { stream: !0 }), t.cancel(), `${S(i)}... [truncated]`;
2190
+ o += h.byteLength, i += r.decode(h, { stream: !0 });
2191
+ }
2192
+ } catch {
2193
+ t?.cancel();
2194
+ return;
2195
+ } finally {
2196
+ s !== null && window.clearTimeout(s);
2197
+ }
2198
+ }
2199
+ function Fs(e, t) {
2200
+ if (Ft(new Headers(t)))
1788
2201
  try {
1789
- return I(await e.clone().text());
2202
+ return e.responseType === "" || e.responseType === "text" ? S(e.responseText ?? "") : void 0;
1790
2203
  } catch {
1791
2204
  return;
1792
2205
  }
1793
2206
  }
1794
- async function Ve(e) {
2207
+ function It(e) {
2208
+ if (typeof e == "string")
2209
+ return S(e);
2210
+ }
2211
+ function Ws(e) {
2212
+ return A({
2213
+ ...e,
2214
+ requestBody: St(e.requestBody),
2215
+ responseBody: St(e.responseBody)
2216
+ });
2217
+ }
2218
+ function St(e) {
2219
+ if (typeof e != "string")
2220
+ return e;
2221
+ const t = e.trim();
2222
+ if (!t.startsWith("{") && !t.startsWith("["))
2223
+ return B(e);
1795
2224
  try {
1796
- return I(await e.clone().text());
1797
- } catch (t) {
1798
- return { error: t instanceof Error ? t.message : "unavailable" };
2225
+ return JSON.stringify(A(JSON.parse(e)));
2226
+ } catch {
2227
+ return B(e);
1799
2228
  }
1800
2229
  }
1801
- function Ye(e) {
2230
+ function Ft(e) {
2231
+ if (!e)
2232
+ return !1;
2233
+ const t = e.get("content-type")?.toLowerCase() ?? "", s = e.get("content-length"), n = Number(s);
2234
+ return s !== null && Number.isInteger(n) && n >= 0 && n <= rt && (t.startsWith("text/") || t.includes("json") || t.includes("javascript"));
2235
+ }
2236
+ function P(e, t = {}, s) {
2237
+ if (js(s))
2238
+ return !0;
2239
+ const n = Object.entries(t).find(([r]) => r.toLowerCase() === "content-type")?.[1]?.toLowerCase();
2240
+ if (n?.includes("multipart/form-data") || n?.includes("application/octet-stream"))
2241
+ return !0;
1802
2242
  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" };
2243
+ const r = new URL(e, location.href);
2244
+ if (r.protocol !== "http:" && r.protocol !== "https:")
2245
+ return !0;
2246
+ const i = r.hostname.toLowerCase(), o = r.pathname.toLowerCase();
2247
+ 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));
2248
+ } catch {
2249
+ return !0;
1806
2250
  }
1807
2251
  }
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
- }
2252
+ function xs(e, t) {
2253
+ if (P(e))
2254
+ return !0;
2255
+ try {
2256
+ const s = new URL(e, location.href), n = new URL(t);
2257
+ return s.origin === n.origin && s.pathname.startsWith("/api/product-agent/");
2258
+ } catch {
2259
+ return !0;
1825
2260
  }
1826
2261
  }
1827
- function Ze(e) {
2262
+ function js(e) {
2263
+ return e instanceof FormData || e instanceof Blob || e instanceof ArrayBuffer || ArrayBuffer.isView(e) || typeof ReadableStream < "u" && e instanceof ReadableStream;
2264
+ }
2265
+ function $s(e) {
1828
2266
  const t = {};
1829
2267
  for (const s of e.trim().split(/[\r\n]+/)) {
1830
2268
  const n = s.indexOf(":");
1831
- n <= 0 || (t[s.slice(0, n).trim()] = s.slice(n + 1).trim());
2269
+ if (n <= 0)
2270
+ continue;
2271
+ if (Object.keys(t).length >= it)
2272
+ break;
2273
+ const r = s.slice(0, n).trim();
2274
+ t[r] = ct(r, s.slice(n + 1).trim());
1832
2275
  }
1833
2276
  return t;
1834
2277
  }
1835
- function I(e) {
1836
- return e.length <= F ? e : `${e.slice(0, F)}... [truncated ${e.length - F} chars]`;
2278
+ function S(e, t = rt) {
2279
+ return e.length <= t ? e : `${e.slice(0, t)}... [truncated ${e.length - t} chars]`;
1837
2280
  }
1838
- function U(e) {
2281
+ function J(e) {
1839
2282
  return `${e}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
1840
2283
  }
1841
- class C extends Error {
2284
+ class L extends Error {
1842
2285
  constructor(t, s) {
1843
2286
  super(`${t} (${s})`), this.status = s, this.name = "AttachmentUploadHttpError";
1844
2287
  }
1845
2288
  status;
1846
2289
  }
1847
- async function H(e, t) {
2290
+ async function V(e, t) {
1848
2291
  let s = null;
1849
- for (let n = 0; n < Y; n += 1)
2292
+ for (let n = 0; n < pt; n += 1)
1850
2293
  try {
1851
2294
  return await e();
1852
2295
  } catch (r) {
1853
- if (s = r, n >= Y - 1 || !ts(r))
2296
+ if (s = r, n >= pt - 1 || !Gs(r))
1854
2297
  throw r;
1855
- await Qe(n);
2298
+ await zs(n);
1856
2299
  }
1857
2300
  throw s instanceof Error ? s : new Error(t);
1858
2301
  }
1859
- function Qe(e) {
2302
+ function zs(e) {
1860
2303
  return new Promise((t) => {
1861
- window.setTimeout(t, $t[e] ?? 0);
2304
+ window.setTimeout(t, Se[e] ?? 0);
1862
2305
  });
1863
2306
  }
1864
- function ts(e) {
1865
- return e instanceof C ? es(e.status) : e instanceof TypeError;
2307
+ function Gs(e) {
2308
+ return e instanceof L ? Xs(e.status) : e instanceof TypeError;
1866
2309
  }
1867
- function es(e) {
2310
+ function Xs(e) {
1868
2311
  return e === 408 || e === 409 || e === 429 || e >= 500;
1869
2312
  }
1870
- function ss(e) {
2313
+ function Ks(e) {
1871
2314
  return e === 401 || e === 403;
1872
2315
  }
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());
2316
+ 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 = /[),.;\]]+$/;
2317
+ function A(e) {
2318
+ return q(e, 0, /* @__PURE__ */ new WeakSet());
1876
2319
  }
1877
- function M(e, t, s) {
2320
+ function q(e, t, s) {
1878
2321
  if (typeof e == "string")
1879
- return e.startsWith("data:image/") || e.startsWith("data:application/pdf;") ? e : ds(e);
2322
+ return e.startsWith("data:image/") || e.startsWith("data:application/pdf;") ? e : B(e);
1880
2323
  if (e === null || typeof e != "object")
1881
2324
  return e;
1882
- if (t >= rs)
2325
+ if (t >= Vs)
1883
2326
  return "[REDACTED_MAX_DEPTH]";
1884
2327
  if (s.has(e))
1885
2328
  return "[REDACTED_CIRCULAR]";
1886
2329
  if (s.add(e), Array.isArray(e))
1887
- return e.map((r) => M(r, t + 1, s));
2330
+ return e.map((r) => q(r, t + 1, s));
1888
2331
  const n = {};
1889
2332
  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);
2333
+ zt(r) ? n[r] = x : n[r] = r.toLowerCase() === "url" ? en(i) : q(i, t + 1, s);
1891
2334
  return n;
1892
2335
  }
1893
- function ls(e) {
2336
+ function zt(e) {
1894
2337
  const t = e.replace(/[^a-z0-9]/gi, "").toLowerCase();
1895
2338
  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
2339
  }
1897
- function us(e) {
1898
- return typeof e == "string" ? Pt(e) : M(e, 0, /* @__PURE__ */ new WeakSet());
2340
+ function en(e) {
2341
+ return typeof e == "string" ? Gt(e) : q(e, 0, /* @__PURE__ */ new WeakSet());
1899
2342
  }
1900
- function Pt(e) {
2343
+ function Gt(e) {
1901
2344
  try {
1902
2345
  const t = new URL(e, location.href);
1903
2346
  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();
2347
+ Ys.test(s) && t.searchParams.set(s, k);
2348
+ return t.username && (t.username = k), t.password && (t.password = k), t.toString();
1906
2349
  } catch {
1907
- return hs(e);
2350
+ return sn(e);
1908
2351
  }
1909
2352
  }
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}`);
2353
+ function B(e) {
2354
+ 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
2355
  }
1913
- function hs(e) {
1914
- return e.replace(kt, `Bearer ${w}`).replace(Et, `Basic ${w}`).replace(Rt, w).replace(_t, (t, s) => `${s}: ${X}`);
2356
+ function sn(e) {
2357
+ return e.replace(Wt, `Bearer ${k}`).replace(xt, `Basic ${k}`).replace(jt, k).replace($t, (t, s) => `${s}: ${x}`);
1915
2358
  }
1916
- function ps(e) {
1917
- const t = e.match(cs)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
1918
- return `${Pt(s)}${t}`;
2359
+ function nn(e) {
2360
+ const t = e.match(tn)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
2361
+ return `${Gt(s)}${t}`;
1919
2362
  }
1920
2363
  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
2364
+ lt as PLUNO_PRODUCT_AGENT_SDK_PREVIEW_HOST_SELECTOR,
2365
+ Z as PLUNO_PRODUCT_AGENT_WIDGET_HOST_SELECTOR,
2366
+ ie as PLUNO_PRODUCT_AGENT_WIDGET_PANEL_SELECTOR,
2367
+ re as PLUNO_PRODUCT_AGENT_WIDGET_ROOT_SELECTOR,
2368
+ oe as PLUNO_PRODUCT_AGENT_WIDGET_TIMELINE_SELECTOR,
2369
+ Pt as PlunoProductAgent,
2370
+ be as calculateReconnectDelay,
2371
+ Pt as default,
2372
+ We as getProductAgentOriginAccessErrorMessage
1929
2373
  };