@pluno/product-agent-web 0.1.6 → 0.1.8

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 x = "https://app.pluno.ai";
2
+ const R = "pluno.productAgent.state.";
3
+ class M {
4
4
  constructor(t) {
5
5
  this.options = t;
6
- const s = Q(t.clientId);
6
+ const s = ot(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 M({
40
41
  ...t,
41
- backendUrl: B(t.backendUrl ?? P),
42
- clientId: t.clientId ?? j()
42
+ backendUrl: B(t.backendUrl ?? x),
43
+ clientId: t.clientId ?? J()
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 {
@@ -67,7 +68,7 @@ class k {
67
68
  const t = L(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(j(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 = G(), 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,17 +135,17 @@ 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),
147
+ this.runtimeHelperJavascript = X(t.runtimeHelpers)?.javascript ?? null, this.setState({
148
+ user: W(t.user),
148
149
  starterPrompts: $(t, "starterPrompts"),
149
150
  status: "connected"
150
151
  }), this.state.sessionId && this.send({
@@ -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: I(t.session, "id") ?? this.state.sessionId,
163
+ messages: v(s),
164
+ ...et(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: I(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: Q(this.state.messages, s),
175
176
  assistantDraft: s.role === "assistant" ? "" : this.state.assistantDraft,
176
- ...C(t.item.data) ? { assistantDraft: "", isThinking: !1 } : {}
177
+ ...D(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 || !ct(n))
221
222
  return;
222
- const o = await H(r).catch((a) => ({
223
+ const i = await this.executeRuntimeHelper(), a = await A(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(z(a, i))
236
237
  });
237
238
  }
239
+ async executeRuntimeHelper() {
240
+ if (!this.runtimeHelperJavascript?.trim())
241
+ return null;
242
+ const t = await A({
243
+ javascript: this.runtimeHelperJavascript
244
+ });
245
+ return t.ok === !1 ? F(t) : null;
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 ?? "", _ = (a?.method ?? u?.method ?? "GET").toUpperCase(), T = k(new Headers(a?.headers ?? u?.headers ?? void 0)), w = await ut(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: _,
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: k(l.headers),
264
+ responseBody: await lt(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: _,
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 = b(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: pt(this.getAllResponseHeaders()),
318
+ responseBody: dt(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 }, it(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 A(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,30 +382,30 @@ 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
411
  function B(e) {
@@ -413,7 +422,7 @@ function g() {
413
422
  origin: location.origin
414
423
  };
415
424
  }
416
- function x(e) {
425
+ function j(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" };
@@ -425,19 +434,41 @@ function $(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) : [];
438
+ }
439
+ function X(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 z(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 F(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;
429
460
  }
430
- function j() {
461
+ function J() {
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 G() {
438
469
  return crypto.randomUUID();
439
470
  }
440
- function z(e) {
471
+ function W(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,46 @@ 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 v(e) {
483
+ return Array.isArray(e) ? S(
484
+ e.map(C).filter((t) => t !== null)
485
+ ) : [];
453
486
  }
454
- function R(e) {
487
+ function C(e) {
455
488
  if (!e || typeof e != "object")
456
489
  return null;
457
490
  const t = e, s = t.data;
458
491
  if (!s || typeof s != "object")
459
492
  return null;
460
- const n = s;
461
- if (n.type === "message") {
462
- const r = n.role === "assistant" ? "assistant" : n.role === "user" ? "user" : "system";
493
+ const r = s;
494
+ if (r.type === "message") {
495
+ const n = r.role === "assistant" ? "assistant" : r.role === "user" ? "user" : "system";
463
496
  return {
464
497
  id: String(t.id ?? crypto.randomUUID()),
465
- role: r,
466
- content: K(n.content),
498
+ role: n,
499
+ content: Z(r.content),
467
500
  createdAt: typeof t.createdAt == "string" ? t.createdAt : (/* @__PURE__ */ new Date()).toISOString()
468
501
  };
469
502
  }
470
- return n.type === "function_call" || n.type === "tool_call" || n.type === "web_search_call" ? {
503
+ return r.type === "function_call" || r.type === "tool_call" || r.type === "web_search_call" ? {
471
504
  id: String(t.id ?? crypto.randomUUID()),
472
505
  role: "tool",
473
- content: W(n),
506
+ content: Y(r),
474
507
  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 : {
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 : {
478
511
  id: String(t.id ?? crypto.randomUUID()),
479
512
  role: "system",
480
- content: G(n),
513
+ content: K(r),
481
514
  createdAt: typeof t.createdAt == "string" ? t.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
482
- dataType: String(n.type)
515
+ dataType: String(r.type)
483
516
  } : null;
484
517
  }
485
- function G(e) {
518
+ function K(e) {
486
519
  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
520
  }
488
- function W(e) {
521
+ function Y(e) {
489
522
  if (e.type === "web_search_call") {
490
523
  const t = e.action;
491
524
  if (t && typeof t == "object") {
@@ -497,9 +530,9 @@ function W(e) {
497
530
  }
498
531
  return "Searching the web";
499
532
  }
500
- return J(e);
533
+ return V(e);
501
534
  }
502
- function J(e) {
535
+ function V(e) {
503
536
  if (typeof e.summary == "string" && e.summary.trim().length > 0)
504
537
  return e.summary;
505
538
  if (typeof e.arguments == "string")
@@ -512,7 +545,7 @@ function J(e) {
512
545
  }
513
546
  return typeof e.name == "string" && e.name.trim().length > 0 ? e.name : "Run tool";
514
547
  }
515
- function K(e) {
548
+ function Z(e) {
516
549
  return typeof e == "string" ? e : Array.isArray(e) ? e.map((t) => {
517
550
  if (!t || typeof t != "object")
518
551
  return "";
@@ -520,69 +553,85 @@ function K(e) {
520
553
  return typeof s.text == "string" ? s.text : typeof s.content == "string" ? s.content : "";
521
554
  }).filter(Boolean).join("") : "";
522
555
  }
523
- function v(e, t) {
524
- const s = Y(e, t), n = s.findIndex((o) => o.id === t.id);
525
- if (n === -1)
526
- return [...s, t];
527
- const r = [...s];
528
- return r[n] = t, r;
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);
529
562
  }
530
- function Y(e, t) {
563
+ function tt(e, t) {
531
564
  if (t.role !== "user")
532
565
  return e;
533
566
  const s = e.findIndex(
534
- (r) => r.role === "user" && r.id.startsWith("local-") && r.content === t.content
567
+ (n) => n.role === "user" && n.id.startsWith("local-") && n.content === t.content
535
568
  );
536
569
  if (s === -1)
537
570
  return e;
538
- const n = [...e];
539
- return n.splice(s, 1), n;
571
+ const r = [...e];
572
+ return r.splice(s, 1), r;
540
573
  }
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));
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));
544
577
  }
545
- function Z(e) {
578
+ function st(e) {
546
579
  for (let t = e.length - 1; t >= 0; t -= 1) {
547
580
  const s = e[t];
548
581
  if (!s || typeof s != "object")
549
582
  continue;
550
- const n = s.data;
551
- if (!n || typeof n != "object")
583
+ const r = s.data;
584
+ if (!r || typeof r != "object")
552
585
  continue;
553
- const r = n;
554
- if (r.type === "message" && r.role === "user")
586
+ const n = r;
587
+ if (n.type === "message" && n.role === "user")
555
588
  return t;
556
589
  }
557
590
  return null;
558
591
  }
559
- function C(e) {
592
+ function D(e) {
560
593
  if (!e || typeof e != "object")
561
594
  return !1;
562
595
  const t = e;
563
- return t.type === "message" && t.role === "assistant" || t.type === "run_error" ? !0 : t.type === "run_status" && (t.status === "stopped" || t.status === "interrupted");
596
+ 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
+ }
598
+ function S(e) {
599
+ return e.filter((t, s) => rt(t) ? !nt(e, s) : !0);
564
600
  }
565
- function _(e, t) {
601
+ function rt(e) {
602
+ return e.role === "system" && (e.dataType === "run_status" || e.dataType === "run_error");
603
+ }
604
+ function nt(e, t) {
605
+ for (let s = t + 1; s < e.length; s += 1) {
606
+ const r = e[s];
607
+ if (r.role === "user")
608
+ return !1;
609
+ if (r.role === "assistant")
610
+ return !0;
611
+ }
612
+ return !1;
613
+ }
614
+ function I(e, t) {
566
615
  return e && typeof e == "object" && typeof e[t] == "string" ? e[t] : null;
567
616
  }
568
- function Q(e) {
617
+ function ot(e) {
569
618
  try {
570
- const t = window.localStorage.getItem(`${I}${e}`);
619
+ const t = window.localStorage.getItem(`${R}${e}`);
571
620
  if (!t)
572
621
  return null;
573
- const s = JSON.parse(t), n = Array.isArray(s.messages) ? s.messages.map(et).filter((r) => !!r) : [];
622
+ const s = JSON.parse(t), r = Array.isArray(s.messages) ? s.messages.map(at).filter((n) => !!n) : [];
574
623
  return {
575
624
  sessionId: typeof s.sessionId == "string" ? s.sessionId : null,
576
- messages: n
625
+ messages: r
577
626
  };
578
627
  } catch {
579
628
  return null;
580
629
  }
581
630
  }
582
- function tt(e, t) {
631
+ function it(e, t) {
583
632
  try {
584
633
  window.localStorage.setItem(
585
- `${I}${e}`,
634
+ `${R}${e}`,
586
635
  JSON.stringify({
587
636
  sessionId: t.sessionId,
588
637
  messages: t.messages.slice(-100)
@@ -592,7 +641,7 @@ function tt(e, t) {
592
641
  return;
593
642
  }
594
643
  }
595
- function et(e) {
644
+ function at(e) {
596
645
  if (!e || typeof e != "object")
597
646
  return null;
598
647
  const t = e;
@@ -605,18 +654,18 @@ function et(e) {
605
654
  loading: typeof t.loading == "boolean" ? t.loading : void 0
606
655
  };
607
656
  }
608
- function st(e) {
657
+ function ct(e) {
609
658
  return !!e && typeof e == "object" && typeof e.summary == "string" && typeof e.javascript == "string";
610
659
  }
611
- function A(e) {
660
+ function k(e) {
612
661
  const t = {};
613
- return e?.forEach((s, n) => {
614
- t[n] = s;
662
+ return e?.forEach((s, r) => {
663
+ t[r] = s;
615
664
  }), t;
616
665
  }
617
- async function nt(e, t) {
666
+ async function ut(e, t) {
618
667
  if (typeof t?.body < "u")
619
- return M(t.body);
668
+ return b(t.body);
620
669
  if (e)
621
670
  try {
622
671
  return p(await e.clone().text());
@@ -624,21 +673,21 @@ async function nt(e, t) {
624
673
  return;
625
674
  }
626
675
  }
627
- async function rt(e) {
676
+ async function lt(e) {
628
677
  try {
629
678
  return p(await e.clone().text());
630
679
  } catch (t) {
631
680
  return { error: t instanceof Error ? t.message : "unavailable" };
632
681
  }
633
682
  }
634
- function ot(e) {
683
+ function dt(e) {
635
684
  try {
636
685
  return e.responseType === "" || e.responseType === "text" ? p(e.responseText ?? "") : e.responseType === "json" ? p(JSON.stringify(e.response)) : `[unsupported xhr responseType: ${e.responseType || "unknown"}]`;
637
686
  } catch (t) {
638
687
  return { error: t instanceof Error ? t.message : "unavailable" };
639
688
  }
640
689
  }
641
- function M(e) {
690
+ function b(e) {
642
691
  if (!(e === null || typeof e > "u")) {
643
692
  if (typeof e == "string")
644
693
  return p(e);
@@ -646,7 +695,7 @@ function M(e) {
646
695
  return p(e.toString());
647
696
  if (e instanceof FormData) {
648
697
  const t = [];
649
- return e.forEach((s, n) => t.push([n, s instanceof File ? `[file:${s.name}]` : String(s)])), p(JSON.stringify(t));
698
+ return e.forEach((s, r) => t.push([r, s instanceof File ? `[file:${s.name}]` : String(s)])), p(JSON.stringify(t));
650
699
  }
651
700
  if (e instanceof Blob)
652
701
  return `[blob:${e.type || "application/octet-stream"}:${e.size}]`;
@@ -657,11 +706,11 @@ function M(e) {
657
706
  }
658
707
  }
659
708
  }
660
- function it(e) {
709
+ function pt(e) {
661
710
  const t = {};
662
711
  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());
712
+ const r = s.indexOf(":");
713
+ r <= 0 || (t[s.slice(0, r).trim()] = s.slice(r + 1).trim());
665
714
  }
666
715
  return t;
667
716
  }
@@ -671,54 +720,54 @@ function p(e) {
671
720
  function y(e) {
672
721
  return `${e}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
673
722
  }
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 = /[),.;\]]+$/;
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 = /[),.;\]]+$/;
675
724
  function f(e) {
676
725
  return m(e, 0, /* @__PURE__ */ new WeakSet());
677
726
  }
678
727
  function m(e, t, s) {
679
728
  if (typeof e == "string")
680
- return gt(e);
729
+ return Tt(e);
681
730
  if (e === null || typeof e != "object")
682
731
  return e;
683
- if (t >= ct)
732
+ if (t >= ht)
684
733
  return "[REDACTED_MAX_DEPTH]";
685
734
  if (s.has(e))
686
735
  return "[REDACTED_CIRCULAR]";
687
736
  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;
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;
693
742
  }
694
- function ft(e) {
743
+ function Et(e) {
695
744
  const t = e.replace(/[^a-z0-9]/gi, "").toLowerCase();
696
745
  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
746
  }
698
- function ht(e) {
699
- return typeof e == "string" ? O(e) : m(e, 0, /* @__PURE__ */ new WeakSet());
747
+ function _t(e) {
748
+ return typeof e == "string" ? P(e) : m(e, 0, /* @__PURE__ */ new WeakSet());
700
749
  }
701
- function O(e) {
750
+ function P(e) {
702
751
  try {
703
752
  const t = new URL(e, location.href);
704
753
  for (const s of Array.from(t.searchParams.keys()))
705
- ut.test(s) && t.searchParams.set(s, d);
754
+ gt.test(s) && t.searchParams.set(s, d);
706
755
  return t.username && (t.username = d), t.password && (t.password = d), t.toString();
707
756
  } catch {
708
- return yt(e);
757
+ return wt(e);
709
758
  }
710
759
  }
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}`);
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}`);
713
762
  }
714
- function yt(e) {
715
- return e.replace(D, `Bearer ${d}`).replace(N, `Basic ${d}`).replace(b, d).replace(q, (t, s) => `${s}: ${S}`);
763
+ function wt(e) {
764
+ return e.replace(N, `Bearer ${d}`).replace(H, `Basic ${d}`).replace(q, d).replace(U, (t, s) => `${s}: ${E}`);
716
765
  }
717
- function mt(e) {
718
- const t = e.match(pt)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
719
- return `${O(s)}${t}`;
766
+ function At(e) {
767
+ const t = e.match(St)?.[0] ?? "", s = t ? e.slice(0, -t.length) : e;
768
+ return `${P(s)}${t}`;
720
769
  }
721
770
  export {
722
- k as PlunoProductAgent,
723
- k as default
771
+ M as PlunoProductAgent,
772
+ M as default
724
773
  };
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.8",
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",