@pluno/product-agent-web 0.1.211 → 0.1.213

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,6 +1,6 @@
1
- function h(s) {
1
+ function h(i) {
2
2
  return {
3
- key: s,
3
+ key: i,
4
4
  status: "not_requested",
5
5
  data: null,
6
6
  error: null,
@@ -9,8 +9,8 @@ function h(s) {
9
9
  };
10
10
  }
11
11
  class b {
12
- constructor(e, t, i = (n, r) => r) {
13
- this.loader = t, this.merge = i, this.state = h(e);
12
+ constructor(e, t, s = (n, r) => r) {
13
+ this.loader = t, this.merge = s, this.state = h(e);
14
14
  }
15
15
  loader;
16
16
  merge;
@@ -52,16 +52,16 @@ class b {
52
52
  for (; this.trailingLoad; ) {
53
53
  const e = this.trailingLoad;
54
54
  this.trailingLoad = null;
55
- const t = this.state.key, i = this.state.requestId + 1;
55
+ const t = this.state.key, s = this.state.requestId + 1;
56
56
  this.state = {
57
57
  ...this.state,
58
58
  status: e.mode === "append" ? "loading_more" : this.state.data === null ? "loading" : "refreshing",
59
59
  error: null,
60
- requestId: i
60
+ requestId: s
61
61
  }, this.publish();
62
62
  try {
63
63
  const n = await this.loader({ key: t, cursor: e.cursor });
64
- if (t !== this.state.key || i !== this.state.requestId) continue;
64
+ if (t !== this.state.key || s !== this.state.requestId) continue;
65
65
  this.state = {
66
66
  ...this.state,
67
67
  status: "ready",
@@ -70,7 +70,7 @@ class b {
70
70
  updatedAt: Date.now()
71
71
  }, this.publish();
72
72
  } catch (n) {
73
- if (t !== this.state.key || i !== this.state.requestId) continue;
73
+ if (t !== this.state.key || s !== this.state.requestId) continue;
74
74
  this.state = {
75
75
  ...this.state,
76
76
  status: "error",
@@ -83,53 +83,53 @@ class b {
83
83
  for (const e of this.listeners) e(this.state);
84
84
  }
85
85
  }
86
- function p(s) {
86
+ function p(i) {
87
87
  const e = {}, t = [];
88
- for (const i of s.entities)
89
- e[i.id] || t.push(i.id), e[i.id] = i;
88
+ for (const s of i.entities)
89
+ e[s.id] || t.push(s.id), e[s.id] = s;
90
90
  return {
91
91
  entitiesById: e,
92
92
  ids: t,
93
- nextCursor: s.nextCursor
93
+ nextCursor: i.nextCursor
94
94
  };
95
95
  }
96
- function _(s, e, t) {
97
- if (t === "replace" || s === null) return e;
98
- const i = { ...s.entitiesById, ...e.entitiesById }, n = [...s.ids];
96
+ function E(i, e, t) {
97
+ if (t === "replace" || i === null) return e;
98
+ const s = { ...i.entitiesById, ...e.entitiesById }, n = [...i.ids];
99
99
  for (const r of e.ids)
100
- s.entitiesById[r] || n.push(r);
101
- return { entitiesById: i, ids: n, nextCursor: e.nextCursor };
100
+ i.entitiesById[r] || n.push(r);
101
+ return { entitiesById: s, ids: n, nextCursor: e.nextCursor };
102
102
  }
103
- function w(s) {
104
- return s ? s.ids.map((e) => s.entitiesById[e]).filter((e) => !!e) : [];
103
+ function w(i) {
104
+ return i ? i.ids.map((e) => i.entitiesById[e]).filter((e) => !!e) : [];
105
105
  }
106
- function C(s) {
107
- return s.visible ? s.minimized ? { state: "minimized" } : { state: s.open ? "visible_open" : "visible_closed" } : { state: "hidden" };
106
+ function R(i) {
107
+ return i.visible ? i.minimized ? { state: "minimized" } : { state: i.open ? "visible_open" : "visible_closed" } : { state: "hidden" };
108
108
  }
109
- function L(s, e) {
110
- return e === "limit_exceeded" ? { allowed: !1, reason: "credits_exhausted", actions: ["upgrade", "earn_credits"] } : e === "subscription_required" || e === "subscription_inactive" || e === "payment_issue" || e === "subscription_invalid" || e === "payment_required" ? { allowed: !1, reason: "payment_issue", actions: ["upgrade"] } : s ?? { allowed: !0, reason: "allowed", actions: [] };
109
+ function C(i, e) {
110
+ return e === "limit_exceeded" ? { allowed: !1, reason: "credits_exhausted", actions: ["upgrade", "earn_credits"] } : e === "subscription_required" || e === "subscription_inactive" || e === "payment_issue" || e === "subscription_invalid" || e === "payment_required" ? { allowed: !1, reason: "payment_issue", actions: ["upgrade"] } : i ?? { allowed: !0, reason: "allowed", actions: [] };
111
111
  }
112
- function k(s) {
113
- if (!s || typeof s != "object") return !1;
114
- const e = s.paidCreditFallbackModel;
112
+ function L(i) {
113
+ if (!i || typeof i != "object") return !1;
114
+ const e = i.paidCreditFallbackModel;
115
115
  return typeof e == "string" && e.length > 0;
116
116
  }
117
- function q(s) {
118
- return s ? s.submissionGate?.allowed === !1 ? { state: "action_required", reason: s.submissionGate.reason } : s.usingPaidCreditFallback === !0 ? { state: "paid_credit_fallback" } : s.creditLimit !== null && s.creditLimit > 0 && s.creditsRemaining !== null && s.creditsRemaining > 0 && s.creditsRemaining / s.creditLimit <= 0.2 ? { state: "low_credits" } : s.creditsUsed !== null ? { state: "usage" } : { state: "hidden" } : { state: "hidden" };
117
+ function q(i) {
118
+ return i ? i.submissionGate?.allowed === !1 ? { state: "action_required", reason: i.submissionGate.reason } : i.usingPaidCreditFallback === !0 ? { state: "paid_credit_fallback" } : i.creditLimit !== null && i.creditLimit > 0 && i.creditsRemaining !== null && i.creditsRemaining > 0 && i.creditsRemaining / i.creditLimit <= 0.2 ? { state: "low_credits" } : i.creditsUsed !== null ? { state: "usage" } : { state: "hidden" } : { state: "hidden" };
119
119
  }
120
- function Q(s) {
121
- const e = s.hasDraftMessage || s.hasPreSubmittedAttachment;
122
- return s.hasRunningAssistantTurn && !e ? {
120
+ function Q(i) {
121
+ const e = i.hasDraftMessage || i.hasPreSubmittedAttachment;
122
+ return i.hasRunningAssistantTurn && !e ? {
123
123
  action: "stop",
124
- disabled: !s.canStopRunningTurn
124
+ disabled: !i.canStopRunningTurn
125
125
  } : {
126
126
  action: "send",
127
- disabled: !e || !s.canSubmitMessage
127
+ disabled: !e || !i.canSubmitMessage
128
128
  };
129
129
  }
130
130
  class $ {
131
- constructor(e, t, i = 20) {
132
- this.loadPage = t, this.limit = i, this.recentQuery = new b(
131
+ constructor(e, t, s = 20) {
132
+ this.loadPage = t, this.limit = s, this.recentQuery = new b(
133
133
  `${e}:recent`,
134
134
  async ({ cursor: n }) => p(
135
135
  await this.loadPage({ cursor: n, limit: this.limit, pinned: !1 }).then((r) => ({
@@ -137,7 +137,7 @@ class $ {
137
137
  nextCursor: r.nextCursor
138
138
  }))
139
139
  ),
140
- _
140
+ E
141
141
  ), this.pinnedQuery = new b(
142
142
  `${e}:pinned`,
143
143
  async () => p({
@@ -159,10 +159,10 @@ class $ {
159
159
  completedRefreshSequence = 0;
160
160
  activityReconciliationScheduled = !1;
161
161
  getState() {
162
- const e = this.recentQuery.getState(), t = this.pinnedQuery.getState(), i = [
162
+ const e = this.recentQuery.getState(), t = this.pinnedQuery.getState(), s = [
163
163
  ...u(t.data),
164
164
  ...u(e.data)
165
- ], n = new Map(i.map((o) => [o.id, o])), r = Array.from(n.values()).map(
165
+ ], n = new Map(s.map((o) => [o.id, o])), r = Array.from(n.values()).map(
166
166
  (o) => this.applyOverrides(o, this.completedRefreshSequence)
167
167
  ), a = Array.from(this.optimisticEntities.values()).filter((o) => !n.has(o.id)).reverse(), l = e.data || t.data || a.length > 0 ? p({
168
168
  entities: [...a, ...r],
@@ -170,7 +170,7 @@ class $ {
170
170
  }) : null;
171
171
  return {
172
172
  key: e.key.slice(0, -7),
173
- status: I(e, t),
173
+ status: _(e, t),
174
174
  data: l,
175
175
  error: e.error ?? t.error,
176
176
  requestId: Math.max(e.requestId, t.requestId),
@@ -216,20 +216,20 @@ class $ {
216
216
  isActive: t,
217
217
  confirmAfterRefresh: this.completedRefreshSequence + 1,
218
218
  releaseAfterRefresh: this.completedRefreshSequence + 2
219
- }), this.updateEntity(e, (i) => ({ ...i, isActive: t }));
219
+ }), this.updateEntity(e, (s) => ({ ...s, isActive: t }));
220
220
  }
221
221
  setPinned(e, t) {
222
- const i = { pinned: t, confirmAfterRefresh: Number.POSITIVE_INFINITY };
223
- return this.pinnedOverrides.set(e, i), this.updateEntity(e, (n) => ({ ...n, isPinned: t })), i;
222
+ const s = { pinned: t, confirmAfterRefresh: Number.POSITIVE_INFINITY };
223
+ return this.pinnedOverrides.set(e, s), this.updateEntity(e, (n) => ({ ...n, isPinned: t })), s;
224
224
  }
225
225
  confirmPinned(e, t) {
226
226
  this.pinnedOverrides.get(e) === t && (t.confirmAfterRefresh = this.completedRefreshSequence + 1);
227
227
  }
228
- rollbackPinned(e, t, i) {
229
- this.pinnedOverrides.get(e) === t && (this.pinnedOverrides.delete(e), this.updateEntity(e, (n) => ({ ...n, isPinned: i })));
228
+ rollbackPinned(e, t, s) {
229
+ this.pinnedOverrides.get(e) === t && (this.pinnedOverrides.delete(e), this.updateEntity(e, (n) => ({ ...n, isPinned: s })));
230
230
  }
231
231
  setTitle(e, t) {
232
- this.titleOverrides.set(e, t), this.updateEntity(e, (i) => ({ ...i, customTitle: t }));
232
+ this.titleOverrides.set(e, t), this.updateEntity(e, (s) => ({ ...s, customTitle: t }));
233
233
  }
234
234
  confirmTitle(e) {
235
235
  this.titleOverrides.delete(e);
@@ -238,34 +238,34 @@ class $ {
238
238
  const e = [
239
239
  ...u(this.pinnedQuery.getState().data),
240
240
  ...u(this.recentQuery.getState().data)
241
- ], t = new Set(e.map((i) => i.id));
242
- for (const i of this.optimisticEntities.keys())
243
- t.has(i) && this.optimisticEntities.delete(i);
244
- for (const i of e) this.applyOverrides(i, this.completedRefreshSequence);
241
+ ], t = new Set(e.map((s) => s.id));
242
+ for (const s of this.optimisticEntities.keys())
243
+ t.has(s) && this.optimisticEntities.delete(s);
244
+ for (const s of e) this.applyOverrides(s, this.completedRefreshSequence);
245
245
  this.publish();
246
246
  }
247
247
  async loadAllPinned() {
248
248
  const e = [];
249
249
  let t = null;
250
250
  do {
251
- const i = await this.loadPage({ cursor: t, limit: this.limit, pinned: !0 });
252
- e.push(...i.sessions), t = i.nextCursor;
251
+ const s = await this.loadPage({ cursor: t, limit: this.limit, pinned: !0 });
252
+ e.push(...s.sessions), t = s.nextCursor;
253
253
  } while (t);
254
254
  return e;
255
255
  }
256
256
  applyOverrides(e, t) {
257
- let i = e;
257
+ let s = e;
258
258
  const n = this.activityOverrides.get(e.id);
259
- n && (t >= n.confirmAfterRefresh && e.isActive === n.isActive ? this.activityOverrides.delete(e.id) : t >= n.releaseAfterRefresh ? this.activityOverrides.delete(e.id) : i = { ...i, isActive: n.isActive });
259
+ n && (t >= n.confirmAfterRefresh && e.isActive === n.isActive ? this.activityOverrides.delete(e.id) : t >= n.releaseAfterRefresh ? this.activityOverrides.delete(e.id) : s = { ...s, isActive: n.isActive });
260
260
  const r = this.pinnedOverrides.get(e.id);
261
- return r && (t >= r.confirmAfterRefresh && e.isPinned === !0 === r.pinned ? this.pinnedOverrides.delete(e.id) : i = { ...i, isPinned: r.pinned }), this.titleOverrides.has(e.id) && (i = { ...i, customTitle: this.titleOverrides.get(e.id) ?? null }), i;
261
+ return r && (t >= r.confirmAfterRefresh && e.isPinned === !0 === r.pinned ? this.pinnedOverrides.delete(e.id) : s = { ...s, isPinned: r.pinned }), this.titleOverrides.has(e.id) && (s = { ...s, customTitle: this.titleOverrides.get(e.id) ?? null }), s;
262
262
  }
263
263
  updateProjection() {
264
264
  this.publish();
265
265
  }
266
266
  updateEntity(e, t) {
267
- const i = this.optimisticEntities.get(e);
268
- i && this.optimisticEntities.set(e, t(i)), this.publish();
267
+ const s = this.optimisticEntities.get(e);
268
+ s && this.optimisticEntities.set(e, t(s)), this.publish();
269
269
  }
270
270
  hasUnconfirmedActivityOverride() {
271
271
  return Array.from(this.activityOverrides.values()).some(
@@ -276,16 +276,16 @@ class $ {
276
276
  for (const e of this.listeners) e(this.getState());
277
277
  }
278
278
  }
279
- function u(s) {
280
- return s ? s.ids.map((e) => s.entitiesById[e]).filter((e) => !!e) : [];
279
+ function u(i) {
280
+ return i ? i.ids.map((e) => i.entitiesById[e]).filter((e) => !!e) : [];
281
281
  }
282
- function I(s, e) {
283
- return s.status === "error" || e.status === "error" ? "error" : s.status === "loading" || e.status === "loading" ? "loading" : s.status === "refreshing" || e.status === "refreshing" ? "refreshing" : s.status === "loading_more" ? "loading_more" : s.status === "ready" || e.status === "ready" ? "ready" : "not_requested";
282
+ function _(i, e) {
283
+ return i.status === "error" || e.status === "error" ? "error" : i.status === "loading" || e.status === "loading" ? "loading" : i.status === "refreshing" || e.status === "refreshing" ? "refreshing" : i.status === "loading_more" ? "loading_more" : i.status === "ready" || e.status === "ready" ? "ready" : "not_requested";
284
284
  }
285
285
  class K {
286
286
  constructor(e, t = null) {
287
287
  this.storage = e, t && (this.decisions = new Map(
288
- t.filter(m).map((i) => [this.getDecisionKey(i), i])
288
+ t.filter(y).map((s) => [this.getDecisionKey(s), s])
289
289
  ), this.initialized = !0);
290
290
  }
291
291
  storage;
@@ -297,102 +297,102 @@ class K {
297
297
  if (this.initialized) return;
298
298
  const e = await this.storage.load();
299
299
  this.decisions = new Map(
300
- e.filter(m).map((t) => [this.getDecisionKey(t), t])
300
+ e.filter(y).map((t) => [this.getDecisionKey(t), t])
301
301
  ), this.initialized = !0;
302
302
  }
303
303
  isEligible(e, t = Date.now()) {
304
- const i = this.scheduledEligibility.get(this.getExactKey(e));
305
- return i !== void 0 && i > t ? !1 : this.isDecisionEligible(this.decisions.get(this.getExactKey(e)), t) && this.isDecisionEligible(this.decisions.get(this.getCategoryKey(e)), t);
304
+ const s = this.scheduledEligibility.get(this.getExactKey(e));
305
+ return s !== void 0 && s > t ? !1 : this.isDecisionEligible(this.decisions.get(this.getExactKey(e)), t) && this.isDecisionEligible(this.decisions.get(this.getCategoryKey(e)), t);
306
306
  }
307
307
  getDecision(e) {
308
308
  return this.decisions.get(this.getExactKey(e)) ?? this.decisions.get(this.getCategoryKey(e)) ?? null;
309
309
  }
310
310
  getStatus(e, t = Date.now()) {
311
- const i = this.scheduledEligibility.get(this.getExactKey(e));
312
- if (i !== void 0 && i > t) return "scheduled";
311
+ const s = this.scheduledEligibility.get(this.getExactKey(e));
312
+ if (s !== void 0 && s > t) return "scheduled";
313
313
  const n = this.getDecision(e);
314
314
  return n ? n.action === "never" || n.action === "dont_show_again" ? "suppressed" : n.action === "dismiss" ? "resolved" : n.nextEligibleAt && Date.parse(n.nextEligibleAt) > t ? "snoozed" : "presentable" : "presentable";
315
315
  }
316
316
  scheduleEligibility(e, t) {
317
- const i = this.getExactKey(e), n = this.scheduledEligibility.get(i);
318
- return n !== void 0 ? n : (this.scheduledEligibility.set(i, t), t);
317
+ const s = this.getExactKey(e), n = this.scheduledEligibility.get(s);
318
+ return n !== void 0 ? n : (this.scheduledEligibility.set(s, t), t);
319
319
  }
320
320
  getNextEligibilityAt(e = Date.now()) {
321
- for (const [i, n] of this.scheduledEligibility)
322
- n <= e && this.scheduledEligibility.delete(i);
321
+ for (const [s, n] of this.scheduledEligibility)
322
+ n <= e && this.scheduledEligibility.delete(s);
323
323
  const t = [
324
324
  ...this.scheduledEligibility.values(),
325
- ...Array.from(this.decisions.values()).map((i) => i.nextEligibleAt ? Date.parse(i.nextEligibleAt) : Number.NaN).filter((i) => Number.isFinite(i) && i > e)
325
+ ...Array.from(this.decisions.values()).map((s) => s.nextEligibleAt ? Date.parse(s.nextEligibleAt) : Number.NaN).filter((s) => Number.isFinite(s) && s > e)
326
326
  ];
327
327
  return t.length > 0 ? Math.min(...t) : null;
328
328
  }
329
- act(e, t, i = {}) {
330
- const n = this.actionQueue.then(() => this.applyAction(e, t, i));
329
+ act(e, t, s = {}) {
330
+ const n = this.actionQueue.then(() => this.applyAction(e, t, s));
331
331
  return this.actionQueue = n.then(() => {
332
332
  }, () => {
333
333
  }), n;
334
334
  }
335
- async applyAction(e, t, i) {
335
+ async applyAction(e, t, s) {
336
336
  if (!e.allowedActions.includes(t))
337
337
  throw new Error(`Interaction ${e.key} does not allow ${t}.`);
338
- if (!E(t))
338
+ if (!I(t))
339
339
  throw new Error(`Interaction action ${t} is not a persistence decision.`);
340
- const n = i.now ?? /* @__PURE__ */ new Date(), r = {
340
+ const n = s.now ?? /* @__PURE__ */ new Date(), r = {
341
341
  promptKey: e.key,
342
342
  category: e.category,
343
343
  action: t,
344
344
  scope: e.scope,
345
345
  decidedAt: n.toISOString(),
346
- nextEligibleAt: this.getNextEligibleAt(e, t, n, i.snoozeUntil)
346
+ nextEligibleAt: this.getNextEligibleAt(e, t, n, s.snoozeUntil)
347
347
  }, a = t === "dont_show_again" ? this.getCategoryKey(e) : this.getExactKey(e), l = new Map(this.decisions);
348
348
  return l.set(a, r), await this.storage.save([...l.values()]), this.decisions = l, r;
349
349
  }
350
350
  isDecisionEligible(e, t) {
351
351
  return e ? e.action === "dismiss" || e.action === "never" || e.action === "dont_show_again" ? !1 : !e.nextEligibleAt || Date.parse(e.nextEligibleAt) <= t : !0;
352
352
  }
353
- getNextEligibleAt(e, t, i, n) {
353
+ getNextEligibleAt(e, t, s, n) {
354
354
  if (t === "later")
355
- return new Date(i.getTime() + (e.laterDelayMs ?? 3600 * 1e3)).toISOString();
355
+ return new Date(s.getTime() + (e.laterDelayMs ?? 3600 * 1e3)).toISOString();
356
356
  if (t === "snooze") {
357
- if (!n || n.getTime() <= i.getTime())
357
+ if (!n || n.getTime() <= s.getTime())
358
358
  throw new Error("Snooze requires a future next-eligible time.");
359
359
  return n.toISOString();
360
360
  }
361
361
  return null;
362
362
  }
363
363
  getDecisionKey(e) {
364
- const t = f(e.scope);
364
+ const t = m(e.scope);
365
365
  return e.action === "dont_show_again" ? `${t}:category:${e.category}` : `${t}:interaction:${e.promptKey}`;
366
366
  }
367
367
  getExactKey(e) {
368
- return `${f(e.scope)}:interaction:${e.key}`;
368
+ return `${m(e.scope)}:interaction:${e.key}`;
369
369
  }
370
370
  getCategoryKey(e) {
371
- return `${f(e.scope)}:category:${e.category}`;
371
+ return `${m(e.scope)}:category:${e.category}`;
372
372
  }
373
373
  }
374
- function F(s, e) {
374
+ function F(i, e) {
375
375
  return {
376
- load: async () => P(s, e),
377
- save: async (t) => s.setItem(e, JSON.stringify(t))
376
+ load: async () => P(i, e),
377
+ save: async (t) => i.setItem(e, JSON.stringify(t))
378
378
  };
379
379
  }
380
- function P(s, e) {
381
- const t = s.getItem(e);
380
+ function P(i, e) {
381
+ const t = i.getItem(e);
382
382
  if (!t) return [];
383
- const i = JSON.parse(t);
384
- return Array.isArray(i) ? i.filter(m) : [];
383
+ const s = JSON.parse(t);
384
+ return Array.isArray(s) ? s.filter(y) : [];
385
385
  }
386
- function f(s) {
387
- return `${s.level}:${s.key}`;
386
+ function m(i) {
387
+ return `${i.level}:${i.key}`;
388
388
  }
389
- function E(s) {
390
- return s === "dismiss" || s === "later" || s === "snooze" || s === "never" || s === "dont_show_again";
389
+ function I(i) {
390
+ return i === "dismiss" || i === "later" || i === "snooze" || i === "never" || i === "dont_show_again";
391
391
  }
392
- function m(s) {
393
- if (!s || typeof s != "object") return !1;
394
- const e = s;
395
- return typeof e.promptKey == "string" && typeof e.category == "string" && typeof e.decidedAt == "string" && (e.nextEligibleAt === null || typeof e.nextEligibleAt == "string") && E(e.action) && !!(e.scope && typeof e.scope == "object" && typeof e.scope.level == "string" && typeof e.scope.key == "string");
392
+ function y(i) {
393
+ if (!i || typeof i != "object") return !1;
394
+ const e = i;
395
+ return typeof e.promptKey == "string" && typeof e.category == "string" && typeof e.decidedAt == "string" && (e.nextEligibleAt === null || typeof e.nextEligibleAt == "string") && I(e.action) && !!(e.scope && typeof e.scope == "object" && typeof e.scope.level == "string" && typeof e.scope.key == "string");
396
396
  }
397
397
  const T = {
398
398
  working: "⏳",
@@ -400,10 +400,10 @@ const T = {
400
400
  failed: "❗",
401
401
  stopped: "⏹️"
402
402
  }, M = /^(?:⌛|⏳|✅|❗|⏹️) Pluno(?:: )?/;
403
- function D(s, e) {
404
- if (!e) return g(s);
405
- const t = g(s), i = `${T[e]} Pluno`;
406
- return t ? `${i}: ${t}` : i;
403
+ function D(i, e) {
404
+ if (!e) return g(i);
405
+ const t = g(i), s = `${T[e]} Pluno`;
406
+ return t ? `${s}: ${t}` : s;
407
407
  }
408
408
  class z {
409
409
  constructor(e) {
@@ -422,16 +422,16 @@ class z {
422
422
  this.liveStatusVersion += 1, this.applyClear();
423
423
  }
424
424
  async syncStatus(e) {
425
- const t = this.liveStatusVersion, i = await e();
426
- i === void 0 || t !== this.liveStatusVersion || (i ? this.applyStatus(i) : this.applyClear());
425
+ const t = this.liveStatusVersion, s = await e();
426
+ s === void 0 || t !== this.liveStatusVersion || (s ? this.applyStatus(s) : this.applyClear());
427
427
  }
428
428
  applyStatus(e) {
429
429
  const t = this.titleDocument.getTitle();
430
430
  t !== this.lastAppliedTitle && (this.baseTitle = g(t)), this.status = e, this.stopObserving || (this.stopObserving = this.titleDocument.observeTitle(() => this.handleTitleChanged())), this.applyTitle();
431
431
  }
432
432
  applyClear() {
433
- const e = this.titleDocument.getTitle(), t = this.lastAppliedTitle !== null && e === this.lastAppliedTitle, i = this.lastAppliedTitle === null ? g(e) : e;
434
- this.status = null, this.lastAppliedTitle = null, this.stopObserving?.(), this.stopObserving = null, t ? this.titleDocument.setTitle(this.baseTitle) : i !== e && this.titleDocument.setTitle(i);
433
+ const e = this.titleDocument.getTitle(), t = this.lastAppliedTitle !== null && e === this.lastAppliedTitle, s = this.lastAppliedTitle === null ? g(e) : e;
434
+ this.status = null, this.lastAppliedTitle = null, this.stopObserving?.(), this.stopObserving = null, t ? this.titleDocument.setTitle(this.baseTitle) : s !== e && this.titleDocument.setTitle(s);
435
435
  }
436
436
  handleTitleChanged() {
437
437
  !this.status || this.titleDocument.getTitle() === this.lastAppliedTitle || this.applyTitle();
@@ -443,15 +443,15 @@ class z {
443
443
  this.lastAppliedTitle = e, this.titleDocument.getTitle() !== e && this.titleDocument.setTitle(e);
444
444
  }
445
445
  }
446
- function B(s) {
446
+ function B(i) {
447
447
  return {
448
- getTitle: () => s.title,
448
+ getTitle: () => i.title,
449
449
  setTitle: (e) => {
450
- s.title = e;
450
+ i.title = e;
451
451
  },
452
452
  observeTitle: (e) => {
453
453
  const t = new MutationObserver(e);
454
- return t.observe(s.head, {
454
+ return t.observe(i.head, {
455
455
  childList: !0,
456
456
  subtree: !0,
457
457
  characterData: !0
@@ -459,15 +459,15 @@ function B(s) {
459
459
  }
460
460
  };
461
461
  }
462
- function g(s) {
463
- return s.replace(M, "");
462
+ function g(i) {
463
+ return i.replace(M, "");
464
464
  }
465
- const A = 500;
466
- function O(s) {
467
- const e = s.replace(/\n\s*at\s[\s\S]*$/, "").replace(/-----BEGIN [^-]*PRIVATE KEY-----[\s\S]*?(?:-----END [^-]*PRIVATE KEY-----|$)/g, "[REDACTED]").replace(/\b(?:set-cookie|cookie)\s*[:=]\s*[^\n]+/gi, "cookie=[REDACTED]").replace(/\bdata:[^\s<>"']+/gi, "[DATA]").replace(/\b(?:https?:\/\/|www\.)[^\s<>"']+/gi, "[URL]").replace(/\b(?:Bearer|Basic)\s+[^\s,;"']+/gi, "[REDACTED]").replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)?/g, "[REDACTED]").replace(/\b(?:sk|pk|ghp|gho|github_pat|xoxb|xoxp)[-_][A-Za-z0-9_-]{8,}/g, "[REDACTED]").replace(/\b((?:access|refresh|id|auth)[_-]?token|api[_-]?key|client[_-]?secret|password|passwd|pwd|secret|token|jwt|authorization|cookie|set-cookie)\b["']?\s*[:=]\s*(?:"[^"]*"|'[^']*'|[^\s,;}&]+)/gi, "$1=[REDACTED]").replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, "[EMAIL]").replace(/(?:[A-Z]:[\\/]|\\\\|(?:~|\.\.?)?\/|[\w.-]+[\\/])[^\s<>"']+/gi, "[FILE]").replace(new RegExp("(?<![\\w.])(?:[\\w.-]+\\.[A-Z][A-Z0-9]{0,15}|\\.[A-Z][\\w.-]*)\\b", "gi"), "[FILE]").replace(/\s+/g, " ").trim();
468
- return e.length > A ? `${e.slice(0, A - 1)}…` : e;
465
+ const S = 500;
466
+ function k(i) {
467
+ const e = i.replace(/\n\s*at\s[\s\S]*$/, "").replace(/-----BEGIN [^-]*PRIVATE KEY-----[\s\S]*?(?:-----END [^-]*PRIVATE KEY-----|$)/g, "[REDACTED]").replace(/\b(?:set-cookie|cookie)\s*[:=]\s*[^\n]+/gi, "cookie=[REDACTED]").replace(/\bdata:[^\s<>"']+/gi, "[DATA]").replace(/\b(?:https?:\/\/|www\.)[^\s<>"']+/gi, "[URL]").replace(/\b(?:Bearer|Basic)\s+[^\s,;"']+/gi, "[REDACTED]").replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)?/g, "[REDACTED]").replace(/\b(?:sk|pk|ghp|gho|github_pat|xoxb|xoxp)[-_][A-Za-z0-9_-]{8,}/g, "[REDACTED]").replace(/\b((?:access|refresh|id|auth)[_-]?token|api[_-]?key|client[_-]?secret|password|passwd|pwd|secret|token|jwt|authorization|cookie|set-cookie)\b["']?\s*[:=]\s*(?:"[^"]*"|'[^']*'|[^\s,;}&]+)/gi, "$1=[REDACTED]").replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, "[EMAIL]").replace(/(?:[A-Z]:[\\/]|\\\\|(?:~|\.\.?)?\/|[\w.-]+[\\/])[^\s<>"']+/gi, "[FILE]").replace(new RegExp("(?<![\\w.])(?:[\\w.-]+\\.[A-Z][A-Z0-9]{0,15}|\\.[A-Z][\\w.-]*)\\b", "gi"), "[FILE]").replace(/\s+/g, " ").trim();
468
+ return e.length > S ? `${e.slice(0, S - 1)}…` : e;
469
469
  }
470
- const x = {
470
+ const O = {
471
471
  "duplicate-message-item": "A canonical message rendered more than once.",
472
472
  "duplicate-canonical-item": "A canonical session item rendered more than once.",
473
473
  "duplicate-tool-call": "A tool call rendered more than once.",
@@ -476,14 +476,16 @@ const x = {
476
476
  "foreign-session-item-visible": "The visible transcript contains state owned by another session.",
477
477
  "terminal-response-reactivated": "A terminal response became active again.",
478
478
  "terminal-history-not-append-only": "An established terminal outcome disappeared or changed order.",
479
- "runtime-transcript-not-rendered": "A nonempty runtime transcript is displaying starter prompts."
479
+ "runtime-transcript-not-rendered": "A nonempty runtime transcript is displaying starter prompts.",
480
+ "thinking-groups-without-user-message": "Multiple thinking groups appeared without a user message between them.",
481
+ "thinking-without-progress": "Thinking remained visible without progress for five minutes."
480
482
  };
481
- function R(s) {
482
- return typeof s == "string" && s.startsWith("ui_invariant:") && Object.prototype.hasOwnProperty.call(x, s.slice(13));
483
+ function x(i) {
484
+ return typeof i == "string" && i.startsWith("ui_invariant:") && Object.prototype.hasOwnProperty.call(O, i.slice(13));
483
485
  }
484
- function N(s) {
485
- if (!s || typeof s != "object" || !("type" in s)) return !1;
486
- const e = s;
486
+ function N(i) {
487
+ if (!i || typeof i != "object" || !("type" in i)) return !1;
488
+ const e = i;
487
489
  switch (e.type) {
488
490
  case "runtime.connect":
489
491
  case "session.new":
@@ -495,7 +497,7 @@ function N(s) {
495
497
  case "runtime.report_displayed_error":
496
498
  return (e.reason === "conversation_error" || e.reason === "attachment_error" || e.reason === "history_error" || e.reason === "action_error") && typeof e.errorFingerprint == "string" && /^fnv1a-[0-9a-f]{8}$/.test(e.errorFingerprint) && (e.displayedMessage === void 0 || typeof e.displayedMessage == "string" && e.displayedMessage.length <= 500);
497
499
  case "runtime.report_invalid_state_transition":
498
- return (e.reason === "submitted_turn_returned_to_welcome_without_new_chat" || e.reason === "new_messages_button_without_user_scroll" || R(e.reason)) && (e.clientMessageId === void 0 || typeof e.clientMessageId == "string");
500
+ return (e.reason === "submitted_turn_returned_to_welcome_without_new_chat" || e.reason === "new_messages_button_without_user_scroll" || x(e.reason)) && (e.clientMessageId === void 0 || typeof e.clientMessageId == "string");
499
501
  case "runtime.widget_lifecycle":
500
502
  return (e.action === "opened" || e.action === "closed" || e.action === "minimized") && typeof e.trigger == "string";
501
503
  case "session.load":
@@ -523,8 +525,8 @@ function N(s) {
523
525
  }
524
526
  }
525
527
  class H {
526
- constructor(e, t, i) {
527
- this.adapter = t, this.state = y(e), this.model = i;
528
+ constructor(e, t, s) {
529
+ this.adapter = t, this.state = f(e), this.model = s;
528
530
  }
529
531
  adapter;
530
532
  listeners = {};
@@ -538,19 +540,30 @@ class H {
538
540
  interactions = [];
539
541
  account = null;
540
542
  stagedProactiveSuggestionClientMessageId = null;
543
+ unacknowledgedSubmissions = /* @__PURE__ */ new Map();
541
544
  operationQueue = Promise.resolve();
542
545
  destroyed = !1;
543
546
  on(e, t) {
544
- const i = this.listeners[e] ?? /* @__PURE__ */ new Set();
545
- return i.add(t), this.listeners[e] = i, () => i.delete(t);
547
+ const s = this.listeners[e] ?? /* @__PURE__ */ new Set();
548
+ return s.add(t), this.listeners[e] = s, () => s.delete(t);
546
549
  }
547
550
  getState() {
548
- return y(this.state);
551
+ return f(this.state);
549
552
  }
550
- updateProjection(e, t, i, n, r) {
553
+ updateProjection(e, t, s, n, r) {
551
554
  if (!this.destroyed) {
552
- if (this.state = y(e), t !== void 0 && (this.model = t), i) {
553
- this.sessionHistoryState = S(i);
555
+ this.state = f(e);
556
+ for (const [a, l] of this.unacknowledgedSubmissions) {
557
+ if (e.user?.id !== l.userId || l.sessionId !== null && e.sessionId !== l.sessionId || e.messages.some(
558
+ (o) => o.clientMessageId === a
559
+ )) {
560
+ this.unacknowledgedSubmissions.delete(a);
561
+ continue;
562
+ }
563
+ l.sessionId ??= e.sessionId, this.state.messages.push(l.message), this.state.pendingMessageStatus = "sending", this.state.turnPhase ??= "sending", this.state.taskStatus ??= "working";
564
+ }
565
+ if (t !== void 0 && (this.model = t), s) {
566
+ this.sessionHistoryState = A(s);
554
567
  for (const a of this.sessionHistoryListeners)
555
568
  a(this.getSessionHistoryState());
556
569
  }
@@ -570,7 +583,7 @@ class H {
570
583
  }
571
584
  destroy() {
572
585
  if (!this.destroyed) {
573
- this.destroyed = !0, this.attachmentFiles.clear(), this.sessionHistoryListeners.clear(), this.interactionListeners.clear(), this.accountListeners.clear();
586
+ this.destroyed = !0, this.unacknowledgedSubmissions.clear(), this.attachmentFiles.clear(), this.sessionHistoryListeners.clear(), this.interactionListeners.clear(), this.accountListeners.clear();
574
587
  for (const e of Object.values(this.listeners)) e?.clear();
575
588
  this.adapter.onDisconnect?.();
576
589
  }
@@ -590,27 +603,31 @@ class H {
590
603
  }).catch(() => {
591
604
  });
592
605
  }
593
- reportDisplayedError(e, t, i) {
606
+ reportDisplayedError(e, t, s) {
594
607
  this.adapter.dispatch({
595
608
  type: "runtime.report_displayed_error",
596
609
  reason: e,
597
610
  errorFingerprint: t,
598
- ...i ? { displayedMessage: O(i) } : {}
611
+ ...s ? { displayedMessage: k(s) } : {}
599
612
  }).catch(() => {
600
613
  });
601
614
  }
602
615
  sendMessage(e, t = {}) {
603
- const i = e.trim(), n = t.attachments ?? [];
604
- if (!i && n.length === 0) return Promise.resolve(null);
616
+ const s = e.trim(), n = t.attachments ?? [];
617
+ if (!s && n.length === 0) return Promise.resolve(null);
605
618
  const r = t.clientMessageId ?? (t.proactiveSuggestionQuestion && this.stagedProactiveSuggestionClientMessageId ? this.stagedProactiveSuggestionClientMessageId : crypto.randomUUID()), a = t.submittedAt ?? Date.now(), l = this.state, o = {
606
619
  id: `local-${r}`,
607
620
  role: "user",
608
- content: i,
621
+ content: s,
609
622
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
610
623
  ...n.length > 0 ? { attachments: n } : {},
611
624
  clientMessageId: r
612
625
  };
613
- return this.state = {
626
+ return this.unacknowledgedSubmissions.set(r, {
627
+ message: { ...o, attachments: o.attachments?.map((c) => ({ ...c })) },
628
+ sessionId: l.sessionId,
629
+ userId: l.user?.id
630
+ }), this.state = {
614
631
  ...this.state,
615
632
  messages: [...this.state.messages, o],
616
633
  pendingMessageStatus: "sending",
@@ -619,12 +636,12 @@ class H {
619
636
  isRetrying: !1,
620
637
  lastError: null
621
638
  }, this.emit("state", this.getState()), this.enqueueOperation(() => this.sendMessageNow(
622
- i,
639
+ s,
623
640
  { ...t, clientMessageId: r, submittedAt: a },
624
641
  l
625
642
  ));
626
643
  }
627
- async sendMessageNow(e, t, i) {
644
+ async sendMessageNow(e, t, s) {
628
645
  const n = e, r = t.clientMessageId;
629
646
  let a = t.attachments ?? [], l = !1;
630
647
  try {
@@ -663,15 +680,15 @@ class H {
663
680
  c.id && this.attachmentFiles.delete(c.id);
664
681
  return r === this.stagedProactiveSuggestionClientMessageId && (this.stagedProactiveSuggestionClientMessageId = null), o?.clientMessageId ?? r;
665
682
  } catch (o) {
666
- throw this.state = {
683
+ throw this.unacknowledgedSubmissions.delete(r), this.state = {
667
684
  ...this.state,
668
685
  messages: this.state.messages.filter(
669
686
  (c) => c.id !== `local-${r}` && c.id !== `optimistic-user-message:${r}`
670
687
  ),
671
- pendingMessageStatus: i.pendingMessageStatus,
672
- turnPhase: i.turnPhase,
673
- isThinking: i.isThinking,
674
- taskStatus: i.taskStatus
688
+ pendingMessageStatus: s.pendingMessageStatus,
689
+ turnPhase: s.turnPhase,
690
+ isThinking: s.isThinking,
691
+ taskStatus: s.taskStatus
675
692
  }, this.emit("state", this.getState()), l && await this.adapter.dispatch({
676
693
  type: "conversation.fail_staged",
677
694
  clientMessageId: r,
@@ -699,11 +716,11 @@ class H {
699
716
  };
700
717
  }
701
718
  stop() {
702
- return this.dispatch({ type: "run.stop" }).then(() => {
719
+ return this.unacknowledgedSubmissions.clear(), this.dispatch({ type: "run.stop" }).then(() => {
703
720
  });
704
721
  }
705
722
  startNewSession(e = {}) {
706
- return e.notifyTransport === !1 ? Promise.resolve() : this.dispatch({ type: "session.new" }).then(() => {
723
+ return this.unacknowledgedSubmissions.clear(), e.notifyTransport === !1 ? Promise.resolve() : this.dispatch({ type: "session.new" }).then(() => {
707
724
  });
708
725
  }
709
726
  async listSessions(e = {}) {
@@ -715,7 +732,7 @@ class H {
715
732
  };
716
733
  }
717
734
  getSessionHistoryState() {
718
- return S(this.sessionHistoryState);
735
+ return A(this.sessionHistoryState);
719
736
  }
720
737
  subscribeSessionHistory(e) {
721
738
  return this.sessionHistoryListeners.add(e), e(this.getSessionHistoryState()), () => this.sessionHistoryListeners.delete(e);
@@ -743,12 +760,12 @@ class H {
743
760
  subscribeInteractions(e) {
744
761
  return this.interactionListeners.add(e), e(this.getInteractions()), () => this.interactionListeners.delete(e);
745
762
  }
746
- actOnInteraction(e, t, i, n = {}) {
763
+ actOnInteraction(e, t, s, n = {}) {
747
764
  return this.dispatch({
748
765
  type: "interaction.act",
749
766
  interactionId: e,
750
767
  action: t,
751
- expectedRevision: i,
768
+ expectedRevision: s,
752
769
  ...n
753
770
  }).then(() => {
754
771
  });
@@ -763,17 +780,17 @@ class H {
763
780
  return Promise.resolve();
764
781
  }
765
782
  loadSession(e) {
766
- return this.dispatch({ type: "session.load", sessionId: e }).then(() => {
783
+ return this.unacknowledgedSubmissions.clear(), this.dispatch({ type: "session.load", sessionId: e }).then(() => {
767
784
  });
768
785
  }
769
786
  stageProactiveSuggestionQuestion(e) {
770
787
  const t = e.trim();
771
788
  if (!t) return Promise.resolve();
772
- const i = this.stagedProactiveSuggestionClientMessageId ?? crypto.randomUUID();
773
- return this.stagedProactiveSuggestionClientMessageId = i, this.dispatch({
789
+ const s = this.stagedProactiveSuggestionClientMessageId ?? crypto.randomUUID();
790
+ return this.stagedProactiveSuggestionClientMessageId = s, this.dispatch({
774
791
  type: "conversation.stage_proactive_suggestion",
775
792
  question: t,
776
- clientMessageId: i
793
+ clientMessageId: s
777
794
  }).then(() => {
778
795
  });
779
796
  }
@@ -790,40 +807,40 @@ class H {
790
807
  ), t;
791
808
  }
792
809
  emit(e, t) {
793
- const i = this.listeners[e];
794
- for (const n of i ?? []) n(t);
810
+ const s = this.listeners[e];
811
+ for (const n of s ?? []) n(t);
795
812
  }
796
813
  }
797
- function y(s) {
814
+ function f(i) {
798
815
  return {
799
- ...s,
800
- starterPrompts: [...s.starterPrompts],
801
- appearance: s.appearance ? { ...s.appearance } : null,
802
- messages: s.messages.map((e) => {
816
+ ...i,
817
+ starterPrompts: [...i.starterPrompts],
818
+ appearance: i.appearance ? { ...i.appearance } : null,
819
+ messages: i.messages.map((e) => {
803
820
  const t = {
804
821
  ...e,
805
822
  attachments: e.attachments?.map((a) => ({ ...a }))
806
- }, i = e.assistantDraftItemId, n = e.clientMessageId, r = e.proactiveSuggestionClientMessageId;
823
+ }, s = e.assistantDraftItemId, n = e.clientMessageId, r = e.proactiveSuggestionClientMessageId;
807
824
  return r && Object.defineProperty(t, "proactiveSuggestionClientMessageId", {
808
825
  value: r,
809
826
  enumerable: !1
810
- }), i && Object.defineProperty(t, "assistantDraftItemId", {
811
- value: i,
827
+ }), s && Object.defineProperty(t, "assistantDraftItemId", {
828
+ value: s,
812
829
  enumerable: !1
813
830
  }), n && Object.defineProperty(t, "clientMessageId", {
814
831
  value: n,
815
832
  enumerable: !1
816
833
  }), t;
817
834
  }),
818
- activeScheduledFollowUps: s.activeScheduledFollowUps?.map((e) => ({ ...e })) ?? null
835
+ activeScheduledFollowUps: i.activeScheduledFollowUps?.map((e) => ({ ...e })) ?? null
819
836
  };
820
837
  }
821
- function S(s) {
838
+ function A(i) {
822
839
  return {
823
- ...s,
824
- data: s.data ? p({
825
- entities: w(s.data).map((e) => ({ ...e })),
826
- nextCursor: s.data.nextCursor
840
+ ...i,
841
+ data: i.data ? p({
842
+ entities: w(i.data).map((e) => ({ ...e })),
843
+ nextCursor: i.data.nextCursor
827
844
  }) : null
828
845
  };
829
846
  }
@@ -837,14 +854,14 @@ export {
837
854
  h as createProductAgentQueryState,
838
855
  B as createProductAgentTaskPageTitleDocument,
839
856
  D as formatProductAgentTaskPageTitle,
840
- k as hasProductAgentPaidCreditFallback,
857
+ L as hasProductAgentPaidCreditFallback,
841
858
  N as isProductAgentRuntimeCommand,
842
- _ as mergeProductAgentEntityPages,
859
+ E as mergeProductAgentEntityPages,
843
860
  p as normalizeProductAgentEntityPage,
844
861
  P as readLocalStorageInteractionDecisions,
845
- L as reconcileProductAgentSubmissionGate,
862
+ C as reconcileProductAgentSubmissionGate,
846
863
  q as resolveProductAgentBillingPresentation,
847
864
  Q as resolveProductAgentComposerAction,
848
- C as resolveProductAgentWidgetPresentation,
865
+ R as resolveProductAgentWidgetPresentation,
849
866
  w as selectProductAgentQueryEntities
850
867
  };