@artooi/ag-ui-web-component 0.42.0 → 0.43.0

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.
@@ -518,9 +518,12 @@ export declare class AgUiChat extends HTMLElement {
518
518
  * History is truncated to the most recent user message inclusive and the run
519
519
  * repeats, so the agent answers what it was asked rather than being told its
520
520
  * last answer was wrong. Returns `false` when there is nothing to retry, or
521
- * while anything that refuses a send is in flight: a run, a send or another
521
+ * while anything that holds a send is in flight: a run, a send or another
522
522
  * retry whose run has not started yet, a checkpoint continuation, or a
523
- * reload's restore that will resume a run. Also `false` when host code it
523
+ * restore of the stored conversation that is still loading. It does not wait
524
+ * for a restore as a send does: nothing is on screen to retry yet, and after
525
+ * the load it would re-ask the previous visit's last question. Also `false`
526
+ * when host code it
524
527
  * runs before its run starts -- the store's save, or an activity or tool
525
528
  * renderer the replay draws through -- has stopped it by starting a new chat
526
529
  * or changing `user-key`. A tool or context provider that stops it does so
@@ -560,16 +563,41 @@ export declare class AgUiChat extends HTMLElement {
560
563
  * `attachments` are durable {@link AttachmentRef}s — what {@link attachFile}
561
564
  * resolves to and what {@link ATTACHMENT_EVENT} reports.
562
565
  *
563
- * No-ops on an empty message, and while a run or a picked checkpoint's
564
- * continuation is in flight, since a second concurrent run would orphan the
565
- * first. A send is in flight from the moment it is taken rather than from
566
- * its run's start, so this no-ops from a {@link SUBMIT_EVENT} listener and
567
- * for a second call in the same task too.
566
+ * Resolves `true` once the turn has been handed to the client for its run,
567
+ * which is when the interaction settles, frontend-tool rounds included; a
568
+ * run a tool or context provider then stops still counts, as it does for
569
+ * {@link retryLastTurn}. Resolves `false` when nothing was sent.
570
+ *
571
+ * Nothing is sent for an empty message, nor while a run or a picked
572
+ * checkpoint's continuation is in flight, since a second concurrent run
573
+ * would orphan the first. A send is in flight from the moment it is taken
574
+ * rather than from its run's start, so nothing is sent from a
575
+ * {@link SUBMIT_EVENT} listener or for a second call in the same task
576
+ * either. Nor with no `endpoint`, which says so in the transcript. Nor
577
+ * behind a reload's restore that will resume a run a navigating tool
578
+ * interrupted, since that restore ends by starting the run.
579
+ *
580
+ * **While the element restores a stored conversation with no run to resume
581
+ * -- on connect, {@link reload}, a thread picked from the drawer, a change
582
+ * from one `user-key` to another -- it waits, then sends.** The turn has to follow the
583
+ * conversation it is part of: sent at once, it went out without it, the
584
+ * conversation was then drawn under it, and its save replaced the stored
585
+ * one. So the bubble, the {@link SUBMIT_EVENT} and the request all come after
586
+ * the replay, by the length of the store's load. A New chat, a thread
587
+ * switch, a change from one `user-key` to another, a reload or the element
588
+ * leaving the page while it waits drops it, resolving `false`: the
589
+ * conversation it was addressed to is no longer on screen. Leaving the page
590
+ * resolves it only once the load answers or the element is back, since
591
+ * that is when the restore learns it was stopped. A first `user-key` on an
592
+ * anonymous conversation adopts it rather than replacing it, and stops
593
+ * nothing. A second call while one waits is
594
+ * refused, as a second call in the same task is.
595
+ *
568
596
  * Unlike the built-in Send it does not queue: it returns, and the caller
569
597
  * keeps what it tried to send. Nor does it consult the tray -- what you pass
570
598
  * is what is sent.
571
599
  */
572
- sendMessage(content: string, attachments?: readonly AttachmentRef[]): Promise<void>;
600
+ sendMessage(content: string, attachments?: readonly AttachmentRef[]): Promise<boolean>;
573
601
  /**
574
602
  * Queue a file for upload into the attachment tray, exactly as the file
575
603
  * picker and drag-and-drop do — validation, progress chip, and all.
@@ -1 +1 @@
1
- {"version":3,"file":"ag_ui_chat.d.ts","sourceRoot":"","sources":["../../src/core/ag_ui_chat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ag_ui_chat.d.ts","sourceRoot":"","sources":["../../src/core/ag_ui_chat.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -987,6 +987,7 @@ var DEFAULT_UI_STRINGS = {
987
987
  notConnected: "This chat isn\u2019t connected to an agent, so the message wasn\u2019t sent.",
988
988
  continueNeedsTurn: "Type the next turn in the composer first, then pick a run to continue.",
989
989
  continueWhileRunning: "Wait for the current answer or stop it, then pick a run to continue.",
990
+ continueWhileLoading: "Wait for the conversation to finish loading, then pick a run to continue.",
990
991
  skillNeeds: "\u201C{title}\u201D needs {fields} \u2014 fill it in below, then send.",
991
992
  message: "Message",
992
993
  inputPlaceholder: "Ask anything\u2026",
@@ -1736,13 +1737,17 @@ var ToolDispatch = class {
1736
1737
  * check that it has not. A Stop while the host's predicate is pending ends
1737
1738
  * the call there, and one while the card is open declines it. A handover
1738
1739
  * during any of the three leaves the call with no transcript to draw in and
1739
- * no store to write to, so it does neither.
1740
+ * no store to write to, so it does neither. Any other reset of the
1741
+ * conversation -- New chat, a drawer switch, `reload()` -- leaves the call
1742
+ * its store and its result but not the transcript, so it still settles and
1743
+ * returns, and does not show the run waiting in a conversation it is not in.
1740
1744
  */
1741
1745
  async execute(call) {
1742
1746
  if (skillNameFrom(call) !== null) {
1743
1747
  return null;
1744
1748
  }
1745
1749
  const tenure = this.#host.tenure();
1750
+ const conversation = this.#host.conversation();
1746
1751
  const threadId = this.#host.threadId();
1747
1752
  const card = this.#host.transcript.cardFor(call);
1748
1753
  this.#host.transcript.forgetCard(call.id);
@@ -1796,7 +1801,9 @@ var ToolDispatch = class {
1796
1801
  if (!accepted) {
1797
1802
  const message = this.#host.strings().declinedAction;
1798
1803
  card.settle(TOOL_CALL_STATUS.DECLINED, message);
1799
- this.#host.transcript.showPending();
1804
+ if (this.#host.conversation() === conversation) {
1805
+ this.#host.transcript.showPending();
1806
+ }
1800
1807
  return { content: message, outcome: TOOL_OUTCOME.DENIED };
1801
1808
  }
1802
1809
  if (signal.aborted) {
@@ -1821,7 +1828,9 @@ var ToolDispatch = class {
1821
1828
  }
1822
1829
  const content = JSON.stringify(result ?? null);
1823
1830
  card.settle(TOOL_CALL_STATUS.DONE, content);
1824
- this.#host.transcript.showPending();
1831
+ if (this.#host.conversation() === conversation) {
1832
+ this.#host.transcript.showPending();
1833
+ }
1825
1834
  return { content };
1826
1835
  } catch (error) {
1827
1836
  if (this.#host.tenure() !== tenure) {
@@ -1832,7 +1841,9 @@ var ToolDispatch = class {
1832
1841
  }
1833
1842
  const message = error instanceof Error ? error.message : String(error);
1834
1843
  card.settle(TOOL_CALL_STATUS.ERROR, message);
1835
- this.#host.transcript.showPending();
1844
+ if (this.#host.conversation() === conversation) {
1845
+ this.#host.transcript.showPending();
1846
+ }
1836
1847
  return { content: `Error: ${message}`, error: message, outcome: TOOL_OUTCOME.FAILED };
1837
1848
  }
1838
1849
  }
@@ -3073,6 +3084,8 @@ var VoiceInput = class {
3073
3084
  #capTimer = null;
3074
3085
  #hitCap = false;
3075
3086
  #disposed = false;
3087
+ /** Identifies the newest start; an older one that settles is stale. */
3088
+ #startToken = {};
3076
3089
  constructor(options) {
3077
3090
  this.#transcribe = options.transcribe;
3078
3091
  this.#onText = options.onText;
@@ -3102,31 +3115,42 @@ var VoiceInput = class {
3102
3115
  await this.#start();
3103
3116
  }
3104
3117
  async #start() {
3118
+ const token = {};
3119
+ this.#startToken = token;
3105
3120
  let stream;
3106
3121
  try {
3107
3122
  stream = await navigator.mediaDevices.getUserMedia({ audio: true });
3108
3123
  } catch {
3109
- this.#fail(this.#strings.transcriptionFailed);
3110
- return;
3124
+ stream = null;
3111
3125
  }
3112
- if (this.#disposed) {
3113
- for (const track of stream.getTracks()) {
3126
+ if (token !== this.#startToken || this.#disposed) {
3127
+ for (const track of stream?.getTracks() ?? []) {
3114
3128
  track.stop();
3115
3129
  }
3116
3130
  return;
3117
3131
  }
3132
+ if (stream === null) {
3133
+ this.#fail(this.#strings.transcriptionFailed);
3134
+ return;
3135
+ }
3118
3136
  this.#stream = stream;
3119
3137
  this.#chunks = [];
3120
3138
  this.#hitCap = false;
3121
- const recorder = new MediaRecorder(stream);
3122
- recorder.addEventListener("dataavailable", (event) => {
3123
- this.#chunks.push(event.data);
3124
- });
3125
- recorder.addEventListener("stop", () => {
3126
- void this.#finish(recorder.mimeType);
3127
- });
3128
- this.#recorder = recorder;
3129
- recorder.start();
3139
+ let recorder;
3140
+ try {
3141
+ recorder = new MediaRecorder(stream);
3142
+ recorder.addEventListener("dataavailable", (event) => {
3143
+ this.#chunks.push(event.data);
3144
+ });
3145
+ recorder.addEventListener("stop", () => {
3146
+ void this.#finish(recorder.mimeType);
3147
+ });
3148
+ this.#recorder = recorder;
3149
+ recorder.start();
3150
+ } catch {
3151
+ this.#fail(this.#strings.transcriptionFailed);
3152
+ return;
3153
+ }
3130
3154
  this.#capTimer = setTimeout(() => {
3131
3155
  this.#hitCap = true;
3132
3156
  this.#stop();
@@ -3152,8 +3176,8 @@ var VoiceInput = class {
3152
3176
  * a detached element.
3153
3177
  *
3154
3178
  * Disposal is final: nothing un-disposes an instance, and the host's next
3155
- * wiring builds a new one. So the disposed flag alone tells a stale
3156
- * continuation from a live one, and a clip already posted when this runs is
3179
+ * wiring builds a new one. So the disposed flag alone tells a continuation
3180
+ * that outlived the control from a live one, and a clip already posted when this runs is
3157
3181
  * dropped whenever its answer arrives.
3158
3182
  */
3159
3183
  dispose() {
@@ -4166,8 +4190,6 @@ function toolStatusFromOutcome(outcome) {
4166
4190
  }
4167
4191
 
4168
4192
  // src/ui/history/conversation_history.ts
4169
- var UNHELD = Object.freeze({ release: () => {
4170
- } });
4171
4193
  var ConversationHistory = class {
4172
4194
  #host;
4173
4195
  /** The active thread's id. Empty until the element connects. */
@@ -4204,6 +4226,17 @@ var ConversationHistory = class {
4204
4226
  * reaches it. `null` when none is running.
4205
4227
  */
4206
4228
  #continuation = null;
4229
+ /**
4230
+ * Settles what a host's send waits on while the restore now current, one
4231
+ * with no run to resume, loads and replays; `null` when no such restore is
4232
+ * under way. Called when that restore ends, and as soon as it is stopped by
4233
+ * anything that moves the generation, so a send waiting on a conversation
4234
+ * that is no longer on screen hears so at once rather than when an
4235
+ * abandoned load answers.
4236
+ *
4237
+ * Also what tells a pick refused for a load from one refused for a run.
4238
+ */
4239
+ #loading = null;
4207
4240
  constructor(host) {
4208
4241
  this.#host = host;
4209
4242
  }
@@ -4245,6 +4278,13 @@ var ConversationHistory = class {
4245
4278
  this.#restored = [];
4246
4279
  this.#cleared += 1;
4247
4280
  this.#generation += 1;
4281
+ this.#endWait();
4282
+ }
4283
+ /** Settle what waits on the restore now loading, if anything does, and forget it. */
4284
+ #endWait() {
4285
+ const end = this.#loading;
4286
+ this.#loading = null;
4287
+ end?.();
4248
4288
  }
4249
4289
  /** Delete the active thread if nothing was ever sent in it. */
4250
4290
  reapUnsent() {
@@ -4349,7 +4389,10 @@ var ConversationHistory = class {
4349
4389
  return;
4350
4390
  }
4351
4391
  if (this.#host.running() || this.#continuation !== null) {
4352
- this.#refuse(this.#host.strings().continueWhileRunning);
4392
+ const strings = this.#host.strings();
4393
+ this.#refuse(
4394
+ this.#loading === null ? strings.continueWhileRunning : strings.continueWhileLoading
4395
+ );
4353
4396
  return;
4354
4397
  }
4355
4398
  const content = this.#host.input.value.trim();
@@ -4435,16 +4478,30 @@ var ConversationHistory = class {
4435
4478
  * exclusion is held by "resumes with the landed page's result, and its card says
4436
4479
  * so" in `ag_ui_chat_reload_mid_run.test.ts`.
4437
4480
  *
4438
- * **A restore that resumes holds the composer from before the load.** The
4439
- * resume is a run, and it starts only once the store has answered. With a
4440
- * remote store that is a real request, and a send, a Retry or a pick in it
4441
- * was refused by nothing: each built the conversation's client before the
4442
- * conversation had loaded, so a send went out carrying none of it and its
4443
- * first save replaced the stored one, and the resume then ran on that same
4444
- * client as a second run, answering a call the request no longer held. So
4445
- * the composer is held as a send holds it, and the resume gives way to
4446
- * nothing: what was typed parks behind the resumed run and goes out after its
4447
- * answer, and a host's send or Retry is refused as it is behind any run.
4481
+ * **Every restore holds the composer from before the load.** Until the
4482
+ * store answers, the conversation's client can only be seeded from nothing.
4483
+ * With a remote store that is a real request, and a send, a Retry or a pick
4484
+ * in it was refused by nothing: each built the conversation's client before
4485
+ * the conversation had loaded, so a send went out carrying none of it, its
4486
+ * first save replaced the stored one, and the replay then drew the stored
4487
+ * conversation under the new turn. The client stayed cached without it, so
4488
+ * every later turn went out without it too. So the composer is held as a
4489
+ * send holds it: what was typed parks and goes out after the replay, and a
4490
+ * Retry and a pick are refused -- a Retry has nothing on screen to retry, and
4491
+ * after the load it would re-ask the previous visit's last question.
4492
+ *
4493
+ * **A host's send waits for a restore with no run to resume.** It is
4494
+ * usually a prompt fired as the element mounts, which no host could time
4495
+ * against a load nothing announces, and refusing it would lose the turn.
4496
+ * So it waits for this restore to end, taking the hold over as it does,
4497
+ * and then sends with the conversation drawn above it; what the built-in
4498
+ * Send parked goes out after its run. Stopped while it waits, it is dropped,
4499
+ * as a send stopped by its own submit listener is.
4500
+ *
4501
+ * **A restore that resumes refuses a host's send instead.** The resume is a
4502
+ * run, and the restore ends by starting it, so a send that waited would only
4503
+ * reach that run and be refused there. The resume gives way to nothing: what
4504
+ * was typed parks behind the resumed run and goes out after its answer.
4448
4505
  *
4449
4506
  * The other way round, the resume standing down for the send, was rejected.
4450
4507
  * The send that got in first had already gone out without the conversation,
@@ -4457,8 +4514,8 @@ var ConversationHistory = class {
4457
4514
  * page can each come while the store answers, and from host code the restore
4458
4515
  * runs itself: the activity and tool renderers each replayed message draws
4459
4516
  * through, and `navigationResult`. From then on it draws nothing more and
4460
- * resumes nothing. The hold cannot say so, because a restore with no run to
4461
- * resume holds nothing. So the restore asks its generation, which clearing
4517
+ * resumes nothing. The hold cannot say so, because a host's send that
4518
+ * waited may hold it by then. So the restore asks its generation, which clearing
4462
4519
  * the conversation moves on as a newer restore does, and asks it after the
4463
4520
  * load, after each replayed message -- as a Retry asks after each one -- and
4464
4521
  * once more before the resume. Stopped by anything but the element leaving
@@ -4466,10 +4523,6 @@ var ConversationHistory = class {
4466
4523
  * for the run it would have resumed -- unless what replaced it is a restore
4467
4524
  * of the same conversation, still current, which answers for that run
4468
4525
  * instead; see `#forgetStopped`.
4469
- *
4470
- * What a restore with no run to resume still does not do is refuse a send
4471
- * made while it loads. That send goes out without the stored conversation,
4472
- * and its save replaces it.
4473
4526
  */
4474
4527
  async rehydrate() {
4475
4528
  this.#generation += 1;
@@ -4478,7 +4531,11 @@ var ConversationHistory = class {
4478
4531
  const store = this.#host.conversationStore();
4479
4532
  this.#claim = { generation, store, threadId };
4480
4533
  const checkpoint = store.loadCheckpoint(threadId);
4481
- const hold = checkpoint === null ? UNHELD : this.#host.holdRun();
4534
+ const restored = checkpoint === null ? new Promise((resolve) => {
4535
+ this.#loading = resolve;
4536
+ }) : null;
4537
+ const waiting = this.#loading;
4538
+ const hold = this.#host.holdRun(restored);
4482
4539
  try {
4483
4540
  this.#host.element.setAttribute("data-restoring", "");
4484
4541
  let messages;
@@ -4495,7 +4552,7 @@ var ConversationHistory = class {
4495
4552
  }
4496
4553
  if (messages !== null) {
4497
4554
  const unfinished = this.#host.strings().callNotFinished;
4498
- const restored = answerUnansweredCalls(
4555
+ const restored2 = answerUnansweredCalls(
4499
4556
  messages,
4500
4557
  // The shape the store holds for a call the client answered the same
4501
4558
  // way: its tool message, with the outcome in its metadata.
@@ -4508,8 +4565,8 @@ var ConversationHistory = class {
4508
4565
  }),
4509
4566
  new Set(checkpoint === null ? [] : [checkpoint.toolCallId])
4510
4567
  );
4511
- this.#restored = restored;
4512
- for (const message of restored) {
4568
+ this.#restored = restored2;
4569
+ for (const message of restored2) {
4513
4570
  this.replay(message);
4514
4571
  if (!this.#restoring(generation)) {
4515
4572
  this.#forgetStopped(store, threadId, checkpoint);
@@ -4524,6 +4581,9 @@ var ConversationHistory = class {
4524
4581
  this.#noticeIfRunUnfinished(messages);
4525
4582
  } finally {
4526
4583
  hold.release();
4584
+ if (this.#loading === waiting) {
4585
+ this.#endWait();
4586
+ }
4527
4587
  }
4528
4588
  }
4529
4589
  /**
@@ -17124,6 +17184,26 @@ var AgUiChat = class extends HTMLElement {
17124
17184
  * conversation the handover purged.
17125
17185
  */
17126
17186
  #tenure = {};
17187
+ /**
17188
+ * The conversation on screen: replaced every time the transcript is cleared
17189
+ * for another one -- New chat, a drawer switch, deleting the active thread,
17190
+ * `reload()`, re-insertion and a handover all pass through
17191
+ * {@link #resetConversation} -- and captured by each frontend tool call as it
17192
+ * is dispatched, so the call can tell whether the conversation it was drawn
17193
+ * in is still the one showing.
17194
+ *
17195
+ * A call outlives the reset that stops its run. A handler cannot be aborted,
17196
+ * and a card open at the time is declined, so the call resumes once the new
17197
+ * conversation is showing; drawing the run's pending indicator then put it
17198
+ * in a conversation with no run to take it down.
17199
+ *
17200
+ * Not {@link #tenure}, which only a handover replaces. A reset is not a
17201
+ * change of principal: the call still belongs to someone this element
17202
+ * serves, so it still settles its card, clears its checkpoint and returns
17203
+ * its result, and only the drawing is skipped. The tenure checks end the
17204
+ * call before any of that.
17205
+ */
17206
+ #conversation = {};
17127
17207
  /**
17128
17208
  * The remote store `data-threads-url` wrapped around the conversation store,
17129
17209
  * and the store inside it, so connecting again can wrap that store rather
@@ -17154,9 +17234,9 @@ var AgUiChat = class extends HTMLElement {
17154
17234
  * requests, and the listener's turn drawn between the user's turn and its
17155
17235
  * answer. It is the gap a picked checkpoint closes by counting from the pick,
17156
17236
  * closed the same way for a send. A retry asks for its run the same way, so
17157
- * it takes the same hold, and so does a restore that will resume a run, from
17158
- * before it asks the store for the conversation, through the history host's
17159
- * `holdRun`.
17237
+ * it takes the same hold, and so does every restore, from before it asks the
17238
+ * store for the conversation, through the history host's `holdRun`: until
17239
+ * the store answers, the client can only be built from nothing.
17160
17240
  *
17161
17241
  * Let go of once the run starts, because `running` holds from then until the
17162
17242
  * run settles, and a send held past that would refuse a host's follow-up from
@@ -17166,9 +17246,18 @@ var AgUiChat = class extends HTMLElement {
17166
17246
  * An object rather than a flag, so a send or a retry ending releases only
17167
17247
  * what it took. By the time either ends, the turn queued behind it has
17168
17248
  * usually taken the field for itself, and a Stop lets go of it for the next
17169
- * send to take; the earlier one ending must release neither.
17249
+ * send to take; the earlier one ending must release neither. It is also how
17250
+ * {@link sendMessage} tells the one hold it waits on from all the others it
17251
+ * refuses behind: see {@link #restoreHold}.
17170
17252
  */
17171
17253
  #sending = null;
17254
+ /**
17255
+ * The hold the latest restore with no run to resume took, and what settles
17256
+ * once that restore has ended or been stopped; `null` when the latest
17257
+ * restore will resume a run. Only meaningful while `#sending` is that hold:
17258
+ * then a host's {@link sendMessage} waits for it rather than refusing.
17259
+ */
17260
+ #restoreHold = null;
17172
17261
  /** The decision a run is suspended on, which a Stop abandons. */
17173
17262
  #decision = new PendingDecision();
17174
17263
  /**
@@ -17261,7 +17350,9 @@ var AgUiChat = class extends HTMLElement {
17261
17350
  threadId: () => this.#history.threadId,
17262
17351
  // Read live and compared, the way each client compares the one it was
17263
17352
  // built with: see #tenure.
17264
- tenure: () => this.#tenure
17353
+ tenure: () => this.#tenure,
17354
+ // The same, for the conversation on screen: see #conversation.
17355
+ conversation: () => this.#conversation
17265
17356
  });
17266
17357
  this.#runHandlers = new RunHandlers({
17267
17358
  element: this,
@@ -17409,25 +17500,29 @@ var AgUiChat = class extends HTMLElement {
17409
17500
  // A held send or retry is as much in flight to a pick as a run is: it has
17410
17501
  // asked this element's client for a run that has not started, and a
17411
17502
  // continuation started beside it was a second run in one conversation.
17412
- // So is a restore that will resume a run, which holds through the same
17413
- // field from before the store answers.
17503
+ // So is a restore, which holds through the same field from before the
17504
+ // store answers.
17414
17505
  running: () => this.#running || this.#sending !== null,
17415
- // The hold a send takes, taken for a restore that will resume a run, so
17416
- // what refuses a send held short of its run refuses one made while the
17417
- // store is still answering: `sendMessage` returns, Send parks the turn,
17418
- // a Retry and a pick refuse. The same field rather than a flag beside it,
17419
- // because what lets go of a send's hold is right for this one too. The
17420
- // resumed run starting lets go, in `#setRunning`, so there is no gap
17421
- // after the resume is asked for, and a Stop does, in `#cancelRun`. A flag
17422
- // the restore cleared itself would still be set when the resumed run
17423
- // settles and sends the parked turn, so that send would be refused after
17424
- // the turn had left the queue, and lost.
17506
+ // The hold a send takes, taken for every restore, so what refuses a send
17507
+ // held short of its run holds one made while the store is still
17508
+ // answering: Send parks the turn, a Retry and a pick refuse, and
17509
+ // `sendMessage` refuses behind a restore that will resume a run and waits
17510
+ // for one that will not -- `restored` is what it waits on, given only for
17511
+ // that kind. The same field rather than a flag beside it, because what
17512
+ // lets go of a send's hold is right for this one too. The resumed run
17513
+ // starting lets go, in `#setRunning`, so there is no gap after the resume
17514
+ // is asked for, and a Stop does, in `#cancelRun`. A flag the restore
17515
+ // cleared itself would still be set when the resumed run settles and
17516
+ // sends the parked turn, so that send would be refused after the turn had
17517
+ // left the queue, and lost.
17425
17518
  //
17426
- // Whether the restore was stopped is not read off this hold, because one
17427
- // with nothing to resume takes none; the restore asks its own generation.
17428
- holdRun: () => {
17519
+ // Whether the restore was stopped is not read off this hold, because a
17520
+ // host's send that waited takes it over; the restore asks its own
17521
+ // generation.
17522
+ holdRun: (restored) => {
17429
17523
  const hold = {};
17430
17524
  this.#sending = hold;
17525
+ this.#restoreHold = restored === null ? null : { hold, restored };
17431
17526
  return {
17432
17527
  release: () => {
17433
17528
  if (this.#sending === hold) {
@@ -18247,6 +18342,7 @@ var AgUiChat = class extends HTMLElement {
18247
18342
  #resetConversation() {
18248
18343
  this.#client = null;
18249
18344
  this.#runHandlers.detach();
18345
+ this.#conversation = {};
18250
18346
  this.#clearTranscript();
18251
18347
  this.#history.forgetRestored();
18252
18348
  }
@@ -18275,9 +18371,12 @@ var AgUiChat = class extends HTMLElement {
18275
18371
  * History is truncated to the most recent user message inclusive and the run
18276
18372
  * repeats, so the agent answers what it was asked rather than being told its
18277
18373
  * last answer was wrong. Returns `false` when there is nothing to retry, or
18278
- * while anything that refuses a send is in flight: a run, a send or another
18374
+ * while anything that holds a send is in flight: a run, a send or another
18279
18375
  * retry whose run has not started yet, a checkpoint continuation, or a
18280
- * reload's restore that will resume a run. Also `false` when host code it
18376
+ * restore of the stored conversation that is still loading. It does not wait
18377
+ * for a restore as a send does: nothing is on screen to retry yet, and after
18378
+ * the load it would re-ask the previous visit's last question. Also `false`
18379
+ * when host code it
18281
18380
  * runs before its run starts -- the store's save, or an activity or tool
18282
18381
  * renderer the replay draws through -- has stopped it by starting a new chat
18283
18382
  * or changing `user-key`. A tool or context provider that stops it does so
@@ -18798,18 +18897,57 @@ var AgUiChat = class extends HTMLElement {
18798
18897
  * `attachments` are durable {@link AttachmentRef}s — what {@link attachFile}
18799
18898
  * resolves to and what {@link ATTACHMENT_EVENT} reports.
18800
18899
  *
18801
- * No-ops on an empty message, and while a run or a picked checkpoint's
18802
- * continuation is in flight, since a second concurrent run would orphan the
18803
- * first. A send is in flight from the moment it is taken rather than from
18804
- * its run's start, so this no-ops from a {@link SUBMIT_EVENT} listener and
18805
- * for a second call in the same task too.
18900
+ * Resolves `true` once the turn has been handed to the client for its run,
18901
+ * which is when the interaction settles, frontend-tool rounds included; a
18902
+ * run a tool or context provider then stops still counts, as it does for
18903
+ * {@link retryLastTurn}. Resolves `false` when nothing was sent.
18904
+ *
18905
+ * Nothing is sent for an empty message, nor while a run or a picked
18906
+ * checkpoint's continuation is in flight, since a second concurrent run
18907
+ * would orphan the first. A send is in flight from the moment it is taken
18908
+ * rather than from its run's start, so nothing is sent from a
18909
+ * {@link SUBMIT_EVENT} listener or for a second call in the same task
18910
+ * either. Nor with no `endpoint`, which says so in the transcript. Nor
18911
+ * behind a reload's restore that will resume a run a navigating tool
18912
+ * interrupted, since that restore ends by starting the run.
18913
+ *
18914
+ * **While the element restores a stored conversation with no run to resume
18915
+ * -- on connect, {@link reload}, a thread picked from the drawer, a change
18916
+ * from one `user-key` to another -- it waits, then sends.** The turn has to follow the
18917
+ * conversation it is part of: sent at once, it went out without it, the
18918
+ * conversation was then drawn under it, and its save replaced the stored
18919
+ * one. So the bubble, the {@link SUBMIT_EVENT} and the request all come after
18920
+ * the replay, by the length of the store's load. A New chat, a thread
18921
+ * switch, a change from one `user-key` to another, a reload or the element
18922
+ * leaving the page while it waits drops it, resolving `false`: the
18923
+ * conversation it was addressed to is no longer on screen. Leaving the page
18924
+ * resolves it only once the load answers or the element is back, since
18925
+ * that is when the restore learns it was stopped. A first `user-key` on an
18926
+ * anonymous conversation adopts it rather than replacing it, and stops
18927
+ * nothing. A second call while one waits is
18928
+ * refused, as a second call in the same task is.
18929
+ *
18806
18930
  * Unlike the built-in Send it does not queue: it returns, and the caller
18807
18931
  * keeps what it tried to send. Nor does it consult the tray -- what you pass
18808
18932
  * is what is sent.
18809
18933
  */
18810
18934
  async sendMessage(content, attachments = []) {
18811
- if (this.#running || this.#sending !== null || this.#history.continuation !== null || content === "" && attachments.length === 0) {
18812
- return;
18935
+ if (content === "" && attachments.length === 0) {
18936
+ return false;
18937
+ }
18938
+ const restore = this.#restoreHold;
18939
+ if (restore !== null && this.#sending === restore.hold) {
18940
+ const waiting = {};
18941
+ this.#sending = waiting;
18942
+ await restore.restored;
18943
+ if (this.#sending !== waiting) {
18944
+ return false;
18945
+ }
18946
+ this.#sending = null;
18947
+ return this.sendMessage(content, attachments);
18948
+ }
18949
+ if (this.#running || this.#sending !== null || this.#history.continuation !== null) {
18950
+ return false;
18813
18951
  }
18814
18952
  const send = {};
18815
18953
  this.#sending = send;
@@ -18819,9 +18957,11 @@ var AgUiChat = class extends HTMLElement {
18819
18957
  }
18820
18958
  this.#announceTurn(content, attachments);
18821
18959
  if (this.#sending !== send) {
18822
- return;
18960
+ return false;
18823
18961
  }
18962
+ const connected = this.endpoint !== "";
18824
18963
  await this.#client_send(content, attachments);
18964
+ return connected;
18825
18965
  } finally {
18826
18966
  if (this.#sending === send) {
18827
18967
  this.#sending = null;
@@ -19137,7 +19277,7 @@ function setControlValue(el2, value) {
19137
19277
  }
19138
19278
 
19139
19279
  // src/version.ts
19140
- var VERSION = "0.42.0";
19280
+ var VERSION = "0.43.0";
19141
19281
  export {
19142
19282
  ATTACHMENT_EVENT,
19143
19283
  AgUiChat,