@artooi/ag-ui-web-component 0.46.0 → 0.47.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +87 -1
  2. package/README.md +130 -19
  3. package/dist/ag-ui-web-component.bundle.js +99 -94
  4. package/dist/ag-ui-web-component.bundle.js.map +4 -4
  5. package/dist/constants.d.ts +10 -0
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/core/ag_ui_chat.d.ts +38 -0
  8. package/dist/core/ag_ui_chat.d.ts.map +1 -1
  9. package/dist/core/chat_registry.d.ts +23 -0
  10. package/dist/core/chat_registry.d.ts.map +1 -0
  11. package/dist/core/events/run_finished_detail.d.ts +6 -0
  12. package/dist/core/events/run_finished_detail.d.ts.map +1 -1
  13. package/dist/core/events/thread_detail.d.ts +27 -0
  14. package/dist/core/events/thread_detail.d.ts.map +1 -0
  15. package/dist/core/run_handlers.d.ts +6 -1
  16. package/dist/core/run_handlers.d.ts.map +1 -1
  17. package/dist/dom/animations.d.ts +21 -6
  18. package/dist/dom/animations.d.ts.map +1 -1
  19. package/dist/dom/highlight_overlay.d.ts +7 -1
  20. package/dist/dom/highlight_overlay.d.ts.map +1 -1
  21. package/dist/dom/ring_color.d.ts +14 -0
  22. package/dist/dom/ring_color.d.ts.map +1 -0
  23. package/dist/index.d.ts +3 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +249 -54
  26. package/dist/index.js.map +4 -4
  27. package/dist/ui/history/conversation_history.d.ts +10 -1
  28. package/dist/ui/history/conversation_history.d.ts.map +1 -1
  29. package/dist/ui/placement/panel_placement.d.ts +6 -0
  30. package/dist/ui/placement/panel_placement.d.ts.map +1 -1
  31. package/dist/ui/placement/small_viewport_styles.d.ts.map +1 -1
  32. package/dist/ui/progress/tool_call_card.d.ts.map +1 -1
  33. package/dist/ui/progress/tool_step_group.d.ts.map +1 -1
  34. package/package.json +1 -1
  35. package/src/constants.ts +11 -0
  36. package/src/core/ag_ui_chat.ts +108 -5
  37. package/src/core/chat_registry.ts +53 -0
  38. package/src/core/events/run_finished_detail.ts +6 -0
  39. package/src/core/events/thread_detail.ts +26 -0
  40. package/src/core/run_handlers.ts +9 -4
  41. package/src/dom/animations.ts +30 -31
  42. package/src/dom/highlight_overlay.ts +9 -5
  43. package/src/dom/ring_color.ts +85 -0
  44. package/src/index.ts +3 -0
  45. package/src/ui/history/conversation_history.ts +28 -4
  46. package/src/ui/placement/embedded_styles.ts +2 -2
  47. package/src/ui/placement/panel_placement.ts +34 -9
  48. package/src/ui/placement/preset_styles.ts +1 -1
  49. package/src/ui/placement/sidebar_styles.ts +1 -1
  50. package/src/ui/placement/small_viewport_styles.ts +5 -0
  51. package/src/ui/progress/tool_call_card.ts +18 -8
  52. package/src/ui/progress/tool_step_group.ts +3 -0
  53. package/src/ui/shell/token_styles.ts +2 -2
  54. package/src/version.ts +1 -1
@@ -3,6 +3,7 @@ import type { ActivityRegistry } from "../../core/activity_registry.js";
3
3
  import type { AgUiClient } from "../../core/agui_client.js";
4
4
  import type { ClientSeed } from "../../core/client_seed.js";
5
5
  import type { ClientConversationStore, NavigationCheckpoint } from "../../core/conversation_store.js";
6
+ import type { ThreadDetail } from "../../core/events/thread_detail.js";
6
7
  import type { MessageRole } from "../../core/message_role.js";
7
8
  import { RunIndex } from "../../core/run_index.js";
8
9
  import type { ToolCatalog } from "../../tools/tool_catalog.js";
@@ -109,6 +110,11 @@ export interface ConversationHistoryHost {
109
110
  readonly resetState: () => void;
110
111
  /** Swap the composer between Send and Stop, which the composer owns. */
111
112
  readonly setRunning: (running: boolean) => void;
113
+ /**
114
+ * Say the conversation on screen changed, once its transcript is replaced.
115
+ * The element fills in the thread it replaced, which it last reported.
116
+ */
117
+ readonly threadChanged: (threadId: string, reason: ThreadDetail["reason"]) => void;
112
118
  }
113
119
  /**
114
120
  * A hold {@link ConversationHistoryHost.holdRun} took.
@@ -277,8 +283,11 @@ export declare class ConversationHistory {
277
283
  * for the run it would have resumed -- unless what replaced it is a restore
278
284
  * of the same conversation, still current, which answers for that run
279
285
  * instead; see `#forgetStopped`.
286
+ *
287
+ * `reason` is what the thread event this restore ends with reports as why
288
+ * the conversation changed. A restore that is stopped reports nothing.
280
289
  */
281
- rehydrate(): Promise<void>;
290
+ rehydrate(reason: ThreadDetail["reason"]): Promise<void>;
282
291
  /**
283
292
  * Replay a restored message: text bubbles *and* tool activity. An assistant
284
293
  * turn may carry `toolCalls` (rendered as cards) and/or text; a `tool` turn
@@ -1 +1 @@
1
- {"version":3,"file":"conversation_history.d.ts","sourceRoot":"","sources":["../../../src/ui/history/conversation_history.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,qEAAqE;AACrE,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,gEAAgE;IAChE,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;IACpC,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC;IAClC,uDAAuD;IACvD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;IAC1D,0CAA0C;IAC1C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,qBAAqB,GAAG,IAAI,CAAC;IAChE,wCAAwC;IACxC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,UAAU,EAAE,oBAAoB,KAAK,OAAO,CAAC;IAC/E,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7D,yDAAyD;IACzD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,kBAAkB,GAAG,SAAS,CAAC;IAClE,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,KAAK,cAAc,CAAC;IAC/E;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,iBAAiB,EAAE,MAAM,IAAI,CAAC;IACvC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,UAAU,GAAG,IAAI,CAAC;IACzC,yDAAyD;IACzD,QAAQ,CAAC,YAAY,EAAE,MAAM,UAAU,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,UAAU,CAAC;IACvD;;;;OAIG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC;IAChC;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,OAAO,CAAC;IAC9D,8BAA8B;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;IAChC,wEAAwE;IACxE,QAAQ,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACjD;AAED;;;;;;;;GAQG;AACH,UAAU,OAAO;IACf;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B;AAYD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,mBAAmB;;IAgD9B,YAAY,IAAI,EAAE,uBAAuB,EAExC;IAED,8BAA8B;IAC9B,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,qEAAqE;IACrE,IAAI,QAAQ,IAAI,SAAS,OAAO,EAAE,CAEjC;IAED,6EAA6E;IAC7E,IAAI,YAAY,IAAI,UAAU,GAAG,IAAI,CAEpC;IAED,oDAAoD;IACpD,iBAAiB,IAAI,IAAI,CAExB;IAED,mDAAmD;IACnD,WAAW,IAAI,IAAI,CAElB;IAED;;;;;;;;OAQG;IACH,gBAAgB,IAAI,IAAI,CAGvB;IAED,6EAA6E;IAC7E,cAAc,IAAI,IAAI,CAgBrB;IASD,+DAA+D;IAC/D,UAAU,IAAI,IAAI,CAOjB;IAED,yEAAyE;IACzE,IAAI,IAAI,QAAQ,GAAG,IAAI,CAatB;IAED,mEAAmE;IACnE,WAAW,IAAI,IAAI,CAQlB;IAED,mEAAmE;IACnE,eAAe,IAAI,IAAI,CAKtB;IAED,0EAA0E;IACpE,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUlD;IAED,kEAAkE;IAClE,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGlD;IAED,4EAA4E;IAC5E,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAYnC;IAED,kEAAkE;IAC5D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAMnC;IAWD;;;;;;;;;;;;;;;;;;OAkBG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAiJpE;IAYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2EG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CA8H/B;IAsID;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsG7B;CA2DF"}
1
+ {"version":3,"file":"conversation_history.d.ts","sourceRoot":"","sources":["../../../src/ui/history/conversation_history.ts"],"names":[],"mappings":"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"}
@@ -58,6 +58,12 @@ export declare class PanelPlacement {
58
58
  mountResizeGrips(chat: HTMLElement): void;
59
59
  /** Restore a dragged size before the panel paints. */
60
60
  restoreSize(): void;
61
+ /**
62
+ * Drop the dragged size and its stored copy, so the placement's own size and
63
+ * the host's tokens apply again. For a host entering a sized state of its
64
+ * own, which a user's drag would otherwise outrank.
65
+ */
66
+ resetSize(): void;
61
67
  /**
62
68
  * A zero-sized box carrying the host's viewport insets as padding, so they
63
69
  * can be read back as used pixel lengths. See the `.viewport-probe` rule for
@@ -1 +1 @@
1
- {"version":3,"file":"panel_placement.d.ts","sourceRoot":"","sources":["../../../src/ui/placement/panel_placement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAmFlD;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;IAClC,uCAAuC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC;IACpC,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC;IAClC,qDAAqD;IACrD,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACzD,kDAAkD;IAClD,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,iDAAiD;IACjD,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,uEAAuE;IACvE,QAAQ,CAAC,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CAC1E;AAED;;;;;;;GAOG;AACH,qBAAa,cAAc;;IAGzB,YAAY,IAAI,EAAE,aAAa,EAE9B;IAED;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAOzC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAS5C;IAED,mFAAmF;IACnF,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAqBxC;IAED,sDAAsD;IACtD,WAAW,IAAI,IAAI,CAElB;IAED;;;;OAIG;IACH,QAAQ,CAAC,KAAK,iBAAiC;IAqE/C;;;;;;OAMG;IACH,QAAQ,IAAI,OAAO,CAKlB;IAED,+EAA+E;IAC/E,eAAe,IAAI,iBAAiB,CAwBnC;IAED,oEAAoE;IACpE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CA2CjF;IA0HD,sEAAsE;IACtE,gBAAgB,IAAI,IAAI,CAYvB;IA0CD;;;;;;OAMG;IACH,gBAAgB,IAAI,IAAI,CAQvB;IAsFD;;;;;;;;;;;;OAYG;IACH,qBAAqB,IAAI,IAAI,CAgD5B;IA8PD;;;;;OAKG;IACH,uBAAuB,IAAI,IAAI,CAmB9B;IAiCD;;;;OAIG;IACH,uBAAuB,IAAI,IAAI,CAU9B;CAwGF"}
1
+ {"version":3,"file":"panel_placement.d.ts","sourceRoot":"","sources":["../../../src/ui/placement/panel_placement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AA8FlD;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;IAClC,uCAAuC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC;IACpC,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC;IAClC,qDAAqD;IACrD,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACzD,kDAAkD;IAClD,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,iDAAiD;IACjD,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,uEAAuE;IACvE,QAAQ,CAAC,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CAC1E;AAED;;;;;;;GAOG;AACH,qBAAa,cAAc;;IAGzB,YAAY,IAAI,EAAE,aAAa,EAE9B;IAED;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAOzC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAS5C;IAED,mFAAmF;IACnF,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAqBxC;IAED,sDAAsD;IACtD,WAAW,IAAI,IAAI,CAElB;IAED;;;;OAIG;IACH,SAAS,IAAI,IAAI,CAOhB;IAED;;;;OAIG;IACH,QAAQ,CAAC,KAAK,iBAAiC;IAqE/C;;;;;;OAMG;IACH,QAAQ,IAAI,OAAO,CAKlB;IAED,+EAA+E;IAC/E,eAAe,IAAI,iBAAiB,CAwBnC;IAED,oEAAoE;IACpE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CA2CjF;IA0HD,sEAAsE;IACtE,gBAAgB,IAAI,IAAI,CAYvB;IA0CD;;;;;;OAMG;IACH,gBAAgB,IAAI,IAAI,CAQvB;IAsFD;;;;;;;;;;;;OAYG;IACH,qBAAqB,IAAI,IAAI,CAgD5B;IA8PD;;;;;OAKG;IACH,uBAAuB,IAAI,IAAI,CAmB9B;IAiCD;;;;OAIG;IACH,uBAAuB,IAAI,IAAI,CAU9B;CAwGF"}
@@ -1 +1 @@
1
- {"version":3,"file":"small_viewport_styles.d.ts","sourceRoot":"","sources":["../../../src/ui/placement/small_viewport_styles.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,qBAAqB,EAAE,MAsDnC,CAAC"}
1
+ {"version":3,"file":"small_viewport_styles.d.ts","sourceRoot":"","sources":["../../../src/ui/placement/small_viewport_styles.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,qBAAqB,EAAE,MA2DnC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool_call_card.d.ts","sourceRoot":"","sources":["../../../src/ui/progress/tool_call_card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEtE,4CAA4C;AAC5C,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAEtF,sCAAsC;AACtC,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE/E,iEAAiE;AACjE,MAAM,MAAM,eAAe,GAAG,OAAO,gBAAgB,CAAC,OAAO,GAAG,OAAO,gBAAgB,CAAC,QAAQ,CAAC;AAEjG,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;AAiCrE;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,WAAW,GACnB;IACE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEN;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;AAElF,8EAA8E;AAC9E,MAAM,WAAW,mBAAmB;IAClC,sFAAsF;IACtF,QAAQ,CAAC,aAAa,CAAC,EAAE,oBAAoB,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,YAAY;;IACvB,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAEjC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;IAEtC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;IAStC;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAMvC,YACE,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,GAAE,SAA8B,EACvC,OAAO,GAAE,mBAAwB,EAkFlC;IAED;;;;;;OAMG;IACH,IAAI,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAMlC;IAED;;;;;;OAMG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAE/B;IAED;;;;OAIG;IACH,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAKlD;IAED,gFAAgF;IAChF,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAgBhD;CAkEF"}
1
+ {"version":3,"file":"tool_call_card.d.ts","sourceRoot":"","sources":["../../../src/ui/progress/tool_call_card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEtE,4CAA4C;AAC5C,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAEtF,sCAAsC;AACtC,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE/E,iEAAiE;AACjE,MAAM,MAAM,eAAe,GAAG,OAAO,gBAAgB,CAAC,OAAO,GAAG,OAAO,gBAAgB,CAAC,QAAQ,CAAC;AAEjG,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;AAiCrE;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,WAAW,GACnB;IACE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEN;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;AAElF,8EAA8E;AAC9E,MAAM,WAAW,mBAAmB;IAClC,sFAAsF;IACtF,QAAQ,CAAC,aAAa,CAAC,EAAE,oBAAoB,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,YAAY;;IACvB,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAEjC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;IAEtC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;IAStC;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAMvC,YACE,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,GAAE,SAA8B,EACvC,OAAO,GAAE,mBAAwB,EA+ElC;IAED;;;;;;OAMG;IACH,IAAI,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAKlC;IAED;;;;;;OAMG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAE/B;IAED;;;;OAIG;IACH,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAKlD;IAED,gFAAgF;IAChF,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAehD;CAiFF"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool_step_group.d.ts","sourceRoot":"","sources":["../../../src/ui/progress/tool_step_group.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AA6ClD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAa;;IACxB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAWjC,YAAY,OAAO,EAAE,SAAS,EAgD7B;IAED;;;;;;;;;OASG;IACH,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAczC;IAED,uCAAuC;IACvC,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAG3B;IAED;;;;;;;;;;OAUG;IACH,MAAM,IAAI,IAAI,CAGb;CAkGF"}
1
+ {"version":3,"file":"tool_step_group.d.ts","sourceRoot":"","sources":["../../../src/ui/progress/tool_step_group.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AA6ClD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAa;;IACxB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAWjC,YAAY,OAAO,EAAE,SAAS,EAgD7B;IAED;;;;;;;;;OASG;IACH,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAczC;IAED,uCAAuC;IACvC,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAG3B;IAED;;;;;;;;;;OAUG;IACH,MAAM,IAAI,IAAI,CAGb;CAqGF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artooi/ag-ui-web-component",
3
- "version": "0.46.0",
3
+ "version": "0.47.0",
4
4
  "description": "Framework-free <ag-ui-chat> Web Component over the AG-UI protocol. Drop-in chat sidebar with a pluggable client-side tool registry, DOM driver primitives, animations, and destructive-action confirmation modal.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/constants.ts CHANGED
@@ -61,6 +61,17 @@ export const ATTACHMENT_EVENT = "ag-ui-attachments";
61
61
  */
62
62
  export const RUN_FINISHED_EVENT = "ag-ui-run-finished";
63
63
 
64
+ /**
65
+ * The conversation on screen changed: a new chat, a thread switched to, the
66
+ * active thread deleted, the stored thread restored, or a `user-key` change
67
+ * handing the element to another principal. `detail` is {@link ThreadDetail}.
68
+ *
69
+ * Fires once per change, after the transcript has been replaced, so a listener
70
+ * reads the conversation it is told about. A host listing conversations in its
71
+ * own chrome marks the active one from here rather than watching attributes.
72
+ */
73
+ export const THREAD_EVENT = "ag-ui-thread";
74
+
64
75
  /**
65
76
  * The agent sent an AG-UI `CUSTOM` event. `detail` is {@link CustomAgentDetail}.
66
77
  *
@@ -10,6 +10,7 @@ import {
10
10
  STATE_EVENT,
11
11
  SUBMIT_EVENT,
12
12
  SUGGESTIONS_ACTIVITY_TYPE,
13
+ THREAD_EVENT,
13
14
  TOGGLE_EVENT,
14
15
  TOOL_DISPLAY,
15
16
  UNREAD_EVENT,
@@ -75,6 +76,7 @@ import type { ActivityRenderer } from "./activity_renderer.js";
75
76
  import { AgUiClient } from "./agui_client.js";
76
77
  // biome-ignore lint/style/useImportType: the emitted declaration file copies this form
77
78
  import { type AttachmentRef } from "./attachment.js";
79
+ import { ChatRegistration } from "./chat_registry.js";
78
80
  import type { ClientSeed } from "./client_seed.js";
79
81
  import {
80
82
  type ClientConversationStore,
@@ -85,6 +87,7 @@ import {
85
87
  import { type AgentFactory, createHttpAgent } from "./create_http_agent.js";
86
88
  import type { StateDetail } from "./events/state_detail.js";
87
89
  import type { SubmitDetail } from "./events/submit_detail.js";
90
+ import type { ThreadDetail } from "./events/thread_detail.js";
88
91
  import type { ToggleDetail } from "./events/toggle_detail.js";
89
92
  import type { UnreadDetail } from "./events/unread_detail.js";
90
93
  import type { MessageRole } from "./message_role.js";
@@ -750,6 +753,11 @@ export class AgUiChat extends HTMLElement {
750
753
  * then a host's {@link sendMessage} waits for it rather than refusing.
751
754
  */
752
755
  #restoreHold: { readonly hold: object; readonly restored: Promise<void> } | null = null;
756
+ /**
757
+ * The thread the latest {@link THREAD_EVENT} reported, which the next one
758
+ * names as the thread it replaced; `null` before the first.
759
+ */
760
+ #shownThread: string | null = null;
753
761
  /** The decision a run is suspended on, which a Stop abandons. */
754
762
  readonly #decision = new PendingDecision();
755
763
  /**
@@ -781,6 +789,8 @@ export class AgUiChat extends HTMLElement {
781
789
  allowImages: () => this.allowImages,
782
790
  follow: () => this.#transcript.follow(),
783
791
  });
792
+ // This chat's place among the connected ones, which a free highlight ring reads.
793
+ readonly #chatRegistration = new ChatRegistration(this);
784
794
  /**
785
795
  * Which storage keys are this element's: the namespace it claims, the keys
786
796
  * its layout preferences live under, and the built-in store scoped to them.
@@ -1043,6 +1053,7 @@ export class AgUiChat extends HTMLElement {
1043
1053
  cancelRun: () => this.#cancelRun(),
1044
1054
  resetState: () => this.#resetState(),
1045
1055
  setRunning: (running) => this.#setRunning(running),
1056
+ threadChanged: (threadId, reason) => this.#dispatchThread(threadId, reason),
1046
1057
  });
1047
1058
  }
1048
1059
 
@@ -1448,6 +1459,7 @@ export class AgUiChat extends HTMLElement {
1448
1459
  // this instance doesn't share collapsed/theme/thread state with another on
1449
1460
  // the same origin.
1450
1461
  this.#storage.claim();
1462
+ this.#chatRegistration.join();
1451
1463
  // Restore a dragged size before the panel paints, so it does not snap from
1452
1464
  // the placement default to the user's width on the first frame.
1453
1465
  this.#placement.restoreSize();
@@ -1530,7 +1542,10 @@ export class AgUiChat extends HTMLElement {
1530
1542
  // The catalog requests go out a microtask later, so a host configuring
1531
1543
  // through a framework ref still has a chance to be heard — see #startup.
1532
1544
  queueMicrotask(() => this.#startup());
1533
- void this.#history.rehydrate();
1545
+ // A key changed while the element was away handed it over all the same,
1546
+ // and the restore is the arriving principal's: reported as the live change
1547
+ // is. An adoption is not a handover, and restores the same conversation.
1548
+ void this.#history.rehydrate(changed && held !== "" ? "rescope" : "restore");
1534
1549
  if (changed) {
1535
1550
  // The last of what a live change does: a drawer left open across the
1536
1551
  // move still lists the threads of the principal who left, titles and
@@ -1594,7 +1609,7 @@ export class AgUiChat extends HTMLElement {
1594
1609
  await Promise.all([
1595
1610
  this.#tools.fetchCatalog(),
1596
1611
  this.#skills.fetch(),
1597
- this.#history.rehydrate(),
1612
+ this.#history.rehydrate("restore"),
1598
1613
  ]);
1599
1614
  }
1600
1615
 
@@ -1611,6 +1626,7 @@ export class AgUiChat extends HTMLElement {
1611
1626
  window.visualViewport?.removeEventListener("resize", this.#onViewportResize);
1612
1627
  window.visualViewport?.removeEventListener("scroll", this.#onViewportResize);
1613
1628
  this.#storage.release();
1629
+ this.#chatRegistration.leave();
1614
1630
  this.#cancelRun();
1615
1631
  this.#excerpts.detachPageOffer();
1616
1632
  this.#attachments.tray?.dispose();
@@ -1794,6 +1810,28 @@ export class AgUiChat extends HTMLElement {
1794
1810
  return this.#unread;
1795
1811
  }
1796
1812
 
1813
+ /**
1814
+ * The thread on screen; `null` before the element first connects.
1815
+ *
1816
+ * Only reads. `conversationStore.threadId()` mints and stores a thread when
1817
+ * the store points at none, so a host asking which conversation is showing
1818
+ * could start one; this never does. {@link THREAD_EVENT} says when it changes.
1819
+ */
1820
+ get threadId(): string | null {
1821
+ const threadId = this.#history.threadId;
1822
+ return threadId === "" ? null : threadId;
1823
+ }
1824
+
1825
+ /**
1826
+ * Whether an interaction is in flight: the composer's own state, the one that
1827
+ * shows Stop. It spans every tool round, a retry and a checkpoint
1828
+ * continuation as well as a send, which {@link SUBMIT_EVENT} alone does not.
1829
+ * Reflected as `data-running` on the element, for a host's CSS.
1830
+ */
1831
+ get running(): boolean {
1832
+ return this.#running;
1833
+ }
1834
+
1797
1835
  /**
1798
1836
  * Whether to mount collapsed.
1799
1837
  *
@@ -1850,6 +1888,14 @@ export class AgUiChat extends HTMLElement {
1850
1888
  return this.#placement.moveTo(corner, options);
1851
1889
  }
1852
1890
 
1891
+ /**
1892
+ * Drop a size the user dragged, and its stored copy, so the placement's
1893
+ * default and the host's `--ag-ui-width` / `--ag-ui-height` apply again.
1894
+ */
1895
+ resetSize(): void {
1896
+ this.#placement.resetSize();
1897
+ }
1898
+
1853
1899
  /** Flip the collapsed state. Bound to the built-in header toggle. */
1854
1900
  toggleCollapsed(): void {
1855
1901
  this.setCollapsed(!this.collapsed);
@@ -1960,7 +2006,7 @@ export class AgUiChat extends HTMLElement {
1960
2006
  this.#voice.dispose();
1961
2007
  this.#voice.wire();
1962
2008
  this.#history.adoptActiveThread();
1963
- void this.#history.rehydrate();
2009
+ void this.#history.rehydrate("rescope");
1964
2010
  void this.#history.refreshDrawer();
1965
2011
  }
1966
2012
 
@@ -2031,6 +2077,36 @@ export class AgUiChat extends HTMLElement {
2031
2077
  this.#checkpoints.close();
2032
2078
  }
2033
2079
 
2080
+ /**
2081
+ * Put a stored thread on screen, as picking it in the conversation list does,
2082
+ * for a host that lists conversations in its own chrome.
2083
+ *
2084
+ * Resolves once the thread has been replayed, when {@link THREAD_EVENT} has
2085
+ * fired. **A run in flight is cancelled**, as the list and {@link newChat} do;
2086
+ * a host that would rather wait reads {@link running} first. The thread
2087
+ * already on screen is left alone, and so is everything before the element
2088
+ * connects, since until then it has no store to read the thread from.
2089
+ */
2090
+ async switchThread(threadId: string): Promise<void> {
2091
+ if (!this.#connected) {
2092
+ return;
2093
+ }
2094
+ await this.#history.switchThread(threadId);
2095
+ }
2096
+
2097
+ /**
2098
+ * Delete a stored thread, as the conversation list's delete does. Deleting the
2099
+ * thread on screen cancels its run and puts a fresh thread in its place, and
2100
+ * {@link THREAD_EVENT} reports it; deleting another leaves the screen alone.
2101
+ * Does nothing before the element connects.
2102
+ */
2103
+ deleteThread(threadId: string): void {
2104
+ if (!this.#connected) {
2105
+ return;
2106
+ }
2107
+ this.#history.deleteThread(threadId);
2108
+ }
2109
+
2034
2110
  /**
2035
2111
  * Open the checkpoints panel, or close it if it is already open — what the
2036
2112
  * built-in ⭯ button does, because a control that opens a panel is read as the
@@ -2066,6 +2142,7 @@ export class AgUiChat extends HTMLElement {
2066
2142
  this.#history.startThread();
2067
2143
  this.#setRunning(false);
2068
2144
  this.#setUnread(0);
2145
+ this.#dispatchThread(this.#history.threadId, "new");
2069
2146
  // Whichever control started it: the header's, the history list's (which
2070
2147
  // hands focus back to its opener as it closes, before this runs), or a
2071
2148
  // host's own. A keyboard user otherwise had to find their way back to the
@@ -2340,6 +2417,12 @@ export class AgUiChat extends HTMLElement {
2340
2417
  onFilesPicked: () => this.#attachments.onFilesPicked(),
2341
2418
  });
2342
2419
 
2420
+ // Host content against the input, after everything of the turn being
2421
+ // written. A bare slot, whose own box is none, so an empty one takes no
2422
+ // space and the greeting layout carries a filled one with the composer.
2423
+ const aboveComposer = document.createElement("slot");
2424
+ aboveComposer.name = "above-composer";
2425
+
2343
2426
  // A coarse footer slot below the composer.
2344
2427
  const footer = document.createElement("slot");
2345
2428
  footer.name = "footer";
@@ -2351,7 +2434,8 @@ export class AgUiChat extends HTMLElement {
2351
2434
 
2352
2435
  // Composer surfaces sit just above the input: the skills palette (opens on
2353
2436
  // `/`), the chips, the hint saying what the composer still needs, the
2354
- // queued messages and the pending-attachments tray.
2437
+ // queued messages and the pending-attachments tray, then the host's own
2438
+ // content directly over the input.
2355
2439
  this.#chat.replaceChildren(
2356
2440
  header,
2357
2441
  this.#messagesWrap,
@@ -2360,6 +2444,7 @@ export class AgUiChat extends HTMLElement {
2360
2444
  this.#composerHint,
2361
2445
  this.#queuedRow,
2362
2446
  this.#attachSlot,
2447
+ aboveComposer,
2363
2448
  inputRow,
2364
2449
  footer,
2365
2450
  this.#drawer.element,
@@ -2594,6 +2679,22 @@ export class AgUiChat extends HTMLElement {
2594
2679
  this.#history.stopContinuation();
2595
2680
  }
2596
2681
 
2682
+ /**
2683
+ * Say the conversation on screen changed: {@link THREAD_EVENT}.
2684
+ *
2685
+ * The thread it replaced is the one last reported, rather than the one the
2686
+ * element last pointed at: a switch superseded before it replayed never drew
2687
+ * its thread, so naming it as the previous one left a host's own list
2688
+ * marking a thread that was never shown and still marking the one that was.
2689
+ */
2690
+ #dispatchThread(threadId: string, reason: ThreadDetail["reason"]): void {
2691
+ const detail: ThreadDetail = { threadId, previousThreadId: this.#shownThread, reason };
2692
+ this.#shownThread = threadId;
2693
+ this.dispatchEvent(
2694
+ new CustomEvent<ThreadDetail>(THREAD_EVENT, { detail, bubbles: true, composed: true }),
2695
+ );
2696
+ }
2697
+
2597
2698
  /**
2598
2699
  * Swap the composer button between Send (idle) and Stop (running).
2599
2700
  *
@@ -2615,6 +2716,8 @@ export class AgUiChat extends HTMLElement {
2615
2716
  this.#send.title = label;
2616
2717
  this.#send.setAttribute("aria-label", label);
2617
2718
  this.#send.dataset["state"] = running ? "running" : "idle";
2719
+ // For a host's CSS, as `data-empty` is: the same state, on the element.
2720
+ this.toggleAttribute("data-running", running);
2618
2721
  if (settled) {
2619
2722
  this.#flushQueued();
2620
2723
  }
@@ -3006,7 +3109,7 @@ export class AgUiChat extends HTMLElement {
3006
3109
  });
3007
3110
  return new AgUiClient({
3008
3111
  agent,
3009
- handlers: this.#runHandlers.forClient(),
3112
+ handlers: this.#runHandlers.forClient(threadId),
3010
3113
  getTools: () => this.#tools.advertise(),
3011
3114
  getContext: () => this.#dispatch.buildContext(),
3012
3115
  executeTool: (call) => this.#dispatch.execute(call),
@@ -0,0 +1,53 @@
1
+ /**
2
+ * The `<ag-ui-chat>` elements connected to this document, oldest first.
3
+ *
4
+ * The highlight ring is drawn in the host's page, outside every chat, so a
5
+ * token set on a chat never reaches it through the cascade. A free `flash()`
6
+ * still has to answer "which widget is this ring speaking for", and that is a
7
+ * question about the live elements rather than about any one of them.
8
+ *
9
+ * Module-level on purpose, and the second piece of shared mutable state the
10
+ * repository's `CLAUDE.md` records, beside the claimed storage namespaces. See
11
+ * the conditions it states, and how this one meets them, before adding a
12
+ * third.
13
+ */
14
+ const CONNECTED_CHATS = new Set<HTMLElement>();
15
+
16
+ /**
17
+ * One chat's place in the document's list of connected chats.
18
+ *
19
+ * Owned one-to-one by an `<ag-ui-chat>`, which joins on connect and leaves on
20
+ * disconnect, so the list holds exactly the elements that are in a document
21
+ * now. Typed as `HTMLElement` rather than the element's class, because the DOM
22
+ * driver reads it and must not import the element.
23
+ */
24
+ export class ChatRegistration {
25
+ readonly #chat: HTMLElement;
26
+
27
+ constructor(chat: HTMLElement) {
28
+ this.#chat = chat;
29
+ }
30
+
31
+ /**
32
+ * Join, as the most recently connected chat. An element moved in the DOM
33
+ * left on disconnect before it reconnected, so it rejoins at the end and no
34
+ * entry needs removing first.
35
+ */
36
+ join(): void {
37
+ CONNECTED_CHATS.add(this.#chat);
38
+ }
39
+
40
+ /** Leave. The previous chat, if one is still connected, becomes the latest. */
41
+ leave(): void {
42
+ CONNECTED_CHATS.delete(this.#chat);
43
+ }
44
+
45
+ /** The most recently connected chat still in the document, or `null`. */
46
+ static latest(): HTMLElement | null {
47
+ let latest: HTMLElement | null = null;
48
+ for (const chat of CONNECTED_CHATS) {
49
+ latest = chat;
50
+ }
51
+ return latest;
52
+ }
53
+ }
@@ -2,6 +2,12 @@ import type { ToolRun } from "./tool_run.js";
2
2
 
3
3
  /** `detail` shape of the {@link RUN_FINISHED_EVENT} CustomEvent. */
4
4
  export interface RunFinishedDetail {
5
+ /**
6
+ * The thread the run belonged to, fixed when its client was built. Not always
7
+ * the thread on screen: a run stopped by a new chat or a thread switch still
8
+ * reports once its request closes, and by then another thread is.
9
+ */
10
+ readonly threadId: string;
5
11
  /** In settle order. Empty when the interaction called no tools. */
6
12
  readonly tools: readonly ToolRun[];
7
13
  /**
@@ -0,0 +1,26 @@
1
+ /** `detail` shape of the {@link THREAD_EVENT} CustomEvent. */
2
+ export interface ThreadDetail {
3
+ /** The thread now on screen. */
4
+ readonly threadId: string;
5
+ /**
6
+ * The thread on screen before the change: the one the previous event
7
+ * reported, and `null` before the first, as at the restore when the element
8
+ * first connects. Equal to `threadId` when the same thread was restored
9
+ * again (`reload()`, the element connecting again).
10
+ */
11
+ readonly previousThreadId: string | null;
12
+ /**
13
+ * What changed it:
14
+ *
15
+ * - `new`: `newChat()` or the built-in New chat button.
16
+ * - `switch`: `switchThread()` or a row picked in the conversation list.
17
+ * - `delete`: the active thread was deleted, and a fresh one took its place.
18
+ * - `restore`: the stored thread was replayed, on connect or by `reload()`.
19
+ * - `rescope`: a `user-key` change handed the element to another principal,
20
+ * live or while it was out of the document.
21
+ *
22
+ * A closed set today; a host should ignore a reason it does not know, so a
23
+ * later one can be added without breaking it.
24
+ */
25
+ readonly reason: "new" | "switch" | "delete" | "restore" | "rescope";
26
+ }
@@ -176,8 +176,13 @@ export class RunHandlers {
176
176
  * A handler table for one AG-UI client. Every table built for the current
177
177
  * conversation draws into the same transcript and shares its bookkeeping, so
178
178
  * a continuation run reports into the interaction the user is looking at.
179
+ *
180
+ * `threadId` is the thread the client was built for, named on the
181
+ * run-finished detail. Taken here rather than read when the run settles,
182
+ * because a stopped run settles after the reset that stopped it, when the
183
+ * thread on screen is already the next one.
179
184
  */
180
- forClient(): AgUiClientHandlers {
185
+ forClient(threadId: string): AgUiClientHandlers {
181
186
  const ledger = this.#ledger;
182
187
  const attached = (): boolean => ledger === this.#ledger;
183
188
  const { onSettled, ...drawing } = this.#tableFor(ledger);
@@ -190,7 +195,7 @@ export class RunHandlers {
190
195
  // Last, so a listener that refetches sees a transcript that has already
191
196
  // stopped changing -- and outside the check, because what a run did is
192
197
  // true whichever conversation is on screen when it ends.
193
- this.#dispatchRunFinished(ledger);
198
+ this.#dispatchRunFinished(ledger, threadId);
194
199
  },
195
200
  };
196
201
  }
@@ -444,7 +449,7 @@ export class RunHandlers {
444
449
  * server is a fact about the run, and a name can appear on both sides across a
445
450
  * conversation.
446
451
  */
447
- #dispatchRunFinished(ledger: RunLedger): void {
452
+ #dispatchRunFinished(ledger: RunLedger, threadId: string): void {
448
453
  const tools: ToolRun[] = ledger.tools.map(({ id, name }) => ({
449
454
  name,
450
455
  side: ledger.serverSettled.has(id) ? "server" : "client",
@@ -455,7 +460,7 @@ export class RunHandlers {
455
460
  ledger.invalidated.clear();
456
461
  this.#host.element.dispatchEvent(
457
462
  new CustomEvent<RunFinishedDetail>(RUN_FINISHED_EVENT, {
458
- detail: { tools, invalidated },
463
+ detail: { threadId, tools, invalidated },
459
464
  bubbles: true,
460
465
  composed: true,
461
466
  }),