@pluno/product-agent-web 0.1.6 → 0.1.7

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.
package/dist/index.d.ts CHANGED
@@ -65,6 +65,7 @@ export declare class PlunoProductAgent {
65
65
  private queuedNetworkEvents;
66
66
  private queuedClientEvents;
67
67
  private retryAttemptsByClientMessageId;
68
+ private runtimeHelperJavascript;
68
69
  private state;
69
70
  private constructor();
70
71
  static init(options: ProductAgentInitOptions): Promise<PlunoProductAgent>;
@@ -82,6 +83,7 @@ export declare class PlunoProductAgent {
82
83
  private handleServerEvent;
83
84
  private retryAfterRetryableError;
84
85
  private executeToolCall;
86
+ private executeRuntimeHelper;
85
87
  private enableNetworkCapture;
86
88
  private enqueueNetworkEvent;
87
89
  private scheduleReconnect;
@@ -1,9 +1,9 @@
1
- const P = "https://app.pluno.ai";
2
- const I = "pluno.productAgent.state.";
3
- class k {
1
+ const U = "https://app.pluno.ai";
2
+ const k = "pluno.productAgent.state.";
3
+ class R {
4
4
  constructor(t) {
5
5
  this.options = t;
6
- const s = Q(t.clientId);
6
+ const s = st(t.clientId);
7
7
  s && (this.state = {
8
8
  ...this.state,
9
9
  ...s,
@@ -25,6 +25,7 @@ class k {
25
25
  queuedNetworkEvents = [];
26
26
  queuedClientEvents = [];
27
27
  retryAttemptsByClientMessageId = {};
28
+ runtimeHelperJavascript = null;
28
29
  state = {
29
30
  status: "idle",
30
31
  user: null,
@@ -36,21 +37,21 @@ class k {
36
37
  lastError: null
37
38
  };
38
39
  static async init(t) {
39
- const s = new k({
40
+ const s = new R({
40
41
  ...t,
41
- backendUrl: B(t.backendUrl ?? P),
42
- clientId: t.clientId ?? j()
42
+ backendUrl: x(t.backendUrl ?? U),
43
+ clientId: t.clientId ?? F()
43
44
  });
44
45
  try {
45
46
  s.enableNetworkCapture(), t.autoConnect !== !1 && await s.connect();
46
- } catch (n) {
47
- throw s.destroy(), n;
47
+ } catch (r) {
48
+ throw s.destroy(), r;
48
49
  }
49
50
  return s;
50
51
  }
51
52
  on(t, s) {
52
- const n = this.listeners[t] ?? /* @__PURE__ */ new Set();
53
- return n.add(s), this.listeners[t] = n, () => n.delete(s);
53
+ const r = this.listeners[t] ?? /* @__PURE__ */ new Set();
54
+ return r.add(s), this.listeners[t] = r, () => r.delete(s);
54
55
  }
55
56
  getState() {
56
57
  return {
@@ -64,10 +65,10 @@ class k {
64
65
  return;
65
66
  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)
66
67
  throw new Error("Product Agent requires a token or tokenProvider");
67
- const t = L(this.options.backendUrl);
68
+ const t = B(this.options.backendUrl);
68
69
  this.socket = this.options.webSocketFactory?.(t) ?? new WebSocket(t), this.socket.addEventListener("open", () => {
69
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 });
70
- }), this.socket.addEventListener("message", (s) => this.handleServerEvent(x(s.data))), this.socket.addEventListener("close", () => {
71
+ }), this.socket.addEventListener("message", (s) => this.handleServerEvent(L(s.data))), this.socket.addEventListener("close", () => {
71
72
  this.stopHeartbeat(), this.socket = null, this.state.status !== "closed" && (this.setState({ status: "reconnecting" }), this.scheduleReconnect());
72
73
  }), this.socket.addEventListener("error", () => {
73
74
  this.setState({ status: "error", lastError: "Product Agent connection failed" });
@@ -85,23 +86,23 @@ class k {
85
86
  const s = t.trim();
86
87
  if (!s)
87
88
  return;
88
- const n = g(), r = X(), o = {
89
- id: `local-${r}`,
89
+ const r = g(), n = J(), i = {
90
+ id: `local-${n}`,
90
91
  role: "user",
91
92
  content: s,
92
93
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
93
94
  };
94
95
  this.setState({
95
- messages: [...this.state.messages, o],
96
+ messages: [...this.state.messages, i],
96
97
  assistantDraft: "",
97
98
  isThinking: !0,
98
99
  lastError: null
99
- }), this.emit("message", o), this.send({
100
+ }), this.emit("message", i), this.send({
100
101
  type: "chat.user_message",
101
102
  sessionId: this.state.sessionId ?? void 0,
102
- clientMessageId: r,
103
+ clientMessageId: n,
103
104
  content: s,
104
- page: n,
105
+ page: r,
105
106
  model: this.options.model,
106
107
  metadata: this.options.metadata
107
108
  });
@@ -134,18 +135,18 @@ class k {
134
135
  return;
135
136
  const t = this.queuedClientEvents.splice(0, this.queuedClientEvents.length);
136
137
  for (let s = 0; s < t.length; s += 1) {
137
- const n = t[s];
138
- if (!this.sendNow(f(n))) {
139
- this.queuedClientEvents.unshift(n, ...t.slice(s + 1));
138
+ const r = t[s];
139
+ if (!this.sendNow(f(r))) {
140
+ this.queuedClientEvents.unshift(r, ...t.slice(s + 1));
140
141
  return;
141
142
  }
142
143
  }
143
144
  }
144
145
  handleServerEvent(t) {
145
146
  if (t.type === "auth.ok") {
146
- this.setState({
147
- user: z(t.user),
148
- starterPrompts: $(t, "starterPrompts"),
147
+ this.runtimeHelperJavascript = $(t.runtimeHelpers)?.javascript ?? null, this.setState({
148
+ user: G(t.user),
149
+ starterPrompts: j(t, "starterPrompts"),
149
150
  status: "connected"
150
151
  }), this.state.sessionId && this.send({
151
152
  type: "page.upsert",
@@ -158,22 +159,22 @@ class k {
158
159
  if (t.type === "conversation.state") {
159
160
  const s = Array.isArray(t.items) ? t.items : [];
160
161
  this.setState({
161
- sessionId: _(t.session, "id") ?? this.state.sessionId,
162
- messages: F(s),
163
- ...V(s) ? { assistantDraft: "", isThinking: !1 } : {}
162
+ sessionId: A(t.session, "id") ?? this.state.sessionId,
163
+ messages: W(s),
164
+ ...tt(s) ? { assistantDraft: "", isThinking: !1 } : {}
164
165
  });
165
166
  return;
166
167
  }
167
168
  if (t.type === "session.updated") {
168
- this.setState({ sessionId: _(t.session, "id") ?? this.state.sessionId });
169
+ this.setState({ sessionId: A(t.session, "id") ?? this.state.sessionId });
169
170
  return;
170
171
  }
171
172
  if (t.type === "session.item") {
172
- const s = R(t.item);
173
+ const s = C(t.item);
173
174
  s && (this.setState({
174
- messages: v(this.state.messages, s),
175
+ messages: Z(this.state.messages, s),
175
176
  assistantDraft: s.role === "assistant" ? "" : this.state.assistantDraft,
176
- ...C(t.item.data) ? { assistantDraft: "", isThinking: !1 } : {}
177
+ ...M(t.item.data) ? { assistantDraft: "", isThinking: !1 } : {}
177
178
  }), this.emit("message", s));
178
179
  return;
179
180
  }
@@ -199,94 +200,102 @@ class k {
199
200
  }
200
201
  }
201
202
  retryAfterRetryableError(t) {
202
- const s = typeof t.sessionId == "string" ? t.sessionId : this.state.sessionId, n = typeof t.clientMessageId == "string" ? t.clientMessageId : null;
203
- if (!(t.retryable === !0 || t.code === "transient_model_error") || !s || !n)
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)
204
205
  return !1;
205
- const o = this.retryAttemptsByClientMessageId[n] ?? 0;
206
- if (o >= 1)
206
+ const i = this.retryAttemptsByClientMessageId[r] ?? 0;
207
+ if (i >= 1)
207
208
  return !1;
208
- this.retryAttemptsByClientMessageId[n] = o + 1;
209
+ this.retryAttemptsByClientMessageId[r] = i + 1;
209
210
  const a = typeof t.retryAfterMs == "number" ? t.retryAfterMs : 2e3;
210
211
  return this.setState({ status: "reconnecting", isThinking: !0, lastError: null }), window.setTimeout(() => {
211
212
  this.setState({ status: "connected", isThinking: !0, lastError: null }), this.send({
212
213
  type: "chat.retry_last_user_message",
213
214
  sessionId: s,
214
- clientMessageId: n
215
+ clientMessageId: r
215
216
  });
216
217
  }, a), !0;
217
218
  }
218
219
  async executeToolCall(t) {
219
- const s = typeof t.sessionId == "string" ? t.sessionId : null, n = typeof t.callId == "string" ? t.callId : null, r = t.rawInput;
220
- if (!s || !n || !st(r))
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 || !ot(n))
221
222
  return;
222
- const o = await H(r).catch((a) => ({
223
+ const i = await this.executeRuntimeHelper(), a = await _(n).catch((o) => ({
223
224
  ok: !1,
224
225
  exception: {
225
- message: a instanceof Error ? a.message : String(a)
226
+ message: o instanceof Error ? o.message : String(o)
226
227
  }
227
228
  }));
228
229
  this.send({
229
230
  type: "tool.result",
230
231
  sessionId: s,
231
- callId: n,
232
+ callId: r,
232
233
  toolName: "execute_code",
233
- summary: r.summary,
234
- rawInput: f(r),
235
- rawOutput: f(o)
234
+ summary: n.summary,
235
+ rawInput: f(n),
236
+ rawOutput: f(X(a, i))
237
+ });
238
+ }
239
+ async executeRuntimeHelper() {
240
+ if (!this.runtimeHelperJavascript?.trim())
241
+ return null;
242
+ const t = await _({
243
+ javascript: this.runtimeHelperJavascript
236
244
  });
245
+ return t.ok === !1 ? z(t) : null;
237
246
  }
238
247
  enableNetworkCapture() {
239
248
  if (this.networkCaptureCleanup)
240
249
  return;
241
- const t = window.fetch.bind(window), s = XMLHttpRequest.prototype.open, n = XMLHttpRequest.prototype.setRequestHeader, r = XMLHttpRequest.prototype.send;
242
- window.fetch = async (o, a) => {
243
- const i = Date.now(), c = new Date(i).toISOString(), u = o instanceof Request ? o : null, h = typeof o == "string" ? o : o instanceof URL ? o.toString() : u?.url ?? "", w = (a?.method ?? u?.method ?? "GET").toUpperCase(), E = A(new Headers(a?.headers ?? u?.headers ?? void 0)), T = await nt(u, a);
250
+ const t = window.fetch.bind(window), s = XMLHttpRequest.prototype.open, r = XMLHttpRequest.prototype.setRequestHeader, n = XMLHttpRequest.prototype.send;
251
+ 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 ?? "", E = (a?.method ?? u?.method ?? "GET").toUpperCase(), T = I(new Headers(a?.headers ?? u?.headers ?? void 0)), w = await it(u, a);
244
253
  try {
245
- const l = await t(o, a);
254
+ const l = await t(i, a);
246
255
  return this.enqueueNetworkEvent({
247
256
  requestId: y("fetch"),
248
257
  url: h,
249
- method: w,
250
- requestHeaders: E,
251
- requestBody: T,
258
+ method: E,
259
+ requestHeaders: T,
260
+ requestBody: w,
252
261
  resourceType: "fetch",
253
262
  responseStatus: l.status,
254
- responseHeaders: A(l.headers),
255
- responseBody: await rt(l),
263
+ responseHeaders: I(l.headers),
264
+ responseBody: await at(l),
256
265
  startedAt: c,
257
- durationMs: Date.now() - i
266
+ durationMs: Date.now() - o
258
267
  }), l;
259
268
  } catch (l) {
260
269
  throw this.enqueueNetworkEvent({
261
270
  requestId: y("fetch"),
262
271
  url: h,
263
- method: w,
264
- requestHeaders: E,
265
- requestBody: T,
272
+ method: E,
273
+ requestHeaders: T,
274
+ requestBody: w,
266
275
  resourceType: "fetch",
267
276
  errorText: l instanceof Error ? l.message : String(l),
268
277
  startedAt: c,
269
- durationMs: Date.now() - i
278
+ durationMs: Date.now() - o
270
279
  }), l;
271
280
  }
272
- }, XMLHttpRequest.prototype.open = function(a, i, c, u, h) {
281
+ }, XMLHttpRequest.prototype.open = function(a, o, c, u, h) {
273
282
  return this.__plunoMeta = {
274
283
  requestId: y("xhr"),
275
284
  method: String(a ?? "GET").toUpperCase(),
276
- url: typeof i == "string" ? i : i.toString(),
285
+ url: typeof o == "string" ? o : o.toString(),
277
286
  requestHeaders: {},
278
287
  startedAtMs: Date.now(),
279
288
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
280
- }, s.call(this, a, i, c ?? !0, u ?? void 0, h ?? void 0);
281
- }, XMLHttpRequest.prototype.setRequestHeader = function(a, i) {
289
+ }, s.call(this, a, o, c ?? !0, u ?? void 0, h ?? void 0);
290
+ }, XMLHttpRequest.prototype.setRequestHeader = function(a, o) {
282
291
  const c = this.__plunoMeta;
283
292
  if (c) {
284
293
  const u = c.requestHeaders ?? {};
285
- u[a] = i, c.requestHeaders = u;
294
+ u[a] = o, c.requestHeaders = u;
286
295
  }
287
- return n.call(this, a, i);
296
+ return r.call(this, a, o);
288
297
  }, XMLHttpRequest.prototype.send = function(a) {
289
- const i = window.__plunoProductAgentInstance, c = this.__plunoMeta ?? {
298
+ const o = window.__plunoProductAgentInstance, c = this.__plunoMeta ?? {
290
299
  requestId: y("xhr"),
291
300
  method: "GET",
292
301
  url: "",
@@ -294,10 +303,10 @@ class k {
294
303
  startedAtMs: Date.now(),
295
304
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
296
305
  };
297
- return c.requestBody = M(a), this.__plunoMeta = c, this.addEventListener(
306
+ return c.requestBody = D(a), this.__plunoMeta = c, this.addEventListener(
298
307
  "loadend",
299
308
  function() {
300
- !i || !this.__plunoMeta || i.enqueueNetworkEvent({
309
+ !o || !this.__plunoMeta || o.enqueueNetworkEvent({
301
310
  requestId: String(this.__plunoMeta.requestId),
302
311
  url: String(this.__plunoMeta.url ?? ""),
303
312
  method: String(this.__plunoMeta.method ?? "GET"),
@@ -305,17 +314,17 @@ class k {
305
314
  requestBody: typeof this.__plunoMeta.requestBody == "string" ? this.__plunoMeta.requestBody : void 0,
306
315
  resourceType: "xhr",
307
316
  responseStatus: this.status,
308
- responseHeaders: it(this.getAllResponseHeaders()),
309
- responseBody: ot(this),
317
+ responseHeaders: ut(this.getAllResponseHeaders()),
318
+ responseBody: ct(this),
310
319
  errorText: this.status === 0 ? "XHR request failed or was aborted" : void 0,
311
320
  startedAt: String(this.__plunoMeta.startedAt),
312
321
  durationMs: Date.now() - Number(this.__plunoMeta.startedAtMs ?? Date.now())
313
322
  });
314
323
  },
315
324
  { once: !0 }
316
- ), r.call(this, a ?? null);
325
+ ), n.call(this, a ?? null);
317
326
  }, window.__plunoProductAgentInstance = this, this.networkCaptureCleanup = () => {
318
- window.fetch = t, XMLHttpRequest.prototype.open = s, XMLHttpRequest.prototype.setRequestHeader = n, XMLHttpRequest.prototype.send = r, window.__plunoProductAgentInstance === this && delete window.__plunoProductAgentInstance;
327
+ window.fetch = t, XMLHttpRequest.prototype.open = s, XMLHttpRequest.prototype.setRequestHeader = r, XMLHttpRequest.prototype.send = n, window.__plunoProductAgentInstance === this && delete window.__plunoProductAgentInstance;
319
328
  };
320
329
  }
321
330
  enqueueNetworkEvent(t) {
@@ -346,22 +355,22 @@ class k {
346
355
  this.heartbeatTimer !== null && (window.clearInterval(this.heartbeatTimer), this.heartbeatTimer = null);
347
356
  }
348
357
  setState(t) {
349
- this.state = { ...this.state, ...t }, tt(this.options.clientId, this.state), this.emit("state", this.getState());
358
+ this.state = { ...this.state, ...t }, rt(this.options.clientId, this.state), this.emit("state", this.getState());
350
359
  }
351
360
  emit(t, s) {
352
- this.listeners[t]?.forEach((r) => r(s));
361
+ this.listeners[t]?.forEach((n) => n(s));
353
362
  }
354
363
  }
355
- const U = 5e3;
356
- async function H(e) {
364
+ const O = 5e3;
365
+ async function _(e) {
357
366
  const t = Object.getPrototypeOf(async function() {
358
- }).constructor, s = U, n = Date.now(), r = [], o = {
367
+ }).constructor, s = O, r = Date.now(), n = [], i = {
359
368
  log: console.log,
360
369
  info: console.info,
361
370
  warn: console.warn,
362
371
  error: console.error
363
- }, a = (i) => (...c) => {
364
- r.push({ level: i, args: c }), o[i](...c);
372
+ }, a = (o) => (...c) => {
373
+ n.push({ level: o, args: c }), i[o](...c);
365
374
  };
366
375
  console.log = a("log"), console.info = a("info"), console.warn = a("warn"), console.error = a("error");
367
376
  try {
@@ -373,36 +382,36 @@ async function H(e) {
373
382
  (c, u) => window.setTimeout(() => u(new Error(`execute_code timed out after ${s}ms`)), s)
374
383
  )
375
384
  ]),
376
- console: r,
385
+ console: n,
377
386
  metadata: {
378
- durationMs: Date.now() - n,
387
+ durationMs: Date.now() - r,
379
388
  url: location.href,
380
389
  origin: location.origin
381
390
  }
382
391
  };
383
- } catch (i) {
392
+ } catch (o) {
384
393
  return {
385
394
  ok: !1,
386
- console: r,
395
+ console: n,
387
396
  exception: {
388
- name: i instanceof Error ? i.name : "Error",
389
- message: i instanceof Error ? i.message : String(i),
390
- stack: i instanceof Error ? i.stack : void 0
397
+ name: o instanceof Error ? o.name : "Error",
398
+ message: o instanceof Error ? o.message : String(o),
399
+ stack: o instanceof Error ? o.stack : void 0
391
400
  },
392
401
  metadata: {
393
- durationMs: Date.now() - n,
402
+ durationMs: Date.now() - r,
394
403
  url: location.href,
395
404
  origin: location.origin
396
405
  }
397
406
  };
398
407
  } finally {
399
- console.log = o.log, console.info = o.info, console.warn = o.warn, console.error = o.error;
408
+ console.log = i.log, console.info = i.info, console.warn = i.warn, console.error = i.error;
400
409
  }
401
410
  }
402
- function B(e) {
411
+ function x(e) {
403
412
  return e.replace(/\/+$/, "");
404
413
  }
405
- function L(e) {
414
+ function B(e) {
406
415
  const t = new URL("/api/product-agent/embed/ws", e);
407
416
  return t.protocol = t.protocol === "https:" ? "wss:" : "ws:", t.toString();
408
417
  }
@@ -413,7 +422,7 @@ function g() {
413
422
  origin: location.origin
414
423
  };
415
424
  }
416
- function x(e) {
425
+ function L(e) {
417
426
  try {
418
427
  const t = JSON.parse(e);
419
428
  return t && typeof t == "object" ? t : { type: "error", message: "Invalid server event" };
@@ -421,23 +430,45 @@ function x(e) {
421
430
  return { type: "error", message: "Invalid server event" };
422
431
  }
423
432
  }
424
- function $(e, t) {
433
+ function j(e, t) {
425
434
  if (!e || typeof e != "object")
426
435
  return [];
427
436
  const s = e[t];
428
- return Array.isArray(s) ? s.filter((n) => typeof n == "string" && n.trim().length > 0) : [];
437
+ return Array.isArray(s) ? s.filter((r) => typeof r == "string" && r.trim().length > 0) : [];
429
438
  }
430
- function j() {
439
+ function $(e) {
440
+ if (!e || typeof e != "object")
441
+ return null;
442
+ const t = e.javascript;
443
+ return typeof t != "string" || !t.trim() ? null : { javascript: t };
444
+ }
445
+ function X(e, t) {
446
+ return t ? e && typeof e == "object" ? {
447
+ ...e,
448
+ helperError: t
449
+ } : {
450
+ ok: !0,
451
+ result: e,
452
+ helperError: t
453
+ } : e;
454
+ }
455
+ function z(e) {
456
+ if (!e || typeof e != "object")
457
+ return e;
458
+ const t = e;
459
+ return typeof t.exception?.message == "string" ? t.exception.message : typeof t.error == "string" ? t.error : e;
460
+ }
461
+ function F() {
431
462
  const e = "pluno.productAgent.clientId", t = window.localStorage.getItem(e);
432
463
  if (t)
433
464
  return t;
434
465
  const s = crypto.randomUUID();
435
466
  return window.localStorage.setItem(e, s), s;
436
467
  }
437
- function X() {
468
+ function J() {
438
469
  return crypto.randomUUID();
439
470
  }
440
- function z(e) {
471
+ function G(e) {
441
472
  if (!e || typeof e != "object")
442
473
  return null;
443
474
  const t = e, s = typeof t.id == "string" ? t.id : null;
@@ -448,44 +479,44 @@ function z(e) {
448
479
  avatarUrl: typeof t.avatarUrl == "string" ? t.avatarUrl : null
449
480
  } : null;
450
481
  }
451
- function F(e) {
452
- return Array.isArray(e) ? e.map(R).filter((t) => t !== null) : [];
482
+ function W(e) {
483
+ return Array.isArray(e) ? e.map(C).filter((t) => t !== null) : [];
453
484
  }
454
- function R(e) {
485
+ function C(e) {
455
486
  if (!e || typeof e != "object")
456
487
  return null;
457
488
  const t = e, s = t.data;
458
489
  if (!s || typeof s != "object")
459
490
  return null;
460
- const n = s;
461
- if (n.type === "message") {
462
- const r = n.role === "assistant" ? "assistant" : n.role === "user" ? "user" : "system";
491
+ const r = s;
492
+ if (r.type === "message") {
493
+ const n = r.role === "assistant" ? "assistant" : r.role === "user" ? "user" : "system";
463
494
  return {
464
495
  id: String(t.id ?? crypto.randomUUID()),
465
- role: r,
466
- content: K(n.content),
496
+ role: n,
497
+ content: V(r.content),
467
498
  createdAt: typeof t.createdAt == "string" ? t.createdAt : (/* @__PURE__ */ new Date()).toISOString()
468
499
  };
469
500
  }
470
- return n.type === "function_call" || n.type === "tool_call" || n.type === "web_search_call" ? {
501
+ return r.type === "function_call" || r.type === "tool_call" || r.type === "web_search_call" ? {
471
502
  id: String(t.id ?? crypto.randomUUID()),
472
503
  role: "tool",
473
- content: W(n),
504
+ content: K(r),
474
505
  createdAt: typeof t.createdAt == "string" ? t.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
475
- dataType: String(n.type),
476
- loading: n.localExecutionStatus === "running"
477
- } : n.type === "run_status" || n.type === "run_error" ? n.type === "run_status" && (n.status === "running" || n.status === "retrying") ? null : {
506
+ dataType: String(r.type),
507
+ loading: r.localExecutionStatus === "running"
508
+ } : r.type === "run_status" || r.type === "run_error" ? r.type === "run_status" && (r.status === "running" || r.status === "retrying") ? null : {
478
509
  id: String(t.id ?? crypto.randomUUID()),
479
510
  role: "system",
480
- content: G(n),
511
+ content: v(r),
481
512
  createdAt: typeof t.createdAt == "string" ? t.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
482
- dataType: String(n.type)
513
+ dataType: String(r.type)
483
514
  } : null;
484
515
  }
485
- function G(e) {
516
+ function v(e) {
486
517
  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.";
487
518
  }
488
- function W(e) {
519
+ function K(e) {
489
520
  if (e.type === "web_search_call") {
490
521
  const t = e.action;
491
522
  if (t && typeof t == "object") {
@@ -497,9 +528,9 @@ function W(e) {
497
528
  }
498
529
  return "Searching the web";
499
530
  }
500
- return J(e);
531
+ return Y(e);
501
532
  }
502
- function J(e) {
533
+ function Y(e) {
503
534
  if (typeof e.summary == "string" && e.summary.trim().length > 0)
504
535
  return e.summary;
505
536
  if (typeof e.arguments == "string")
@@ -512,7 +543,7 @@ function J(e) {
512
543
  }
513
544
  return typeof e.name == "string" && e.name.trim().length > 0 ? e.name : "Run tool";
514
545
  }
515
- function K(e) {
546
+ function V(e) {
516
547
  return typeof e == "string" ? e : Array.isArray(e) ? e.map((t) => {
517
548
  if (!t || typeof t != "object")
518
549
  return "";
@@ -520,69 +551,69 @@ function K(e) {
520
551
  return typeof s.text == "string" ? s.text : typeof s.content == "string" ? s.content : "";
521
552
  }).filter(Boolean).join("") : "";
522
553
  }
523
- function v(e, t) {
524
- const s = Y(e, t), n = s.findIndex((o) => o.id === t.id);
525
- if (n === -1)
554
+ function Z(e, t) {
555
+ const s = Q(e, t), r = s.findIndex((i) => i.id === t.id);
556
+ if (r === -1)
526
557
  return [...s, t];
527
- const r = [...s];
528
- return r[n] = t, r;
558
+ const n = [...s];
559
+ return n[r] = t, n;
529
560
  }
530
- function Y(e, t) {
561
+ function Q(e, t) {
531
562
  if (t.role !== "user")
532
563
  return e;
533
564
  const s = e.findIndex(
534
- (r) => r.role === "user" && r.id.startsWith("local-") && r.content === t.content
565
+ (n) => n.role === "user" && n.id.startsWith("local-") && n.content === t.content
535
566
  );
536
567
  if (s === -1)
537
568
  return e;
538
- const n = [...e];
539
- return n.splice(s, 1), n;
569
+ const r = [...e];
570
+ return r.splice(s, 1), r;
540
571
  }
541
- function V(e) {
542
- const t = Z(e);
543
- return t === null ? !1 : e.slice(t + 1).some((s) => !s || typeof s != "object" ? !1 : C(s.data));
572
+ function tt(e) {
573
+ const t = et(e);
574
+ return t === null ? !1 : e.slice(t + 1).some((s) => !s || typeof s != "object" ? !1 : M(s.data));
544
575
  }
545
- function Z(e) {
576
+ function et(e) {
546
577
  for (let t = e.length - 1; t >= 0; t -= 1) {
547
578
  const s = e[t];
548
579
  if (!s || typeof s != "object")
549
580
  continue;
550
- const n = s.data;
551
- if (!n || typeof n != "object")
581
+ const r = s.data;
582
+ if (!r || typeof r != "object")
552
583
  continue;
553
- const r = n;
554
- if (r.type === "message" && r.role === "user")
584
+ const n = r;
585
+ if (n.type === "message" && n.role === "user")
555
586
  return t;
556
587
  }
557
588
  return null;
558
589
  }
559
- function C(e) {
590
+ function M(e) {
560
591
  if (!e || typeof e != "object")
561
592
  return !1;
562
593
  const t = e;
563
594
  return t.type === "message" && t.role === "assistant" || t.type === "run_error" ? !0 : t.type === "run_status" && (t.status === "stopped" || t.status === "interrupted");
564
595
  }
565
- function _(e, t) {
596
+ function A(e, t) {
566
597
  return e && typeof e == "object" && typeof e[t] == "string" ? e[t] : null;
567
598
  }
568
- function Q(e) {
599
+ function st(e) {
569
600
  try {
570
- const t = window.localStorage.getItem(`${I}${e}`);
601
+ const t = window.localStorage.getItem(`${k}${e}`);
571
602
  if (!t)
572
603
  return null;
573
- const s = JSON.parse(t), n = Array.isArray(s.messages) ? s.messages.map(et).filter((r) => !!r) : [];
604
+ const s = JSON.parse(t), r = Array.isArray(s.messages) ? s.messages.map(nt).filter((n) => !!n) : [];
574
605
  return {
575
606
  sessionId: typeof s.sessionId == "string" ? s.sessionId : null,
576
- messages: n
607
+ messages: r
577
608
  };
578
609
  } catch {
579
610
  return null;
580
611
  }
581
612
  }
582
- function tt(e, t) {
613
+ function rt(e, t) {
583
614
  try {
584
615
  window.localStorage.setItem(
585
- `${I}${e}`,
616
+ `${k}${e}`,
586
617
  JSON.stringify({
587
618
  sessionId: t.sessionId,
588
619
  messages: t.messages.slice(-100)
@@ -592,7 +623,7 @@ function tt(e, t) {
592
623
  return;
593
624
  }
594
625
  }
595
- function et(e) {
626
+ function nt(e) {
596
627
  if (!e || typeof e != "object")
597
628
  return null;
598
629
  const t = e;
@@ -605,18 +636,18 @@ function et(e) {
605
636
  loading: typeof t.loading == "boolean" ? t.loading : void 0
606
637
  };
607
638
  }
608
- function st(e) {
639
+ function ot(e) {
609
640
  return !!e && typeof e == "object" && typeof e.summary == "string" && typeof e.javascript == "string";
610
641
  }
611
- function A(e) {
642
+ function I(e) {
612
643
  const t = {};
613
- return e?.forEach((s, n) => {
614
- t[n] = s;
644
+ return e?.forEach((s, r) => {
645
+ t[r] = s;
615
646
  }), t;
616
647
  }
617
- async function nt(e, t) {
648
+ async function it(e, t) {
618
649
  if (typeof t?.body < "u")
619
- return M(t.body);
650
+ return D(t.body);
620
651
  if (e)
621
652
  try {
622
653
  return p(await e.clone().text());
@@ -624,21 +655,21 @@ async function nt(e, t) {
624
655
  return;
625
656
  }
626
657
  }
627
- async function rt(e) {
658
+ async function at(e) {
628
659
  try {
629
660
  return p(await e.clone().text());
630
661
  } catch (t) {
631
662
  return { error: t instanceof Error ? t.message : "unavailable" };
632
663
  }
633
664
  }
634
- function ot(e) {
665
+ function ct(e) {
635
666
  try {
636
667
  return e.responseType === "" || e.responseType === "text" ? p(e.responseText ?? "") : e.responseType === "json" ? p(JSON.stringify(e.response)) : `[unsupported xhr responseType: ${e.responseType || "unknown"}]`;
637
668
  } catch (t) {
638
669
  return { error: t instanceof Error ? t.message : "unavailable" };
639
670
  }
640
671
  }
641
- function M(e) {
672
+ function D(e) {
642
673
  if (!(e === null || typeof e > "u")) {
643
674
  if (typeof e == "string")
644
675
  return p(e);
@@ -646,7 +677,7 @@ function M(e) {
646
677
  return p(e.toString());
647
678
  if (e instanceof FormData) {
648
679
  const t = [];
649
- return e.forEach((s, n) => t.push([n, s instanceof File ? `[file:${s.name}]` : String(s)])), p(JSON.stringify(t));
680
+ return e.forEach((s, r) => t.push([r, s instanceof File ? `[file:${s.name}]` : String(s)])), p(JSON.stringify(t));
650
681
  }
651
682
  if (e instanceof Blob)
652
683
  return `[blob:${e.type || "application/octet-stream"}:${e.size}]`;
@@ -657,11 +688,11 @@ function M(e) {
657
688
  }
658
689
  }
659
690
  }
660
- function it(e) {
691
+ function ut(e) {
661
692
  const t = {};
662
693
  for (const s of e.trim().split(/[\r\n]+/)) {
663
- const n = s.indexOf(":");
664
- n <= 0 || (t[s.slice(0, n).trim()] = s.slice(n + 1).trim());
694
+ const r = s.indexOf(":");
695
+ r <= 0 || (t[s.slice(0, r).trim()] = s.slice(r + 1).trim());
665
696
  }
666
697
  return t;
667
698
  }
@@ -671,54 +702,54 @@ function p(e) {
671
702
  function y(e) {
672
703
  return `${e}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
673
704
  }
674
- const S = "[REDACTED_SECRET]", d = "[REDACTED_TOKEN]", at = "[REDACTED_SIGNED_URL]", ct = 20, ut = /^(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, D = /\bBearer\s+[A-Za-z0-9._~+/=-]{12,}/gi, N = /\bBasic\s+[A-Za-z0-9+/=-]{12,}/gi, b = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, q = /\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, lt = /\bhttps?:\/\/[^\s"'<>]+(?:X-Amz-Signature|X-Goog-Signature|Signature|sig=)[^\s"'<>]*/gi, dt = /\bhttps?:\/\/[^\s"'<>]+/gi, pt = /[),.;\]]+$/;
705
+ const S = "[REDACTED_SECRET]", d = "[REDACTED_TOKEN]", lt = "[REDACTED_SIGNED_URL]", dt = 20, pt = /^(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, b = /\bBearer\s+[A-Za-z0-9._~+/=-]{12,}/gi, N = /\bBasic\s+[A-Za-z0-9+/=-]{12,}/gi, H = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, q = /\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, ft = /\bhttps?:\/\/[^\s"'<>]+(?:X-Amz-Signature|X-Goog-Signature|Signature|sig=)[^\s"'<>]*/gi, ht = /\bhttps?:\/\/[^\s"'<>]+/gi, gt = /[),.;\]]+$/;
675
706
  function f(e) {
676
707
  return m(e, 0, /* @__PURE__ */ new WeakSet());
677
708
  }
678
709
  function m(e, t, s) {
679
710
  if (typeof e == "string")
680
- return gt(e);
711
+ return St(e);
681
712
  if (e === null || typeof e != "object")
682
713
  return e;
683
- if (t >= ct)
714
+ if (t >= dt)
684
715
  return "[REDACTED_MAX_DEPTH]";
685
716
  if (s.has(e))
686
717
  return "[REDACTED_CIRCULAR]";
687
718
  if (s.add(e), Array.isArray(e))
688
- return e.map((r) => m(r, t + 1, s));
689
- const n = {};
690
- for (const [r, o] of Object.entries(e))
691
- ft(r) ? n[r] = S : n[r] = r.toLowerCase() === "url" ? ht(o) : m(o, t + 1, s);
692
- return n;
719
+ return e.map((n) => m(n, t + 1, s));
720
+ const r = {};
721
+ for (const [n, i] of Object.entries(e))
722
+ yt(n) ? r[n] = S : r[n] = n.toLowerCase() === "url" ? mt(i) : m(i, t + 1, s);
723
+ return r;
693
724
  }
694
- function ft(e) {
725
+ function yt(e) {
695
726
  const t = e.replace(/[^a-z0-9]/gi, "").toLowerCase();
696
727
  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");
697
728
  }
698
- function ht(e) {
699
- return typeof e == "string" ? O(e) : m(e, 0, /* @__PURE__ */ new WeakSet());
729
+ function mt(e) {
730
+ return typeof e == "string" ? P(e) : m(e, 0, /* @__PURE__ */ new WeakSet());
700
731
  }
701
- function O(e) {
732
+ function P(e) {
702
733
  try {
703
734
  const t = new URL(e, location.href);
704
735
  for (const s of Array.from(t.searchParams.keys()))
705
- ut.test(s) && t.searchParams.set(s, d);
736
+ pt.test(s) && t.searchParams.set(s, d);
706
737
  return t.username && (t.username = d), t.password && (t.password = d), t.toString();
707
738
  } catch {
708
- return yt(e);
739
+ return Et(e);
709
740
  }
710
741
  }
711
- function gt(e) {
712
- return e.replace(lt, at).replace(dt, mt).replace(D, `Bearer ${d}`).replace(N, `Basic ${d}`).replace(b, d).replace(q, (t, s) => `${s}: ${S}`);
742
+ function St(e) {
743
+ return e.replace(ft, lt).replace(ht, Tt).replace(b, `Bearer ${d}`).replace(N, `Basic ${d}`).replace(H, d).replace(q, (t, s) => `${s}: ${S}`);
713
744
  }
714
- function yt(e) {
715
- return e.replace(D, `Bearer ${d}`).replace(N, `Basic ${d}`).replace(b, d).replace(q, (t, s) => `${s}: ${S}`);
745
+ function Et(e) {
746
+ return e.replace(b, `Bearer ${d}`).replace(N, `Basic ${d}`).replace(H, d).replace(q, (t, s) => `${s}: ${S}`);
716
747
  }
717
- function mt(e) {
718
- const t = e.match(pt)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
719
- return `${O(s)}${t}`;
748
+ function Tt(e) {
749
+ const t = e.match(gt)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
750
+ return `${P(s)}${t}`;
720
751
  }
721
752
  export {
722
- k as PlunoProductAgent,
723
- k as default
753
+ R as PlunoProductAgent,
754
+ R as default
724
755
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluno/product-agent-web",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Browser SDK and default widget for embedding Pluno Product Agent into customer web apps.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",