@pluno/product-agent-web 0.1.59 → 0.1.61

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 Et = "pluno-product-agent-attachments";
2
- const H = "files";
3
- async function it(e) {
4
- const t = await U();
5
- await at(t, "readwrite", (s) => s.put(e));
6
- }
7
- async function Rt(e) {
8
- const t = await U(), s = await at(
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 Ct(e) {
8
+ const t = await D(), s = await lt(
9
9
  t,
10
10
  "readonly",
11
11
  (r) => r.get(e)
@@ -13,12 +13,12 @@ async function Rt(e) {
13
13
  if (!s)
14
14
  return null;
15
15
  const n = Date.now();
16
- return await ot(e, { lastUsedAt: n }), { ...s, lastUsedAt: n };
16
+ return await ct(e, { lastUsedAt: n }), { ...s, lastUsedAt: n };
17
17
  }
18
- async function ot(e, t) {
19
- const s = await U();
20
- await v(s, "readwrite", async (n) => {
21
- const r = await j(
18
+ async function ct(e, t) {
19
+ const s = await D();
20
+ await $(s, "readwrite", async (n) => {
21
+ const r = await z(
22
22
  n.get(e)
23
23
  );
24
24
  r && n.put({
@@ -27,28 +27,28 @@ async function ot(e, t) {
27
27
  });
28
28
  });
29
29
  }
30
- async function _t(e = 864e5) {
31
- const t = await U(), s = Date.now() - e;
32
- await v(t, "readwrite", async (n) => {
30
+ async function Mt(e = 864e5) {
31
+ const t = await D(), s = Date.now() - e;
32
+ await $(t, "readwrite", async (n) => {
33
33
  const r = n.index("lastUsedAt");
34
- (await j(r.getAllKeys(IDBKeyRange.upperBound(s)))).forEach((o) => n.delete(o));
34
+ (await z(r.getAllKeys(IDBKeyRange.upperBound(s)))).forEach((o) => n.delete(o));
35
35
  });
36
36
  }
37
- function U() {
37
+ function D() {
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(Et, 1);
39
+ const s = indexedDB.open(Ut, 1);
40
40
  s.onupgradeneeded = () => {
41
- const r = s.result.createObjectStore(H, { keyPath: "attachmentId" });
41
+ const r = s.result.createObjectStore(W, { 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 at(e, t, s) {
47
- return await v(e, t, async (n) => await j(s(n)));
46
+ async function lt(e, t, s) {
47
+ return await $(e, t, async (n) => await z(s(n)));
48
48
  }
49
- function v(e, t, s) {
49
+ function $(e, t, s) {
50
50
  return new Promise((n, r) => {
51
- const i = e.transaction(H, t), o = i.objectStore(H);
51
+ const i = e.transaction(W, t), o = i.objectStore(W);
52
52
  let c, a = !1;
53
53
  s(o).then((d) => {
54
54
  c = d;
@@ -68,19 +68,20 @@ function v(e, t, s) {
68
68
  };
69
69
  });
70
70
  }
71
- function j(e) {
71
+ function z(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"]', Pt = '.pluno-pa-widget[data-pluno-product-agent-ui-root="widget"]', Mt = ".pluno-pa-widget__panel", bt = ".pluno-pa-widget__timeline", X = `${B}[data-pluno-sdk-preview-channel]`, Ut = "https://app.pluno.ai", Ct = "gpt-5.4", Dt = 2e4, Nt = 2e3, E = 6e4, qt = 15e3, K = 2, Ot = 15e3, Ft = 5e3, Ht = 1e3, Bt = 8e3, Wt = 15e3, J = 3, Lt = [300, 1e3], q = 1e5, xt = 200 * 1024 * 1024, vt = "Image is too large for model vision input.", jt = 100, ct = "pluno.productAgent.state.", W = "pluno.productAgent.pendingEvents.", V = "pluno.productAgent.transportId";
77
- class ut {
76
+ const B = '.pluno-pa-widget-host[data-pluno-product-agent-ui="widget"]', bt = '.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, C = /* @__PURE__ */ new Set();
77
+ let R = null;
78
+ class dt {
78
79
  constructor(t) {
79
- this.options = t, this.transportId = ue(), this.state = {
80
+ this.options = t, this.transportId = me(), this.state = {
80
81
  ...this.state,
81
- starterPrompts: ne(t.initialStarterPrompts)
82
+ starterPrompts: ue(t.initialStarterPrompts)
82
83
  };
83
- const s = t.restorePersistedState === !1 ? null : Ne(t.clientId, t.expectedPersistedSessionId);
84
+ const s = t.restorePersistedState === !1 ? null : We(t.clientId, t.expectedPersistedSessionId);
84
85
  s && (this.state = {
85
86
  ...this.state,
86
87
  ...s,
@@ -91,7 +92,7 @@ class ut {
91
92
  assistantDraftRunId: null,
92
93
  isThinking: !1,
93
94
  lastError: null
94
- }), this.queuedClientEvents = Oe(t.clientId);
95
+ }), this.queuedClientEvents = ve(t.clientId);
95
96
  }
96
97
  options;
97
98
  listeners = {};
@@ -122,6 +123,9 @@ class ut {
122
123
  sessionUserFilesApiCleanup = null;
123
124
  transientStarterPromptsRequestInFlight = !1;
124
125
  transientStarterPromptsRequestAttempted = !1;
126
+ locationChangeCleanup = null;
127
+ starterPromptUrlRefreshTimer = null;
128
+ lastStarterPromptPageUrl = location.href;
125
129
  state = {
126
130
  status: "idle",
127
131
  user: null,
@@ -138,18 +142,18 @@ class ut {
138
142
  lastErrorCode: null
139
143
  };
140
144
  static async init(t) {
141
- const s = new ut({
145
+ const s = new dt({
142
146
  ...t,
143
- backendUrl: Yt(t.backendUrl ?? Ut),
144
- clientId: t.clientId ?? ce(),
145
- model: t.model ?? Ct
147
+ backendUrl: se(t.backendUrl ?? qt),
148
+ clientId: t.clientId ?? fe(),
149
+ model: t.model ?? Ot
146
150
  });
147
151
  try {
148
- _t().catch((n) => {
152
+ Mt().catch((n) => {
149
153
  g("web-sdk.attachments", "Failed to delete stale Product Agent attachments", {
150
154
  message: n instanceof Error ? n.message : String(n)
151
155
  });
152
- }), s.enableNetworkCapture(), t.autoConnect !== !1 && await s.connect();
156
+ }), s.enableNetworkCapture(), s.startStarterPromptUrlWatcher(), t.autoConnect !== !1 && await s.connect();
153
157
  } catch (n) {
154
158
  throw s.destroy(), n;
155
159
  }
@@ -172,7 +176,7 @@ class ut {
172
176
  return;
173
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)
174
178
  throw new Error("Pluno requires a token or tokenProvider");
175
- const t = Zt(this.options.backendUrl), s = this.options.webSocketFactory?.(t) ?? new WebSocket(t);
179
+ const t = ne(this.options.backendUrl), s = this.options.webSocketFactory?.(t) ?? new WebSocket(t);
176
180
  this.socket = s, s.addEventListener("open", () => {
177
181
  this.socket === s && (g("web-sdk.agent", "Pluno socket opened", {
178
182
  queuedClientEventCount: this.queuedClientEvents.length,
@@ -181,10 +185,11 @@ class ut {
181
185
  type: "auth.session",
182
186
  token: this.token,
183
187
  clientId: this.options.clientId,
184
- transportId: this.transportId
188
+ transportId: this.transportId,
189
+ pageUrl: location.href
185
190
  }), this.flushQueuedClientEvents(), this.startHeartbeat(), this.setState({ status: "connected", lastError: null }));
186
191
  }), s.addEventListener("message", (n) => {
187
- this.socket === s && this.handleServerEvent(se(n.data));
192
+ this.socket === s && this.handleServerEvent(le(n.data));
188
193
  }), s.addEventListener("close", (n) => {
189
194
  this.socket === s && (this.stopHeartbeat(), this.socket = null, this.state.status !== "closed" && (g("web-sdk.agent", "Pluno socket closed; scheduling reconnect", {
190
195
  code: typeof n?.code == "number" ? n.code : null,
@@ -201,18 +206,18 @@ class ut {
201
206
  });
202
207
  }
203
208
  disconnect() {
204
- this.setState({ status: "closed", isThinking: !1 }), this.stopHeartbeat(), 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;
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;
205
210
  }
206
211
  destroy() {
207
- this.disconnect(), this.cleanupSessionUserFilesApi(), this.networkCaptureCleanup?.(), this.networkCaptureCleanup = null;
212
+ this.disconnect(), this.locationChangeCleanup?.(), this.locationChangeCleanup = null, this.cleanupSessionUserFilesApi(), this.networkCaptureCleanup?.(), this.networkCaptureCleanup = null;
208
213
  for (const t of Object.values(this.listeners))
209
214
  t?.clear();
210
215
  }
211
216
  sendMessage(t, s = {}) {
212
- const n = t.trim(), r = s.attachments ?? [], i = r.map($);
217
+ const n = t.trim(), r = s.attachments ?? [], i = r.map(G);
213
218
  if (!n && i.length === 0)
214
219
  return null;
215
- const o = y(), c = R(), a = {
220
+ const o = y(), c = _(), a = {
216
221
  id: `local-${c}`,
217
222
  role: "user",
218
223
  content: n,
@@ -237,20 +242,20 @@ class ut {
237
242
  attachments: i.length > 0 ? i : void 0,
238
243
  page: o,
239
244
  model: this.options.model,
240
- metadata: Y(this.options.metadata)
245
+ metadata: Q(this.options.metadata)
241
246
  };
242
247
  return this.activeClientMessageId = c, this.activeUserMessageEvent = d, this.markThinkingProgress(), this.send(d), this.startBackgroundAttachmentUploads(c, i), c;
243
248
  }
244
249
  createLocalAttachment(t) {
245
- const s = R(), n = {
250
+ const s = _(), n = {
246
251
  id: s,
247
252
  name: t.name || "attachment",
248
- mimeType: nt(t),
253
+ mimeType: it(t),
249
254
  sizeBytes: t.size
250
255
  };
251
256
  this.attachmentFiles.set(s, t), this.attachmentBlobCache.set(s, t);
252
257
  const r = Date.now();
253
- return it({
258
+ return at({
254
259
  attachmentId: s,
255
260
  name: n.name,
256
261
  mimeType: n.mimeType,
@@ -273,7 +278,7 @@ class ut {
273
278
  return await this.uploadAttachmentForMessage({
274
279
  file: t,
275
280
  attachment: s,
276
- clientMessageId: R(),
281
+ clientMessageId: _(),
277
282
  waitForSession: !1,
278
283
  notifyCompletion: !1
279
284
  });
@@ -305,7 +310,7 @@ class ut {
305
310
  waitForSession: r,
306
311
  notifyCompletion: i
307
312
  }) {
308
- const o = r ? await this.waitForSessionId() : this.state.sessionId, c = nt(t), a = {
313
+ const o = r ? await this.waitForSessionId() : this.state.sessionId, c = it(t), a = {
309
314
  sessionId: o ?? void 0,
310
315
  attachmentId: s.id,
311
316
  clientId: this.options.clientId,
@@ -315,32 +320,32 @@ class ut {
315
320
  sizeBytes: t.size,
316
321
  page: y(),
317
322
  model: this.options.model,
318
- metadata: Y(this.options.metadata)
319
- }, d = this.options.prepareAttachmentUpload ? await F(
323
+ metadata: Q(this.options.metadata)
324
+ }, d = this.options.prepareAttachmentUpload ? await H(
320
325
  () => this.options.prepareAttachmentUpload(a),
321
326
  "Failed to prepare attachment upload"
322
327
  ) : await this.prepareEmbedAttachmentUpload(a);
323
- await F(async () => {
324
- const u = await fetch(d.uploadUrl, {
328
+ await H(async () => {
329
+ const l = await fetch(d.uploadUrl, {
325
330
  method: d.uploadMethod,
326
331
  headers: d.uploadHeaders,
327
332
  body: t
328
333
  });
329
- if (!u.ok)
330
- throw new M("Failed to upload attachment", u.status);
331
- return u;
334
+ if (!l.ok)
335
+ throw new M("Failed to upload attachment", l.status);
336
+ return l;
332
337
  }, "Failed to upload attachment"), this.setState({ sessionId: d.sessionId });
333
- const h = yt(d.attachment, this.options.backendUrl);
334
- return this.updateAttachmentInState(s.id, h), s.id && ot(s.id, {
338
+ const h = At(d.attachment, this.options.backendUrl);
339
+ return this.updateAttachmentInState(s.id, h), s.id && ct(s.id, {
335
340
  sessionId: d.sessionId,
336
341
  fileUrl: h.fileUrl,
337
342
  gcsPath: h.gcsPath,
338
343
  lastUsedAt: Date.now()
339
- }).catch((u) => {
344
+ }).catch((l) => {
340
345
  g("web-sdk.attachments", "Failed to update persisted Product Agent attachment", {
341
346
  attachmentId: s.id,
342
347
  name: h.name,
343
- message: u instanceof Error ? u.message : String(u)
348
+ message: l instanceof Error ? l.message : String(l)
344
349
  });
345
350
  }), i && h.gcsPath && this.send({
346
351
  type: "attachment.upload_completed",
@@ -353,7 +358,7 @@ class ut {
353
358
  return this.state.sessionId ? Promise.resolve(this.state.sessionId) : new Promise((t, s) => {
354
359
  const n = window.setTimeout(() => {
355
360
  r(), s(new Error("Timed out waiting for Pluno session before persisting attachment"));
356
- }, Wt), r = this.on("state", (i) => {
361
+ }, jt), r = this.on("state", (i) => {
357
362
  i.sessionId && (window.clearTimeout(n), r(), t(i.sessionId));
358
363
  });
359
364
  });
@@ -371,11 +376,11 @@ class ut {
371
376
  }
372
377
  async prepareEmbedAttachmentUpload(t) {
373
378
  let s = !1;
374
- return await F(async () => {
379
+ return await H(async () => {
375
380
  const n = await this.fetchEmbedAttachmentUpload(t);
376
381
  if (n.ok)
377
382
  return await n.json();
378
- if (Je(n.status) && this.options.tokenProvider && !s) {
383
+ if (es(n.status) && this.options.tokenProvider && !s) {
379
384
  s = !0;
380
385
  const r = await this.fetchEmbedAttachmentUpload(t);
381
386
  if (r.ok)
@@ -416,10 +421,10 @@ class ut {
416
421
  });
417
422
  }
418
423
  listSessions(t = {}) {
419
- const s = R(), n = new Promise((i, o) => {
424
+ const s = _(), n = new Promise((i, o) => {
420
425
  const c = window.setTimeout(() => {
421
426
  this.pendingSessionHistoryRequests.delete(s), o(new Error("Session history did not respond in time"));
422
- }, Bt);
427
+ }, xt);
423
428
  this.pendingSessionHistoryRequests.set(s, { resolve: i, reject: o, timeout: c });
424
429
  }), r = {
425
430
  type: "sessions.list",
@@ -450,7 +455,7 @@ class ut {
450
455
  });
451
456
  }
452
457
  send(t) {
453
- this.sendNow(w(t)) || (this.queuedClientEvents.push(t), _(this.options.clientId, this.queuedClientEvents), this.setState({ status: "reconnecting" }), this.scheduleReconnect());
458
+ this.sendNow(T(t)) || (this.queuedClientEvents.push(t), P(this.options.clientId, this.queuedClientEvents), this.setState({ status: "reconnecting" }), this.scheduleReconnect());
454
459
  }
455
460
  async getUploadToken() {
456
461
  const t = this.options.token ?? await this.options.tokenProvider?.() ?? this.token ?? null;
@@ -476,9 +481,9 @@ class ut {
476
481
  if (this.state.starterPromptsLoading || this.transientStarterPromptsRequestInFlight || this.transientStarterPromptsRequestAttempted)
477
482
  return;
478
483
  this.transientStarterPromptsRequestInFlight = !0, this.transientStarterPromptsRequestAttempted = !0, this.setState({ starterPromptsLoading: !0 });
479
- const t = Qt();
484
+ const t = re();
480
485
  this.sendNow(
481
- w({
486
+ T({
482
487
  type: "starter_prompts.page_context",
483
488
  pageUrl: t.pageUrl,
484
489
  pageTitle: t.pageTitle,
@@ -486,18 +491,36 @@ class ut {
486
491
  })
487
492
  ) || (this.transientStarterPromptsRequestInFlight = !1, this.transientStarterPromptsRequestAttempted = !1, this.setState({ starterPromptsLoading: !1 }));
488
493
  }
494
+ startStarterPromptUrlWatcher() {
495
+ this.locationChangeCleanup || (this.locationChangeCleanup = ie(() => this.handleStarterPromptUrlChange()));
496
+ }
497
+ handleStarterPromptUrlChange() {
498
+ const t = location.href;
499
+ t !== this.lastStarterPromptPageUrl && (this.lastStarterPromptPageUrl = t, this.clearStarterPromptUrlRefreshTimer(), this.starterPromptUrlRefreshTimer = window.setTimeout(() => {
500
+ this.starterPromptUrlRefreshTimer = null, this.refreshStarterPromptsForCurrentUrl();
501
+ }, Kt));
502
+ }
503
+ refreshStarterPromptsForCurrentUrl() {
504
+ this.socket?.readyState !== WebSocket.OPEN || this.state.status === "closed" || (this.setState({ starterPromptsLoading: this.state.messages.length === 0 }), this.sendNow({
505
+ type: "starter_prompts.page_url",
506
+ pageUrl: location.href
507
+ }));
508
+ }
509
+ clearStarterPromptUrlRefreshTimer() {
510
+ this.starterPromptUrlRefreshTimer !== null && (window.clearTimeout(this.starterPromptUrlRefreshTimer), this.starterPromptUrlRefreshTimer = null);
511
+ }
489
512
  flushQueuedClientEvents() {
490
513
  if (this.socket?.readyState !== WebSocket.OPEN || this.queuedClientEvents.length === 0)
491
514
  return;
492
515
  const t = this.queuedClientEvents.splice(0, this.queuedClientEvents.length);
493
- _(this.options.clientId, this.queuedClientEvents);
516
+ P(this.options.clientId, this.queuedClientEvents);
494
517
  for (let s = 0; s < t.length; s += 1) {
495
518
  const n = t[s];
496
- if (!this.sendNow(w(n))) {
497
- this.queuedClientEvents.unshift(n, ...t.slice(s + 1)), _(this.options.clientId, this.queuedClientEvents);
519
+ if (!this.sendNow(T(n))) {
520
+ this.queuedClientEvents.unshift(n, ...t.slice(s + 1)), P(this.options.clientId, this.queuedClientEvents);
498
521
  return;
499
522
  }
500
- _(this.options.clientId, this.queuedClientEvents);
523
+ P(this.options.clientId, this.queuedClientEvents);
501
524
  }
502
525
  }
503
526
  handleServerEvent(t) {
@@ -505,18 +528,18 @@ class ut {
505
528
  this.handleRunAck(t);
506
529
  return;
507
530
  }
508
- if ($t(t) && this.markThinkingProgress(), t.type === "auth.ok") {
509
- const s = re(t), n = Object.prototype.hasOwnProperty.call(t, "appearance");
531
+ if (Jt(t) && this.markThinkingProgress(), t.type === "auth.ok") {
532
+ const s = de(t), n = Object.prototype.hasOwnProperty.call(t, "appearance");
510
533
  g("web-sdk.agent", "Received auth.ok appearance", {
511
534
  hasAppearance: n,
512
535
  rawAppearance: t.appearance,
513
536
  normalizedAppearance: s
514
- }), this.runtimeHelperJavascript = ie(t.runtimeHelpers)?.javascript ?? null;
515
- const r = tt(t, "starterPrompts"), i = Object.prototype.hasOwnProperty.call(t, "starterPrompts"), o = t.starterPromptsLoading === !0, c = {
516
- user: le(t.user),
537
+ }), this.runtimeHelperJavascript = he(t.runtimeHelpers)?.javascript ?? null;
538
+ const r = st(t, "starterPrompts"), i = Object.prototype.hasOwnProperty.call(t, "starterPrompts"), o = t.starterPromptsLoading === !0, c = {
539
+ user: ye(t.user),
517
540
  status: "connected"
518
541
  };
519
- (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 && !te() && this.requestTransientStarterPrompts(), this.state.sessionId && this.send({
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 && !ae() && this.requestTransientStarterPrompts(), this.state.sessionId && this.send({
520
543
  type: "page.upsert",
521
544
  sessionId: this.state.sessionId,
522
545
  page: y(),
@@ -526,18 +549,21 @@ class ut {
526
549
  }
527
550
  if (t.type === "starterPrompts.updated") {
528
551
  this.transientStarterPromptsRequestInFlight = !1, this.transientStarterPromptsRequestAttempted = !0, this.setState({
529
- starterPrompts: tt(t, "starterPrompts"),
552
+ starterPrompts: st(t, "starterPrompts"),
530
553
  starterPromptsLoading: !1
531
554
  });
532
555
  return;
533
556
  }
534
557
  if (t.type === "conversation.state") {
535
- const s = Array.isArray(t.items) ? t.items : [], n = we(
558
+ const s = Array.isArray(t.items) ? t.items : [], n = _e(
536
559
  this.state.messages,
537
- de(s, this.options.backendUrl)
538
- ), r = et(n), i = r ? null : _e(s);
539
- this.latestRecoverableClientMessageId = i, ke(n) && this.clearRetryTimers(), this.setState({
540
- sessionId: A(t.session, "id") ?? this.state.sessionId,
560
+ we(s, this.options.backendUrl)
561
+ ), r = nt(n);
562
+ if (!r && be(this.state.messages, s))
563
+ return;
564
+ const i = r ? null : De(s);
565
+ this.latestRecoverableClientMessageId = i, Me(n) && this.clearRetryTimers(), this.setState({
566
+ sessionId: I(t.session, "id") ?? this.state.sessionId,
541
567
  messages: n,
542
568
  ...r ? { assistantDraft: "", assistantDraftRespondsToUserMessageId: null, assistantDraftRunId: null, isThinking: !1 } : i ? {
543
569
  assistantDraft: "",
@@ -552,22 +578,22 @@ class ut {
552
578
  if (t.type === "sessions.page") {
553
579
  const s = typeof t.requestId == "string" ? t.requestId : null, n = s ? this.pendingSessionHistoryRequests.get(s) : null;
554
580
  s && n && (window.clearTimeout(n.timeout), this.pendingSessionHistoryRequests.delete(s), n.resolve({
555
- sessions: he(t.sessions),
581
+ sessions: Te(t.sessions),
556
582
  nextCursor: typeof t.nextCursor == "string" ? t.nextCursor : null
557
583
  }));
558
584
  return;
559
585
  }
560
586
  if (t.type === "session.updated") {
561
- this.clearRunAckResyncRetryTimer(), this.setState({ sessionId: A(t.session, "id") ?? this.state.sessionId });
587
+ this.clearRunAckResyncRetryTimer(), this.setState({ sessionId: I(t.session, "id") ?? this.state.sessionId });
562
588
  return;
563
589
  }
564
590
  if (t.type === "session.item") {
565
- const s = dt(t.item, this.options.backendUrl);
591
+ const s = pt(t.item, this.options.backendUrl);
566
592
  if (s) {
567
593
  s.role === "assistant" && (this.clearRetryTimers(), this.clearRunAckResyncRetryTimer());
568
594
  const n = t.item.data;
569
- Pe(n) && this.clearRunAckResyncRetryTimer();
570
- const r = Te(this.state.messages, s), i = et(r);
595
+ Ne(n) && this.clearRunAckResyncRetryTimer();
596
+ const r = Re(this.state.messages, s), i = nt(r);
571
597
  this.setState({
572
598
  messages: r,
573
599
  assistantDraft: s.role === "assistant" ? "" : this.state.assistantDraft,
@@ -666,7 +692,7 @@ class ut {
666
692
  scheduleRunAckWatchdog(t) {
667
693
  this.runAckWatchdogTimer !== null && window.clearTimeout(this.runAckWatchdogTimer), this.runAckWatchdogTimer = window.setTimeout(() => {
668
694
  this.runAckWatchdogTimer = null, this.recoverMissedRunAck(t);
669
- }, Ot);
695
+ }, Wt);
670
696
  }
671
697
  recoverMissedRunAck(t) {
672
698
  !this.state.isThinking || this.state.status === "closed" || this.activeClientMessageId !== t || (g("web-sdk.agent", "Pluno run ack missed; resyncing session", {
@@ -676,7 +702,7 @@ class ut {
676
702
  }
677
703
  scheduleRunAckResyncRetry(t) {
678
704
  this.clearRunAckResyncRetryTimer(), this.runAckResyncRetryTimer = window.setTimeout(() => {
679
- 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] = K, this.setState({
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({
680
706
  status: this.state.status === "reconnecting" ? "reconnecting" : "connected",
681
707
  isThinking: !0,
682
708
  lastError: null
@@ -688,7 +714,7 @@ class ut {
688
714
  sessionId: this.state.sessionId,
689
715
  clientMessageId: t
690
716
  }) : this.activeUserMessageEvent && this.send(this.activeUserMessageEvent), this.scheduleThinkingWatchdog(E)));
691
- }, Ft);
717
+ }, Bt);
692
718
  }
693
719
  clearRunAckResyncRetryTimer() {
694
720
  this.runAckResyncRetryTimer !== null && (window.clearTimeout(this.runAckResyncRetryTimer), this.runAckResyncRetryTimer = null);
@@ -712,10 +738,10 @@ class ut {
712
738
  sessionId: this.state.sessionId,
713
739
  clientMessageId: t,
714
740
  resyncAttempts: s + 1
715
- }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(qt);
741
+ }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(Ht);
716
742
  return;
717
743
  }
718
- if (n >= K) {
744
+ if (n >= V) {
719
745
  g("web-sdk.agent", "Pluno thinking watchdog retry limit reached; continuing resync", {
720
746
  sessionId: this.state.sessionId,
721
747
  clientMessageId: t,
@@ -749,15 +775,15 @@ class ut {
749
775
  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;
750
776
  if (!s || !n || !r)
751
777
  return;
752
- if (r !== "execute_code" || !xe(o)) {
778
+ if (r !== "execute_code" || !Xe(o)) {
753
779
  this.send({
754
780
  type: "tool.result",
755
781
  sessionId: s,
756
782
  callId: n,
757
783
  toolName: r,
758
784
  summary: i,
759
- rawInput: w(o),
760
- rawOutput: w({
785
+ rawInput: T(o),
786
+ rawOutput: T({
761
787
  ok: !1,
762
788
  toolName: r,
763
789
  error: `Unsupported browser tool: ${r}`
@@ -765,10 +791,10 @@ class ut {
765
791
  });
766
792
  return;
767
793
  }
768
- const c = Gt(this.state.messages);
794
+ const c = Yt(this.state.messages);
769
795
  this.installSessionUserFilesApi(c);
770
796
  let a = null, d;
771
- a = await this.executeRuntimeHelper(), d = await Q(o).catch((h) => ({
797
+ a = await this.executeRuntimeHelper(), d = await et(o).catch((h) => ({
772
798
  ok: !1,
773
799
  exception: {
774
800
  message: h instanceof Error ? h.message : String(h)
@@ -779,51 +805,51 @@ class ut {
779
805
  callId: n,
780
806
  toolName: r,
781
807
  summary: o.summary,
782
- rawInput: w(o),
783
- rawOutput: w(oe(d, a))
808
+ rawInput: T(o),
809
+ rawOutput: T(pe(d, a))
784
810
  });
785
811
  }
786
812
  installSessionUserFilesApi(t) {
787
- this.cleanupSessionUserFilesApi(), this.sessionUserFilesApiCleanup = Xt(t, this.attachmentFiles, this.attachmentBlobCache);
813
+ this.cleanupSessionUserFilesApi(), this.sessionUserFilesApiCleanup = Zt(t, this.attachmentFiles, this.attachmentBlobCache);
788
814
  }
789
815
  cleanupSessionUserFilesApi() {
790
- this.sessionUserFilesApiCleanup && (Kt(this.sessionUserFilesApiCleanup), this.sessionUserFilesApiCleanup = null);
816
+ this.sessionUserFilesApiCleanup && (Qt(this.sessionUserFilesApiCleanup), this.sessionUserFilesApiCleanup = null);
791
817
  }
792
818
  async executeRuntimeHelper() {
793
819
  if (!this.runtimeHelperJavascript?.trim())
794
820
  return null;
795
- const t = await Q({
821
+ const t = await et({
796
822
  javascript: this.runtimeHelperJavascript
797
823
  });
798
- return t.ok === !1 ? ae(t) : null;
824
+ return t.ok === !1 ? ge(t) : null;
799
825
  }
800
826
  enableNetworkCapture() {
801
827
  if (this.networkCaptureCleanup)
802
828
  return;
803
829
  const t = window.fetch.bind(window), s = XMLHttpRequest.prototype.open, n = XMLHttpRequest.prototype.setRequestHeader, r = XMLHttpRequest.prototype.send;
804
830
  window.fetch = async (i, o) => {
805
- 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 ?? "", u = (o?.method ?? d?.method ?? "GET").toUpperCase(), l = rt(new Headers(o?.headers ?? d?.headers ?? void 0)), f = await ve(d, 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 Ke(d, o);
806
832
  try {
807
833
  const p = await t(i, o);
808
834
  return this.enqueueNetworkEvent({
809
- requestId: P("fetch"),
835
+ requestId: U("fetch"),
810
836
  url: h,
811
- method: u,
812
- requestHeaders: l,
837
+ method: l,
838
+ requestHeaders: u,
813
839
  requestBody: f,
814
840
  resourceType: "fetch",
815
841
  responseStatus: p.status,
816
- responseHeaders: rt(p.headers),
817
- responseBody: await je(p),
842
+ responseHeaders: ot(p.headers),
843
+ responseBody: await Je(p),
818
844
  startedAt: a,
819
845
  durationMs: Date.now() - c
820
846
  }), p;
821
847
  } catch (p) {
822
848
  throw this.enqueueNetworkEvent({
823
- requestId: P("fetch"),
849
+ requestId: U("fetch"),
824
850
  url: h,
825
- method: u,
826
- requestHeaders: l,
851
+ method: l,
852
+ requestHeaders: u,
827
853
  requestBody: f,
828
854
  resourceType: "fetch",
829
855
  errorText: p instanceof Error ? p.message : String(p),
@@ -833,7 +859,7 @@ class ut {
833
859
  }
834
860
  }, XMLHttpRequest.prototype.open = function(o, c, a, d, h) {
835
861
  return this.__plunoMeta = {
836
- requestId: P("xhr"),
862
+ requestId: U("xhr"),
837
863
  method: String(o ?? "GET").toUpperCase(),
838
864
  url: typeof c == "string" ? c : c.toString(),
839
865
  requestHeaders: {},
@@ -849,14 +875,14 @@ class ut {
849
875
  return n.call(this, o, c);
850
876
  }, XMLHttpRequest.prototype.send = function(o) {
851
877
  const c = window.__plunoProductAgentInstance, a = this.__plunoMeta ?? {
852
- requestId: P("xhr"),
878
+ requestId: U("xhr"),
853
879
  method: "GET",
854
880
  url: "",
855
881
  requestHeaders: {},
856
882
  startedAtMs: Date.now(),
857
883
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
858
884
  };
859
- return a.requestBody = Tt(o), this.__plunoMeta = a, this.addEventListener(
885
+ return a.requestBody = St(o), this.__plunoMeta = a, this.addEventListener(
860
886
  "loadend",
861
887
  function() {
862
888
  !c || !this.__plunoMeta || c.enqueueNetworkEvent({
@@ -867,8 +893,8 @@ class ut {
867
893
  requestBody: typeof this.__plunoMeta.requestBody == "string" ? this.__plunoMeta.requestBody : void 0,
868
894
  resourceType: "xhr",
869
895
  responseStatus: this.status,
870
- responseHeaders: ze(this.getAllResponseHeaders()),
871
- responseBody: $e(this),
896
+ responseHeaders: Ye(this.getAllResponseHeaders()),
897
+ responseBody: Ve(this),
872
898
  errorText: this.status === 0 ? "XHR request failed or was aborted" : void 0,
873
899
  startedAt: String(this.__plunoMeta.startedAt),
874
900
  durationMs: Date.now() - Number(this.__plunoMeta.startedAtMs ?? Date.now())
@@ -881,7 +907,7 @@ class ut {
881
907
  };
882
908
  }
883
909
  enqueueNetworkEvent(t) {
884
- this.queuedNetworkEvents.push(w(t)), this.networkBatchTimer === null && (this.networkBatchTimer = window.setTimeout(() => {
910
+ this.queuedNetworkEvents.push(T(t)), this.networkBatchTimer === null && (this.networkBatchTimer = window.setTimeout(() => {
885
911
  this.networkBatchTimer = null;
886
912
  const s = this.queuedNetworkEvents.splice(0, this.queuedNetworkEvents.length);
887
913
  s.length === 0 || this.socket?.readyState !== WebSocket.OPEN || this.sendNow({
@@ -890,7 +916,7 @@ class ut {
890
916
  page: y(),
891
917
  events: s
892
918
  });
893
- }, Ht));
919
+ }, vt));
894
920
  }
895
921
  scheduleReconnect() {
896
922
  this.reconnectTimer !== null || this.state.status === "closed" || (this.reconnectTimer = window.setTimeout(() => {
@@ -901,12 +927,12 @@ class ut {
901
927
  isThinking: this.state.isThinking
902
928
  }), this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect();
903
929
  });
904
- }, Nt));
930
+ }, Lt));
905
931
  }
906
932
  startHeartbeat() {
907
933
  this.stopHeartbeat(), this.heartbeatTimer = window.setInterval(() => {
908
934
  this.sendNow({ type: "runtime.ping" });
909
- }, Dt);
935
+ }, Ft);
910
936
  }
911
937
  stopHeartbeat() {
912
938
  this.heartbeatTimer !== null && (window.clearInterval(this.heartbeatTimer), this.heartbeatTimer = null);
@@ -916,7 +942,7 @@ class ut {
916
942
  ...this.state,
917
943
  ...t,
918
944
  ...t.lastError === null && t.lastErrorCode === void 0 ? { lastErrorCode: null } : {}
919
- }, qe(this.options.clientId, this.state), this.emit("state", this.getState());
945
+ }, Be(this.options.clientId, this.state), this.emit("state", this.getState());
920
946
  }
921
947
  emit(t, s) {
922
948
  this.listeners[t]?.forEach((r) => r(s));
@@ -933,15 +959,15 @@ function g(e, t, s) {
933
959
  }, i = n.__plunoProductAgentDiagnostics__ ?? [];
934
960
  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 }));
935
961
  }
936
- function Y(e) {
962
+ function Q(e) {
937
963
  const t = typeof e == "function" ? e() : e;
938
964
  return t && Object.keys(t).length > 0 ? t : void 0;
939
965
  }
940
- function $t(e) {
966
+ function Jt(e) {
941
967
  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";
942
968
  }
943
- const zt = 5e3;
944
- function Gt(e) {
969
+ const Vt = 5e3;
970
+ function Yt(e) {
945
971
  const t = [];
946
972
  for (const s of e)
947
973
  s.role !== "user" || !s.attachments?.length || s.attachments.forEach((n, r) => {
@@ -952,118 +978,118 @@ function Gt(e) {
952
978
  });
953
979
  return t;
954
980
  }
955
- function Xt(e, t = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map()) {
956
- const n = new Map(e.map((u) => [u.id, u])), r = (u) => ({
957
- id: u.id,
958
- name: u.name,
959
- mimeType: u.mimeType,
960
- sizeBytes: u.sizeBytes,
961
- type: u.mimeType,
962
- size: u.sizeBytes
963
- }), i = (u) => {
964
- const l = n.get(u);
965
- if (!l)
966
- throw new Error(`Unknown Pluno user file: ${u}`);
967
- return l;
968
- }, o = async (u) => {
969
- const l = i(u), f = t.get(l.id);
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);
970
996
  if (f)
971
997
  return f;
972
- const p = s.get(l.id);
998
+ const p = s.get(u.id);
973
999
  if (p)
974
1000
  return p;
975
- const S = await Rt(l.id).then((m) => m?.blob ?? null).catch((m) => (g("web-sdk.attachments", "Failed to load Product Agent attachment from IndexedDB", {
976
- attachmentId: l.id,
977
- name: l.name,
1001
+ const S = await Ct(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,
978
1004
  message: m instanceof Error ? m.message : String(m)
979
1005
  }), null));
980
1006
  if (S)
981
- return s.set(l.id, S), S;
982
- if (!l.fileUrl)
983
- throw new Error(`Pluno user file is missing content: ${u}`);
984
- const D = await fetch(l.fileUrl, Fe(l.fileUrl));
985
- if (!D.ok)
986
- throw new Error(`Failed to load Pluno user file: ${u}`);
987
- const N = await D.blob();
988
- s.set(l.id, N);
989
- const G = Date.now();
990
- return it({
991
- attachmentId: l.id,
992
- name: l.name,
993
- mimeType: l.mimeType,
994
- sizeBytes: l.sizeBytes,
995
- blob: N,
996
- fileUrl: l.fileUrl,
997
- gcsPath: l.gcsPath,
998
- createdAt: G,
999
- lastUsedAt: G
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, xe(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
1000
1026
  }).catch((m) => {
1001
1027
  g("web-sdk.attachments", "Failed to cache Product Agent attachment from fileUrl", {
1002
- attachmentId: l.id,
1003
- name: l.name,
1028
+ attachmentId: u.id,
1029
+ name: u.name,
1004
1030
  message: m instanceof Error ? m.message : String(m)
1005
1031
  });
1006
- }), N;
1007
- }, c = async (u) => {
1008
- const l = i(u), f = await o(u), p = l.mimeType.startsWith("image/") ? l.mimeType : f.type || l.mimeType;
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;
1009
1035
  if (!p.startsWith("image/"))
1010
- throw new Error(`Pluno user file is not an image: ${u}`);
1036
+ throw new Error(`Pluno user file is not an image: ${l}`);
1011
1037
  const S = f.type === p ? f : new Blob([f], { type: p });
1012
- return Jt(p, S.size) > xt ? {
1038
+ return te(p, S.size) > zt ? {
1013
1039
  type: "pluno.userFiles.inspectImage",
1014
- id: l.id,
1015
- name: l.name,
1040
+ id: u.id,
1041
+ name: u.name,
1016
1042
  mimeType: p,
1017
- sizeBytes: l.sizeBytes,
1043
+ sizeBytes: u.sizeBytes,
1018
1044
  imageAttached: !1,
1019
- imageAttachmentError: vt
1045
+ imageAttachmentError: Gt
1020
1046
  } : {
1021
1047
  type: "pluno.userFiles.inspectImage",
1022
- id: l.id,
1023
- name: l.name,
1048
+ id: u.id,
1049
+ name: u.name,
1024
1050
  mimeType: p,
1025
- sizeBytes: l.sizeBytes,
1051
+ sizeBytes: u.sizeBytes,
1026
1052
  imageAttached: !0,
1027
- dataUrl: await Z(S)
1053
+ dataUrl: await tt(S)
1028
1054
  };
1029
1055
  }, a = globalThis, d = a.pluno?.userFiles, h = Object.prototype.hasOwnProperty.call(a.pluno ?? {}, "userFiles");
1030
1056
  return a.pluno = {
1031
1057
  ...a.pluno ?? {},
1032
1058
  userFiles: {
1033
1059
  list: () => e.map(r),
1034
- get: (u) => {
1035
- const l = n.get(u);
1036
- return l ? r(l) : null;
1060
+ get: (l) => {
1061
+ const u = n.get(l);
1062
+ return u ? r(u) : null;
1037
1063
  },
1038
1064
  inspectImage: c,
1039
- getDataUrl: async (u) => (i(u), await Z(await o(u))),
1065
+ getDataUrl: async (l) => (i(l), await tt(await o(l))),
1040
1066
  getBlob: o,
1041
- getArrayBuffer: async (u) => await (await o(u)).arrayBuffer(),
1042
- getFile: async (u) => {
1043
- const l = i(u);
1044
- return new File([await o(u)], l.name, { type: l.mimeType });
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 });
1045
1071
  }
1046
1072
  }
1047
1073
  }, () => {
1048
- const u = a.pluno ?? {};
1074
+ const l = a.pluno ?? {};
1049
1075
  if (h) {
1050
1076
  a.pluno = {
1051
- ...u,
1077
+ ...l,
1052
1078
  userFiles: d
1053
1079
  };
1054
1080
  return;
1055
1081
  }
1056
- const { userFiles: l, ...f } = u;
1082
+ const { userFiles: u, ...f } = l;
1057
1083
  a.pluno = f;
1058
1084
  };
1059
1085
  }
1060
- function Kt(e) {
1086
+ function Qt(e) {
1061
1087
  try {
1062
1088
  e();
1063
1089
  } catch {
1064
1090
  }
1065
1091
  }
1066
- function Z(e) {
1092
+ function tt(e) {
1067
1093
  return new Promise((t, s) => {
1068
1094
  const n = new FileReader();
1069
1095
  n.onload = () => {
@@ -1075,12 +1101,12 @@ function Z(e) {
1075
1101
  }, n.onerror = () => s(n.error ?? new Error("Failed to read Pluno user file")), n.readAsDataURL(e);
1076
1102
  });
1077
1103
  }
1078
- function Jt(e, t) {
1104
+ function te(e, t) {
1079
1105
  return `data:${e};base64,`.length + Math.ceil(t / 3) * 4;
1080
1106
  }
1081
- async function Q(e) {
1107
+ async function et(e) {
1082
1108
  const t = Object.getPrototypeOf(async function() {
1083
- }).constructor, s = e.timeoutMs ?? zt, n = Date.now(), r = [];
1109
+ }).constructor, s = e.timeoutMs ?? Vt, n = Date.now(), r = [];
1084
1110
  let i;
1085
1111
  const o = {
1086
1112
  log: console.log,
@@ -1098,7 +1124,7 @@ async function Q(e) {
1098
1124
  i = window.setTimeout(() => h(a), s);
1099
1125
  })
1100
1126
  ]);
1101
- return d === a ? Vt(s) : {
1127
+ return d === a ? ee(s) : {
1102
1128
  ok: !0,
1103
1129
  result: d,
1104
1130
  console: r,
@@ -1127,7 +1153,7 @@ async function Q(e) {
1127
1153
  i !== void 0 && window.clearTimeout(i), console.log = o.log, console.info = o.info, console.warn = o.warn, console.error = o.error;
1128
1154
  }
1129
1155
  }
1130
- function Vt(e) {
1156
+ function ee(e) {
1131
1157
  return {
1132
1158
  ok: !1,
1133
1159
  exception: {
@@ -1141,15 +1167,15 @@ function Vt(e) {
1141
1167
  }
1142
1168
  };
1143
1169
  }
1144
- function Yt(e) {
1170
+ function se(e) {
1145
1171
  return e.replace(/\/+$/, "");
1146
1172
  }
1147
- function Zt(e) {
1173
+ function ne(e) {
1148
1174
  const t = new URL("/api/product-agent/embed/ws", e);
1149
1175
  return t.protocol = t.protocol === "https:" ? "wss:" : "ws:", t.toString();
1150
1176
  }
1151
1177
  function y() {
1152
- const e = lt();
1178
+ const e = ht();
1153
1179
  return {
1154
1180
  url: location.href,
1155
1181
  title: document.title,
@@ -1157,17 +1183,37 @@ function y() {
1157
1183
  ...e ? { plunoProductAgentUi: e } : {}
1158
1184
  };
1159
1185
  }
1160
- function Qt() {
1186
+ function re() {
1161
1187
  return {
1162
1188
  pageUrl: location.href,
1163
1189
  pageTitle: document.title,
1164
- htmlContent: ee()
1190
+ htmlContent: ce()
1165
1191
  };
1166
1192
  }
1167
- function te() {
1168
- return lt()?.surface === "browser_extension_sdk_preview";
1193
+ function ie(e) {
1194
+ return C.add(e), R || (R = oe()), () => {
1195
+ C.delete(e), C.size === 0 && (R?.(), R = null);
1196
+ };
1169
1197
  }
1170
- function ee() {
1198
+ function oe() {
1199
+ const e = () => {
1200
+ for (const i of Array.from(C))
1201
+ i();
1202
+ }, t = window.history.pushState.bind(window.history), s = window.history.replaceState.bind(window.history), n = ((...i) => {
1203
+ const o = t(...i);
1204
+ return e(), o;
1205
+ }), r = ((...i) => {
1206
+ const o = s(...i);
1207
+ return e(), o;
1208
+ });
1209
+ return window.history.pushState = n, window.history.replaceState = r, window.addEventListener("popstate", e), window.addEventListener("hashchange", e), () => {
1210
+ window.history.pushState === n && (window.history.pushState = t), window.history.replaceState === r && (window.history.replaceState = s), window.removeEventListener("popstate", e), window.removeEventListener("hashchange", e);
1211
+ };
1212
+ }
1213
+ function ae() {
1214
+ return ht()?.surface === "browser_extension_sdk_preview";
1215
+ }
1216
+ function ce() {
1171
1217
  const e = document.body?.cloneNode(!0);
1172
1218
  return e instanceof HTMLElement ? (e.querySelectorAll(
1173
1219
  [
@@ -1191,8 +1237,8 @@ function ee() {
1191
1237
  s.name === "href" || s.name === "aria-label" || s.name === "role" || t.removeAttribute(s.name);
1192
1238
  }), 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) ?? "") : "";
1193
1239
  }
1194
- function lt() {
1195
- const e = document.querySelector(X);
1240
+ function ht() {
1241
+ const e = document.querySelector(J);
1196
1242
  if (!(e ?? document.querySelector(B)))
1197
1243
  return;
1198
1244
  const s = e ? "browser_extension_sdk_preview" : "embedded_widget";
@@ -1202,28 +1248,28 @@ function lt() {
1202
1248
  selectors: [
1203
1249
  {
1204
1250
  name: "widget_host",
1205
- selector: s === "browser_extension_sdk_preview" ? X : B,
1251
+ selector: s === "browser_extension_sdk_preview" ? J : B,
1206
1252
  description: "Finds Pluno's shadow-host element in the host page DOM."
1207
1253
  },
1208
1254
  {
1209
1255
  name: "widget_root",
1210
- selector: Pt,
1256
+ selector: bt,
1211
1257
  description: "Finds Pluno's widget root inside the widget host shadow root."
1212
1258
  },
1213
1259
  {
1214
1260
  name: "widget_panel",
1215
- selector: Mt,
1261
+ selector: Dt,
1216
1262
  description: "Finds Pluno's open chat panel inside the widget host shadow root."
1217
1263
  },
1218
1264
  {
1219
1265
  name: "widget_timeline",
1220
- selector: bt,
1266
+ selector: Nt,
1221
1267
  description: "Finds Pluno's chat timeline inside the widget host shadow root."
1222
1268
  }
1223
1269
  ]
1224
1270
  };
1225
1271
  }
1226
- function se(e) {
1272
+ function le(e) {
1227
1273
  try {
1228
1274
  const t = JSON.parse(e);
1229
1275
  return t && typeof t == "object" ? t : { type: "error", message: "Invalid server event" };
@@ -1231,16 +1277,16 @@ function se(e) {
1231
1277
  return { type: "error", message: "Invalid server event" };
1232
1278
  }
1233
1279
  }
1234
- function tt(e, t) {
1280
+ function st(e, t) {
1235
1281
  if (!e || typeof e != "object")
1236
1282
  return [];
1237
1283
  const s = e[t];
1238
1284
  return Array.isArray(s) ? s.filter((n) => typeof n == "string" && n.trim().length > 0) : [];
1239
1285
  }
1240
- function ne(e) {
1286
+ function ue(e) {
1241
1287
  return Array.isArray(e) ? e.filter((t) => typeof t == "string" && t.trim().length > 0) : [];
1242
1288
  }
1243
- function re(e) {
1289
+ function de(e) {
1244
1290
  if (!e || typeof e != "object")
1245
1291
  return null;
1246
1292
  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;
@@ -1251,13 +1297,13 @@ function re(e) {
1251
1297
  ...c !== null ? { scribbleStyle: c } : {}
1252
1298
  };
1253
1299
  }
1254
- function ie(e) {
1300
+ function he(e) {
1255
1301
  if (!e || typeof e != "object")
1256
1302
  return null;
1257
1303
  const t = e.javascript;
1258
1304
  return typeof t != "string" || !t.trim() ? null : { javascript: t };
1259
1305
  }
1260
- function oe(e, t) {
1306
+ function pe(e, t) {
1261
1307
  return t ? e && typeof e == "object" ? {
1262
1308
  ...e,
1263
1309
  helperError: t
@@ -1267,30 +1313,30 @@ function oe(e, t) {
1267
1313
  helperError: t
1268
1314
  } : e;
1269
1315
  }
1270
- function ae(e) {
1316
+ function ge(e) {
1271
1317
  if (!e || typeof e != "object")
1272
1318
  return e;
1273
1319
  const t = e;
1274
1320
  return typeof t.exception?.message == "string" ? t.exception.message : typeof t.error == "string" ? t.error : e;
1275
1321
  }
1276
- function ce() {
1322
+ function fe() {
1277
1323
  const e = "pluno.productAgent.clientId", t = window.localStorage.getItem(e);
1278
1324
  if (t)
1279
1325
  return t;
1280
1326
  const s = crypto.randomUUID();
1281
1327
  return window.localStorage.setItem(e, s), s;
1282
1328
  }
1283
- function ue() {
1284
- const e = window.sessionStorage.getItem(V);
1329
+ function me() {
1330
+ const e = window.sessionStorage.getItem(Z);
1285
1331
  if (e)
1286
1332
  return e;
1287
1333
  const t = crypto.randomUUID();
1288
- return window.sessionStorage.setItem(V, t), t;
1334
+ return window.sessionStorage.setItem(Z, t), t;
1289
1335
  }
1290
- function R() {
1336
+ function _() {
1291
1337
  return crypto.randomUUID();
1292
1338
  }
1293
- function le(e) {
1339
+ function ye(e) {
1294
1340
  if (!e || typeof e != "object")
1295
1341
  return null;
1296
1342
  const t = e, s = typeof t.id == "string" ? t.id : null;
@@ -1301,23 +1347,23 @@ function le(e) {
1301
1347
  avatarUrl: typeof t.avatarUrl == "string" ? t.avatarUrl : null
1302
1348
  } : null;
1303
1349
  }
1304
- function de(e, t) {
1305
- return Array.isArray(e) ? L(
1306
- x(
1307
- e.map((s) => dt(s, t)).filter((s) => s !== null)
1350
+ function we(e, t) {
1351
+ return Array.isArray(e) ? x(
1352
+ j(
1353
+ e.map((s) => pt(s, t)).filter((s) => s !== null)
1308
1354
  )
1309
1355
  ) : [];
1310
1356
  }
1311
- function he(e) {
1357
+ function Te(e) {
1312
1358
  return Array.isArray(e) ? e.flatMap((t) => {
1313
1359
  if (!t || typeof t != "object")
1314
1360
  return [];
1315
- const s = t, n = A(s, "id"), r = A(s, "createdAt"), i = A(s, "updatedAt"), o = A(s, "lastActiveAt");
1361
+ const s = t, n = I(s, "id"), r = I(s, "createdAt"), i = I(s, "updatedAt"), o = I(s, "lastActiveAt");
1316
1362
  return !n || !r || !i || !o ? [] : [
1317
1363
  {
1318
1364
  id: n,
1319
- title: A(s, "title"),
1320
- firstUserMessage: A(s, "firstUserMessage"),
1365
+ title: I(s, "title"),
1366
+ firstUserMessage: I(s, "firstUserMessage"),
1321
1367
  currentPage: s.currentPage ?? null,
1322
1368
  createdAt: r,
1323
1369
  updatedAt: i,
@@ -1326,7 +1372,7 @@ function he(e) {
1326
1372
  ];
1327
1373
  }) : [];
1328
1374
  }
1329
- function dt(e, t) {
1375
+ function pt(e, t) {
1330
1376
  if (!e || typeof e != "object")
1331
1377
  return null;
1332
1378
  const s = e, n = s.data;
@@ -1338,39 +1384,39 @@ function dt(e, t) {
1338
1384
  return {
1339
1385
  id: String(s.id ?? crypto.randomUUID()),
1340
1386
  role: i,
1341
- content: ye(r.content),
1387
+ content: Ee(r.content),
1342
1388
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
1343
- respondsToUserMessageId: O(r) ?? void 0,
1389
+ respondsToUserMessageId: L(r) ?? void 0,
1344
1390
  ...k(r) ? { runId: k(r) } : {},
1345
- attachments: mt(r.attachments, t)
1391
+ attachments: It(r.attachments, t)
1346
1392
  };
1347
1393
  }
1348
1394
  return r.type === "function_call" || r.type === "tool_call" || r.type === "web_search_call" ? {
1349
1395
  id: String(s.id ?? crypto.randomUUID()),
1350
1396
  role: "tool",
1351
- content: ge(r),
1397
+ content: Ae(r),
1352
1398
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
1353
- respondsToUserMessageId: O(r) ?? void 0,
1399
+ respondsToUserMessageId: L(r) ?? void 0,
1354
1400
  ...k(r) ? { runId: k(r) } : {},
1355
1401
  dataType: String(r.type),
1356
1402
  toolName: typeof r.name == "string" ? r.name : void 0,
1357
- callId: me(r) ?? void 0,
1403
+ callId: ke(r) ?? void 0,
1358
1404
  loading: r.localExecutionStatus === "running"
1359
1405
  } : r.type === "run_status" || r.type === "run_error" ? r.type === "run_error" && r.stage === "tool_execution" ? null : {
1360
1406
  id: String(s.id ?? crypto.randomUUID()),
1361
1407
  role: "system",
1362
- content: pe(r),
1408
+ content: Ie(r),
1363
1409
  createdAt: typeof s.createdAt == "string" ? s.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
1364
- respondsToUserMessageId: O(r) ?? void 0,
1410
+ respondsToUserMessageId: L(r) ?? void 0,
1365
1411
  ...k(r) ? { runId: k(r) } : {},
1366
1412
  dataType: String(r.type),
1367
1413
  loading: r.type === "run_status" && (r.status === "running" || r.status === "retrying")
1368
1414
  } : null;
1369
1415
  }
1370
- function pe(e) {
1416
+ function Ie(e) {
1371
1417
  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.";
1372
1418
  }
1373
- function ge(e) {
1419
+ function Ae(e) {
1374
1420
  if (e.type === "web_search_call") {
1375
1421
  const t = e.action;
1376
1422
  if (t && typeof t == "object") {
@@ -1382,9 +1428,9 @@ function ge(e) {
1382
1428
  }
1383
1429
  return "Searching the web";
1384
1430
  }
1385
- return fe(e);
1431
+ return Se(e);
1386
1432
  }
1387
- function fe(e) {
1433
+ function Se(e) {
1388
1434
  if (typeof e.summary == "string" && e.summary.trim().length > 0)
1389
1435
  return e.summary;
1390
1436
  if (typeof e.arguments == "string")
@@ -1397,11 +1443,11 @@ function fe(e) {
1397
1443
  }
1398
1444
  return typeof e.name == "string" && e.name.trim().length > 0 ? e.name : "Run tool";
1399
1445
  }
1400
- function me(e) {
1446
+ function ke(e) {
1401
1447
  const t = e.callId ?? e.call_id;
1402
1448
  return typeof t == "string" && t ? t : null;
1403
1449
  }
1404
- function ye(e) {
1450
+ function Ee(e) {
1405
1451
  return typeof e == "string" ? e : Array.isArray(e) ? e.map((t) => {
1406
1452
  if (!t || typeof t != "object")
1407
1453
  return "";
@@ -1409,19 +1455,19 @@ function ye(e) {
1409
1455
  return typeof s.text == "string" ? s.text : typeof s.content == "string" ? s.content : "";
1410
1456
  }).filter(Boolean).join("") : "";
1411
1457
  }
1412
- function Te(e, t) {
1413
- const s = ht(e, t), n = Se(e, t), r = n.findIndex((o) => o.id === s.id);
1458
+ function Re(e, t) {
1459
+ const s = gt(e, t), n = Ce(e, t), r = n.findIndex((o) => o.id === s.id);
1414
1460
  if (r === -1)
1415
- return L(
1416
- x([...n, s])
1461
+ return x(
1462
+ j([...n, s])
1417
1463
  );
1418
1464
  const i = [...n];
1419
- return i[r] = s, L(x(i));
1465
+ return i[r] = s, x(j(i));
1420
1466
  }
1421
- function we(e, t) {
1422
- return t.map((s) => ht(e, s));
1467
+ function _e(e, t) {
1468
+ return t.map((s) => gt(e, s));
1423
1469
  }
1424
- function ht(e, t) {
1470
+ function gt(e, t) {
1425
1471
  if (t.role !== "user" || !t.attachments?.length)
1426
1472
  return t;
1427
1473
  const s = e.find(
@@ -1430,19 +1476,19 @@ function ht(e, t) {
1430
1476
  if (!s?.attachments?.length)
1431
1477
  return t;
1432
1478
  const n = t.attachments.map((r) => {
1433
- const i = Ae(s.attachments ?? [], r);
1434
- return i ? Ie(r, i) : r;
1479
+ const i = Pe(s.attachments ?? [], r);
1480
+ return i ? Ue(r, i) : r;
1435
1481
  });
1436
1482
  return { ...t, attachments: n };
1437
1483
  }
1438
- function Ae(e, t) {
1484
+ function Pe(e, t) {
1439
1485
  return t.id ? e.find((s) => s.id === t.id) ?? null : null;
1440
1486
  }
1441
- function Ie(e, t) {
1487
+ function Ue(e, t) {
1442
1488
  const { previewUrl: s } = t;
1443
1489
  return s ? { ...e, previewUrl: s } : e;
1444
1490
  }
1445
- function Se(e, t) {
1491
+ function Ce(e, t) {
1446
1492
  if (t.role !== "user")
1447
1493
  return e;
1448
1494
  const s = e.findIndex(
@@ -1453,24 +1499,24 @@ function Se(e, t) {
1453
1499
  const n = [...e];
1454
1500
  return n.splice(s, 1), n;
1455
1501
  }
1456
- function et(e) {
1457
- const t = pt(e);
1458
- return t === null ? !1 : e.slice(t + 1).some(Ee);
1502
+ function nt(e) {
1503
+ const t = ft(e);
1504
+ return t === null ? !1 : e.slice(t + 1).some(mt);
1459
1505
  }
1460
- function ke(e) {
1461
- const t = pt(e);
1506
+ function Me(e) {
1507
+ const t = ft(e);
1462
1508
  return t === null ? e.some((s) => s.role === "assistant") : e.slice(t + 1).some((s) => s.role === "assistant");
1463
1509
  }
1464
- function pt(e) {
1510
+ function ft(e) {
1465
1511
  for (let t = e.length - 1; t >= 0; t -= 1)
1466
1512
  if (e[t].role === "user")
1467
1513
  return t;
1468
1514
  return null;
1469
1515
  }
1470
- function Ee(e) {
1516
+ function mt(e) {
1471
1517
  return e.role === "assistant" ? !0 : e.role !== "system" ? !1 : e.dataType === "run_error" ? !0 : e.dataType === "run_status" && e.loading !== !0;
1472
1518
  }
1473
- function Re(e) {
1519
+ function yt(e) {
1474
1520
  for (let t = e.length - 1; t >= 0; t -= 1) {
1475
1521
  const s = e[t];
1476
1522
  if (!s || typeof s != "object")
@@ -1484,8 +1530,18 @@ function Re(e) {
1484
1530
  }
1485
1531
  return null;
1486
1532
  }
1487
- function _e(e) {
1488
- const t = Re(e);
1533
+ function be(e, t) {
1534
+ const s = yt(t);
1535
+ if (s === null)
1536
+ return !1;
1537
+ const n = t[s], r = n && typeof n == "object" ? n.id : null;
1538
+ if (typeof r != "string" || !r)
1539
+ return !1;
1540
+ const i = e.findIndex((o) => o.role === "user" && o.id === r);
1541
+ return i === -1 ? !1 : e.slice(i + 1).some(mt);
1542
+ }
1543
+ function De(e) {
1544
+ const t = yt(e);
1489
1545
  if (t === null)
1490
1546
  return null;
1491
1547
  const s = e[t];
@@ -1497,22 +1553,22 @@ function _e(e) {
1497
1553
  const r = n.clientMessageId;
1498
1554
  return typeof r == "string" ? r : null;
1499
1555
  }
1500
- function Pe(e) {
1556
+ function Ne(e) {
1501
1557
  if (!e || typeof e != "object")
1502
1558
  return !1;
1503
1559
  const t = e;
1504
1560
  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";
1505
1561
  }
1506
- function L(e) {
1507
- return e.filter((t, s) => gt(t) ? !De(e, s) && !Ue(e, s) && !Ce(e, s) : Me(t) ? !be(e, s) : !0);
1562
+ function x(e) {
1563
+ return e.filter((t, s) => wt(t) ? !He(e, s) && !Fe(e, s) && !Le(e, s) : qe(t) ? !Oe(e, s) : !0);
1508
1564
  }
1509
- function Me(e) {
1565
+ function qe(e) {
1510
1566
  return e.role === "system" && (e.dataType === "run_status" || e.dataType === "run_error");
1511
1567
  }
1512
- function gt(e) {
1568
+ function wt(e) {
1513
1569
  return e.role === "system" && e.dataType === "run_status" && e.loading === !0;
1514
1570
  }
1515
- function x(e) {
1571
+ function j(e) {
1516
1572
  const t = new Set(e.filter((i) => i.role === "user").map((i) => i.id)), s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Set();
1517
1573
  for (const i of e) {
1518
1574
  if (i.role === "user" || !i.respondsToUserMessageId || !t.has(i.respondsToUserMessageId))
@@ -1528,53 +1584,53 @@ function x(e) {
1528
1584
  n.has(i.id) || (r.push(i), i.role === "user" && r.push(...s.get(i.id) ?? []));
1529
1585
  return r;
1530
1586
  }
1531
- function be(e, t) {
1587
+ function Oe(e, t) {
1532
1588
  const s = e[t];
1533
1589
  for (let n = t + 1; n < e.length; n += 1) {
1534
1590
  const r = e[n];
1535
1591
  if (r.role === "user")
1536
1592
  return !1;
1537
- if (r.role === "assistant" && C(s, r))
1593
+ if (r.role === "assistant" && N(s, r))
1538
1594
  return !0;
1539
1595
  }
1540
1596
  return !1;
1541
1597
  }
1542
- function Ue(e, t) {
1598
+ function Fe(e, t) {
1543
1599
  const s = e[t];
1544
1600
  for (let n = t + 1; n < e.length; n += 1)
1545
- if (e[n].role === "assistant" && C(s, e[n]))
1601
+ if (e[n].role === "assistant" && N(s, e[n]))
1546
1602
  return !0;
1547
1603
  return !1;
1548
1604
  }
1549
- function Ce(e, t) {
1605
+ function Le(e, t) {
1550
1606
  const s = e[t];
1551
1607
  for (let n = t + 1; n < e.length; n += 1)
1552
- if (e[n].role === "tool" && C(s, e[n]))
1608
+ if (e[n].role === "tool" && N(s, e[n]))
1553
1609
  return !0;
1554
1610
  return !1;
1555
1611
  }
1556
- function De(e, t) {
1612
+ function He(e, t) {
1557
1613
  const s = e[t];
1558
1614
  for (let n = t + 1; n < e.length; n += 1)
1559
- if (gt(e[n]) && C(s, e[n]))
1615
+ if (wt(e[n]) && N(s, e[n]))
1560
1616
  return !0;
1561
1617
  return !1;
1562
1618
  }
1563
- function C(e, t) {
1619
+ function N(e, t) {
1564
1620
  return !e.runId || !t.runId ? !0 : e.runId === t.runId;
1565
1621
  }
1566
- function A(e, t) {
1622
+ function I(e, t) {
1567
1623
  return e && typeof e == "object" && typeof e[t] == "string" ? e[t] : null;
1568
1624
  }
1569
- function Ne(e, t) {
1625
+ function We(e, t) {
1570
1626
  try {
1571
- const s = window.localStorage.getItem(`${ct}${e}`);
1627
+ const s = window.localStorage.getItem(`${ut}${e}`);
1572
1628
  if (!s)
1573
1629
  return null;
1574
1630
  const n = JSON.parse(s), r = typeof n.sessionId == "string" ? n.sessionId : null;
1575
1631
  if (t !== void 0 && r !== t)
1576
1632
  return null;
1577
- const i = Array.isArray(n.messages) ? n.messages.map(We).filter((o) => !!o) : [];
1633
+ const i = Array.isArray(n.messages) ? n.messages.map(ze).filter((o) => !!o) : [];
1578
1634
  return {
1579
1635
  sessionId: r,
1580
1636
  messages: i
@@ -1583,58 +1639,58 @@ function Ne(e, t) {
1583
1639
  return null;
1584
1640
  }
1585
1641
  }
1586
- function qe(e, t) {
1642
+ function Be(e, t) {
1587
1643
  try {
1588
1644
  window.localStorage.setItem(
1589
- `${ct}${e}`,
1645
+ `${ut}${e}`,
1590
1646
  JSON.stringify({
1591
1647
  sessionId: t.sessionId,
1592
- messages: t.messages.slice(-jt).map(Le)
1648
+ messages: t.messages.slice(-Xt).map(Ge)
1593
1649
  })
1594
1650
  );
1595
1651
  } catch {
1596
1652
  return;
1597
1653
  }
1598
1654
  }
1599
- function Oe(e) {
1655
+ function ve(e) {
1600
1656
  try {
1601
- const t = window.localStorage.getItem(`${W}${e}`);
1657
+ const t = window.localStorage.getItem(`${v}${e}`);
1602
1658
  if (!t)
1603
1659
  return [];
1604
1660
  const s = JSON.parse(t);
1605
- return Array.isArray(s) ? s.filter(ft) : [];
1661
+ return Array.isArray(s) ? s.filter(Tt) : [];
1606
1662
  } catch {
1607
1663
  return [];
1608
1664
  }
1609
1665
  }
1610
- function _(e, t) {
1666
+ function P(e, t) {
1611
1667
  try {
1612
- const s = t.filter(ft);
1668
+ const s = t.filter(Tt);
1613
1669
  if (s.length === 0) {
1614
- window.localStorage.removeItem(`${W}${e}`);
1670
+ window.localStorage.removeItem(`${v}${e}`);
1615
1671
  return;
1616
1672
  }
1617
1673
  window.localStorage.setItem(
1618
- `${W}${e}`,
1674
+ `${v}${e}`,
1619
1675
  JSON.stringify(s.slice(-25))
1620
1676
  );
1621
1677
  } catch {
1622
1678
  return;
1623
1679
  }
1624
1680
  }
1625
- function ft(e) {
1681
+ function Tt(e) {
1626
1682
  if (!e || typeof e != "object")
1627
1683
  return !1;
1628
1684
  const t = e;
1629
- return t.type === "chat.user_message" ? typeof t.content == "string" && st(t.page) : t.type === "page.upsert" || t.type === "session.reset" || t.type === "network.batch" ? st(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;
1685
+ 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;
1630
1686
  }
1631
- function st(e) {
1687
+ function rt(e) {
1632
1688
  if (!e || typeof e != "object")
1633
1689
  return !1;
1634
1690
  const t = e;
1635
1691
  return typeof t.url == "string" && typeof t.title == "string" && typeof t.origin == "string";
1636
1692
  }
1637
- function mt(e, t) {
1693
+ function It(e, t) {
1638
1694
  if (!Array.isArray(e))
1639
1695
  return;
1640
1696
  const s = e.filter((r) => {
@@ -1642,24 +1698,24 @@ function mt(e, t) {
1642
1698
  return !1;
1643
1699
  const i = r;
1644
1700
  return typeof i.name == "string" && typeof i.mimeType == "string" && typeof i.sizeBytes == "number";
1645
- }), n = t ? s.map((r) => yt(r, t)) : s;
1701
+ }), n = t ? s.map((r) => At(r, t)) : s;
1646
1702
  return n.length > 0 ? n : void 0;
1647
1703
  }
1648
- function yt(e, t) {
1704
+ function At(e, t) {
1649
1705
  return e.fileUrl?.startsWith("/") ? {
1650
1706
  ...e,
1651
1707
  fileUrl: new URL(e.fileUrl, t).toString()
1652
1708
  } : e;
1653
1709
  }
1654
- function Fe(e) {
1655
- if (He(e))
1710
+ function xe(e) {
1711
+ if (je(e))
1656
1712
  return {
1657
1713
  headers: {
1658
1714
  "ngrok-skip-browser-warning": "true"
1659
1715
  }
1660
1716
  };
1661
1717
  }
1662
- function He(e) {
1718
+ function je(e) {
1663
1719
  try {
1664
1720
  const t = new URL(e).hostname;
1665
1721
  return t.endsWith(".ngrok-free.dev") || t.endsWith(".ngrok-free.app") || t.endsWith(".ngrok.app") || t.endsWith(".ngrok.io");
@@ -1667,14 +1723,14 @@ function He(e) {
1667
1723
  return !1;
1668
1724
  }
1669
1725
  }
1670
- function nt(e) {
1671
- return e.type || Be(e.name) || "application/octet-stream";
1726
+ function it(e) {
1727
+ return e.type || $e(e.name) || "application/octet-stream";
1672
1728
  }
1673
- function Be(e) {
1729
+ function $e(e) {
1674
1730
  const t = e.toLowerCase();
1675
1731
  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;
1676
1732
  }
1677
- function We(e) {
1733
+ function ze(e) {
1678
1734
  if (!e || typeof e != "object")
1679
1735
  return null;
1680
1736
  const t = e;
@@ -1686,17 +1742,17 @@ function We(e) {
1686
1742
  respondsToUserMessageId: typeof t.respondsToUserMessageId == "string" ? t.respondsToUserMessageId : void 0,
1687
1743
  ...typeof t.runId == "string" ? { runId: t.runId } : {},
1688
1744
  dataType: typeof t.dataType == "string" ? t.dataType : void 0,
1689
- attachments: mt(t.attachments)?.map($),
1745
+ attachments: It(t.attachments)?.map(G),
1690
1746
  loading: typeof t.loading == "boolean" ? t.loading : void 0
1691
1747
  };
1692
1748
  }
1693
- function Le(e) {
1749
+ function Ge(e) {
1694
1750
  return e.attachments?.length ? {
1695
1751
  ...e,
1696
- attachments: e.attachments.map($)
1752
+ attachments: e.attachments.map(G)
1697
1753
  } : e;
1698
1754
  }
1699
- function $(e) {
1755
+ function G(e) {
1700
1756
  const {
1701
1757
  dataUrl: t,
1702
1758
  objectUrl: s,
@@ -1705,7 +1761,7 @@ function $(e) {
1705
1761
  } = e;
1706
1762
  return r;
1707
1763
  }
1708
- function O(e) {
1764
+ function L(e) {
1709
1765
  const t = e.respondsToUserMessageId;
1710
1766
  return typeof t == "string" && t ? t : null;
1711
1767
  }
@@ -1713,59 +1769,59 @@ function k(e) {
1713
1769
  const t = e.runId;
1714
1770
  return typeof t == "string" && t ? t : null;
1715
1771
  }
1716
- function xe(e) {
1772
+ function Xe(e) {
1717
1773
  return !!e && typeof e == "object" && typeof e.summary == "string" && typeof e.javascript == "string";
1718
1774
  }
1719
- function rt(e) {
1775
+ function ot(e) {
1720
1776
  const t = {};
1721
1777
  return e?.forEach((s, n) => {
1722
1778
  t[n] = s;
1723
1779
  }), t;
1724
1780
  }
1725
- async function ve(e, t) {
1781
+ async function Ke(e, t) {
1726
1782
  if (typeof t?.body < "u")
1727
- return Tt(t.body);
1783
+ return St(t.body);
1728
1784
  if (e)
1729
1785
  try {
1730
- return I(await e.clone().text());
1786
+ return A(await e.clone().text());
1731
1787
  } catch {
1732
1788
  return;
1733
1789
  }
1734
1790
  }
1735
- async function je(e) {
1791
+ async function Je(e) {
1736
1792
  try {
1737
- return I(await e.clone().text());
1793
+ return A(await e.clone().text());
1738
1794
  } catch (t) {
1739
1795
  return { error: t instanceof Error ? t.message : "unavailable" };
1740
1796
  }
1741
1797
  }
1742
- function $e(e) {
1798
+ function Ve(e) {
1743
1799
  try {
1744
- return e.responseType === "" || e.responseType === "text" ? I(e.responseText ?? "") : e.responseType === "json" ? I(JSON.stringify(e.response)) : `[unsupported xhr responseType: ${e.responseType || "unknown"}]`;
1800
+ return e.responseType === "" || e.responseType === "text" ? A(e.responseText ?? "") : e.responseType === "json" ? A(JSON.stringify(e.response)) : `[unsupported xhr responseType: ${e.responseType || "unknown"}]`;
1745
1801
  } catch (t) {
1746
1802
  return { error: t instanceof Error ? t.message : "unavailable" };
1747
1803
  }
1748
1804
  }
1749
- function Tt(e) {
1805
+ function St(e) {
1750
1806
  if (!(e === null || typeof e > "u")) {
1751
1807
  if (typeof e == "string")
1752
- return I(e);
1808
+ return A(e);
1753
1809
  if (e instanceof URLSearchParams)
1754
- return I(e.toString());
1810
+ return A(e.toString());
1755
1811
  if (e instanceof FormData) {
1756
1812
  const t = [];
1757
- return e.forEach((s, n) => t.push([n, s instanceof File ? `[file:${s.name}]` : String(s)])), I(JSON.stringify(t));
1813
+ return e.forEach((s, n) => t.push([n, s instanceof File ? `[file:${s.name}]` : String(s)])), A(JSON.stringify(t));
1758
1814
  }
1759
1815
  if (e instanceof Blob)
1760
1816
  return `[blob:${e.type || "application/octet-stream"}:${e.size}]`;
1761
1817
  try {
1762
- return I(JSON.stringify(e));
1818
+ return A(JSON.stringify(e));
1763
1819
  } catch {
1764
1820
  return `[unserializable body: ${Object.prototype.toString.call(e)}]`;
1765
1821
  }
1766
1822
  }
1767
1823
  }
1768
- function ze(e) {
1824
+ function Ye(e) {
1769
1825
  const t = {};
1770
1826
  for (const s of e.trim().split(/[\r\n]+/)) {
1771
1827
  const n = s.indexOf(":");
@@ -1773,10 +1829,10 @@ function ze(e) {
1773
1829
  }
1774
1830
  return t;
1775
1831
  }
1776
- function I(e) {
1777
- return e.length <= q ? e : `${e.slice(0, q)}... [truncated ${e.length - q} chars]`;
1832
+ function A(e) {
1833
+ return e.length <= F ? e : `${e.slice(0, F)}... [truncated ${e.length - F} chars]`;
1778
1834
  }
1779
- function P(e) {
1835
+ function U(e) {
1780
1836
  return `${e}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
1781
1837
  }
1782
1838
  class M extends Error {
@@ -1785,42 +1841,42 @@ class M extends Error {
1785
1841
  }
1786
1842
  status;
1787
1843
  }
1788
- async function F(e, t) {
1844
+ async function H(e, t) {
1789
1845
  let s = null;
1790
- for (let n = 0; n < J; n += 1)
1846
+ for (let n = 0; n < Y; n += 1)
1791
1847
  try {
1792
1848
  return await e();
1793
1849
  } catch (r) {
1794
- if (s = r, n >= J - 1 || !Xe(r))
1850
+ if (s = r, n >= Y - 1 || !Qe(r))
1795
1851
  throw r;
1796
- await Ge(n);
1852
+ await Ze(n);
1797
1853
  }
1798
1854
  throw s instanceof Error ? s : new Error(t);
1799
1855
  }
1800
- function Ge(e) {
1856
+ function Ze(e) {
1801
1857
  return new Promise((t) => {
1802
- window.setTimeout(t, Lt[e] ?? 0);
1858
+ window.setTimeout(t, $t[e] ?? 0);
1803
1859
  });
1804
1860
  }
1805
- function Xe(e) {
1806
- return e instanceof M ? Ke(e.status) : e instanceof TypeError;
1861
+ function Qe(e) {
1862
+ return e instanceof M ? ts(e.status) : e instanceof TypeError;
1807
1863
  }
1808
- function Ke(e) {
1864
+ function ts(e) {
1809
1865
  return e === 408 || e === 409 || e === 429 || e >= 500;
1810
1866
  }
1811
- function Je(e) {
1867
+ function es(e) {
1812
1868
  return e === 401 || e === 403;
1813
1869
  }
1814
- const z = "[REDACTED_SECRET]", T = "[REDACTED_TOKEN]", Ve = "[REDACTED_SIGNED_URL]", Ye = 20, Ze = /^(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, At = /\bBasic\s+[A-Za-z0-9+/=-]{12,}/gi, It = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, St = /\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, Qe = /\bhttps?:\/\/[^\s"'<>]+(?:X-Amz-Signature|X-Goog-Signature|Signature|sig=)[^\s"'<>]*/gi, ts = /\bhttps?:\/\/[^\s"'<>]+/gi, es = /[),.;\]]+$/;
1815
- function w(e) {
1870
+ const X = "[REDACTED_SECRET]", w = "[REDACTED_TOKEN]", ss = "[REDACTED_SIGNED_URL]", ns = 20, rs = /^(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, is = /\bhttps?:\/\/[^\s"'<>]+(?:X-Amz-Signature|X-Goog-Signature|Signature|sig=)[^\s"'<>]*/gi, os = /\bhttps?:\/\/[^\s"'<>]+/gi, as = /[),.;\]]+$/;
1871
+ function T(e) {
1816
1872
  return b(e, 0, /* @__PURE__ */ new WeakSet());
1817
1873
  }
1818
1874
  function b(e, t, s) {
1819
1875
  if (typeof e == "string")
1820
- return e.startsWith("data:image/") || e.startsWith("data:application/pdf;") ? e : rs(e);
1876
+ return e.startsWith("data:image/") || e.startsWith("data:application/pdf;") ? e : us(e);
1821
1877
  if (e === null || typeof e != "object")
1822
1878
  return e;
1823
- if (t >= Ye)
1879
+ if (t >= ns)
1824
1880
  return "[REDACTED_MAX_DEPTH]";
1825
1881
  if (s.has(e))
1826
1882
  return "[REDACTED_CIRCULAR]";
@@ -1828,42 +1884,42 @@ function b(e, t, s) {
1828
1884
  return e.map((r) => b(r, t + 1, s));
1829
1885
  const n = {};
1830
1886
  for (const [r, i] of Object.entries(e))
1831
- ss(r) ? n[r] = z : n[r] = r.toLowerCase() === "url" ? ns(i) : b(i, t + 1, s);
1887
+ cs(r) ? n[r] = X : n[r] = r.toLowerCase() === "url" ? ls(i) : b(i, t + 1, s);
1832
1888
  return n;
1833
1889
  }
1834
- function ss(e) {
1890
+ function cs(e) {
1835
1891
  const t = e.replace(/[^a-z0-9]/gi, "").toLowerCase();
1836
1892
  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");
1837
1893
  }
1838
- function ns(e) {
1839
- return typeof e == "string" ? kt(e) : b(e, 0, /* @__PURE__ */ new WeakSet());
1894
+ function ls(e) {
1895
+ return typeof e == "string" ? Pt(e) : b(e, 0, /* @__PURE__ */ new WeakSet());
1840
1896
  }
1841
- function kt(e) {
1897
+ function Pt(e) {
1842
1898
  try {
1843
1899
  const t = new URL(e, location.href);
1844
1900
  for (const s of Array.from(t.searchParams.keys()))
1845
- Ze.test(s) && t.searchParams.set(s, T);
1846
- return t.username && (t.username = T), t.password && (t.password = T), t.toString();
1901
+ rs.test(s) && t.searchParams.set(s, w);
1902
+ return t.username && (t.username = w), t.password && (t.password = w), t.toString();
1847
1903
  } catch {
1848
- return is(e);
1904
+ return ds(e);
1849
1905
  }
1850
1906
  }
1851
- function rs(e) {
1852
- return e.replace(Qe, Ve).replace(ts, os).replace(wt, `Bearer ${T}`).replace(At, `Basic ${T}`).replace(It, T).replace(St, (t, s) => `${s}: ${z}`);
1907
+ function us(e) {
1908
+ return e.replace(is, ss).replace(os, hs).replace(kt, `Bearer ${w}`).replace(Et, `Basic ${w}`).replace(Rt, w).replace(_t, (t, s) => `${s}: ${X}`);
1853
1909
  }
1854
- function is(e) {
1855
- return e.replace(wt, `Bearer ${T}`).replace(At, `Basic ${T}`).replace(It, T).replace(St, (t, s) => `${s}: ${z}`);
1910
+ function ds(e) {
1911
+ return e.replace(kt, `Bearer ${w}`).replace(Et, `Basic ${w}`).replace(Rt, w).replace(_t, (t, s) => `${s}: ${X}`);
1856
1912
  }
1857
- function os(e) {
1858
- const t = e.match(es)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
1859
- return `${kt(s)}${t}`;
1913
+ function hs(e) {
1914
+ const t = e.match(as)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
1915
+ return `${Pt(s)}${t}`;
1860
1916
  }
1861
1917
  export {
1862
- X as PLUNO_PRODUCT_AGENT_SDK_PREVIEW_HOST_SELECTOR,
1918
+ J as PLUNO_PRODUCT_AGENT_SDK_PREVIEW_HOST_SELECTOR,
1863
1919
  B as PLUNO_PRODUCT_AGENT_WIDGET_HOST_SELECTOR,
1864
- Mt as PLUNO_PRODUCT_AGENT_WIDGET_PANEL_SELECTOR,
1865
- Pt as PLUNO_PRODUCT_AGENT_WIDGET_ROOT_SELECTOR,
1866
- bt as PLUNO_PRODUCT_AGENT_WIDGET_TIMELINE_SELECTOR,
1867
- ut as PlunoProductAgent,
1868
- ut as default
1920
+ Dt as PLUNO_PRODUCT_AGENT_WIDGET_PANEL_SELECTOR,
1921
+ bt as PLUNO_PRODUCT_AGENT_WIDGET_ROOT_SELECTOR,
1922
+ Nt as PLUNO_PRODUCT_AGENT_WIDGET_TIMELINE_SELECTOR,
1923
+ dt as PlunoProductAgent,
1924
+ dt as default
1869
1925
  };