@pluno/product-agent-web 0.1.283 → 0.1.284

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.
@@ -359,6 +359,7 @@ function Ie(t, e, s) {
359
359
  return G({
360
360
  historyRefreshFailure: r?.historyRefreshFailure ?? null,
361
361
  selectionKey: s ? JSON.stringify([t.authorityId, t.generation, s]) : void 0,
362
+ stableSelectionKey: s ? JSON.stringify([t.authorityId, s]) : void 0,
362
363
  isDraftSession: O,
363
364
  proactiveQuestion: t.proactiveQuestions[s] ?? null,
364
365
  sessionId: i,
@@ -1973,7 +1974,7 @@ function fo(t, e = null) {
1973
1974
  } : void 0);
1974
1975
  return { ...n, ...o ? { auth: o } : {}, submissionGate: a, usingPaidCreditFallback: e ? t.paidFallbackBySession[e] ?? !1 : !1 };
1975
1976
  }
1976
- const go = "0.1.283", Lt = {
1977
+ const go = "0.1.284", Lt = {
1977
1978
  version: go
1978
1979
  }, ln = (t) => t.selectedModel ?? t.historyModel ?? t.defaultModel, mo = (t, e) => t.scopes[e];
1979
1980
  function Ft(t) {
@@ -3809,6 +3810,7 @@ function ds(t, e, s, n) {
3809
3810
  },
3810
3811
  historyPreparation: t.preparation ?? null,
3811
3812
  selectionKey: t.selectionKey,
3813
+ stableSelectionKey: t.stableSelectionKey,
3812
3814
  isDraftSession: t.isDraftSession,
3813
3815
  sessionId: t.sessionId,
3814
3816
  messages: f,
@@ -9287,7 +9289,7 @@ function cu(t) {
9287
9289
  }
9288
9290
  class du {
9289
9291
  constructor(e, s, n) {
9290
- this.adapter = s, this.state = _s(e), this.model = n;
9292
+ this.adapter = s, this.state = _s(e), this.hasBeenReady = e.status === "connected" && e.submissionReady !== !1, this.model = n;
9291
9293
  }
9292
9294
  adapter;
9293
9295
  listeners = {};
@@ -9301,6 +9303,7 @@ class du {
9301
9303
  interactions = [];
9302
9304
  account = null;
9303
9305
  stagedProactiveSuggestionClientMessageId = null;
9306
+ readinessPendingSubmissions = /* @__PURE__ */ new Set();
9304
9307
  pendingTransfers = /* @__PURE__ */ new Map();
9305
9308
  // Presentation of commands in transit only; the background remains the submission/delivery owner.
9306
9309
  submissionPreviews = /* @__PURE__ */ new Map();
@@ -9313,6 +9316,7 @@ class du {
9313
9316
  durabilityWaiters = /* @__PURE__ */ new Set();
9314
9317
  operationQueue = Promise.resolve();
9315
9318
  destroyed = !1;
9319
+ hasBeenReady;
9316
9320
  on(e, s) {
9317
9321
  const n = this.listeners[e] ?? /* @__PURE__ */ new Set();
9318
9322
  return n.add(s), this.listeners[e] = n, () => n.delete(s);
@@ -9329,33 +9333,33 @@ class du {
9329
9333
  }
9330
9334
  updateProjection(e, s, n, i, r) {
9331
9335
  if (this.destroyed) return;
9332
- const a = this.getState();
9333
- (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());
9334
- for (const o of e.messages)
9335
- o.role === "user" && e.receipts?.find((c) => c.userMessageId === o.id)?.durable !== !1 && this.submissionPreviews.delete(o.id);
9336
- this.state = _s(e);
9337
- for (const [o, c] of this.stopPreviews) {
9338
- const d = e.activity?.executionKey;
9339
- (c !== void 0 && c !== "[]" && d !== void 0 && d !== "[]" && (d !== c || ["completed", "failed", "stopped"].includes(e.activity.phase)) || (c === void 0 || c === "[]") && e.messages.some((u) => u.respondsToUserMessageId === o && !u.provisional && u.loading !== !0 && (u.dataType === "run_status" || u.dataType === "run_error" || u.role === "assistant" && u.phase !== "commentary" && (u.streamState === void 0 || ["finished", "stopped", "failed"].includes(u.streamState))))) && this.stopPreviews.delete(o);
9340
- }
9341
- if (this.pendingStop?.userMessageIds.every((o) => !this.stopPreviews.has(o)) && (this.pendingStop = null), a.user?.id === e.user?.id)
9342
- for (const o of this.state.messages) {
9343
- if (o.role !== "user" || !o.attachments?.length) continue;
9344
- const c = a.messages.find((d) => d.role === "user" && d.id === o.id);
9345
- a.sessionId !== e.sessionId && !(a.sessionId === null && c) || (o.attachments = Xc(c?.attachments, o.attachments));
9336
+ const a = this.getState(), o = !this.hasBeenReady && (!a.user || a.user.id === e.user?.id), c = a.stableSelectionKey !== void 0 && a.stableSelectionKey === e.stableSelectionKey && a.user?.id === e.user?.id && a.sessionId === e.sessionId && this.pendingTransfers.size > 0 && this.submissionRetries.size === 0 && [...this.pendingTransfers.keys()].every((d) => this.readinessPendingSubmissions.has(d));
9337
+ !o && !c && (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());
9338
+ for (const d of e.messages)
9339
+ d.role === "user" && e.receipts?.find((l) => l.userMessageId === d.id)?.durable !== !1 && this.submissionPreviews.delete(d.id);
9340
+ this.state = _s(e), e.status === "connected" && e.submissionReady !== !1 && (this.hasBeenReady = !0);
9341
+ for (const [d, l] of this.stopPreviews) {
9342
+ const u = e.activity?.executionKey;
9343
+ (l !== void 0 && l !== "[]" && u !== void 0 && u !== "[]" && (u !== l || ["completed", "failed", "stopped"].includes(e.activity.phase)) || (l === void 0 || l === "[]") && e.messages.some((p) => p.respondsToUserMessageId === d && !p.provisional && p.loading !== !0 && (p.dataType === "run_status" || p.dataType === "run_error" || p.role === "assistant" && p.phase !== "commentary" && (p.streamState === void 0 || ["finished", "stopped", "failed"].includes(p.streamState))))) && this.stopPreviews.delete(d);
9344
+ }
9345
+ if (this.pendingStop?.userMessageIds.every((d) => !this.stopPreviews.has(d)) && (this.pendingStop = null), a.user?.id === e.user?.id)
9346
+ for (const d of this.state.messages) {
9347
+ if (d.role !== "user" || !d.attachments?.length) continue;
9348
+ const l = a.messages.find((u) => u.role === "user" && u.id === d.id);
9349
+ a.sessionId !== e.sessionId && !(a.sessionId === null && l) || (d.attachments = Xc(l?.attachments, d.attachments));
9346
9350
  }
9347
9351
  if (s !== void 0 && (this.model = s), n && JSON.stringify(n) !== JSON.stringify(this.sessionHistoryState)) {
9348
9352
  this.sessionHistoryState = yi(n);
9349
- for (const o of this.sessionHistoryListeners)
9350
- o(this.getSessionHistoryState());
9353
+ for (const d of this.sessionHistoryListeners)
9354
+ d(this.getSessionHistoryState());
9351
9355
  }
9352
9356
  if (i && JSON.stringify(i) !== JSON.stringify(this.interactions)) {
9353
- this.interactions = i.map((o) => ({ ...o }));
9354
- for (const o of this.interactionListeners) o(this.getInteractions());
9357
+ this.interactions = i.map((d) => ({ ...d }));
9358
+ for (const d of this.interactionListeners) d(this.getInteractions());
9355
9359
  }
9356
9360
  if (r !== void 0 && JSON.stringify(r) !== JSON.stringify(this.account)) {
9357
9361
  this.account = r ? { ...r } : null;
9358
- for (const o of this.accountListeners) o(this.getAccount());
9362
+ for (const d of this.accountListeners) d(this.getAccount());
9359
9363
  }
9360
9364
  this.emit("state", this.getState());
9361
9365
  }
@@ -9435,8 +9439,8 @@ class du {
9435
9439
  });
9436
9440
  }
9437
9441
  async sendMessageNow(e, s, n) {
9438
- const i = e, r = s.clientMessageId, a = Q((d) => {
9439
- n === this.submissionGeneration && this.reportOperationTiming(d);
9442
+ const i = e, r = s.clientMessageId, a = Q((l) => {
9443
+ n === this.submissionGeneration && this.reportOperationTiming(l);
9440
9444
  }, {
9441
9445
  operation: "send",
9442
9446
  layer: "renderer",
@@ -9445,51 +9449,58 @@ class du {
9445
9449
  sessionId: this.state.sessionId
9446
9450
  });
9447
9451
  a.mark("submit");
9448
- let o = s.attachments ?? [], c = !1;
9452
+ let o = s.attachments ?? [], c = !1, d = !this.hasBeenReady || this.state.submissionReady === !1;
9449
9453
  if (n !== this.submissionGeneration) return null;
9454
+ d && this.readinessPendingSubmissions.add(r);
9450
9455
  try {
9451
- const d = await a.measure("staging_ipc", async () => {
9452
- const l = await this.enqueueOperation(async () => this.destroyed || n !== this.submissionGeneration ? null : { result: this.adapter.dispatch({
9453
- type: "conversation.stage",
9454
- ...s.reconcileAcceptance ? { reconcileAcceptance: !0, selectionKey: s.selectionKey } : {},
9455
- initiatedBy: s.initiatedBy,
9456
- invocation: s.invocation,
9457
- automationOnboarding: s.automationOnboarding,
9458
- content: i,
9459
- clientMessageId: r,
9460
- proactiveSuggestionQuestion: s.proactiveSuggestionQuestion,
9461
- // Preview URLs belong to the renderer's optimistic snapshot and are not valid runtime-command metadata.
9462
- attachments: o.length > 0 ? o.map(mi) : void 0,
9463
- submittedAt: s.submittedAt
9464
- }) });
9465
- return l ? l.result.then((u) => ({ result: u }), async (u) => {
9466
- const h = Y(u);
9467
- if (h.code !== "submission_checkpoint_pending") throw u;
9468
- const p = this.submissionPreviews.get(r);
9469
- return p && (p.error = h), this.emit("state", this.getState()), await this.waitForSubmissionDurability(r, n) ? { result: void 0 } : null;
9456
+ const l = await a.measure("staging_ipc", async () => {
9457
+ const u = await this.enqueueOperation(async () => {
9458
+ if (d) {
9459
+ if (!await a.measure("authentication", () => this.waitForSubmissionReadiness(n))) return null;
9460
+ this.readinessPendingSubmissions.delete(r), d = !1, s = { ...s, selectionKey: this.state.selectionKey };
9461
+ }
9462
+ return this.destroyed || n !== this.submissionGeneration ? null : { result: this.adapter.dispatch({
9463
+ type: "conversation.stage",
9464
+ ...s.reconcileAcceptance ? { reconcileAcceptance: !0, selectionKey: s.selectionKey } : {},
9465
+ initiatedBy: s.initiatedBy,
9466
+ invocation: s.invocation,
9467
+ automationOnboarding: s.automationOnboarding,
9468
+ content: i,
9469
+ clientMessageId: r,
9470
+ proactiveSuggestionQuestion: s.proactiveSuggestionQuestion,
9471
+ // Preview URLs belong to the renderer's optimistic snapshot and are not valid runtime-command metadata.
9472
+ attachments: o.length > 0 ? o.map(mi) : void 0,
9473
+ submittedAt: s.submittedAt
9474
+ }) };
9475
+ });
9476
+ return u ? u.result.then((h) => ({ result: h }), async (h) => {
9477
+ const p = Y(h);
9478
+ if (p.code !== "submission_checkpoint_pending") throw h;
9479
+ const m = this.submissionPreviews.get(r);
9480
+ return m && (m.error = p), this.emit("state", this.getState()), await this.waitForSubmissionDurability(r, n) ? { result: void 0 } : null;
9470
9481
  }) : null;
9471
9482
  });
9472
- if (!d || n !== this.submissionGeneration) return null;
9473
- if (c = !0, this.submissionRetries.delete(r), d.result?.submissionAccepted) {
9483
+ if (!l || n !== this.submissionGeneration) return null;
9484
+ if (c = !0, this.submissionRetries.delete(r), l.result?.submissionAccepted) {
9474
9485
  r === this.stagedProactiveSuggestionClientMessageId && (this.stagedProactiveSuggestionClientMessageId = null);
9475
- for (const l of s.attachments ?? [])
9476
- l.id && this.attachmentFiles.delete(l.id);
9486
+ for (const u of s.attachments ?? [])
9487
+ u.id && this.attachmentFiles.delete(u.id);
9477
9488
  return r;
9478
9489
  }
9479
9490
  if (o.length > 0) {
9480
9491
  if (!this.adapter.uploadAttachment)
9481
9492
  throw new Error("The runtime does not support attachments.");
9482
- const l = [];
9483
- for (const u of o) {
9484
- if (u.sandboxPath || u.storageKey) {
9485
- l.push(u);
9493
+ const u = [];
9494
+ for (const h of o) {
9495
+ if (h.sandboxPath || h.storageKey) {
9496
+ u.push(h);
9486
9497
  continue;
9487
9498
  }
9488
- const h = u.id ? this.attachmentFiles.get(u.id) : void 0;
9489
- if (!h) throw new Error(`Attachment bytes are unavailable for ${u.name}`);
9490
- if (l.push(await a.measure("attachment_transfer", () => this.adapter.uploadAttachment(h, u, { clientMessageId: r }))), n !== this.submissionGeneration) return null;
9499
+ const p = h.id ? this.attachmentFiles.get(h.id) : void 0;
9500
+ if (!p) throw new Error(`Attachment bytes are unavailable for ${h.name}`);
9501
+ if (u.push(await a.measure("attachment_transfer", () => this.adapter.uploadAttachment(p, h, { clientMessageId: r }))), n !== this.submissionGeneration) return null;
9491
9502
  }
9492
- o = l;
9503
+ o = u;
9493
9504
  }
9494
9505
  if (n !== this.submissionGeneration || (await this.adapter.dispatch({
9495
9506
  type: "conversation.send",
@@ -9501,25 +9512,27 @@ class du {
9501
9512
  proactiveSuggestionQuestion: s.proactiveSuggestionQuestion,
9502
9513
  attachments: o.length > 0 ? o.map(mi) : void 0
9503
9514
  }), n !== this.submissionGeneration)) return null;
9504
- for (const l of s.attachments ?? [])
9505
- l.id && this.attachmentFiles.delete(l.id);
9515
+ for (const u of s.attachments ?? [])
9516
+ u.id && this.attachmentFiles.delete(u.id);
9506
9517
  return r === this.stagedProactiveSuggestionClientMessageId && (this.stagedProactiveSuggestionClientMessageId = null), r;
9507
- } catch (d) {
9518
+ } catch (l) {
9508
9519
  if (n !== this.submissionGeneration) return null;
9509
- if (Xn(d))
9510
- for (const p of s.attachments ?? [])
9511
- p.id && this.attachmentFiles.delete(p.id);
9512
- const u = Y(d).code === "command_not_received";
9513
- !c && !Xn(d) && (u || s.selectionKey !== void 0) && this.submissionRetries.set(r, {
9514
- retry: () => this.sendMessageNow(e, { ...s, reconcileAcceptance: !u }, n),
9515
- attachmentIds: (s.attachments ?? []).flatMap((p) => p.id ? [p.id] : [])
9520
+ if (Xn(l))
9521
+ for (const m of s.attachments ?? [])
9522
+ m.id && this.attachmentFiles.delete(m.id);
9523
+ const h = Y(l).code === "command_not_received";
9524
+ !c && !Xn(l) && (d || h || s.selectionKey !== void 0) && this.submissionRetries.set(r, {
9525
+ retry: async () => (d && await this.connect(), this.sendMessageNow(e, { ...s, reconcileAcceptance: !d && !h }, n)),
9526
+ attachmentIds: (s.attachments ?? []).flatMap((m) => m.id ? [m.id] : [])
9516
9527
  });
9517
- const h = this.submissionPreviews.get(r);
9518
- throw h && (h.pending = !1, h.error = Y(d), this.emit("state", this.getState())), c && await this.adapter.dispatch({
9528
+ const p = this.submissionPreviews.get(r);
9529
+ throw p && (p.pending = !1, p.error = Y(l), this.emit("state", this.getState())), c && await this.adapter.dispatch({
9519
9530
  type: "conversation.fail_staged",
9520
9531
  clientMessageId: r,
9521
- message: Y(d).message
9522
- }), d;
9532
+ message: Y(l).message
9533
+ }), l;
9534
+ } finally {
9535
+ this.readinessPendingSubmissions.delete(r);
9523
9536
  }
9524
9537
  }
9525
9538
  getModel() {
@@ -9555,7 +9568,10 @@ class du {
9555
9568
  }
9556
9569
  stop() {
9557
9570
  if (this.pendingStop) return this.pendingStop.promise;
9558
- const e = this.getState(), s = this.cancelPendingSubmissions(!1), n = [...new Set([
9571
+ const e = this.getState(), s = this.cancelPendingSubmissions(!1);
9572
+ if (!this.hasBeenReady && s.length > 0 && !this.state.isThinking && this.state.turnPhase === null && this.state.pendingMessageStatus === null)
9573
+ return this.emit("state", this.getState()), Promise.resolve();
9574
+ const n = [...new Set([
9559
9575
  ...s,
9560
9576
  e.activeResponseUserMessageId,
9561
9577
  e.messages.filter((d) => d.role === "user").slice(-1)[0]?.id
@@ -9588,6 +9604,26 @@ class du {
9588
9604
  }), c.then(() => {
9589
9605
  });
9590
9606
  }
9607
+ async waitForSubmissionReadiness(e) {
9608
+ let s = () => {
9609
+ }, n = () => {
9610
+ };
9611
+ return new Promise((i, r) => {
9612
+ n = () => {
9613
+ if (this.destroyed || e !== this.submissionGeneration) {
9614
+ i(!1);
9615
+ return;
9616
+ }
9617
+ if (this.state.lastError && ["connection_failed", "unauthorized", "update_required"].includes(this.state.lastErrorCode ?? "")) {
9618
+ r(Object.assign(new Error(this.state.lastError), { code: this.state.lastErrorCode }));
9619
+ return;
9620
+ }
9621
+ this.hasBeenReady && this.state.submissionReady !== !1 && i(!0);
9622
+ }, this.durabilityWaiters.add(n), s = this.on("state", n), n();
9623
+ }).finally(() => {
9624
+ s(), this.durabilityWaiters.delete(n);
9625
+ });
9626
+ }
9591
9627
  async waitForSubmissionDurability(e, s) {
9592
9628
  let n = () => {
9593
9629
  }, i = () => {
@@ -76,7 +76,7 @@ function Qp(t, e, n, i) {
76
76
  function Yp(t) {
77
77
  return Fr(t) > 0.5 ? [24, 24, 27] : [250, 250, 249];
78
78
  }
79
- const Xp = "0.1.283", ci = {
79
+ const Xp = "0.1.284", ci = {
80
80
  version: Xp
81
81
  }, me = (t) => typeof t == "string" && /^[a-zA-Z0-9:_.-]{1,160}$/.test(t) ? t : null;
82
82
  function Md(t) {
@@ -708,6 +708,7 @@ function fn(t, e, n) {
708
708
  return Ge({
709
709
  historyRefreshFailure: o?.historyRefreshFailure ?? null,
710
710
  selectionKey: n ? JSON.stringify([t.authorityId, t.generation, n]) : void 0,
711
+ stableSelectionKey: n ? JSON.stringify([t.authorityId, n]) : void 0,
711
712
  isDraftSession: B,
712
713
  proactiveQuestion: t.proactiveQuestions[n] ?? null,
713
714
  sessionId: s,
@@ -4176,6 +4177,7 @@ function dr(t, e, n, i) {
4176
4177
  },
4177
4178
  historyPreparation: t.preparation ?? null,
4178
4179
  selectionKey: t.selectionKey,
4180
+ stableSelectionKey: t.stableSelectionKey,
4179
4181
  isDraftSession: t.isDraftSession,
4180
4182
  sessionId: t.sessionId,
4181
4183
  messages: f,
@@ -14676,7 +14678,7 @@ async function _w(t = {}) {
14676
14678
  observedConversation: null,
14677
14679
  observedWelcome: null,
14678
14680
  pendingSubmission: !0
14679
- }, Ei()) {
14681
+ }, Ei() && !e.runtimeClient) {
14680
14682
  tn = R;
14681
14683
  return;
14682
14684
  }
@@ -195,6 +195,7 @@ export declare class ProductAgentRemoteRuntimeClient implements ProductAgentRunt
195
195
  private interactions;
196
196
  private account;
197
197
  private stagedProactiveSuggestionClientMessageId;
198
+ private readonly readinessPendingSubmissions;
198
199
  private readonly pendingTransfers;
199
200
  private readonly submissionPreviews;
200
201
  private readonly submissionRetries;
@@ -205,6 +206,7 @@ export declare class ProductAgentRemoteRuntimeClient implements ProductAgentRunt
205
206
  private readonly durabilityWaiters;
206
207
  private operationQueue;
207
208
  private destroyed;
209
+ private hasBeenReady;
208
210
  constructor(initialState: ProductAgentState, adapter: ProductAgentRuntimeClientAdapter, model?: ProductAgentModel);
209
211
  on<T extends ProductAgentRuntimeEventName>(eventName: T, listener: (payload: ProductAgentEventMap[T]) => void): () => void;
210
212
  getState(): ProductAgentState;
@@ -233,6 +235,7 @@ export declare class ProductAgentRemoteRuntimeClient implements ProductAgentRunt
233
235
  retryLastMessage(userMessageId?: string): Promise<boolean>;
234
236
  createLocalAttachment(file: File): ProductAgentAttachment;
235
237
  stop(): Promise<void>;
238
+ private waitForSubmissionReadiness;
236
239
  private waitForSubmissionDurability;
237
240
  private cancelPendingSubmissions;
238
241
  startNewSession(options?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluno/product-agent-web",
3
- "version": "0.1.283",
3
+ "version": "0.1.284",
4
4
  "description": "Browser SDK and default widget for embedding Pluno Product Agent into customer web apps.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",