@pluno/product-agent-web 0.1.52 → 0.1.54

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