@pluno/product-agent-web 0.1.9 → 0.1.11

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,9 +1,12 @@
1
- const x = "https://app.pluno.ai";
2
- const R = "pluno.productAgent.state.";
3
- class M {
1
+ const X = "https://app.pluno.ai";
2
+ const O = "pluno.productAgent.state.", k = "pluno.productAgent.pendingEvents.", R = "pluno.productAgent.transportId";
3
+ class q {
4
4
  constructor(t) {
5
- this.options = t;
6
- const s = ot(t.clientId);
5
+ this.options = t, this.transportId = rt(), this.state = {
6
+ ...this.state,
7
+ starterPrompts: Z(t.initialStarterPrompts)
8
+ };
9
+ const s = mt(t.clientId);
7
10
  s && (this.state = {
8
11
  ...this.state,
9
12
  ...s,
@@ -12,7 +15,7 @@ class M {
12
15
  assistantDraft: "",
13
16
  isThinking: !1,
14
17
  lastError: null
15
- });
18
+ }), this.queuedClientEvents = St(t.clientId);
16
19
  }
17
20
  options;
18
21
  listeners = {};
@@ -24,39 +27,48 @@ class M {
24
27
  networkBatchTimer = null;
25
28
  queuedNetworkEvents = [];
26
29
  queuedClientEvents = [];
30
+ transportId;
27
31
  retryAttemptsByClientMessageId = {};
32
+ retryTimersByClientMessageId = {};
33
+ thinkingWatchdogTimer = null;
34
+ activeClientMessageId = null;
35
+ activeUserMessageEvent = null;
36
+ thinkingWatchdogResyncAttemptsByClientMessageId = {};
37
+ thinkingWatchdogRetryAttemptsByClientMessageId = {};
28
38
  runtimeHelperJavascript = null;
29
39
  state = {
30
40
  status: "idle",
31
41
  user: null,
32
42
  sessionId: null,
33
43
  starterPrompts: [],
44
+ appearance: null,
34
45
  messages: [],
35
46
  assistantDraft: "",
36
47
  isThinking: !1,
37
48
  lastError: null
38
49
  };
39
50
  static async init(t) {
40
- const s = new M({
51
+ const s = new q({
41
52
  ...t,
42
- backendUrl: B(t.backendUrl ?? x),
43
- clientId: t.clientId ?? J()
53
+ backendUrl: K(t.backendUrl ?? X),
54
+ clientId: t.clientId ?? nt()
44
55
  });
45
56
  try {
46
57
  s.enableNetworkCapture(), t.autoConnect !== !1 && await s.connect();
47
- } catch (r) {
48
- throw s.destroy(), r;
58
+ } catch (n) {
59
+ throw s.destroy(), n;
49
60
  }
50
61
  return s;
51
62
  }
52
63
  on(t, s) {
53
- const r = this.listeners[t] ?? /* @__PURE__ */ new Set();
54
- return r.add(s), this.listeners[t] = r, () => r.delete(s);
64
+ const n = this.listeners[t] ?? /* @__PURE__ */ new Set();
65
+ return n.add(s), this.listeners[t] = n, () => n.delete(s);
55
66
  }
56
67
  getState() {
57
68
  return {
58
69
  ...this.state,
59
70
  starterPrompts: [...this.state.starterPrompts],
71
+ appearance: this.state.appearance ? { ...this.state.appearance } : null,
60
72
  messages: [...this.state.messages]
61
73
  };
62
74
  }
@@ -65,17 +77,36 @@ class M {
65
77
  return;
66
78
  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)
67
79
  throw new Error("Product Agent requires a token or tokenProvider");
68
- const t = L(this.options.backendUrl);
69
- this.socket = this.options.webSocketFactory?.(t) ?? new WebSocket(t), this.socket.addEventListener("open", () => {
70
- this.token && this.sendNow({ type: "auth.session", token: this.token, clientId: this.options.clientId }), this.flushQueuedClientEvents(), this.startHeartbeat(), this.setState({ status: "connected", lastError: null });
71
- }), this.socket.addEventListener("message", (s) => this.handleServerEvent(j(s.data))), this.socket.addEventListener("close", () => {
72
- this.stopHeartbeat(), this.socket = null, this.state.status !== "closed" && (this.setState({ status: "reconnecting" }), this.scheduleReconnect());
73
- }), this.socket.addEventListener("error", () => {
74
- this.setState({ status: "error", lastError: "Product Agent connection failed" });
80
+ const t = J(this.options.backendUrl), s = this.options.webSocketFactory?.(t) ?? new WebSocket(t);
81
+ this.socket = s, s.addEventListener("open", () => {
82
+ this.socket === s && (l("web-sdk.agent", "Product Agent socket opened", {
83
+ queuedClientEventCount: this.queuedClientEvents.length,
84
+ isThinking: this.state.isThinking
85
+ }), this.token && this.sendNow({
86
+ type: "auth.session",
87
+ token: this.token,
88
+ clientId: this.options.clientId,
89
+ transportId: this.transportId
90
+ }), this.flushQueuedClientEvents(), this.startHeartbeat(), this.setState({ status: "connected", lastError: null }));
91
+ }), s.addEventListener("message", (n) => {
92
+ this.socket === s && this.handleServerEvent(Y(n.data));
93
+ }), s.addEventListener("close", (n) => {
94
+ this.socket === s && (this.stopHeartbeat(), this.socket = null, this.state.status !== "closed" && (l("web-sdk.agent", "Product Agent socket closed; scheduling reconnect", {
95
+ code: typeof n?.code == "number" ? n.code : null,
96
+ reason: typeof n?.reason == "string" ? n.reason : "",
97
+ wasClean: typeof n?.wasClean == "boolean" ? n.wasClean : null,
98
+ queuedClientEventCount: this.queuedClientEvents.length,
99
+ isThinking: this.state.isThinking
100
+ }), this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect()));
101
+ }), s.addEventListener("error", () => {
102
+ this.socket !== s || this.state.status === "closed" || (l("web-sdk.agent", "Product Agent socket error; scheduling reconnect", {
103
+ queuedClientEventCount: this.queuedClientEvents.length,
104
+ isThinking: this.state.isThinking
105
+ }), this.stopHeartbeat(), this.socket = null, this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect(), s.readyState !== WebSocket.CLOSED && s.readyState !== WebSocket.CLOSING && s.close());
75
106
  });
76
107
  }
77
108
  disconnect() {
78
- this.setState({ status: "closed", isThinking: !1 }), this.stopHeartbeat(), this.reconnectTimer !== null && (window.clearTimeout(this.reconnectTimer), this.reconnectTimer = null), this.queuedClientEvents = [], this.socket?.close(), this.socket = null;
109
+ this.setState({ status: "closed", isThinking: !1 }), this.stopHeartbeat(), this.clearRetryTimers(), this.clearThinkingWatchdog(), this.reconnectTimer !== null && (window.clearTimeout(this.reconnectTimer), this.reconnectTimer = null), this.queuedClientEvents = [], this.socket?.close(), this.socket = null;
79
110
  }
80
111
  destroy() {
81
112
  this.disconnect(), this.networkCaptureCleanup?.(), this.networkCaptureCleanup = null;
@@ -86,8 +117,8 @@ class M {
86
117
  const s = t.trim();
87
118
  if (!s)
88
119
  return;
89
- const r = g(), n = G(), i = {
90
- id: `local-${n}`,
120
+ const n = g(), r = it(), i = {
121
+ id: `local-${r}`,
91
122
  role: "user",
92
123
  content: s,
93
124
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -97,21 +128,23 @@ class M {
97
128
  assistantDraft: "",
98
129
  isThinking: !0,
99
130
  lastError: null
100
- }), this.emit("message", i), this.send({
131
+ }), this.emit("message", i);
132
+ const a = {
101
133
  type: "chat.user_message",
102
134
  sessionId: this.state.sessionId ?? void 0,
103
- clientMessageId: n,
135
+ clientMessageId: r,
104
136
  content: s,
105
- page: r,
137
+ page: n,
106
138
  model: this.options.model,
107
139
  metadata: this.options.metadata
108
- });
140
+ };
141
+ this.activeClientMessageId = r, this.activeUserMessageEvent = a, this.markThinkingProgress(), this.send(a);
109
142
  }
110
143
  stop() {
111
- this.state.sessionId && (this.send({ type: "run.stop", sessionId: this.state.sessionId }), this.setState({ isThinking: !1 }));
144
+ this.state.sessionId && (this.send({ type: "run.stop", sessionId: this.state.sessionId }), this.setState({ isThinking: !1 }), this.clearThinkingWatchdog());
112
145
  }
113
146
  startNewSession() {
114
- 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.send({
147
+ 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({
115
148
  type: "session.reset",
116
149
  sessionId: this.state.sessionId ?? void 0,
117
150
  page: g()
@@ -125,30 +158,50 @@ class M {
125
158
  });
126
159
  }
127
160
  send(t) {
128
- this.sendNow(f(t)) || (this.queuedClientEvents.push(t), this.setState({ status: "reconnecting" }), this.scheduleReconnect());
161
+ this.sendNow(f(t)) || (this.queuedClientEvents.push(t), m(this.options.clientId, this.queuedClientEvents), this.setState({ status: "reconnecting" }), this.scheduleReconnect());
129
162
  }
130
163
  sendNow(t) {
131
- return !this.socket || this.socket.readyState !== WebSocket.OPEN ? !1 : (this.socket.send(JSON.stringify(t)), !0);
164
+ if (!this.socket || this.socket.readyState !== WebSocket.OPEN)
165
+ return !1;
166
+ const s = this.socket;
167
+ try {
168
+ return s.send(JSON.stringify(t)), !0;
169
+ } catch (n) {
170
+ return l("web-sdk.agent", "Product Agent socket send failed; scheduling reconnect", {
171
+ message: n instanceof Error ? n.message : String(n),
172
+ queuedClientEventCount: this.queuedClientEvents.length,
173
+ isThinking: this.state.isThinking
174
+ }), this.socket === s && (this.stopHeartbeat(), this.socket = null, this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect()), s.readyState !== WebSocket.CLOSED && s.readyState !== WebSocket.CLOSING && s.close(), !1;
175
+ }
132
176
  }
133
177
  flushQueuedClientEvents() {
134
178
  if (this.socket?.readyState !== WebSocket.OPEN || this.queuedClientEvents.length === 0)
135
179
  return;
136
180
  const t = this.queuedClientEvents.splice(0, this.queuedClientEvents.length);
181
+ m(this.options.clientId, this.queuedClientEvents);
137
182
  for (let s = 0; s < t.length; s += 1) {
138
- const r = t[s];
139
- if (!this.sendNow(f(r))) {
140
- this.queuedClientEvents.unshift(r, ...t.slice(s + 1));
183
+ const n = t[s];
184
+ if (!this.sendNow(f(n))) {
185
+ this.queuedClientEvents.unshift(n, ...t.slice(s + 1)), m(this.options.clientId, this.queuedClientEvents);
141
186
  return;
142
187
  }
188
+ m(this.options.clientId, this.queuedClientEvents);
143
189
  }
144
190
  }
145
191
  handleServerEvent(t) {
146
- if (t.type === "auth.ok") {
147
- this.runtimeHelperJavascript = X(t.runtimeHelpers)?.javascript ?? null, this.setState({
148
- user: W(t.user),
149
- starterPrompts: $(t, "starterPrompts"),
192
+ if (F(t) && this.markThinkingProgress(), t.type === "auth.ok") {
193
+ const s = Q(t), n = Object.prototype.hasOwnProperty.call(t, "appearance");
194
+ l("web-sdk.agent", "Received auth.ok appearance", {
195
+ hasAppearance: n,
196
+ rawAppearance: t.appearance,
197
+ normalizedAppearance: s
198
+ }), this.runtimeHelperJavascript = tt(t.runtimeHelpers)?.javascript ?? null;
199
+ const r = {
200
+ user: ot(t.user),
201
+ starterPrompts: V(t, "starterPrompts"),
150
202
  status: "connected"
151
- }), this.state.sessionId && this.send({
203
+ };
204
+ (n || s) && (r.appearance = s), this.setState(r), this.state.sessionId && this.send({
152
205
  type: "page.upsert",
153
206
  sessionId: this.state.sessionId,
154
207
  page: g(),
@@ -158,34 +211,34 @@ class M {
158
211
  }
159
212
  if (t.type === "conversation.state") {
160
213
  const s = Array.isArray(t.items) ? t.items : [];
161
- this.setState({
162
- sessionId: I(t.session, "id") ?? this.state.sessionId,
163
- messages: v(s),
164
- ...et(s) ? { assistantDraft: "", isThinking: !1 } : {}
165
- });
214
+ gt(s) && this.clearRetryTimers(), this.setState({
215
+ sessionId: D(t.session, "id") ?? this.state.sessionId,
216
+ messages: at(s),
217
+ ...N(s) ? { assistantDraft: "", isThinking: !1 } : {}
218
+ }), N(s) && this.clearThinkingWatchdog();
166
219
  return;
167
220
  }
168
221
  if (t.type === "session.updated") {
169
- this.setState({ sessionId: I(t.session, "id") ?? this.state.sessionId });
222
+ this.setState({ sessionId: D(t.session, "id") ?? this.state.sessionId });
170
223
  return;
171
224
  }
172
225
  if (t.type === "session.item") {
173
- const s = C(t.item);
174
- s && (this.setState({
175
- messages: Q(this.state.messages, s),
226
+ const s = U(t.item);
227
+ s && (s.role === "assistant" && this.clearRetryTimers(), this.setState({
228
+ messages: ht(this.state.messages, s),
176
229
  assistantDraft: s.role === "assistant" ? "" : this.state.assistantDraft,
177
- ...D(t.item.data) ? { assistantDraft: "", isThinking: !1 } : {}
178
- }), this.emit("message", s));
230
+ ...I(t.item.data) ? { assistantDraft: "", isThinking: !1 } : {}
231
+ }), I(t.item.data) && this.clearThinkingWatchdog(), this.emit("message", s));
179
232
  return;
180
233
  }
181
234
  if (t.type === "chat.assistant_delta") {
182
235
  const s = typeof t.delta == "string" ? t.delta : "";
183
- this.setState({ assistantDraft: `${this.state.assistantDraft}${s}`, isThinking: !0 }), this.emit("delta", s);
236
+ this.setState({ assistantDraft: `${this.state.assistantDraft}${s}`, isThinking: !0 }), this.markThinkingProgress(), this.emit("delta", s);
184
237
  return;
185
238
  }
186
239
  if (t.type === "chat.assistant_done") {
187
240
  const s = typeof t.sessionId == "string" ? t.sessionId : this.state.sessionId;
188
- this.setState({ sessionId: s, assistantDraft: "", isThinking: !1 });
241
+ this.setState({ sessionId: s, assistantDraft: "", isThinking: !1 }), this.clearThinkingWatchdog();
189
242
  return;
190
243
  }
191
244
  if (t.type === "tool.call") {
@@ -196,31 +249,96 @@ class M {
196
249
  if (this.retryAfterRetryableError(t))
197
250
  return;
198
251
  const s = new Error(typeof t.message == "string" ? t.message : "Product Agent error");
199
- this.setState({ status: "error", isThinking: !1, lastError: s.message }), this.emit("error", s);
252
+ this.setState({ status: "error", isThinking: !1, lastError: s.message }), this.clearThinkingWatchdog(), this.emit("error", s);
200
253
  }
201
254
  }
202
255
  retryAfterRetryableError(t) {
203
- const s = typeof t.sessionId == "string" ? t.sessionId : this.state.sessionId, r = typeof t.clientMessageId == "string" ? t.clientMessageId : null;
204
- if (!(t.retryable === !0 || t.code === "transient_model_error") || !s || !r)
256
+ const s = typeof t.sessionId == "string" ? t.sessionId : this.state.sessionId, n = typeof t.clientMessageId == "string" ? t.clientMessageId : null;
257
+ if (!(t.retryable === !0 || t.code === "transient_model_error") || !s || !n)
205
258
  return !1;
206
- const i = this.retryAttemptsByClientMessageId[r] ?? 0;
259
+ const i = this.retryAttemptsByClientMessageId[n] ?? 0;
207
260
  if (i >= 1)
208
261
  return !1;
209
- this.retryAttemptsByClientMessageId[r] = i + 1;
262
+ this.retryAttemptsByClientMessageId[n] = i + 1;
210
263
  const a = typeof t.retryAfterMs == "number" ? t.retryAfterMs : 2e3;
211
- return this.setState({ status: "reconnecting", isThinking: !0, lastError: null }), window.setTimeout(() => {
212
- this.setState({ status: "connected", isThinking: !0, lastError: null }), this.send({
264
+ return this.setState({ status: "reconnecting", isThinking: !0, lastError: null }), this.retryTimersByClientMessageId[n] = window.setTimeout(() => {
265
+ delete this.retryTimersByClientMessageId[n], this.setState({ status: "connected", isThinking: !0, lastError: null }), this.markThinkingProgress(), this.send({
213
266
  type: "chat.retry_last_user_message",
214
267
  sessionId: s,
215
- clientMessageId: r
268
+ clientMessageId: n
216
269
  });
217
270
  }, a), !0;
218
271
  }
272
+ clearRetryTimers() {
273
+ for (const t of Object.values(this.retryTimersByClientMessageId))
274
+ window.clearTimeout(t);
275
+ this.retryTimersByClientMessageId = {};
276
+ }
277
+ markThinkingProgress() {
278
+ !this.state.isThinking || this.state.status === "closed" || this.scheduleThinkingWatchdog(6e4);
279
+ }
280
+ scheduleThinkingWatchdog(t) {
281
+ this.thinkingWatchdogTimer !== null && window.clearTimeout(this.thinkingWatchdogTimer), this.thinkingWatchdogTimer = window.setTimeout(() => {
282
+ this.thinkingWatchdogTimer = null, this.recoverStuckThinking();
283
+ }, t);
284
+ }
285
+ clearThinkingWatchdog() {
286
+ this.thinkingWatchdogTimer !== null && (window.clearTimeout(this.thinkingWatchdogTimer), this.thinkingWatchdogTimer = null), this.activeClientMessageId = null, this.activeUserMessageEvent = null;
287
+ }
288
+ recoverStuckThinking() {
289
+ if (!this.state.isThinking || this.state.status === "closed")
290
+ return;
291
+ const t = this.activeClientMessageId;
292
+ if (!t) {
293
+ l("web-sdk.agent", "Product Agent thinking watchdog resyncing without active message id", {
294
+ sessionId: this.state.sessionId
295
+ }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(6e4);
296
+ return;
297
+ }
298
+ const s = this.thinkingWatchdogResyncAttemptsByClientMessageId[t] ?? 0, n = this.thinkingWatchdogRetryAttemptsByClientMessageId[t] ?? 0;
299
+ if (s <= n) {
300
+ this.thinkingWatchdogResyncAttemptsByClientMessageId[t] = s + 1, l("web-sdk.agent", "Product Agent thinking watchdog resyncing session", {
301
+ sessionId: this.state.sessionId,
302
+ clientMessageId: t,
303
+ resyncAttempts: s + 1
304
+ }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(15e3);
305
+ return;
306
+ }
307
+ if (n >= 2) {
308
+ l("web-sdk.agent", "Product Agent thinking watchdog retry limit reached; continuing resync", {
309
+ sessionId: this.state.sessionId,
310
+ clientMessageId: t,
311
+ retryAttempts: n
312
+ }), this.resyncThinkingSession(), this.scheduleThinkingWatchdog(6e4);
313
+ return;
314
+ }
315
+ this.thinkingWatchdogRetryAttemptsByClientMessageId[t] = n + 1, this.setState({
316
+ status: this.state.status === "reconnecting" ? "reconnecting" : "connected",
317
+ isThinking: !0,
318
+ lastError: null
319
+ }), l("web-sdk.agent", "Product Agent thinking watchdog retrying last user message", {
320
+ sessionId: this.state.sessionId,
321
+ clientMessageId: t,
322
+ retryAttempts: n + 1
323
+ }), this.state.sessionId ? this.send({
324
+ type: "chat.retry_last_user_message",
325
+ sessionId: this.state.sessionId,
326
+ clientMessageId: t
327
+ }) : this.activeUserMessageEvent && this.send(this.activeUserMessageEvent), this.scheduleThinkingWatchdog(6e4);
328
+ }
329
+ resyncThinkingSession() {
330
+ this.state.sessionId ? this.send({
331
+ type: "page.upsert",
332
+ sessionId: this.state.sessionId,
333
+ page: g(),
334
+ model: this.options.model
335
+ }) : (!this.socket || this.socket.readyState !== WebSocket.OPEN) && (this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect());
336
+ }
219
337
  async executeToolCall(t) {
220
- const s = typeof t.sessionId == "string" ? t.sessionId : null, r = typeof t.callId == "string" ? t.callId : null, n = t.rawInput;
221
- if (!s || !r || !ct(n))
338
+ const s = typeof t.sessionId == "string" ? t.sessionId : null, n = typeof t.callId == "string" ? t.callId : null, r = t.rawInput;
339
+ if (!s || !n || !It(r))
222
340
  return;
223
- const i = await this.executeRuntimeHelper(), a = await A(n).catch((o) => ({
341
+ const i = await this.executeRuntimeHelper(), a = await M(r).catch((o) => ({
224
342
  ok: !1,
225
343
  exception: {
226
344
  message: o instanceof Error ? o.message : String(o)
@@ -229,81 +347,81 @@ class M {
229
347
  this.send({
230
348
  type: "tool.result",
231
349
  sessionId: s,
232
- callId: r,
350
+ callId: n,
233
351
  toolName: "execute_code",
234
- summary: n.summary,
235
- rawInput: f(n),
236
- rawOutput: f(z(a, i))
352
+ summary: r.summary,
353
+ rawInput: f(r),
354
+ rawOutput: f(et(a, i))
237
355
  });
238
356
  }
239
357
  async executeRuntimeHelper() {
240
358
  if (!this.runtimeHelperJavascript?.trim())
241
359
  return null;
242
- const t = await A({
360
+ const t = await M({
243
361
  javascript: this.runtimeHelperJavascript
244
362
  });
245
- return t.ok === !1 ? F(t) : null;
363
+ return t.ok === !1 ? st(t) : null;
246
364
  }
247
365
  enableNetworkCapture() {
248
366
  if (this.networkCaptureCleanup)
249
367
  return;
250
- const t = window.fetch.bind(window), s = XMLHttpRequest.prototype.open, r = XMLHttpRequest.prototype.setRequestHeader, n = XMLHttpRequest.prototype.send;
368
+ const t = window.fetch.bind(window), s = XMLHttpRequest.prototype.open, n = XMLHttpRequest.prototype.setRequestHeader, r = XMLHttpRequest.prototype.send;
251
369
  window.fetch = async (i, a) => {
252
- const o = Date.now(), c = new Date(o).toISOString(), u = i instanceof Request ? i : null, h = typeof i == "string" ? i : i instanceof URL ? i.toString() : u?.url ?? "", _ = (a?.method ?? u?.method ?? "GET").toUpperCase(), T = k(new Headers(a?.headers ?? u?.headers ?? void 0)), w = await ut(u, a);
370
+ const o = Date.now(), c = new Date(o).toISOString(), u = i instanceof Request ? i : null, y = typeof i == "string" ? i : i instanceof URL ? i.toString() : u?.url ?? "", w = (a?.method ?? u?.method ?? "GET").toUpperCase(), A = H(new Headers(a?.headers ?? u?.headers ?? void 0)), C = await _t(u, a);
253
371
  try {
254
- const l = await t(i, a);
372
+ const d = await t(i, a);
255
373
  return this.enqueueNetworkEvent({
256
- requestId: y("fetch"),
257
- url: h,
258
- method: _,
259
- requestHeaders: T,
260
- requestBody: w,
374
+ requestId: T("fetch"),
375
+ url: y,
376
+ method: w,
377
+ requestHeaders: A,
378
+ requestBody: C,
261
379
  resourceType: "fetch",
262
- responseStatus: l.status,
263
- responseHeaders: k(l.headers),
264
- responseBody: await lt(l),
380
+ responseStatus: d.status,
381
+ responseHeaders: H(d.headers),
382
+ responseBody: await Et(d),
265
383
  startedAt: c,
266
384
  durationMs: Date.now() - o
267
- }), l;
268
- } catch (l) {
385
+ }), d;
386
+ } catch (d) {
269
387
  throw this.enqueueNetworkEvent({
270
- requestId: y("fetch"),
271
- url: h,
272
- method: _,
273
- requestHeaders: T,
274
- requestBody: w,
388
+ requestId: T("fetch"),
389
+ url: y,
390
+ method: w,
391
+ requestHeaders: A,
392
+ requestBody: C,
275
393
  resourceType: "fetch",
276
- errorText: l instanceof Error ? l.message : String(l),
394
+ errorText: d instanceof Error ? d.message : String(d),
277
395
  startedAt: c,
278
396
  durationMs: Date.now() - o
279
- }), l;
397
+ }), d;
280
398
  }
281
- }, XMLHttpRequest.prototype.open = function(a, o, c, u, h) {
399
+ }, XMLHttpRequest.prototype.open = function(a, o, c, u, y) {
282
400
  return this.__plunoMeta = {
283
- requestId: y("xhr"),
401
+ requestId: T("xhr"),
284
402
  method: String(a ?? "GET").toUpperCase(),
285
403
  url: typeof o == "string" ? o : o.toString(),
286
404
  requestHeaders: {},
287
405
  startedAtMs: Date.now(),
288
406
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
289
- }, s.call(this, a, o, c ?? !0, u ?? void 0, h ?? void 0);
407
+ }, s.call(this, a, o, c ?? !0, u ?? void 0, y ?? void 0);
290
408
  }, XMLHttpRequest.prototype.setRequestHeader = function(a, o) {
291
409
  const c = this.__plunoMeta;
292
410
  if (c) {
293
411
  const u = c.requestHeaders ?? {};
294
412
  u[a] = o, c.requestHeaders = u;
295
413
  }
296
- return r.call(this, a, o);
414
+ return n.call(this, a, o);
297
415
  }, XMLHttpRequest.prototype.send = function(a) {
298
416
  const o = window.__plunoProductAgentInstance, c = this.__plunoMeta ?? {
299
- requestId: y("xhr"),
417
+ requestId: T("xhr"),
300
418
  method: "GET",
301
419
  url: "",
302
420
  requestHeaders: {},
303
421
  startedAtMs: Date.now(),
304
422
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
305
423
  };
306
- return c.requestBody = b(a), this.__plunoMeta = c, this.addEventListener(
424
+ return c.requestBody = B(a), this.__plunoMeta = c, this.addEventListener(
307
425
  "loadend",
308
426
  function() {
309
427
  !o || !this.__plunoMeta || o.enqueueNetworkEvent({
@@ -314,17 +432,17 @@ class M {
314
432
  requestBody: typeof this.__plunoMeta.requestBody == "string" ? this.__plunoMeta.requestBody : void 0,
315
433
  resourceType: "xhr",
316
434
  responseStatus: this.status,
317
- responseHeaders: pt(this.getAllResponseHeaders()),
318
- responseBody: dt(this),
435
+ responseHeaders: At(this.getAllResponseHeaders()),
436
+ responseBody: wt(this),
319
437
  errorText: this.status === 0 ? "XHR request failed or was aborted" : void 0,
320
438
  startedAt: String(this.__plunoMeta.startedAt),
321
439
  durationMs: Date.now() - Number(this.__plunoMeta.startedAtMs ?? Date.now())
322
440
  });
323
441
  },
324
442
  { once: !0 }
325
- ), n.call(this, a ?? null);
443
+ ), r.call(this, a ?? null);
326
444
  }, window.__plunoProductAgentInstance = this, this.networkCaptureCleanup = () => {
327
- window.fetch = t, XMLHttpRequest.prototype.open = s, XMLHttpRequest.prototype.setRequestHeader = r, XMLHttpRequest.prototype.send = n, window.__plunoProductAgentInstance === this && delete window.__plunoProductAgentInstance;
445
+ window.fetch = t, XMLHttpRequest.prototype.open = s, XMLHttpRequest.prototype.setRequestHeader = n, XMLHttpRequest.prototype.send = r, window.__plunoProductAgentInstance === this && delete window.__plunoProductAgentInstance;
328
446
  };
329
447
  }
330
448
  enqueueNetworkEvent(t) {
@@ -342,7 +460,11 @@ class M {
342
460
  scheduleReconnect() {
343
461
  this.reconnectTimer !== null || this.state.status === "closed" || (this.reconnectTimer = window.setTimeout(() => {
344
462
  this.reconnectTimer = null, this.connect().catch((t) => {
345
- this.setState({ status: "error", lastError: t instanceof Error ? t.message : String(t) });
463
+ l("web-sdk.agent", "Product Agent reconnect failed; retrying", {
464
+ message: t instanceof Error ? t.message : String(t),
465
+ queuedClientEventCount: this.queuedClientEvents.length,
466
+ isThinking: this.state.isThinking
467
+ }), this.setState({ status: "reconnecting", lastError: null }), this.scheduleReconnect();
346
468
  });
347
469
  }, 2e3));
348
470
  }
@@ -355,22 +477,36 @@ class M {
355
477
  this.heartbeatTimer !== null && (window.clearInterval(this.heartbeatTimer), this.heartbeatTimer = null);
356
478
  }
357
479
  setState(t) {
358
- this.state = { ...this.state, ...t }, it(this.options.clientId, this.state), this.emit("state", this.getState());
480
+ this.state = { ...this.state, ...t }, Tt(this.options.clientId, this.state), this.emit("state", this.getState());
359
481
  }
360
482
  emit(t, s) {
361
- this.listeners[t]?.forEach((n) => n(s));
483
+ this.listeners[t]?.forEach((r) => r(s));
362
484
  }
363
485
  }
364
- const O = 5e3;
365
- async function A(e) {
486
+ function l(e, t, s) {
487
+ if (typeof window > "u")
488
+ return;
489
+ const n = window, r = {
490
+ at: (/* @__PURE__ */ new Date()).toISOString(),
491
+ source: e,
492
+ message: t,
493
+ details: s
494
+ }, i = n.__plunoProductAgentDiagnostics__ ?? [];
495
+ 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 }));
496
+ }
497
+ function F(e) {
498
+ 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";
499
+ }
500
+ const z = 5e3;
501
+ async function M(e) {
366
502
  const t = Object.getPrototypeOf(async function() {
367
- }).constructor, s = O, r = Date.now(), n = [], i = {
503
+ }).constructor, s = z, n = Date.now(), r = [], i = {
368
504
  log: console.log,
369
505
  info: console.info,
370
506
  warn: console.warn,
371
507
  error: console.error
372
508
  }, a = (o) => (...c) => {
373
- n.push({ level: o, args: c }), i[o](...c);
509
+ r.push({ level: o, args: c }), i[o](...c);
374
510
  };
375
511
  console.log = a("log"), console.info = a("info"), console.warn = a("warn"), console.error = a("error");
376
512
  try {
@@ -382,9 +518,9 @@ async function A(e) {
382
518
  (c, u) => window.setTimeout(() => u(new Error(`execute_code timed out after ${s}ms`)), s)
383
519
  )
384
520
  ]),
385
- console: n,
521
+ console: r,
386
522
  metadata: {
387
- durationMs: Date.now() - r,
523
+ durationMs: Date.now() - n,
388
524
  url: location.href,
389
525
  origin: location.origin
390
526
  }
@@ -392,14 +528,14 @@ async function A(e) {
392
528
  } catch (o) {
393
529
  return {
394
530
  ok: !1,
395
- console: n,
531
+ console: r,
396
532
  exception: {
397
533
  name: o instanceof Error ? o.name : "Error",
398
534
  message: o instanceof Error ? o.message : String(o),
399
535
  stack: o instanceof Error ? o.stack : void 0
400
536
  },
401
537
  metadata: {
402
- durationMs: Date.now() - r,
538
+ durationMs: Date.now() - n,
403
539
  url: location.href,
404
540
  origin: location.origin
405
541
  }
@@ -408,10 +544,10 @@ async function A(e) {
408
544
  console.log = i.log, console.info = i.info, console.warn = i.warn, console.error = i.error;
409
545
  }
410
546
  }
411
- function B(e) {
547
+ function K(e) {
412
548
  return e.replace(/\/+$/, "");
413
549
  }
414
- function L(e) {
550
+ function J(e) {
415
551
  const t = new URL("/api/product-agent/embed/ws", e);
416
552
  return t.protocol = t.protocol === "https:" ? "wss:" : "ws:", t.toString();
417
553
  }
@@ -422,7 +558,7 @@ function g() {
422
558
  origin: location.origin
423
559
  };
424
560
  }
425
- function j(e) {
561
+ function Y(e) {
426
562
  try {
427
563
  const t = JSON.parse(e);
428
564
  return t && typeof t == "object" ? t : { type: "error", message: "Invalid server event" };
@@ -430,19 +566,32 @@ function j(e) {
430
566
  return { type: "error", message: "Invalid server event" };
431
567
  }
432
568
  }
433
- function $(e, t) {
569
+ function V(e, t) {
434
570
  if (!e || typeof e != "object")
435
571
  return [];
436
572
  const s = e[t];
437
- return Array.isArray(s) ? s.filter((r) => typeof r == "string" && r.trim().length > 0) : [];
573
+ return Array.isArray(s) ? s.filter((n) => typeof n == "string" && n.trim().length > 0) : [];
574
+ }
575
+ function Z(e) {
576
+ return Array.isArray(e) ? e.filter((t) => typeof t == "string" && t.trim().length > 0) : [];
577
+ }
578
+ function Q(e) {
579
+ if (!e || typeof e != "object")
580
+ return null;
581
+ 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, a = typeof n.fontFamily == "string" && n.fontFamily.trim() ? n.fontFamily : null;
582
+ return !r && !i && !a ? null : {
583
+ ...r ? { accentColor: r } : {},
584
+ ...i ? { colorScheme: i } : {},
585
+ ...a ? { fontFamily: a } : {}
586
+ };
438
587
  }
439
- function X(e) {
588
+ function tt(e) {
440
589
  if (!e || typeof e != "object")
441
590
  return null;
442
591
  const t = e.javascript;
443
592
  return typeof t != "string" || !t.trim() ? null : { javascript: t };
444
593
  }
445
- function z(e, t) {
594
+ function et(e, t) {
446
595
  return t ? e && typeof e == "object" ? {
447
596
  ...e,
448
597
  helperError: t
@@ -452,23 +601,30 @@ function z(e, t) {
452
601
  helperError: t
453
602
  } : e;
454
603
  }
455
- function F(e) {
604
+ function st(e) {
456
605
  if (!e || typeof e != "object")
457
606
  return e;
458
607
  const t = e;
459
608
  return typeof t.exception?.message == "string" ? t.exception.message : typeof t.error == "string" ? t.error : e;
460
609
  }
461
- function J() {
610
+ function nt() {
462
611
  const e = "pluno.productAgent.clientId", t = window.localStorage.getItem(e);
463
612
  if (t)
464
613
  return t;
465
614
  const s = crypto.randomUUID();
466
615
  return window.localStorage.setItem(e, s), s;
467
616
  }
468
- function G() {
617
+ function rt() {
618
+ const e = window.sessionStorage.getItem(R);
619
+ if (e)
620
+ return e;
621
+ const t = crypto.randomUUID();
622
+ return window.sessionStorage.setItem(R, t), t;
623
+ }
624
+ function it() {
469
625
  return crypto.randomUUID();
470
626
  }
471
- function W(e) {
627
+ function ot(e) {
472
628
  if (!e || typeof e != "object")
473
629
  return null;
474
630
  const t = e, s = typeof t.id == "string" ? t.id : null;
@@ -479,46 +635,46 @@ function W(e) {
479
635
  avatarUrl: typeof t.avatarUrl == "string" ? t.avatarUrl : null
480
636
  } : null;
481
637
  }
482
- function v(e) {
483
- return Array.isArray(e) ? S(
484
- e.map(C).filter((t) => t !== null)
638
+ function at(e) {
639
+ return Array.isArray(e) ? _(
640
+ e.map(U).filter((t) => t !== null)
485
641
  ) : [];
486
642
  }
487
- function C(e) {
643
+ function U(e) {
488
644
  if (!e || typeof e != "object")
489
645
  return null;
490
646
  const t = e, s = t.data;
491
647
  if (!s || typeof s != "object")
492
648
  return null;
493
- const r = s;
494
- if (r.type === "message") {
495
- const n = r.role === "assistant" ? "assistant" : r.role === "user" ? "user" : "system";
649
+ const n = s;
650
+ if (n.type === "message") {
651
+ const r = n.role === "assistant" ? "assistant" : n.role === "user" ? "user" : "system";
496
652
  return {
497
653
  id: String(t.id ?? crypto.randomUUID()),
498
- role: n,
499
- content: Z(r.content),
654
+ role: r,
655
+ content: dt(n.content),
500
656
  createdAt: typeof t.createdAt == "string" ? t.createdAt : (/* @__PURE__ */ new Date()).toISOString()
501
657
  };
502
658
  }
503
- return r.type === "function_call" || r.type === "tool_call" || r.type === "web_search_call" ? {
659
+ return n.type === "function_call" || n.type === "tool_call" || n.type === "web_search_call" ? {
504
660
  id: String(t.id ?? crypto.randomUUID()),
505
661
  role: "tool",
506
- content: Y(r),
662
+ content: ut(n),
507
663
  createdAt: typeof t.createdAt == "string" ? t.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
508
- dataType: String(r.type),
509
- loading: r.localExecutionStatus === "running"
510
- } : r.type === "run_status" || r.type === "run_error" ? r.type === "run_status" && (r.status === "running" || r.status === "retrying") || r.type === "run_error" && r.stage === "tool_execution" ? null : {
664
+ dataType: String(n.type),
665
+ loading: n.localExecutionStatus === "running"
666
+ } : n.type === "run_status" || n.type === "run_error" ? n.type === "run_status" && (n.status === "running" || n.status === "retrying") || n.type === "run_error" && n.stage === "tool_execution" ? null : {
511
667
  id: String(t.id ?? crypto.randomUUID()),
512
668
  role: "system",
513
- content: K(r),
669
+ content: ct(n),
514
670
  createdAt: typeof t.createdAt == "string" ? t.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
515
- dataType: String(r.type)
671
+ dataType: String(n.type)
516
672
  } : null;
517
673
  }
518
- function K(e) {
674
+ function ct(e) {
519
675
  return typeof e.message == "string" && e.message.trim().length > 0 ? e.message : e.type === "run_status" && e.status === "interrupted" ? "Product Agent was interrupted before it could finish this message." : e.type === "run_status" && e.status === "stopped" ? "Product Agent stopped." : "Product Agent run status changed.";
520
676
  }
521
- function Y(e) {
677
+ function ut(e) {
522
678
  if (e.type === "web_search_call") {
523
679
  const t = e.action;
524
680
  if (t && typeof t == "object") {
@@ -530,9 +686,9 @@ function Y(e) {
530
686
  }
531
687
  return "Searching the web";
532
688
  }
533
- return V(e);
689
+ return lt(e);
534
690
  }
535
- function V(e) {
691
+ function lt(e) {
536
692
  if (typeof e.summary == "string" && e.summary.trim().length > 0)
537
693
  return e.summary;
538
694
  if (typeof e.arguments == "string")
@@ -545,7 +701,7 @@ function V(e) {
545
701
  }
546
702
  return typeof e.name == "string" && e.name.trim().length > 0 ? e.name : "Run tool";
547
703
  }
548
- function Z(e) {
704
+ function dt(e) {
549
705
  return typeof e == "string" ? e : Array.isArray(e) ? e.map((t) => {
550
706
  if (!t || typeof t != "object")
551
707
  return "";
@@ -553,85 +709,95 @@ function Z(e) {
553
709
  return typeof s.text == "string" ? s.text : typeof s.content == "string" ? s.content : "";
554
710
  }).filter(Boolean).join("") : "";
555
711
  }
556
- function Q(e, t) {
557
- const s = tt(e, t), r = s.findIndex((i) => i.id === t.id);
558
- if (r === -1)
559
- return S([...s, t]);
560
- const n = [...s];
561
- return n[r] = t, S(n);
712
+ function ht(e, t) {
713
+ const s = pt(e, t), n = s.findIndex((i) => i.id === t.id);
714
+ if (n === -1)
715
+ return _([...s, t]);
716
+ const r = [...s];
717
+ return r[n] = t, _(r);
562
718
  }
563
- function tt(e, t) {
719
+ function pt(e, t) {
564
720
  if (t.role !== "user")
565
721
  return e;
566
722
  const s = e.findIndex(
567
- (n) => n.role === "user" && n.id.startsWith("local-") && n.content === t.content
723
+ (r) => r.role === "user" && r.id.startsWith("local-") && r.content === t.content
568
724
  );
569
725
  if (s === -1)
570
726
  return e;
571
- const r = [...e];
572
- return r.splice(s, 1), r;
727
+ const n = [...e];
728
+ return n.splice(s, 1), n;
573
729
  }
574
- function et(e) {
575
- const t = st(e);
576
- return t === null ? !1 : e.slice(t + 1).some((s) => !s || typeof s != "object" ? !1 : D(s.data));
730
+ function N(e) {
731
+ const t = W(e);
732
+ return t === null ? !1 : e.slice(t + 1).some((s) => !s || typeof s != "object" ? !1 : I(s.data));
577
733
  }
578
- function st(e) {
734
+ function gt(e) {
735
+ const t = W(e);
736
+ return t === null ? e.some((s) => !s || typeof s != "object" ? !1 : b(s.data)) : e.slice(t + 1).some((s) => !s || typeof s != "object" ? !1 : b(s.data));
737
+ }
738
+ function W(e) {
579
739
  for (let t = e.length - 1; t >= 0; t -= 1) {
580
740
  const s = e[t];
581
741
  if (!s || typeof s != "object")
582
742
  continue;
583
- const r = s.data;
584
- if (!r || typeof r != "object")
743
+ const n = s.data;
744
+ if (!n || typeof n != "object")
585
745
  continue;
586
- const n = r;
587
- if (n.type === "message" && n.role === "user")
746
+ const r = n;
747
+ if (r.type === "message" && r.role === "user")
588
748
  return t;
589
749
  }
590
750
  return null;
591
751
  }
592
- function D(e) {
752
+ function b(e) {
753
+ if (!e || typeof e != "object")
754
+ return !1;
755
+ const t = e;
756
+ return t.type === "message" && t.role === "assistant";
757
+ }
758
+ function I(e) {
593
759
  if (!e || typeof e != "object")
594
760
  return !1;
595
761
  const t = e;
596
762
  return t.type === "message" && t.role === "assistant" ? !0 : t.type === "run_error" ? t.stage !== "tool_execution" : t.type === "run_status" && (t.status === "stopped" || t.status === "interrupted");
597
763
  }
598
- function S(e) {
599
- return e.filter((t, s) => rt(t) ? !nt(e, s) : !0);
764
+ function _(e) {
765
+ return e.filter((t, s) => ft(t) ? !yt(e, s) : !0);
600
766
  }
601
- function rt(e) {
767
+ function ft(e) {
602
768
  return e.role === "system" && (e.dataType === "run_status" || e.dataType === "run_error");
603
769
  }
604
- function nt(e, t) {
770
+ function yt(e, t) {
605
771
  for (let s = t + 1; s < e.length; s += 1) {
606
- const r = e[s];
607
- if (r.role === "user")
772
+ const n = e[s];
773
+ if (n.role === "user")
608
774
  return !1;
609
- if (r.role === "assistant")
775
+ if (n.role === "assistant")
610
776
  return !0;
611
777
  }
612
778
  return !1;
613
779
  }
614
- function I(e, t) {
780
+ function D(e, t) {
615
781
  return e && typeof e == "object" && typeof e[t] == "string" ? e[t] : null;
616
782
  }
617
- function ot(e) {
783
+ function mt(e) {
618
784
  try {
619
- const t = window.localStorage.getItem(`${R}${e}`);
785
+ const t = window.localStorage.getItem(`${O}${e}`);
620
786
  if (!t)
621
787
  return null;
622
- const s = JSON.parse(t), r = Array.isArray(s.messages) ? s.messages.map(at).filter((n) => !!n) : [];
788
+ const s = JSON.parse(t), n = Array.isArray(s.messages) ? s.messages.map(kt).filter((r) => !!r) : [];
623
789
  return {
624
790
  sessionId: typeof s.sessionId == "string" ? s.sessionId : null,
625
- messages: r
791
+ messages: n
626
792
  };
627
793
  } catch {
628
794
  return null;
629
795
  }
630
796
  }
631
- function it(e, t) {
797
+ function Tt(e, t) {
632
798
  try {
633
799
  window.localStorage.setItem(
634
- `${R}${e}`,
800
+ `${O}${e}`,
635
801
  JSON.stringify({
636
802
  sessionId: t.sessionId,
637
803
  messages: t.messages.slice(-100)
@@ -641,7 +807,45 @@ function it(e, t) {
641
807
  return;
642
808
  }
643
809
  }
644
- function at(e) {
810
+ function St(e) {
811
+ try {
812
+ const t = window.localStorage.getItem(`${k}${e}`);
813
+ if (!t)
814
+ return [];
815
+ const s = JSON.parse(t);
816
+ return Array.isArray(s) ? s.filter(x) : [];
817
+ } catch {
818
+ return [];
819
+ }
820
+ }
821
+ function m(e, t) {
822
+ try {
823
+ const s = t.filter(x);
824
+ if (s.length === 0) {
825
+ window.localStorage.removeItem(`${k}${e}`);
826
+ return;
827
+ }
828
+ window.localStorage.setItem(
829
+ `${k}${e}`,
830
+ JSON.stringify(s.slice(-25))
831
+ );
832
+ } catch {
833
+ return;
834
+ }
835
+ }
836
+ function x(e) {
837
+ if (!e || typeof e != "object")
838
+ return !1;
839
+ const t = e;
840
+ return t.type === "chat.user_message" ? typeof t.content == "string" && P(t.page) : t.type === "page.upsert" || t.type === "session.reset" || t.type === "network.batch" ? P(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;
841
+ }
842
+ function P(e) {
843
+ if (!e || typeof e != "object")
844
+ return !1;
845
+ const t = e;
846
+ return typeof t.url == "string" && typeof t.title == "string" && typeof t.origin == "string";
847
+ }
848
+ function kt(e) {
645
849
  if (!e || typeof e != "object")
646
850
  return null;
647
851
  const t = e;
@@ -654,18 +858,18 @@ function at(e) {
654
858
  loading: typeof t.loading == "boolean" ? t.loading : void 0
655
859
  };
656
860
  }
657
- function ct(e) {
861
+ function It(e) {
658
862
  return !!e && typeof e == "object" && typeof e.summary == "string" && typeof e.javascript == "string";
659
863
  }
660
- function k(e) {
864
+ function H(e) {
661
865
  const t = {};
662
- return e?.forEach((s, r) => {
663
- t[r] = s;
866
+ return e?.forEach((s, n) => {
867
+ t[n] = s;
664
868
  }), t;
665
869
  }
666
- async function ut(e, t) {
870
+ async function _t(e, t) {
667
871
  if (typeof t?.body < "u")
668
- return b(t.body);
872
+ return B(t.body);
669
873
  if (e)
670
874
  try {
671
875
  return p(await e.clone().text());
@@ -673,21 +877,21 @@ async function ut(e, t) {
673
877
  return;
674
878
  }
675
879
  }
676
- async function lt(e) {
880
+ async function Et(e) {
677
881
  try {
678
882
  return p(await e.clone().text());
679
883
  } catch (t) {
680
884
  return { error: t instanceof Error ? t.message : "unavailable" };
681
885
  }
682
886
  }
683
- function dt(e) {
887
+ function wt(e) {
684
888
  try {
685
889
  return e.responseType === "" || e.responseType === "text" ? p(e.responseText ?? "") : e.responseType === "json" ? p(JSON.stringify(e.response)) : `[unsupported xhr responseType: ${e.responseType || "unknown"}]`;
686
890
  } catch (t) {
687
891
  return { error: t instanceof Error ? t.message : "unavailable" };
688
892
  }
689
893
  }
690
- function b(e) {
894
+ function B(e) {
691
895
  if (!(e === null || typeof e > "u")) {
692
896
  if (typeof e == "string")
693
897
  return p(e);
@@ -695,7 +899,7 @@ function b(e) {
695
899
  return p(e.toString());
696
900
  if (e instanceof FormData) {
697
901
  const t = [];
698
- return e.forEach((s, r) => t.push([r, s instanceof File ? `[file:${s.name}]` : String(s)])), p(JSON.stringify(t));
902
+ return e.forEach((s, n) => t.push([n, s instanceof File ? `[file:${s.name}]` : String(s)])), p(JSON.stringify(t));
699
903
  }
700
904
  if (e instanceof Blob)
701
905
  return `[blob:${e.type || "application/octet-stream"}:${e.size}]`;
@@ -706,68 +910,68 @@ function b(e) {
706
910
  }
707
911
  }
708
912
  }
709
- function pt(e) {
913
+ function At(e) {
710
914
  const t = {};
711
915
  for (const s of e.trim().split(/[\r\n]+/)) {
712
- const r = s.indexOf(":");
713
- r <= 0 || (t[s.slice(0, r).trim()] = s.slice(r + 1).trim());
916
+ const n = s.indexOf(":");
917
+ n <= 0 || (t[s.slice(0, n).trim()] = s.slice(n + 1).trim());
714
918
  }
715
919
  return t;
716
920
  }
717
921
  function p(e) {
718
922
  return e.length <= 1e5 ? e : `${e.slice(0, 1e5)}... [truncated ${e.length - 1e5} chars]`;
719
923
  }
720
- function y(e) {
924
+ function T(e) {
721
925
  return `${e}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
722
926
  }
723
- const E = "[REDACTED_SECRET]", d = "[REDACTED_TOKEN]", ft = "[REDACTED_SIGNED_URL]", ht = 20, gt = /^(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, N = /\bBearer\s+[A-Za-z0-9._~+/=-]{12,}/gi, H = /\bBasic\s+[A-Za-z0-9+/=-]{12,}/gi, q = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, U = /\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, yt = /\bhttps?:\/\/[^\s"'<>]+(?:X-Amz-Signature|X-Goog-Signature|Signature|sig=)[^\s"'<>]*/gi, mt = /\bhttps?:\/\/[^\s"'<>]+/gi, St = /[),.;\]]+$/;
927
+ const E = "[REDACTED_SECRET]", h = "[REDACTED_TOKEN]", Ct = "[REDACTED_SIGNED_URL]", Rt = 20, Mt = /^(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, L = /\bBearer\s+[A-Za-z0-9._~+/=-]{12,}/gi, j = /\bBasic\s+[A-Za-z0-9+/=-]{12,}/gi, v = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, G = /\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, Nt = /\bhttps?:\/\/[^\s"'<>]+(?:X-Amz-Signature|X-Goog-Signature|Signature|sig=)[^\s"'<>]*/gi, bt = /\bhttps?:\/\/[^\s"'<>]+/gi, Dt = /[),.;\]]+$/;
724
928
  function f(e) {
725
- return m(e, 0, /* @__PURE__ */ new WeakSet());
929
+ return S(e, 0, /* @__PURE__ */ new WeakSet());
726
930
  }
727
- function m(e, t, s) {
931
+ function S(e, t, s) {
728
932
  if (typeof e == "string")
729
- return Tt(e);
933
+ return Ot(e);
730
934
  if (e === null || typeof e != "object")
731
935
  return e;
732
- if (t >= ht)
936
+ if (t >= Rt)
733
937
  return "[REDACTED_MAX_DEPTH]";
734
938
  if (s.has(e))
735
939
  return "[REDACTED_CIRCULAR]";
736
940
  if (s.add(e), Array.isArray(e))
737
- return e.map((n) => m(n, t + 1, s));
738
- const r = {};
739
- for (const [n, i] of Object.entries(e))
740
- Et(n) ? r[n] = E : r[n] = n.toLowerCase() === "url" ? _t(i) : m(i, t + 1, s);
741
- return r;
941
+ return e.map((r) => S(r, t + 1, s));
942
+ const n = {};
943
+ for (const [r, i] of Object.entries(e))
944
+ Pt(r) ? n[r] = E : n[r] = r.toLowerCase() === "url" ? Ht(i) : S(i, t + 1, s);
945
+ return n;
742
946
  }
743
- function Et(e) {
947
+ function Pt(e) {
744
948
  const t = e.replace(/[^a-z0-9]/gi, "").toLowerCase();
745
949
  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");
746
950
  }
747
- function _t(e) {
748
- return typeof e == "string" ? P(e) : m(e, 0, /* @__PURE__ */ new WeakSet());
951
+ function Ht(e) {
952
+ return typeof e == "string" ? $(e) : S(e, 0, /* @__PURE__ */ new WeakSet());
749
953
  }
750
- function P(e) {
954
+ function $(e) {
751
955
  try {
752
956
  const t = new URL(e, location.href);
753
957
  for (const s of Array.from(t.searchParams.keys()))
754
- gt.test(s) && t.searchParams.set(s, d);
755
- return t.username && (t.username = d), t.password && (t.password = d), t.toString();
958
+ Mt.test(s) && t.searchParams.set(s, h);
959
+ return t.username && (t.username = h), t.password && (t.password = h), t.toString();
756
960
  } catch {
757
- return wt(e);
961
+ return qt(e);
758
962
  }
759
963
  }
760
- function Tt(e) {
761
- return e.replace(yt, ft).replace(mt, At).replace(N, `Bearer ${d}`).replace(H, `Basic ${d}`).replace(q, d).replace(U, (t, s) => `${s}: ${E}`);
964
+ function Ot(e) {
965
+ return e.replace(Nt, Ct).replace(bt, Ut).replace(L, `Bearer ${h}`).replace(j, `Basic ${h}`).replace(v, h).replace(G, (t, s) => `${s}: ${E}`);
762
966
  }
763
- function wt(e) {
764
- return e.replace(N, `Bearer ${d}`).replace(H, `Basic ${d}`).replace(q, d).replace(U, (t, s) => `${s}: ${E}`);
967
+ function qt(e) {
968
+ return e.replace(L, `Bearer ${h}`).replace(j, `Basic ${h}`).replace(v, h).replace(G, (t, s) => `${s}: ${E}`);
765
969
  }
766
- function At(e) {
767
- const t = e.match(St)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
768
- return `${P(s)}${t}`;
970
+ function Ut(e) {
971
+ const t = e.match(Dt)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
972
+ return `${$(s)}${t}`;
769
973
  }
770
974
  export {
771
- M as PlunoProductAgent,
772
- M as default
975
+ q as PlunoProductAgent,
976
+ q as default
773
977
  };