@pluno/product-agent-web 0.1.229 → 0.1.232

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.
Files changed (41) hide show
  1. package/dist/adapters/web/backendHttp.d.ts +16 -2
  2. package/dist/adapters/web/backendTransport.d.ts +3 -0
  3. package/dist/adapters/web/conversationAdapters.d.ts +59 -0
  4. package/dist/adapters/web/conversationCheckpoint.d.ts +16 -0
  5. package/dist/adapters/web/conversationInteractionAdapter.d.ts +11 -0
  6. package/dist/adapters/web/conversationPresentation.d.ts +4 -0
  7. package/dist/adapters/web/directoryAdapters.d.ts +2 -2
  8. package/dist/adapters/web/socketIOTransport.d.ts +4 -0
  9. package/dist/chatPresentation.d.ts +7 -0
  10. package/dist/core/conversation/contracts.d.ts +181 -1
  11. package/dist/core/conversation/delivery.d.ts +22 -0
  12. package/dist/core/conversation/deliveryContracts.d.ts +100 -0
  13. package/dist/core/conversation/display.d.ts +134 -0
  14. package/dist/core/conversation/reducer.d.ts +8 -0
  15. package/dist/core/conversation/selectors.d.ts +59 -0
  16. package/dist/core/conversation/state.d.ts +6 -0
  17. package/dist/core/index.d.ts +6 -0
  18. package/dist/core/model-selection/commands.d.ts +1 -1
  19. package/dist/displayedErrors.d.ts +1 -1
  20. package/dist/entrySurface.d.ts +2 -0
  21. package/dist/index.d.ts +51 -117
  22. package/dist/interactionManager.d.ts +3 -0
  23. package/dist/interruptState.d.ts +1 -1
  24. package/dist/operationTiming.d.ts +21 -0
  25. package/dist/product-agent-runtime.cjs +1 -1
  26. package/dist/product-agent-runtime.js +578 -375
  27. package/dist/product-agent-sdk.js +4195 -4637
  28. package/dist/product-agent-widget.js +8748 -9160
  29. package/dist/protocolTrace.d.ts +3 -0
  30. package/dist/public/operationRoutes.d.ts +2 -0
  31. package/dist/renderDiagnostics.d.ts +31 -0
  32. package/dist/responseDiagnostics.d.ts +1 -0
  33. package/dist/runtime/composition.d.ts +13 -5
  34. package/dist/runtime/modelSelection.d.ts +1 -1
  35. package/dist/runtime.d.ts +2 -2
  36. package/dist/runtimeClient.d.ts +20 -6
  37. package/dist/runtimeState.d.ts +15 -0
  38. package/dist/shareCard.d.ts +1 -0
  39. package/dist/uiFlightRecorder.d.ts +4 -1
  40. package/dist/uiInvariants.d.ts +2 -0
  41. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
- function f(i) {
1
+ function f(s) {
2
2
  return {
3
- key: i,
3
+ key: s,
4
4
  status: "not_requested",
5
5
  data: null,
6
6
  error: null,
@@ -8,9 +8,9 @@ function f(i) {
8
8
  updatedAt: null
9
9
  };
10
10
  }
11
- class w {
12
- constructor(e, t, s = (n, a) => a) {
13
- this.loader = t, this.merge = s, this.state = f(e);
11
+ class P {
12
+ constructor(e, t, i = (n, r) => r) {
13
+ this.loader = t, this.merge = i, this.state = f(e);
14
14
  }
15
15
  loader;
16
16
  merge;
@@ -52,16 +52,16 @@ class w {
52
52
  for (; this.trailingLoad; ) {
53
53
  const e = this.trailingLoad;
54
54
  this.trailingLoad = null;
55
- const t = this.state.key, s = this.state.requestId + 1;
55
+ const t = this.state.key, i = 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: s
60
+ requestId: i
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 || s !== this.state.requestId) continue;
64
+ if (t !== this.state.key || i !== this.state.requestId) continue;
65
65
  this.state = {
66
66
  ...this.state,
67
67
  status: "ready",
@@ -70,7 +70,7 @@ class w {
70
70
  updatedAt: Date.now()
71
71
  }, this.publish();
72
72
  } catch (n) {
73
- if (t !== this.state.key || s !== this.state.requestId) continue;
73
+ if (t !== this.state.key || i !== this.state.requestId) continue;
74
74
  this.state = {
75
75
  ...this.state,
76
76
  status: "error",
@@ -83,62 +83,69 @@ class w {
83
83
  for (const e of this.listeners) e(this.state);
84
84
  }
85
85
  }
86
- function m(i) {
86
+ function m(s) {
87
87
  const e = {}, t = [];
88
- for (const s of i.entities)
89
- e[s.id] || t.push(s.id), e[s.id] = s;
88
+ for (const i of s.entities)
89
+ e[i.id] || t.push(i.id), e[i.id] = i;
90
90
  return {
91
91
  entitiesById: e,
92
92
  ids: t,
93
- nextCursor: i.nextCursor
93
+ nextCursor: s.nextCursor
94
94
  };
95
95
  }
96
- function O(i, e, t) {
97
- if (t === "replace" || i === null) return e;
98
- const s = { ...i.entitiesById, ...e.entitiesById }, n = [...i.ids];
99
- for (const a of e.ids)
100
- i.entitiesById[a] || n.push(a);
101
- return { entitiesById: s, ids: n, nextCursor: e.nextCursor };
96
+ function U(s, e, t) {
97
+ if (t === "replace" || s === null) return e;
98
+ const i = { ...s.entitiesById, ...e.entitiesById }, n = [...s.ids];
99
+ for (const r of e.ids)
100
+ s.entitiesById[r] || n.push(r);
101
+ return { entitiesById: i, ids: n, nextCursor: e.nextCursor };
102
102
  }
103
- function k(i) {
104
- return i ? i.ids.map((e) => i.entitiesById[e]).filter((e) => !!e) : [];
103
+ function $(s) {
104
+ return s ? s.ids.map((e) => s.entitiesById[e]).filter((e) => !!e) : [];
105
105
  }
106
- function N(i) {
107
- return i.visible ? i.minimized ? { state: "minimized" } : { state: i.open ? "visible_open" : "visible_closed" } : { state: "hidden" };
106
+ function oe(s) {
107
+ return s.visible ? s.minimized ? { state: "minimized" } : { state: s.open ? "visible_open" : "visible_closed" } : { state: "hidden" };
108
108
  }
109
- function B(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: [] };
109
+ function ae(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: [] };
111
111
  }
112
- function j(i) {
113
- if (!i || typeof i != "object") return !1;
114
- const e = i.paidCreditFallbackModel;
112
+ function le(s) {
113
+ if (!s || typeof s != "object") return !1;
114
+ const e = s.paidCreditFallbackModel;
115
115
  return typeof e == "string" && e.length > 0;
116
116
  }
117
- function F(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" };
117
+ function ce(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" };
119
119
  }
120
- function z(i) {
121
- const e = i.hasDraftMessage || i.hasPreSubmittedAttachment;
122
- return i.hasRunningAssistantTurn && !i.hasDraftMessage ? {
120
+ function de(s) {
121
+ return s.submissionAllowed && s.isAuthenticated && s.hasWorkspace && !s.isWebsiteBlocked && s.isCurrentPageResolved && !s.isSubmitting && !s.hasPendingMessage;
122
+ }
123
+ function ue(s) {
124
+ const e = s.hasDraftMessage || s.hasPreSubmittedAttachment;
125
+ return s.hasRunningAssistantTurn && !e ? {
123
126
  action: "stop",
124
- disabled: !i.canStopRunningTurn
127
+ disabled: !s.canStopRunningTurn
125
128
  } : {
126
129
  action: "send",
127
- disabled: !e || !i.canSubmitMessage
130
+ disabled: !e || !s.canSubmitMessage
128
131
  };
129
132
  }
130
- class H {
131
- constructor(e, t, s = 20) {
132
- this.loadPage = t, this.limit = s, this.recentQuery = new w(
133
+ const j = "Pluno is reconnecting. Try again in a moment.";
134
+ function Q(s) {
135
+ return (s instanceof Error ? s.message : s) === j;
136
+ }
137
+ class pe {
138
+ constructor(e, t, i = 20) {
139
+ this.loadPage = t, this.limit = i, this.recentQuery = new P(
133
140
  `${e}:recent`,
134
141
  async ({ cursor: n }) => m(
135
- await this.loadPage({ cursor: n, limit: this.limit, pinned: !1 }).then((a) => ({
136
- entities: a.sessions,
137
- nextCursor: a.nextCursor
142
+ await this.loadPage({ cursor: n, limit: this.limit, pinned: !1 }).then((r) => ({
143
+ entities: r.sessions,
144
+ nextCursor: r.nextCursor
138
145
  }))
139
146
  ),
140
- O
141
- ), this.pinnedQuery = new w(
147
+ U
148
+ ), this.pinnedQuery = new P(
142
149
  `${e}:pinned`,
143
150
  async () => m({
144
151
  entities: await this.loadAllPinned(),
@@ -159,19 +166,19 @@ class H {
159
166
  completedRefreshSequence = 0;
160
167
  activityReconciliationScheduled = !1;
161
168
  getState() {
162
- const e = this.recentQuery.getState(), t = this.pinnedQuery.getState(), s = [
163
- ...g(t.data),
164
- ...g(e.data)
165
- ], n = new Map(s.map((o) => [o.id, o])), a = Array.from(n.values()).map(
166
- (o) => this.applyOverrides(o, this.completedRefreshSequence)
167
- ), l = Array.from(this.optimisticEntities.values()).filter((o) => !n.has(o.id)).reverse(), r = e.data || t.data || l.length > 0 ? m({
168
- entities: [...l, ...a],
169
+ const e = this.recentQuery.getState(), t = this.pinnedQuery.getState(), i = [
170
+ ...h(t.data),
171
+ ...h(e.data)
172
+ ], n = new Map(i.map((l) => [l.id, l])), r = Array.from(n.values()).map(
173
+ (l) => this.applyOverrides(l, this.completedRefreshSequence)
174
+ ), a = Array.from(this.optimisticEntities.values()).filter((l) => !n.has(l.id)).reverse(), o = e.data || t.data || a.length > 0 ? m({
175
+ entities: [...a, ...r],
169
176
  nextCursor: e.data?.nextCursor ?? null
170
177
  }) : null;
171
178
  return {
172
179
  key: e.key.slice(0, -7),
173
- status: R(e, t),
174
- data: r,
180
+ status: B(e, t),
181
+ data: o,
175
182
  error: e.error ?? t.error,
176
183
  requestId: Math.max(e.requestId, t.requestId),
177
184
  updatedAt: Math.max(e.updatedAt ?? 0, t.updatedAt ?? 0) || null
@@ -216,56 +223,56 @@ class H {
216
223
  isActive: t,
217
224
  confirmAfterRefresh: this.completedRefreshSequence + 1,
218
225
  releaseAfterRefresh: this.completedRefreshSequence + 2
219
- }), this.updateEntity(e, (s) => ({ ...s, isActive: t }));
226
+ }), this.updateEntity(e, (i) => ({ ...i, isActive: t }));
220
227
  }
221
228
  setPinned(e, t) {
222
- const s = { pinned: t, confirmAfterRefresh: Number.POSITIVE_INFINITY };
223
- return this.pinnedOverrides.set(e, s), this.updateEntity(e, (n) => ({ ...n, isPinned: t })), s;
229
+ const i = { pinned: t, confirmAfterRefresh: Number.POSITIVE_INFINITY };
230
+ return this.pinnedOverrides.set(e, i), this.updateEntity(e, (n) => ({ ...n, isPinned: t })), i;
224
231
  }
225
232
  confirmPinned(e, t) {
226
233
  this.pinnedOverrides.get(e) === t && (t.confirmAfterRefresh = this.completedRefreshSequence + 1);
227
234
  }
228
- rollbackPinned(e, t, s) {
229
- this.pinnedOverrides.get(e) === t && (this.pinnedOverrides.delete(e), this.updateEntity(e, (n) => ({ ...n, isPinned: s })));
235
+ rollbackPinned(e, t, i) {
236
+ this.pinnedOverrides.get(e) === t && (this.pinnedOverrides.delete(e), this.updateEntity(e, (n) => ({ ...n, isPinned: i })));
230
237
  }
231
238
  setTitle(e, t) {
232
- this.titleOverrides.set(e, t), this.updateEntity(e, (s) => ({ ...s, customTitle: t }));
239
+ this.titleOverrides.set(e, t), this.updateEntity(e, (i) => ({ ...i, customTitle: t }));
233
240
  }
234
241
  confirmTitle(e) {
235
242
  this.titleOverrides.delete(e);
236
243
  }
237
244
  reconcileDurableEntities() {
238
245
  const e = [
239
- ...g(this.pinnedQuery.getState().data),
240
- ...g(this.recentQuery.getState().data)
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);
246
+ ...h(this.pinnedQuery.getState().data),
247
+ ...h(this.recentQuery.getState().data)
248
+ ], t = new Set(e.map((i) => i.id));
249
+ for (const i of this.optimisticEntities.keys())
250
+ t.has(i) && this.optimisticEntities.delete(i);
251
+ for (const i of e) this.applyOverrides(i, this.completedRefreshSequence);
245
252
  this.publish();
246
253
  }
247
254
  async loadAllPinned() {
248
255
  const e = [];
249
256
  let t = null;
250
257
  do {
251
- const s = await this.loadPage({ cursor: t, limit: this.limit, pinned: !0 });
252
- e.push(...s.sessions), t = s.nextCursor;
258
+ const i = await this.loadPage({ cursor: t, limit: this.limit, pinned: !0 });
259
+ e.push(...i.sessions), t = i.nextCursor;
253
260
  } while (t);
254
261
  return e;
255
262
  }
256
263
  applyOverrides(e, t) {
257
- let s = e;
264
+ let i = e;
258
265
  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) : s = { ...s, isActive: n.isActive });
260
- const a = this.pinnedOverrides.get(e.id);
261
- return a && (t >= a.confirmAfterRefresh && e.isPinned === !0 === a.pinned ? this.pinnedOverrides.delete(e.id) : s = { ...s, isPinned: a.pinned }), this.titleOverrides.has(e.id) && (s = { ...s, customTitle: this.titleOverrides.get(e.id) ?? null }), s;
266
+ 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 });
267
+ const r = this.pinnedOverrides.get(e.id);
268
+ 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;
262
269
  }
263
270
  updateProjection() {
264
271
  this.publish();
265
272
  }
266
273
  updateEntity(e, t) {
267
- const s = this.optimisticEntities.get(e);
268
- s && this.optimisticEntities.set(e, t(s)), this.publish();
274
+ const i = this.optimisticEntities.get(e);
275
+ i && this.optimisticEntities.set(e, t(i)), this.publish();
269
276
  }
270
277
  hasUnconfirmedActivityOverride() {
271
278
  return Array.from(this.activityOverrides.values()).some(
@@ -276,19 +283,116 @@ class H {
276
283
  for (const e of this.listeners) e(this.getState());
277
284
  }
278
285
  }
279
- function g(i) {
280
- return i ? i.ids.map((e) => i.entitiesById[e]).filter((e) => !!e) : [];
286
+ function h(s) {
287
+ return s ? s.ids.map((e) => s.entitiesById[e]).filter((e) => !!e) : [];
288
+ }
289
+ function B(s, e) {
290
+ 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";
291
+ }
292
+ function M(s) {
293
+ const e = /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.(\d{1,6}))?(?:Z|\+00:00)$/.exec(s);
294
+ if (!e) throw new Error("Display timestamps must retain the backend UTC precision.");
295
+ return `${e[1]}.${(e[2] ?? "").padEnd(6, "0")}`;
281
296
  }
282
- function R(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";
297
+ function A(s) {
298
+ if (s === null || typeof s == "string" || typeof s == "boolean") return !0;
299
+ if (typeof s == "number") return Number.isFinite(s);
300
+ if (Array.isArray(s)) return s.every(A);
301
+ if (typeof s != "object") return !1;
302
+ const e = Object.getPrototypeOf(s);
303
+ return e !== Object.prototype && e !== null ? !1 : Object.values(s).every(A);
284
304
  }
285
- class G {
305
+ function q(s) {
306
+ return s !== null && typeof s == "object" && !Object.isFrozen(s) && (Object.values(s).forEach(q), Object.freeze(s)), s;
307
+ }
308
+ function F(s) {
309
+ if (!A(s)) throw new Error("Conversation inputs must be JSON-safe values.");
310
+ return JSON.parse(JSON.stringify(s));
311
+ }
312
+ function z(s, e) {
313
+ if (!e) return !1;
314
+ const t = s.executionByUserMessage[e];
315
+ if (t) return ["completed", "stopped", "failed"].includes(t.phase);
316
+ const i = Object.values(s.items).sort((r, a) => M(r.created_at).localeCompare(M(a.created_at)) || r.id.localeCompare(a.id));
317
+ let n = !1;
318
+ for (const r of i)
319
+ if (r.type === "user_message" && (n = r.id === e), !!n && (r.type === "stopped" || r.type === "error" || r.type === "final_response" && s.streams[r.id]?.state === "finished" && s.streams[r.id].revision >= r.data.revision))
320
+ return !0;
321
+ return !1;
322
+ }
323
+ class he {
286
324
  constructor(e, t = null) {
287
325
  this.storage = e, t && (this.decisions = new Map(
288
- t.filter(I).map((s) => [this.getDecisionKey(s), s])
326
+ t.filter(I).map((i) => [this.getDecisionKey(i), i])
289
327
  ), this.initialized = !0);
290
328
  }
291
329
  storage;
330
+ conversationReader = null;
331
+ sources = /* @__PURE__ */ new Map();
332
+ invalidateAuth = () => {
333
+ };
334
+ // S6-C installs an input seam on the existing owner. Empty canonical input never falls back to raw tools.
335
+ /** @internal */
336
+ installConversationSources(e, t = () => {
337
+ }) {
338
+ this.sources.clear(), this.conversationReader = e, this.invalidateAuth = t;
339
+ }
340
+ /** @internal */
341
+ receiveConversationSources(e) {
342
+ for (const t of e) {
343
+ if (!Number.isSafeInteger(t.version) || t.version < 0) throw new Error("Invalid interaction source version.");
344
+ const i = JSON.stringify([t.conversation_id, t.id]), n = this.sources.get(i);
345
+ if (n && n.version >= t.version) continue;
346
+ if (n && n.payload.kind !== t.payload.kind) throw new Error("Interaction kind changed.");
347
+ const r = n?.payload.kind === "personal_channel" && n.lifecycle === "completed" ? "completed" : t.lifecycle, a = n?.payload.kind === "sharing" && t.payload.kind === "sharing" ? { ...t.payload, variant: n.payload.variant } : t.payload;
348
+ this.sources.set(i, q(F({ ...t, lifecycle: r, payload: a }))), t.payload.kind === "integration_auth" && this.invalidateAuth(t.payload.request_id);
349
+ }
350
+ }
351
+ /** @internal */
352
+ getIntegrationSource(e) {
353
+ return [...this.sources.values()].find((t) => t.payload.kind === "integration_auth" && t.payload.request_id === e && this.conversationReader?.(t.conversation_id)) ?? null;
354
+ }
355
+ /** @internal */
356
+ getConversationInputs(e) {
357
+ if (!this.conversationReader) return;
358
+ const t = { share: null, integrations: [], channel: null }, i = e ? this.conversationReader(e) : null;
359
+ if (!i) return t;
360
+ const n = [...this.sources.values()].filter((r) => r.conversation_id === e).sort((r, a) => r.version - a.version || r.id.localeCompare(a.id));
361
+ for (const r of n) {
362
+ const a = r.payload;
363
+ if (a.kind === "sharing") {
364
+ if (t.share = null, !a.eligible || r.lifecycle !== "pending" || r.invocation !== "user" || !["main_web_chat", "automation", "extension_sidepanel", "extension_widget"].includes(r.entry_surface ?? "")) continue;
365
+ const o = r.user_message_id ? i.items[r.user_message_id] : null;
366
+ t.share = {
367
+ revision: r.version,
368
+ candidate: {
369
+ id: r.id,
370
+ variant: a.variant,
371
+ userPrompt: o?.type === "user_message" ? o.data.content : "",
372
+ assistantAnswer: ""
373
+ },
374
+ terminal: !a.wait_for_terminal || z(i, r.user_message_id)
375
+ };
376
+ } else a.kind === "integration_auth" ? t.integrations.push({
377
+ revision: r.version,
378
+ request: {
379
+ type: "pipedream_auth_required",
380
+ authRequestId: a.request_id,
381
+ appSlug: a.app_slug,
382
+ appName: a.app_name,
383
+ appLogo: a.app_logo ?? void 0,
384
+ expiresAt: a.expires_at
385
+ },
386
+ lifecycle: r.lifecycle === "pending" && Date.parse(a.expires_at) <= Date.now() ? "expired" : r.lifecycle
387
+ }) : t.channel = { revision: r.version, request: {
388
+ type: "personal_channel_connection_required",
389
+ requestId: a.request_id,
390
+ channel: a.channel,
391
+ managementUrl: a.management_url
392
+ }, lifecycle: r.lifecycle };
393
+ }
394
+ return t;
395
+ }
292
396
  decisions = /* @__PURE__ */ new Map();
293
397
  scheduledEligibility = /* @__PURE__ */ new Map();
294
398
  initialized = !1;
@@ -301,58 +405,58 @@ class G {
301
405
  ), this.initialized = !0;
302
406
  }
303
407
  isEligible(e, t = Date.now()) {
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);
408
+ const i = this.scheduledEligibility.get(this.getExactKey(e));
409
+ 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);
306
410
  }
307
411
  getDecision(e) {
308
412
  return this.decisions.get(this.getExactKey(e)) ?? this.decisions.get(this.getCategoryKey(e)) ?? null;
309
413
  }
310
414
  getStatus(e, t = Date.now()) {
311
- const s = this.scheduledEligibility.get(this.getExactKey(e));
312
- if (s !== void 0 && s > t) return "scheduled";
415
+ const i = this.scheduledEligibility.get(this.getExactKey(e));
416
+ if (i !== void 0 && i > t) return "scheduled";
313
417
  const n = this.getDecision(e);
314
418
  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
419
  }
316
420
  scheduleEligibility(e, t) {
317
- const s = this.getExactKey(e), n = this.scheduledEligibility.get(s);
318
- return n !== void 0 ? n : (this.scheduledEligibility.set(s, t), t);
421
+ const i = this.getExactKey(e), n = this.scheduledEligibility.get(i);
422
+ return n !== void 0 ? n : (this.scheduledEligibility.set(i, t), t);
319
423
  }
320
424
  getNextEligibilityAt(e = Date.now()) {
321
425
  const t = [
322
- ...Array.from(this.scheduledEligibility.values()).filter((s) => s > e),
323
- ...Array.from(this.decisions.values()).map((s) => s.nextEligibleAt ? Date.parse(s.nextEligibleAt) : Number.NaN).filter((s) => Number.isFinite(s) && s > e)
426
+ ...Array.from(this.scheduledEligibility.values()).filter((i) => i > e),
427
+ ...Array.from(this.decisions.values()).map((i) => i.nextEligibleAt ? Date.parse(i.nextEligibleAt) : Number.NaN).filter((i) => Number.isFinite(i) && i > e)
324
428
  ];
325
429
  return t.length > 0 ? Math.min(...t) : null;
326
430
  }
327
- act(e, t, s = {}) {
328
- const n = this.actionQueue.then(() => this.applyAction(e, t, s));
431
+ act(e, t, i = {}) {
432
+ const n = this.actionQueue.then(() => this.applyAction(e, t, i));
329
433
  return this.actionQueue = n.then(() => {
330
434
  }, () => {
331
435
  }), n;
332
436
  }
333
- async applyAction(e, t, s) {
437
+ async applyAction(e, t, i) {
334
438
  if (!e.allowedActions.includes(t))
335
439
  throw new Error(`Interaction ${e.key} does not allow ${t}.`);
336
- if (!D(t))
440
+ if (!L(t))
337
441
  throw new Error(`Interaction action ${t} is not a persistence decision.`);
338
- const n = s.now ?? /* @__PURE__ */ new Date(), a = {
442
+ const n = i.now ?? /* @__PURE__ */ new Date(), r = {
339
443
  promptKey: e.key,
340
444
  category: e.category,
341
445
  action: t,
342
446
  scope: e.scope,
343
447
  decidedAt: n.toISOString(),
344
- nextEligibleAt: this.getNextEligibleAt(e, t, n, s.snoozeUntil)
345
- }, l = t === "dont_show_again" ? this.getCategoryKey(e) : this.getExactKey(e), r = new Map(this.decisions);
346
- return r.set(l, a), await this.storage.save([...r.values()]), this.decisions = r, a;
448
+ nextEligibleAt: this.getNextEligibleAt(e, t, n, i.snoozeUntil)
449
+ }, a = t === "dont_show_again" ? this.getCategoryKey(e) : this.getExactKey(e), o = new Map(this.decisions);
450
+ return o.set(a, r), await this.storage.save([...o.values()]), this.decisions = o, r;
347
451
  }
348
452
  isDecisionEligible(e, t) {
349
453
  return e ? e.action === "dismiss" || e.action === "never" || e.action === "dont_show_again" ? !1 : !e.nextEligibleAt || Date.parse(e.nextEligibleAt) <= t : !0;
350
454
  }
351
- getNextEligibleAt(e, t, s, n) {
455
+ getNextEligibleAt(e, t, i, n) {
352
456
  if (t === "later")
353
- return new Date(s.getTime() + (e.laterDelayMs ?? 3600 * 1e3)).toISOString();
457
+ return new Date(i.getTime() + (e.laterDelayMs ?? 3600 * 1e3)).toISOString();
354
458
  if (t === "snooze") {
355
- if (!n || n.getTime() <= s.getTime())
459
+ if (!n || n.getTime() <= i.getTime())
356
460
  throw new Error("Snooze requires a future next-eligible time.");
357
461
  return n.toISOString();
358
462
  }
@@ -369,41 +473,41 @@ class G {
369
473
  return `${b(e.scope)}:category:${e.category}`;
370
474
  }
371
475
  }
372
- function V(i, e) {
476
+ function ge(s, e) {
373
477
  return {
374
- load: async () => x(i, e),
375
- save: async (t) => i.setItem(e, JSON.stringify(t))
478
+ load: async () => G(s, e),
479
+ save: async (t) => s.setItem(e, JSON.stringify(t))
376
480
  };
377
481
  }
378
- function x(i, e) {
379
- const t = i.getItem(e);
482
+ function G(s, e) {
483
+ const t = s.getItem(e);
380
484
  if (!t) return [];
381
- const s = JSON.parse(t);
382
- return Array.isArray(s) ? s.filter(I) : [];
485
+ const i = JSON.parse(t);
486
+ return Array.isArray(i) ? i.filter(I) : [];
383
487
  }
384
- function b(i) {
385
- return `${i.level}:${i.key}`;
488
+ function b(s) {
489
+ return `${s.level}:${s.key}`;
386
490
  }
387
- function D(i) {
388
- return i === "dismiss" || i === "later" || i === "snooze" || i === "never" || i === "dont_show_again";
491
+ function L(s) {
492
+ return s === "dismiss" || s === "later" || s === "snooze" || s === "never" || s === "dont_show_again";
389
493
  }
390
- function I(i) {
391
- if (!i || typeof i != "object") return !1;
392
- const e = i;
393
- return typeof e.promptKey == "string" && typeof e.category == "string" && typeof e.decidedAt == "string" && (e.nextEligibleAt === null || typeof e.nextEligibleAt == "string") && D(e.action) && !!(e.scope && typeof e.scope == "object" && typeof e.scope.level == "string" && typeof e.scope.key == "string");
494
+ function I(s) {
495
+ if (!s || typeof s != "object") return !1;
496
+ const e = s;
497
+ return typeof e.promptKey == "string" && typeof e.category == "string" && typeof e.decidedAt == "string" && (e.nextEligibleAt === null || typeof e.nextEligibleAt == "string") && L(e.action) && !!(e.scope && typeof e.scope == "object" && typeof e.scope.level == "string" && typeof e.scope.key == "string");
394
498
  }
395
- const C = {
499
+ const H = {
396
500
  working: "⏳",
397
501
  completed: "✅",
398
502
  failed: "❗",
399
503
  stopped: "⏹️"
400
- }, L = /^(?:⌛|⏳|✅|❗|⏹️) Pluno(?:: )?/;
401
- function q(i, e) {
402
- if (!e) return y(i);
403
- const t = y(i), s = `${C[e]} Pluno`;
404
- return t ? `${s}: ${t}` : s;
504
+ }, V = /^(?:⌛|⏳|✅|❗|⏹️) Pluno(?:: )?/;
505
+ function Z(s, e) {
506
+ if (!e) return v(s);
507
+ const t = v(s), i = `${H[e]} Pluno`;
508
+ return t ? `${i}: ${t}` : i;
405
509
  }
406
- class Z {
510
+ class fe {
407
511
  constructor(e) {
408
512
  this.titleDocument = e;
409
513
  }
@@ -420,16 +524,16 @@ class Z {
420
524
  this.liveStatusVersion += 1, this.applyClear();
421
525
  }
422
526
  async syncStatus(e) {
423
- const t = this.liveStatusVersion, s = await e();
424
- s === void 0 || t !== this.liveStatusVersion || (s ? this.applyStatus(s) : this.applyClear());
527
+ const t = this.liveStatusVersion, i = await e();
528
+ i === void 0 || t !== this.liveStatusVersion || (i ? this.applyStatus(i) : this.applyClear());
425
529
  }
426
530
  applyStatus(e) {
427
531
  const t = this.titleDocument.getTitle();
428
- t !== this.lastAppliedTitle && (this.baseTitle = y(t)), this.status = e, this.stopObserving || (this.stopObserving = this.titleDocument.observeTitle(() => this.handleTitleChanged())), this.applyTitle();
532
+ t !== this.lastAppliedTitle && (this.baseTitle = v(t)), this.status = e, this.stopObserving || (this.stopObserving = this.titleDocument.observeTitle(() => this.handleTitleChanged())), this.applyTitle();
429
533
  }
430
534
  applyClear() {
431
- const e = this.titleDocument.getTitle(), t = this.lastAppliedTitle !== null && e === this.lastAppliedTitle, s = this.lastAppliedTitle === null ? y(e) : e;
432
- this.status = null, this.lastAppliedTitle = null, this.stopObserving?.(), this.stopObserving = null, t ? this.titleDocument.setTitle(this.baseTitle) : s !== e && this.titleDocument.setTitle(s);
535
+ const e = this.titleDocument.getTitle(), t = this.lastAppliedTitle !== null && e === this.lastAppliedTitle, i = this.lastAppliedTitle === null ? v(e) : e;
536
+ this.status = null, this.lastAppliedTitle = null, this.stopObserving?.(), this.stopObserving = null, t ? this.titleDocument.setTitle(this.baseTitle) : i !== e && this.titleDocument.setTitle(i);
433
537
  }
434
538
  handleTitleChanged() {
435
539
  !this.status || this.titleDocument.getTitle() === this.lastAppliedTitle || this.applyTitle();
@@ -437,19 +541,19 @@ class Z {
437
541
  applyTitle() {
438
542
  if (!this.status)
439
543
  return;
440
- const e = q(this.baseTitle, this.status);
544
+ const e = Z(this.baseTitle, this.status);
441
545
  this.lastAppliedTitle = e, this.titleDocument.getTitle() !== e && this.titleDocument.setTitle(e);
442
546
  }
443
547
  }
444
- function J(i) {
548
+ function me(s) {
445
549
  return {
446
- getTitle: () => i.title,
550
+ getTitle: () => s.title,
447
551
  setTitle: (e) => {
448
- i.title = e;
552
+ s.title = e;
449
553
  },
450
554
  observeTitle: (e) => {
451
555
  const t = new MutationObserver(e);
452
- return t.observe(i.head, {
556
+ return t.observe(s.head, {
453
557
  childList: !0,
454
558
  subtree: !0,
455
559
  characterData: !0
@@ -457,41 +561,139 @@ function J(i) {
457
561
  }
458
562
  };
459
563
  }
460
- function y(i) {
461
- return i.replace(L, "");
462
- }
463
- function _(i, e) {
464
- const t = new Set([
465
- i.assistantDraftRespondsToUserMessageId,
466
- i.activeResponseUserMessageId,
467
- i.messages.filter((n) => n.role === "user").slice(-1)[0]?.id
468
- ].filter((n) => !!n)), s = i.messages.filter((n) => !(n.dataType === "run_status" && n.loading && t.has(n.respondsToUserMessageId ?? ""))).map((n) => t.has(n.respondsToUserMessageId ?? "") ? { ...n, loading: !1 } : n);
469
- for (const n of t)
470
- s.some((a) => a.respondsToUserMessageId === n && (a.dataType === "run_status" || a.dataType === "run_error" || a.role === "assistant" && a.phase !== "commentary")) || s.push({ id: `local-interrupted:${n}`, role: "system", dataType: "run_status", content: "Run stopped by user.", createdAt: e, respondsToUserMessageId: n });
564
+ function v(s) {
565
+ return s.replace(V, "");
566
+ }
567
+ const J = [
568
+ "submit",
569
+ "stop",
570
+ "staging_ipc",
571
+ "send_ipc",
572
+ "stop_ipc",
573
+ "attachment_transfer",
574
+ "tab_lookup",
575
+ "tab_recovery",
576
+ "session_recovery",
577
+ "conversation_scope",
578
+ "local_stage",
579
+ "view_publication",
580
+ "page_access",
581
+ "authentication",
582
+ "community",
583
+ "preferences",
584
+ "page_capture",
585
+ "session_tabs",
586
+ "context_ready",
587
+ "first_frame",
588
+ "checkpoint",
589
+ "command_http",
590
+ "http_authentication",
591
+ "http_request",
592
+ "receipt_http",
593
+ "attachment_upload",
594
+ "runtime_reading",
595
+ "runtime_stopping",
596
+ "runtime_progress",
597
+ "runtime_stopped",
598
+ "message_painted",
599
+ "reading_painted",
600
+ "stopping_painted",
601
+ "progress_painted",
602
+ "stopped_painted"
603
+ ], W = Math.random().toString(36).slice(2);
604
+ let Y = 0;
605
+ const O = () => `timing:${W}:${++Y}`, g = (s) => typeof s == "string" && /^[a-zA-Z0-9:_-]{1,160}$/.test(s);
606
+ function w(s) {
607
+ if (!s || typeof s != "object") return !1;
608
+ const e = s;
609
+ return Object.keys(e).every((t) => ["entrySurface", "operation", "layer", "stage", "status", "spanId", "requestId", "clientMessageId", "sessionId", "occurredAt", "durationMs"].includes(t)) && (e.entrySurface === void 0 || ["extension_sidepanel", "extension_widget", "main_web_chat", "embedded_widget", "embedded_custom_ui", "automation", "mcp", "whatsapp"].includes(e.entrySurface)) && ["send", "stop"].includes(e.operation) && ["renderer", "sdk", "extension", "http"].includes(e.layer) && J.includes(e.stage) && ["started", "completed", "failed", "observed"].includes(e.status) && g(e.spanId) && g(e.requestId) && (e.clientMessageId === null || g(e.clientMessageId)) && (e.sessionId === null || g(e.sessionId)) && typeof e.occurredAt == "string" && e.occurredAt.length <= 40 && Number.isFinite(Date.parse(e.occurredAt)) && Number.isSafeInteger(e.durationMs) && e.durationMs >= 0;
610
+ }
611
+ function R(s, e) {
612
+ if (!s) return {
613
+ mark: (n) => {
614
+ },
615
+ measure: (n, r) => r()
616
+ };
617
+ const t = performance.now(), i = (n, r, a, o) => {
618
+ const l = {
619
+ ...e,
620
+ stage: n,
621
+ status: r,
622
+ spanId: o,
623
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
624
+ durationMs: Math.max(0, Math.round(performance.now() - a))
625
+ };
626
+ s && w(l) && Promise.resolve().then(() => s(l)).catch(() => {
627
+ });
628
+ };
471
629
  return {
472
- ...i,
473
- messages: s,
630
+ mark: (n) => i(n, "observed", t, O()),
631
+ measure(n, r) {
632
+ const a = performance.now(), o = O();
633
+ return i(n, "started", a, o), r().then(
634
+ (l) => (i(n, "completed", a, o), l),
635
+ (l) => {
636
+ throw i(n, "failed", a, o), l;
637
+ }
638
+ );
639
+ }
640
+ };
641
+ }
642
+ const D = ["messageKeys", "canonicalItemKeys", "terminalResponseKeys", "toolCallKeys", "activeResponseKeys"], E = (s) => typeof s == "string" && /^[a-zA-Z0-9:_-]{1,160}$/.test(s), y = (s) => s === null || E(s), X = (s) => typeof s == "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,6})?(?:Z|\+00:00)$/.test(s) && Number.isFinite(Date.parse(s));
643
+ function N(s) {
644
+ if (!s || typeof s != "object") return !1;
645
+ const e = s;
646
+ return Object.keys(s).every((t) => ["sessionId", "itemId", "userMessageId", "createdAt", "runId", "retryable"].includes(t)) && y(e.sessionId) && E(e.itemId) && y(e.userMessageId) && (e.retryable === void 0 || typeof e.retryable == "boolean") && y(e.runId) && (e.createdAt === null || X(e.createdAt));
647
+ }
648
+ function K(s) {
649
+ if (!s || typeof s != "object" || Object.keys(s).some((i) => i !== "before" && i !== "current")) return !1;
650
+ const e = (i) => {
651
+ if (!i || typeof i != "object") return !1;
652
+ const n = i;
653
+ return Object.keys(i).every((r) => [...D, "sessionId", "runtimeItemCount", "welcome", "truncated", "thinkingSequence"].includes(r)) && (n.thinkingSequence === void 0 || Array.isArray(n.thinkingSequence) && n.thinkingSequence.length <= 20 && n.thinkingSequence.every((r) => r === "user" || r === "thinking")) && y(n.sessionId) && Number.isSafeInteger(n.runtimeItemCount) && n.runtimeItemCount >= 0 && typeof n.welcome == "boolean" && typeof n.truncated == "boolean" && D.every((r) => Array.isArray(n[r]) && n[r].length <= 20 && n[r].every(E));
654
+ }, t = s;
655
+ return (t.before === null || e(t.before)) && e(t.current);
656
+ }
657
+ const _ = (s) => s === null || typeof s == "string" && /^[a-zA-Z0-9:_-]{1,160}$/.test(s);
658
+ function ee(s) {
659
+ if (!s || typeof s != "object") return !1;
660
+ const e = s;
661
+ return typeof e.observedAt == "string" && e.observedAt.length <= 40 && Number.isFinite(Date.parse(e.observedAt)) && _(e.sessionId) && _(e.responseItemId) && _(e.respondsToUserMessageId) && typeof e.panelVisible == "boolean" && typeof e.documentVisible == "boolean" && typeof e.loading == "boolean";
662
+ }
663
+ const k = 500;
664
+ function te(s) {
665
+ 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();
666
+ return e.length > k ? `${e.slice(0, k - 1)}…` : e;
667
+ }
668
+ function se(s, e, t = "stopped", i) {
669
+ const n = new Set(i ?? [
670
+ s.assistantDraftRespondsToUserMessageId,
671
+ s.activeResponseUserMessageId,
672
+ s.messages.filter((o) => o.role === "user").slice(-1)[0]?.id
673
+ ].filter((o) => !!o)), r = s.messages.filter((o) => !(o.dataType === "run_status" && o.loading && n.has(o.respondsToUserMessageId ?? ""))).map((o) => n.has(o.respondsToUserMessageId ?? "") ? { ...o, loading: !1 } : o);
674
+ for (const o of n)
675
+ r.some((l) => l.respondsToUserMessageId === o && (l.dataType === "run_status" || l.dataType === "run_error" || l.role === "assistant" && l.phase !== "commentary")) || r.some((l) => l.role === "user" && l.id === o) && r.push({ id: `local-interrupted:${o}`, role: "system", dataType: "run_status", content: t === "stopping" ? "Stopping…" : "Run stopped by user.", createdAt: e, respondsToUserMessageId: o });
676
+ const a = s.segments?.map((o) => ({ ...o, outcomeIds: [
677
+ ...o.outcomeIds,
678
+ ...r.filter((l) => l.id === `local-interrupted:${o.userMessageId}` && !o.outcomeIds.includes(l.id)).map((l) => l.id)
679
+ ] }));
680
+ return {
681
+ ...s,
682
+ messages: r,
474
683
  isThinking: !1,
475
684
  isRetrying: !1,
476
685
  pendingMessageStatus: null,
477
686
  turnPhase: null,
478
- taskStatus: "stopped",
687
+ segments: a,
688
+ activity: { phase: t, activeItemId: null },
689
+ isLoadingSession: s.isLoadingSession && r.length === 0,
690
+ taskStatus: t === "stopped" ? "stopped" : null,
479
691
  lastError: null,
480
692
  lastErrorCode: null
481
693
  };
482
694
  }
483
- const S = (i) => i === null || typeof i == "string" && /^[a-zA-Z0-9:_-]{1,160}$/.test(i);
484
- function Q(i) {
485
- if (!i || typeof i != "object") return !1;
486
- const e = i;
487
- return typeof e.observedAt == "string" && e.observedAt.length <= 40 && Number.isFinite(Date.parse(e.observedAt)) && S(e.sessionId) && S(e.responseItemId) && S(e.respondsToUserMessageId) && typeof e.panelVisible == "boolean" && typeof e.documentVisible == "boolean" && typeof e.loading == "boolean";
488
- }
489
- const M = 500;
490
- function U(i) {
491
- 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();
492
- return e.length > M ? `${e.slice(0, M - 1)}…` : e;
493
- }
494
- const $ = {
695
+ const ie = {
696
+ "stop-without-rendered-message": "Stop is enabled while no message is rendered or the welcome screen is still visible.",
495
697
  "in-progress-stop-unavailable": "An in-progress response has no visible enabled interrupt control.",
496
698
  "stop-did-not-interrupt": "The stopped response remained in progress after an interrupt click.",
497
699
  "duplicate-message-item": "A canonical message rendered more than once.",
@@ -506,23 +708,23 @@ const $ = {
506
708
  "thinking-groups-without-user-message": "Multiple thinking groups appeared without a user message between them.",
507
709
  "thinking-without-progress": "Thinking remained visible without progress for five minutes."
508
710
  };
509
- function K(i) {
510
- return typeof i == "string" && i.startsWith("ui_invariant:") && Object.prototype.hasOwnProperty.call($, i.slice(13));
711
+ function ne(s) {
712
+ return typeof s == "string" && s.startsWith("ui_invariant:") && Object.prototype.hasOwnProperty.call(ie, s.slice(13));
511
713
  }
512
- function P(i) {
714
+ function C(s) {
513
715
  return {
514
- ...i.id === void 0 ? {} : { id: i.id },
515
- name: i.name,
516
- mimeType: i.mimeType,
517
- sizeBytes: i.sizeBytes,
518
- ...i.sandboxPath === void 0 ? {} : { sandboxPath: i.sandboxPath },
519
- ...i.storageKey === void 0 ? {} : { storageKey: i.storageKey },
520
- ...i.fileUrl === void 0 ? {} : { fileUrl: i.fileUrl }
716
+ ...s.id === void 0 ? {} : { id: s.id },
717
+ name: s.name,
718
+ mimeType: s.mimeType,
719
+ sizeBytes: s.sizeBytes,
720
+ ...s.sandboxPath === void 0 ? {} : { sandboxPath: s.sandboxPath },
721
+ ...s.storageKey === void 0 ? {} : { storageKey: s.storageKey },
722
+ ...s.fileUrl === void 0 ? {} : { fileUrl: s.fileUrl }
521
723
  };
522
724
  }
523
- function Y(i) {
524
- if (!i || typeof i != "object" || !("type" in i)) return !1;
525
- const e = i;
725
+ function ye(s) {
726
+ if (!s || typeof s != "object" || !("type" in s)) return !1;
727
+ const e = s;
526
728
  switch (e.type) {
527
729
  case "runtime.connect":
528
730
  case "session.new":
@@ -531,13 +733,15 @@ function Y(i) {
531
733
  case "run.stop":
532
734
  return e.clientMessageIds === void 0 || Array.isArray(e.clientMessageIds) && e.clientMessageIds.length <= 100 && e.clientMessageIds.every((t) => typeof t == "string" && t.length > 0 && t.length <= 160);
533
735
  case "runtime.report_response_visibility":
534
- return Q(e.observation);
736
+ return ee(e.observation);
535
737
  case "runtime.warmup":
536
738
  return e.reason === "panel_open" || e.reason === "extension_install" || e.reason === "composer_input";
739
+ case "runtime.report_operation_timing":
740
+ return w(e.timing);
537
741
  case "runtime.report_displayed_error":
538
- 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);
742
+ return (e.renderedError === void 0 || N(e.renderedError)) && (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);
539
743
  case "runtime.report_invalid_state_transition":
540
- return (e.reason === "submitted_turn_returned_to_welcome_without_new_chat" || e.reason === "new_messages_button_without_user_scroll" || K(e.reason)) && (e.clientMessageId === void 0 || typeof e.clientMessageId == "string");
744
+ return (e.uiInvariant === void 0 || K(e.uiInvariant)) && (e.reason === "submitted_turn_returned_to_welcome_without_new_chat" || e.reason === "new_messages_button_without_user_scroll" || ne(e.reason)) && (e.clientMessageId === void 0 || typeof e.clientMessageId == "string");
541
745
  case "runtime.widget_lifecycle":
542
746
  return (e.action === "opened" || e.action === "closed" || e.action === "minimized") && typeof e.trigger == "string";
543
747
  case "session.load":
@@ -565,9 +769,9 @@ function Y(i) {
565
769
  return !1;
566
770
  }
567
771
  }
568
- class W {
569
- constructor(e, t, s) {
570
- this.adapter = t, this.state = A(e), this.model = s;
772
+ class ve {
773
+ constructor(e, t, i) {
774
+ this.adapter = t, this.state = S(e), this.model = i;
571
775
  }
572
776
  adapter;
573
777
  listeners = {};
@@ -581,73 +785,48 @@ class W {
581
785
  interactions = [];
582
786
  account = null;
583
787
  stagedProactiveSuggestionClientMessageId = null;
584
- unacknowledgedSubmissions = /* @__PURE__ */ new Map();
788
+ pendingTransfers = /* @__PURE__ */ new Map();
789
+ // Presentation of commands in transit only; the background remains the submission/delivery owner.
790
+ submissionPreviews = /* @__PURE__ */ new Map();
585
791
  submissionGeneration = 0;
586
- stoppedProjection = null;
792
+ pendingStop = null;
793
+ stopError = null;
587
794
  operationQueue = Promise.resolve();
588
795
  destroyed = !1;
589
796
  on(e, t) {
590
- const s = this.listeners[e] ?? /* @__PURE__ */ new Set();
591
- return s.add(t), this.listeners[e] = s, () => s.delete(t);
797
+ const i = this.listeners[e] ?? /* @__PURE__ */ new Set();
798
+ return i.add(t), this.listeners[e] = i, () => i.delete(t);
592
799
  }
593
800
  getState() {
594
- return A(this.state);
801
+ const e = S(this.state);
802
+ for (const [t, i] of this.submissionPreviews)
803
+ e.messages.some((n) => n.id === t) || (e.messages.push({ ...i.message, attachments: i.message.attachments?.map((n) => ({ ...n })) }), e.segments && (e.segments = [...e.segments, { id: t, userMessageId: t, activityIds: [], outcomeIds: [], collapsed: !1 }]), e.isLoadingSession = !1, i.pending && (e.activeResponseUserMessageId = t, e.pendingMessageStatus = "sending", e.turnPhase = "sending", e.activity = { phase: "submitting", activeItemId: null }), i.error && (e.lastError = i.error, e.lastErrorCode = "message_delivery_failed"));
804
+ return this.stopError && (e.lastError = this.stopError, e.lastErrorCode = "stop_failed"), this.pendingStop ? se(e, "", "stopping", this.pendingStop.userMessageIds) : e;
595
805
  }
596
- updateProjection(e, t, s, n, a) {
806
+ updateProjection(e, t, i, n, r) {
597
807
  if (this.destroyed) return;
598
- const l = this.state;
599
- if (this.state = A(e), l.user?.id === e.user?.id)
600
- for (const r of this.state.messages) {
601
- if (r.role !== "user" || !r.attachments?.length) continue;
602
- const o = r.clientMessageId, c = l.messages.find((u) => u.role === "user" && (u.id === r.id || o && u.clientMessageId === o));
603
- l.sessionId !== e.sessionId && !(l.sessionId === null && o && c?.clientMessageId === o) || (r.attachments = T(c?.attachments, r.attachments));
808
+ const a = this.getState();
809
+ (a.user?.id !== e.user?.id || a.selectionKey !== void 0 && a.selectionKey !== e.selectionKey || a.selectionKey === void 0 && a.sessionId !== null && a.sessionId !== e.sessionId) && (this.cancelPendingSubmissions(), this.submissionPreviews.clear());
810
+ for (const o of e.messages)
811
+ o.role === "user" && this.submissionPreviews.delete(o.id);
812
+ if (this.state = S(e), a.user?.id === e.user?.id)
813
+ for (const o of this.state.messages) {
814
+ if (o.role !== "user" || !o.attachments?.length) continue;
815
+ const l = a.messages.find((c) => c.role === "user" && c.id === o.id);
816
+ a.sessionId !== e.sessionId && !(a.sessionId === null && l) || (o.attachments = re(l?.attachments, o.attachments));
604
817
  }
605
- if (this.stoppedProjection) {
606
- const r = this.stoppedProjection, o = new Set(r.messages.filter((d) => d.role === "user").map((d) => d.id)), c = e.sessionId === r.sessionId && e.user?.id === r.user?.id, u = e.messages.some((d) => d.role === "user" && !o.has(d.id) && !r.messages.some((h) => h.clientMessageId && h.clientMessageId === d.clientMessageId));
607
- if (!c || u)
608
- this.stoppedProjection = null;
609
- else {
610
- const d = [
611
- r.activeResponseUserMessageId,
612
- r.assistantDraftRespondsToUserMessageId,
613
- r.messages.filter((v) => v.role === "user").slice(-1)[0]?.id
614
- ].filter(Boolean), h = d.length > 0 && d.every((v) => e.messages.some((p) => p.respondsToUserMessageId === v && !p.loading && (p.dataType === "run_status" || p.dataType === "run_error" || p.role === "assistant" && p.phase !== "commentary")));
615
- this.state = _(h ? this.state : {
616
- ...this.state,
617
- messages: r.messages,
618
- assistantDraft: r.assistantDraft
619
- }, (/* @__PURE__ */ new Date()).toISOString()), this.stoppedProjection = this.getState();
620
- }
621
- }
622
- for (const [r, o] of this.unacknowledgedSubmissions) {
623
- if (e.user?.id !== o.userId || o.sessionId !== null && e.sessionId !== o.sessionId) {
624
- this.unacknowledgedSubmissions.delete(r);
625
- continue;
626
- }
627
- const c = this.state.messages.find(
628
- (u) => u.clientMessageId === r
629
- );
630
- if (c) {
631
- c.attachments = T(
632
- o.message.attachments,
633
- c.attachments
634
- ), this.unacknowledgedSubmissions.delete(r);
635
- continue;
636
- }
637
- o.sessionId ??= e.sessionId, this.state.messages.push(o.message), this.state.pendingMessageStatus = "sending", this.state.turnPhase ??= "sending", this.state.taskStatus ??= "working";
638
- }
639
- if (t !== void 0 && (this.model = t), s && JSON.stringify(s) !== JSON.stringify(this.sessionHistoryState)) {
640
- this.sessionHistoryState = E(s);
641
- for (const r of this.sessionHistoryListeners)
642
- r(this.getSessionHistoryState());
818
+ if (t !== void 0 && (this.model = t), i && JSON.stringify(i) !== JSON.stringify(this.sessionHistoryState)) {
819
+ this.sessionHistoryState = x(i);
820
+ for (const o of this.sessionHistoryListeners)
821
+ o(this.getSessionHistoryState());
643
822
  }
644
823
  if (n && JSON.stringify(n) !== JSON.stringify(this.interactions)) {
645
- this.interactions = n.map((r) => ({ ...r }));
646
- for (const r of this.interactionListeners) r(this.getInteractions());
824
+ this.interactions = n.map((o) => ({ ...o }));
825
+ for (const o of this.interactionListeners) o(this.getInteractions());
647
826
  }
648
- if (a !== void 0 && JSON.stringify(a) !== JSON.stringify(this.account)) {
649
- this.account = a ? { ...a } : null;
650
- for (const r of this.accountListeners) r(this.getAccount());
827
+ if (r !== void 0 && JSON.stringify(r) !== JSON.stringify(this.account)) {
828
+ this.account = r ? { ...r } : null;
829
+ for (const o of this.accountListeners) o(this.getAccount());
651
830
  }
652
831
  this.emit("state", this.getState());
653
832
  }
@@ -656,7 +835,7 @@ class W {
656
835
  }
657
836
  destroy() {
658
837
  if (!this.destroyed) {
659
- this.destroyed = !0, this.unacknowledgedSubmissions.clear(), this.attachmentFiles.clear(), this.sessionHistoryListeners.clear(), this.interactionListeners.clear(), this.accountListeners.clear();
838
+ this.destroyed = !0, this.pendingStop = null, this.pendingTransfers.clear(), this.submissionPreviews.clear(), this.attachmentFiles.clear(), this.sessionHistoryListeners.clear(), this.interactionListeners.clear(), this.accountListeners.clear();
660
839
  for (const e of Object.values(this.listeners)) e?.clear();
661
840
  this.adapter.onDisconnect?.();
662
841
  }
@@ -668,116 +847,117 @@ class W {
668
847
  recordWidgetLifecycle(e, t) {
669
848
  this.dispatch({ type: "runtime.widget_lifecycle", action: e, trigger: t });
670
849
  }
850
+ reportOperationTiming(e) {
851
+ !this.destroyed && w(e) && this.adapter.dispatch({ type: "runtime.report_operation_timing", timing: e }).catch(() => {
852
+ });
853
+ }
671
854
  reportResponseVisibility(e) {
672
855
  this.adapter.dispatch({ type: "runtime.report_response_visibility", observation: e }).catch(() => {
673
856
  });
674
857
  }
675
- reportInvalidStateTransition(e, t) {
676
- this.adapter.dispatch({
858
+ reportInvalidStateTransition(e, t, i) {
859
+ i !== void 0 && !K(i) || this.adapter.dispatch({
677
860
  type: "runtime.report_invalid_state_transition",
678
861
  reason: e,
679
- clientMessageId: t
862
+ clientMessageId: t,
863
+ ...i ? { uiInvariant: i } : {}
680
864
  }).catch(() => {
681
865
  });
682
866
  }
683
- reportDisplayedError(e, t, s) {
684
- this.adapter.dispatch({
867
+ reportDisplayedError(e, t, i, n) {
868
+ n !== void 0 && !N(n) || this.adapter.dispatch({
685
869
  type: "runtime.report_displayed_error",
686
870
  reason: e,
687
871
  errorFingerprint: t,
688
- ...s ? { displayedMessage: U(s) } : {}
872
+ ...n ? { renderedError: n } : {},
873
+ ...i ? { displayedMessage: te(i) } : {}
689
874
  }).catch(() => {
690
875
  });
691
876
  }
692
877
  sendMessage(e, t = {}) {
693
- const s = e.trim(), n = t.attachments ?? [];
694
- if (!s && n.length === 0) return Promise.resolve(null);
695
- const a = t.clientMessageId ?? (t.proactiveSuggestionQuestion && this.stagedProactiveSuggestionClientMessageId ? this.stagedProactiveSuggestionClientMessageId : crypto.randomUUID()), l = t.submittedAt ?? Date.now(), r = this.state, o = this.submissionGeneration, c = {
696
- id: `local-${a}`,
878
+ const i = e.trim(), n = t.attachments ?? [];
879
+ if (!i && n.length === 0) return Promise.resolve(null);
880
+ this.pendingStop = null, this.stopError = null;
881
+ const r = t.clientMessageId ?? (t.proactiveSuggestionQuestion && this.stagedProactiveSuggestionClientMessageId ? this.stagedProactiveSuggestionClientMessageId : crypto.randomUUID()), a = t.submittedAt ?? Date.now(), o = this.submissionGeneration;
882
+ this.pendingTransfers.set(r, n.flatMap((c) => c.id ? [c.id] : [])), this.submissionPreviews.set(r, { pending: !0, message: {
883
+ id: r,
697
884
  role: "user",
698
- content: s,
699
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
700
- ...n.length > 0 ? { attachments: n } : {},
701
- clientMessageId: a
702
- };
703
- this.unacknowledgedSubmissions.set(a, {
704
- message: { ...c, attachments: c.attachments?.map((d) => ({ ...d })) },
705
- sessionId: r.sessionId,
706
- userId: r.user?.id
707
- }), this.state = {
708
- ...this.state,
709
- messages: [...this.state.messages, c],
710
- pendingMessageStatus: "sending",
711
- turnPhase: this.state.isThinking ? this.state.turnPhase : "sending",
712
- taskStatus: "working",
713
- isRetrying: !1,
714
- lastError: null
715
- };
716
- const u = this.enqueueOperation(() => this.sendMessageNow(
717
- s,
718
- { ...t, clientMessageId: a, submittedAt: l },
719
- r,
720
- o
721
- ));
722
- return this.emit("state", this.getState()), u;
723
- }
724
- async sendMessageNow(e, t, s, n) {
725
- const a = e, l = t.clientMessageId;
726
- let r = t.attachments ?? [], o = !1;
727
- if (n !== this.submissionGeneration) return null;
885
+ content: i,
886
+ createdAt: "",
887
+ attachments: n.map((c) => ({ ...c }))
888
+ } });
889
+ const l = this.sendMessageNow(i, { ...t, clientMessageId: r, submittedAt: a }, o);
890
+ return this.emit("state", this.getState()), l.finally(() => {
891
+ this.pendingTransfers.delete(r);
892
+ });
893
+ }
894
+ async sendMessageNow(e, t, i) {
895
+ const n = e, r = t.clientMessageId, a = R((c) => {
896
+ i === this.submissionGeneration && this.reportOperationTiming(c);
897
+ }, {
898
+ operation: "send",
899
+ layer: "renderer",
900
+ requestId: r,
901
+ clientMessageId: r,
902
+ sessionId: this.state.sessionId
903
+ });
904
+ a.mark("submit");
905
+ let o = t.attachments ?? [], l = !1;
906
+ if (i !== this.submissionGeneration) return null;
728
907
  try {
729
- if (await this.adapter.dispatch({
730
- type: "conversation.stage",
731
- content: a,
732
- clientMessageId: l,
733
- proactiveSuggestionQuestion: t.proactiveSuggestionQuestion,
734
- // Preview URLs belong to the renderer's optimistic snapshot and are not valid runtime-command metadata.
735
- attachments: r.length > 0 ? r.map(P) : void 0,
736
- submittedAt: t.submittedAt
737
- }), n !== this.submissionGeneration) return null;
738
- if (o = !0, r.length > 0) {
908
+ if (!await a.measure("staging_ipc", async () => {
909
+ const d = await this.enqueueOperation(async () => this.destroyed || i !== this.submissionGeneration ? null : { result: this.adapter.dispatch({
910
+ type: "conversation.stage",
911
+ initiatedBy: t.initiatedBy,
912
+ invocation: t.invocation,
913
+ automationOnboarding: t.automationOnboarding,
914
+ content: n,
915
+ clientMessageId: r,
916
+ proactiveSuggestionQuestion: t.proactiveSuggestionQuestion,
917
+ // Preview URLs belong to the renderer's optimistic snapshot and are not valid runtime-command metadata.
918
+ attachments: o.length > 0 ? o.map(C) : void 0,
919
+ submittedAt: t.submittedAt
920
+ }) });
921
+ return d ? (await d.result, d) : null;
922
+ }) || i !== this.submissionGeneration) return null;
923
+ if (l = !0, o.length > 0) {
739
924
  if (!this.adapter.uploadAttachment)
740
925
  throw new Error("The runtime does not support attachments.");
741
- const u = [];
742
- for (const d of r) {
743
- if (d.sandboxPath || d.storageKey) {
744
- u.push(d);
926
+ const d = [];
927
+ for (const u of o) {
928
+ if (u.sandboxPath || u.storageKey) {
929
+ d.push(u);
745
930
  continue;
746
931
  }
747
- const h = d.id ? this.attachmentFiles.get(d.id) : void 0;
748
- if (!h) throw new Error(`Attachment bytes are unavailable for ${d.name}`);
749
- if (u.push(await this.adapter.uploadAttachment(h, d, { clientMessageId: l })), n !== this.submissionGeneration) return null;
932
+ const T = u.id ? this.attachmentFiles.get(u.id) : void 0;
933
+ if (!T) throw new Error(`Attachment bytes are unavailable for ${u.name}`);
934
+ if (d.push(await a.measure("attachment_transfer", () => this.adapter.uploadAttachment(T, u, { clientMessageId: r }))), i !== this.submissionGeneration) return null;
750
935
  }
751
- r = u;
936
+ o = d;
752
937
  }
753
- const c = await this.adapter.dispatch({
938
+ const p = await a.measure("send_ipc", () => this.adapter.dispatch({
754
939
  type: "conversation.send",
755
- content: a,
756
- clientMessageId: l,
940
+ content: n,
941
+ clientMessageId: r,
757
942
  initiatedBy: t.initiatedBy,
758
943
  invocation: t.invocation,
759
944
  proactiveSuggestionQuestion: t.proactiveSuggestionQuestion,
760
945
  ...t.automationOnboarding ? { automationOnboarding: !0 } : {},
761
- attachments: r.length > 0 ? r.map(P) : void 0
762
- });
763
- if (n !== this.submissionGeneration) return null;
764
- for (const u of t.attachments ?? [])
765
- u.id && this.attachmentFiles.delete(u.id);
766
- return l === this.stagedProactiveSuggestionClientMessageId && (this.stagedProactiveSuggestionClientMessageId = null), c?.clientMessageId ?? l;
946
+ attachments: o.length > 0 ? o.map(C) : void 0
947
+ }));
948
+ if (i !== this.submissionGeneration) return null;
949
+ for (const d of t.attachments ?? [])
950
+ d.id && this.attachmentFiles.delete(d.id);
951
+ return r === this.stagedProactiveSuggestionClientMessageId && (this.stagedProactiveSuggestionClientMessageId = null), p?.clientMessageId ?? r;
767
952
  } catch (c) {
768
- if (n !== this.submissionGeneration) return null;
769
- throw this.unacknowledgedSubmissions.delete(l), this.state = {
770
- ...this.state,
771
- messages: this.state.messages.filter(
772
- (u) => u.id !== `local-${l}` && u.id !== `optimistic-user-message:${l}`
773
- ),
774
- pendingMessageStatus: s.pendingMessageStatus,
775
- turnPhase: s.turnPhase,
776
- isThinking: s.isThinking,
777
- taskStatus: s.taskStatus
778
- }, this.emit("state", this.getState()), o && await this.adapter.dispatch({
953
+ if (i !== this.submissionGeneration) return null;
954
+ if (Q(c))
955
+ for (const d of t.attachments ?? [])
956
+ d.id && this.attachmentFiles.delete(d.id);
957
+ const p = this.submissionPreviews.get(r);
958
+ throw p && (p.pending = !1, p.error = c instanceof Error ? c.message : String(c), this.emit("state", this.getState())), l && await this.adapter.dispatch({
779
959
  type: "conversation.fail_staged",
780
- clientMessageId: l,
960
+ clientMessageId: r,
781
961
  message: c instanceof Error ? c.message : String(c)
782
962
  }), c;
783
963
  }
@@ -790,7 +970,7 @@ class W {
790
970
  });
791
971
  }
792
972
  retryLastMessage() {
793
- return this.stoppedProjection = null, this.dispatch({ type: "run.retry" }), !0;
973
+ return this.dispatch({ type: "run.retry" }), !0;
794
974
  }
795
975
  createLocalAttachment(e) {
796
976
  const t = crypto.randomUUID();
@@ -802,37 +982,57 @@ class W {
802
982
  };
803
983
  }
804
984
  stop() {
805
- const e = this.cancelPendingSubmissions();
806
- this.state = _(this.state, (/* @__PURE__ */ new Date()).toISOString()), this.stoppedProjection = this.getState(), this.emit("state", this.getState());
807
- const t = this.adapter.dispatch({ type: "run.stop", ...e.length ? { clientMessageIds: e } : {} });
808
- return this.operationQueue = t.then(() => {
985
+ if (this.pendingStop) return this.pendingStop.promise;
986
+ const e = this.getState(), t = this.cancelPendingSubmissions(), i = [...new Set([
987
+ ...t,
988
+ e.activeResponseUserMessageId,
989
+ e.messages.filter((o) => o.role === "user").slice(-1)[0]?.id
990
+ ].filter((o) => !!o))], n = R((o) => this.reportOperationTiming(o), {
991
+ operation: "stop",
992
+ layer: "renderer",
993
+ requestId: crypto.randomUUID(),
994
+ clientMessageId: i[0] ?? null,
995
+ sessionId: e.sessionId
996
+ });
997
+ n.mark("stop");
998
+ const r = { userMessageIds: i, promise: Promise.resolve() };
999
+ this.pendingStop = r, r.promise = n.measure("stop_ipc", () => this.adapter.dispatch({ type: "run.stop", ...t.length ? { clientMessageIds: t } : {} })).then(() => {
1000
+ }, (o) => {
1001
+ this.pendingStop === r && (this.stopError = o instanceof Error ? o.message : String(o));
1002
+ }).finally(() => {
1003
+ this.pendingStop === r && (this.pendingStop = null, this.emit("state", this.getState()));
1004
+ }), this.emit("state", this.getState());
1005
+ const a = r.promise;
1006
+ return this.operationQueue = a.then(() => {
809
1007
  }, () => {
810
- }), t.then(() => {
1008
+ }), a.then(() => {
811
1009
  });
812
1010
  }
813
1011
  cancelPendingSubmissions() {
814
- const e = [...this.unacknowledgedSubmissions.keys()];
1012
+ this.pendingStop = null, this.stopError = null;
1013
+ const e = [...this.pendingTransfers.keys()];
815
1014
  this.submissionGeneration++;
816
- for (const t of this.unacknowledgedSubmissions.values())
817
- for (const s of t.message.attachments ?? [])
818
- s.id && this.attachmentFiles.delete(s.id);
819
- return this.unacknowledgedSubmissions.clear(), this.operationQueue = Promise.resolve(), e;
1015
+ for (const t of this.pendingTransfers.values())
1016
+ for (const i of t) this.attachmentFiles.delete(i);
1017
+ this.pendingTransfers.clear();
1018
+ for (const t of this.submissionPreviews.values()) t.pending = !1;
1019
+ return this.operationQueue = Promise.resolve(), e;
820
1020
  }
821
1021
  startNewSession(e = {}) {
822
- return this.cancelPendingSubmissions(), this.stoppedProjection = null, e.notifyTransport === !1 ? Promise.resolve() : this.dispatch({ type: "session.new" }).then(() => {
1022
+ return this.cancelPendingSubmissions(), this.submissionPreviews.clear(), this.emit("state", this.getState()), e.notifyTransport === !1 ? Promise.resolve() : this.dispatch({ type: "session.new" }).then(() => {
823
1023
  });
824
1024
  }
825
1025
  async listSessions(e = {}) {
826
1026
  const t = await this.dispatch({ type: "session.list", ...e });
827
1027
  if (t === void 0) {
828
- const s = this.getSessionHistoryState().data;
829
- return { sessions: s ? s.ids.map((n) => s.entitiesById[n]) : [], nextCursor: s?.nextCursor ?? null };
1028
+ const i = this.getSessionHistoryState().data;
1029
+ return { sessions: i ? i.ids.map((n) => i.entitiesById[n]) : [], nextCursor: i?.nextCursor ?? null };
830
1030
  }
831
1031
  if (!t?.sessionHistoryPage) throw new Error("Session list command did not return a page.");
832
1032
  return t.sessionHistoryPage;
833
1033
  }
834
1034
  getSessionHistoryState() {
835
- return E(this.sessionHistoryState);
1035
+ return x(this.sessionHistoryState);
836
1036
  }
837
1037
  subscribeSessionHistory(e) {
838
1038
  return this.sessionHistoryListeners.add(e), e(this.getSessionHistoryState()), () => this.sessionHistoryListeners.delete(e);
@@ -860,12 +1060,12 @@ class W {
860
1060
  subscribeInteractions(e) {
861
1061
  return this.interactionListeners.add(e), e(this.getInteractions()), () => this.interactionListeners.delete(e);
862
1062
  }
863
- actOnInteraction(e, t, s, n = {}) {
1063
+ actOnInteraction(e, t, i, n = {}) {
864
1064
  return this.dispatch({
865
1065
  type: "interaction.act",
866
1066
  interactionId: e,
867
1067
  action: t,
868
- expectedRevision: s,
1068
+ expectedRevision: i,
869
1069
  ...n
870
1070
  }).then(() => {
871
1071
  });
@@ -880,22 +1080,22 @@ class W {
880
1080
  return Promise.resolve();
881
1081
  }
882
1082
  loadSession(e) {
883
- return this.unacknowledgedSubmissions.clear(), this.dispatch({ type: "session.load", sessionId: e }).then(() => {
1083
+ return this.cancelPendingSubmissions(), this.submissionPreviews.clear(), this.emit("state", this.getState()), this.dispatch({ type: "session.load", sessionId: e }).then(() => {
884
1084
  });
885
1085
  }
886
1086
  stageProactiveSuggestionQuestion(e) {
887
1087
  const t = e.trim();
888
1088
  if (!t) return Promise.resolve();
889
- const s = this.stagedProactiveSuggestionClientMessageId ?? crypto.randomUUID();
890
- return this.stagedProactiveSuggestionClientMessageId = s, this.dispatch({
1089
+ const i = this.stagedProactiveSuggestionClientMessageId ?? crypto.randomUUID();
1090
+ return this.stagedProactiveSuggestionClientMessageId = i, this.dispatch({
891
1091
  type: "conversation.stage_proactive_suggestion",
892
1092
  question: t,
893
- clientMessageId: s
1093
+ clientMessageId: i
894
1094
  }).then(() => {
895
1095
  });
896
1096
  }
897
1097
  dispatch(e) {
898
- return this.enqueueOperation(() => this.adapter.dispatch(e));
1098
+ return e.type === "session.list" ? this.adapter.dispatch(e) : this.enqueueOperation(() => this.adapter.dispatch(e));
899
1099
  }
900
1100
  enqueueOperation(e) {
901
1101
  const t = this.operationQueue.then(e);
@@ -907,73 +1107,76 @@ class W {
907
1107
  ), t;
908
1108
  }
909
1109
  emit(e, t) {
910
- const s = this.listeners[e];
911
- for (const n of s ?? []) n(t);
1110
+ const i = this.listeners[e];
1111
+ for (const n of i ?? []) n(t);
912
1112
  }
913
1113
  }
914
- function T(i, e) {
915
- if (!e || !i) return e;
1114
+ function re(s, e) {
1115
+ if (!e || !s) return e;
916
1116
  const t = /* @__PURE__ */ new Map();
917
- for (const s of i) {
918
- const n = s.previewUrl;
919
- s.id && n && t.set(s.id, n);
1117
+ for (const i of s) {
1118
+ const n = i.previewUrl;
1119
+ i.id && n && t.set(i.id, n);
920
1120
  }
921
- return e.map((s) => {
922
- const n = s.id ? t.get(s.id) : void 0;
923
- return n ? { ...s, previewUrl: n } : s;
1121
+ return e.map((i) => {
1122
+ const n = i.id ? t.get(i.id) : void 0;
1123
+ return n ? { ...i, previewUrl: n } : i;
924
1124
  });
925
1125
  }
926
- function A(i) {
1126
+ function S(s) {
927
1127
  return {
928
- ...i,
929
- starterPrompts: [...i.starterPrompts],
930
- appearance: i.appearance ? { ...i.appearance } : null,
931
- messages: i.messages.map((e) => {
1128
+ ...s,
1129
+ starterPrompts: [...s.starterPrompts],
1130
+ appearance: s.appearance ? { ...s.appearance } : null,
1131
+ messages: s.messages.map((e) => {
932
1132
  const t = {
933
1133
  ...e,
934
- attachments: e.attachments?.map((l) => ({ ...l }))
935
- }, s = e.assistantDraftItemId, n = e.clientMessageId, a = e.proactiveSuggestionClientMessageId;
936
- return a && Object.defineProperty(t, "proactiveSuggestionClientMessageId", {
937
- value: a,
1134
+ attachments: e.attachments?.map((a) => ({ ...a }))
1135
+ }, i = e.assistantDraftItemId, n = e.clientMessageId, r = e.proactiveSuggestionClientMessageId;
1136
+ return r && Object.defineProperty(t, "proactiveSuggestionClientMessageId", {
1137
+ value: r,
938
1138
  enumerable: !1
939
- }), s && Object.defineProperty(t, "assistantDraftItemId", {
940
- value: s,
1139
+ }), i && Object.defineProperty(t, "assistantDraftItemId", {
1140
+ value: i,
941
1141
  enumerable: !1
942
1142
  }), n && Object.defineProperty(t, "clientMessageId", {
943
1143
  value: n,
944
1144
  enumerable: !1
945
1145
  }), t;
946
1146
  }),
947
- activeScheduledFollowUps: i.activeScheduledFollowUps?.map((e) => ({ ...e })) ?? null
1147
+ activeScheduledFollowUps: s.activeScheduledFollowUps?.map((e) => ({ ...e })) ?? null
948
1148
  };
949
1149
  }
950
- function E(i) {
1150
+ function x(s) {
951
1151
  return {
952
- ...i,
953
- data: i.data ? m({
954
- entities: k(i.data).map((e) => ({ ...e })),
955
- nextCursor: i.data.nextCursor
1152
+ ...s,
1153
+ data: s.data ? m({
1154
+ entities: $(s.data).map((e) => ({ ...e })),
1155
+ nextCursor: s.data.nextCursor
956
1156
  }) : null
957
1157
  };
958
1158
  }
959
1159
  export {
960
- G as ProductAgentInteractionManager,
961
- w as ProductAgentQueryController,
962
- W as ProductAgentRemoteRuntimeClient,
963
- H as ProductAgentSessionHistoryManager,
964
- Z as ProductAgentTaskPageTitleController,
965
- V as createLocalStorageInteractionDecisionStorage,
1160
+ j as PRODUCT_AGENT_AUTH_RECONNECTING_ERROR_MESSAGE,
1161
+ he as ProductAgentInteractionManager,
1162
+ P as ProductAgentQueryController,
1163
+ ve as ProductAgentRemoteRuntimeClient,
1164
+ pe as ProductAgentSessionHistoryManager,
1165
+ fe as ProductAgentTaskPageTitleController,
1166
+ de as canSubmitPersonalProductAgentMessage,
1167
+ ge as createLocalStorageInteractionDecisionStorage,
966
1168
  f as createProductAgentQueryState,
967
- J as createProductAgentTaskPageTitleDocument,
968
- q as formatProductAgentTaskPageTitle,
969
- j as hasProductAgentPaidCreditFallback,
970
- Y as isProductAgentRuntimeCommand,
971
- O as mergeProductAgentEntityPages,
1169
+ me as createProductAgentTaskPageTitleDocument,
1170
+ Z as formatProductAgentTaskPageTitle,
1171
+ le as hasProductAgentPaidCreditFallback,
1172
+ Q as isProductAgentAuthReconnectError,
1173
+ ye as isProductAgentRuntimeCommand,
1174
+ U as mergeProductAgentEntityPages,
972
1175
  m as normalizeProductAgentEntityPage,
973
- x as readLocalStorageInteractionDecisions,
974
- B as reconcileProductAgentSubmissionGate,
975
- F as resolveProductAgentBillingPresentation,
976
- z as resolveProductAgentComposerAction,
977
- N as resolveProductAgentWidgetPresentation,
978
- k as selectProductAgentQueryEntities
1176
+ G as readLocalStorageInteractionDecisions,
1177
+ ae as reconcileProductAgentSubmissionGate,
1178
+ ce as resolveProductAgentBillingPresentation,
1179
+ ue as resolveProductAgentComposerAction,
1180
+ oe as resolveProductAgentWidgetPresentation,
1181
+ $ as selectProductAgentQueryEntities
979
1182
  };