@neuronection/assistant-ui 0.22.0 → 0.24.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 (159) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/README.md +9 -0
  3. package/dist/about.js +1 -1
  4. package/dist/ai-magic-fill.js +1 -1
  5. package/dist/chat-branch-tree.d.ts +45 -0
  6. package/dist/chat-branch-tree.js +3 -0
  7. package/dist/chat-branch-tree.js.map +1 -0
  8. package/dist/chat-composer.d.ts +50 -0
  9. package/dist/chat-composer.js +3 -0
  10. package/dist/chat-composer.js.map +1 -0
  11. package/dist/chat-core.d.ts +154 -0
  12. package/dist/chat-core.js +4 -0
  13. package/dist/chat-core.js.map +1 -0
  14. package/dist/chat-drawer.d.ts +32 -0
  15. package/dist/chat-drawer.js +3 -0
  16. package/dist/chat-drawer.js.map +1 -0
  17. package/dist/chat-launcher.d.ts +28 -0
  18. package/dist/chat-launcher.js +3 -0
  19. package/dist/chat-launcher.js.map +1 -0
  20. package/dist/chat-markdown.d.ts +64 -0
  21. package/dist/chat-markdown.js +3 -0
  22. package/dist/chat-markdown.js.map +1 -0
  23. package/dist/chat-message.d.ts +108 -0
  24. package/dist/chat-message.js +3 -0
  25. package/dist/chat-message.js.map +1 -0
  26. package/dist/chat-panel.d.ts +28 -0
  27. package/dist/chat-panel.js +3 -0
  28. package/dist/chat-panel.js.map +1 -0
  29. package/dist/chat-reasoning.d.ts +27 -0
  30. package/dist/chat-reasoning.js +3 -0
  31. package/dist/chat-reasoning.js.map +1 -0
  32. package/dist/chat-session-list.d.ts +51 -0
  33. package/dist/chat-session-list.js +3 -0
  34. package/dist/chat-session-list.js.map +1 -0
  35. package/dist/chat-tool-card.d.ts +37 -0
  36. package/dist/chat-tool-card.js +3 -0
  37. package/dist/chat-tool-card.js.map +1 -0
  38. package/dist/chat-transcript.d.ts +33 -0
  39. package/dist/chat-transcript.js +3 -0
  40. package/dist/chat-transcript.js.map +1 -0
  41. package/dist/{chunk-CZ2BL2ZL.js → chunk-3JJ2WCPN.js} +2 -2
  42. package/dist/{chunk-CZ2BL2ZL.js.map → chunk-3JJ2WCPN.js.map} +1 -1
  43. package/dist/chunk-5IOLDMDY.js +3 -0
  44. package/dist/chunk-5IOLDMDY.js.map +1 -0
  45. package/dist/{chunk-EODV6JK7.js → chunk-5QTHDB3D.js} +3 -3
  46. package/dist/{chunk-EODV6JK7.js.map → chunk-5QTHDB3D.js.map} +1 -1
  47. package/dist/chunk-6E6RRLKU.js +3 -0
  48. package/dist/chunk-6E6RRLKU.js.map +1 -0
  49. package/dist/chunk-6GNLY2EB.js +272 -0
  50. package/dist/chunk-6GNLY2EB.js.map +1 -0
  51. package/dist/chunk-743FJDRA.js +184 -0
  52. package/dist/chunk-743FJDRA.js.map +1 -0
  53. package/dist/{chunk-4UJKXTWY.js → chunk-AY77TWLT.js} +8 -3
  54. package/dist/chunk-AY77TWLT.js.map +1 -0
  55. package/dist/chunk-BSIWLVDX.js +217 -0
  56. package/dist/chunk-BSIWLVDX.js.map +1 -0
  57. package/dist/chunk-BVJT67B5.js +134 -0
  58. package/dist/chunk-BVJT67B5.js.map +1 -0
  59. package/dist/chunk-DZBTJZZV.js +201 -0
  60. package/dist/chunk-DZBTJZZV.js.map +1 -0
  61. package/dist/chunk-HQIYSW2D.js +131 -0
  62. package/dist/chunk-HQIYSW2D.js.map +1 -0
  63. package/dist/chunk-JPDD5AFN.js +119 -0
  64. package/dist/chunk-JPDD5AFN.js.map +1 -0
  65. package/dist/chunk-LSCWBNG3.js +3 -0
  66. package/dist/chunk-LSCWBNG3.js.map +1 -0
  67. package/dist/chunk-NKYPNEOX.js +198 -0
  68. package/dist/chunk-NKYPNEOX.js.map +1 -0
  69. package/dist/{chunk-INMAUGBK.js → chunk-OH7AJ3WY.js} +3 -3
  70. package/dist/{chunk-INMAUGBK.js.map → chunk-OH7AJ3WY.js.map} +1 -1
  71. package/dist/chunk-PAQ6YQ7Y.js +3 -0
  72. package/dist/chunk-PAQ6YQ7Y.js.map +1 -0
  73. package/dist/chunk-QVDCFZSE.js +72 -0
  74. package/dist/chunk-QVDCFZSE.js.map +1 -0
  75. package/dist/chunk-RPLEI6LQ.js +102 -0
  76. package/dist/chunk-RPLEI6LQ.js.map +1 -0
  77. package/dist/chunk-S62VJVWB.js +36 -0
  78. package/dist/chunk-S62VJVWB.js.map +1 -0
  79. package/dist/chunk-X3C2FBMR.js +141 -0
  80. package/dist/chunk-X3C2FBMR.js.map +1 -0
  81. package/dist/{chunk-7YLR4AGA.js → chunk-XZWLTTHA.js} +2 -2
  82. package/dist/{chunk-7YLR4AGA.js.map → chunk-XZWLTTHA.js.map} +1 -1
  83. package/dist/chunk-Z4IBQ53C.js +75 -0
  84. package/dist/chunk-Z4IBQ53C.js.map +1 -0
  85. package/dist/{chunk-7KD4MG75.js → chunk-ZK2V2LPA.js} +3 -3
  86. package/dist/chunk-ZK2V2LPA.js.map +1 -0
  87. package/dist/copy-button.js +1 -1
  88. package/dist/fonts/KaTeX_AMS-Regular.ttf +0 -0
  89. package/dist/fonts/KaTeX_AMS-Regular.woff +0 -0
  90. package/dist/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  91. package/dist/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  92. package/dist/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  93. package/dist/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  94. package/dist/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  95. package/dist/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  96. package/dist/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  97. package/dist/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  98. package/dist/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  99. package/dist/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  100. package/dist/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  101. package/dist/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  102. package/dist/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  103. package/dist/fonts/KaTeX_Main-Bold.ttf +0 -0
  104. package/dist/fonts/KaTeX_Main-Bold.woff +0 -0
  105. package/dist/fonts/KaTeX_Main-Bold.woff2 +0 -0
  106. package/dist/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  107. package/dist/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  108. package/dist/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  109. package/dist/fonts/KaTeX_Main-Italic.ttf +0 -0
  110. package/dist/fonts/KaTeX_Main-Italic.woff +0 -0
  111. package/dist/fonts/KaTeX_Main-Italic.woff2 +0 -0
  112. package/dist/fonts/KaTeX_Main-Regular.ttf +0 -0
  113. package/dist/fonts/KaTeX_Main-Regular.woff +0 -0
  114. package/dist/fonts/KaTeX_Main-Regular.woff2 +0 -0
  115. package/dist/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  116. package/dist/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  117. package/dist/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  118. package/dist/fonts/KaTeX_Math-Italic.ttf +0 -0
  119. package/dist/fonts/KaTeX_Math-Italic.woff +0 -0
  120. package/dist/fonts/KaTeX_Math-Italic.woff2 +0 -0
  121. package/dist/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  122. package/dist/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  123. package/dist/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  124. package/dist/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  125. package/dist/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  126. package/dist/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  127. package/dist/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  128. package/dist/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  129. package/dist/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  130. package/dist/fonts/KaTeX_Script-Regular.ttf +0 -0
  131. package/dist/fonts/KaTeX_Script-Regular.woff +0 -0
  132. package/dist/fonts/KaTeX_Script-Regular.woff2 +0 -0
  133. package/dist/fonts/KaTeX_Size1-Regular.ttf +0 -0
  134. package/dist/fonts/KaTeX_Size1-Regular.woff +0 -0
  135. package/dist/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  136. package/dist/fonts/KaTeX_Size2-Regular.ttf +0 -0
  137. package/dist/fonts/KaTeX_Size2-Regular.woff +0 -0
  138. package/dist/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  139. package/dist/fonts/KaTeX_Size3-Regular.ttf +0 -0
  140. package/dist/fonts/KaTeX_Size3-Regular.woff +0 -0
  141. package/dist/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  142. package/dist/fonts/KaTeX_Size4-Regular.ttf +0 -0
  143. package/dist/fonts/KaTeX_Size4-Regular.woff +0 -0
  144. package/dist/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  145. package/dist/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  146. package/dist/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  147. package/dist/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  148. package/dist/index.d.ts +15 -0
  149. package/dist/index.js +39 -26
  150. package/dist/index.js.map +1 -1
  151. package/dist/portal.js +1 -1
  152. package/dist/rich-text-editor.js +1 -1
  153. package/dist/settings-shell.js +1 -1
  154. package/dist/styles.css +1 -1
  155. package/dist/tree-YaIz73vo.d.ts +54 -0
  156. package/dist/types-DZwzmyKE.d.ts +44 -0
  157. package/package.json +56 -2
  158. package/dist/chunk-4UJKXTWY.js.map +0 -1
  159. package/dist/chunk-7KD4MG75.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,97 @@
1
1
  # @neuronection/assistant-ui
2
2
 
3
+ ## 0.24.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`b926d22`](https://github.com/neuronection/assistant-ui/commit/b926d224031f657cdc281afac838cec0268573b6) Thanks [@constLiakos](https://github.com/constLiakos)! - chat bubbles (plan 11 L3): `ChatMessage` — the family chat bubble with
8
+ role alignment, hover+focus action row (copy/edit/regenerate + app
9
+ extras), OpenWebUI-style `‹ n/N ›` variant switcher, inline
10
+ edit-and-resend (`ChatMessageEditor`: Cmd/Ctrl+Enter saves, Escape
11
+ cancels), reasoning and below-content slots, badge/chip/attachment rows,
12
+ and accessible error + interrupted states; `ChatReasoning` — the
13
+ collapsible thinking block that streams live reasoning deltas;
14
+ `ChatToolCard` — inline tool-call observation with status, duration and
15
+ expandable args/result panes.
16
+
17
+ - [`7bd487b`](https://github.com/neuronection/assistant-ui/commit/7bd487bca97d87a6d12d0b483f94a642df327a16) Thanks [@constLiakos](https://github.com/constLiakos)! - chat-composer (plan 11 L4): `ChatComposer` — the family chat input.
18
+ Auto-growing IME-safe textarea (Enter sends, Shift+Enter newlines,
19
+ composition never submits — a correctness gap in all three apps today),
20
+ send/stop swap while a turn is in flight, toolbar slots for app
21
+ attach/equation/dictation controls, attachment rail and suggestion strip
22
+ slots, and drag-drop + paste file wiring behind `onAttachFiles`.
23
+
24
+ - [`062fca5`](https://github.com/neuronection/assistant-ui/commit/062fca561466dd9d2985fc2ea7a3d9e751e3cab9) Thanks [@constLiakos](https://github.com/constLiakos)! - chat-core — the headless core of the shared chat layer (plan dev/plans/11,
25
+ ADR-0009): `useChatStream`, a transport-injected live-turn state machine
26
+ (send → pending → streaming → done/error/interrupted) with coalesced
27
+ text/reasoning deltas, tool-call observations, HITL interrupts (resumable)
28
+ and a retryable watchdog; `liveTurnReducer`, the pure fixture-testable turn
29
+ machine; `ChatMessageView`, the normalized message contract every chat
30
+ renderer speaks; `ChatStreamEvent`, the family §5 vocabulary (+ `tool_call`
31
+ observation event); and the branch-tree utilities behind OpenWebUI-style
32
+ versioning (`buildBranchTree`, `linearTree`, `walkActivePath`,
33
+ `activePathSet`, `variantInfo`). No fetching, stores or i18n — apps inject
34
+ the transport (WS/SSE adapters ~50 lines), own sessions and persistence.
35
+
36
+ - [`1ab36a8`](https://github.com/neuronection/assistant-ui/commit/1ab36a820e526094ef2135fe539dead2fb8549ee) Thanks [@constLiakos](https://github.com/constLiakos)! - chat lists (plan 11 L5): `ChatTranscript` — the conversation list with
37
+ `role="log"` semantics, polite screen-reader announcements on assistant
38
+ turn completion (never per token), stick-to-bottom auto-scroll with a
39
+ jump-to-latest pill, and optional dynamic-measurement virtualization for
40
+ thousand-message threads; `ChatBranchTree` — the OpenWebUI-style branch
41
+ rail (commit-graph rows, active-path dots, fork badges, full WAI-ARIA
42
+ tree keyboard navigation) over the family branch-tree contract;
43
+ `ChatSessionList` — fuzzy-searchable, date-grouped session list with
44
+ opt-in rename/delete/export row actions.
45
+
46
+ - [`f27eba3`](https://github.com/neuronection/assistant-ui/commit/f27eba3731f370d8bb49b10c743c2c78aba0666f) Thanks [@constLiakos](https://github.com/constLiakos)! - chat-markdown — the family's read-only streaming markdown surface (plan 11
47
+ L2): `MarkdownSurface` renders GFM tables, KaTeX math (error-tolerant
48
+ while streaming), lazily-imported mermaid diagrams (strict security,
49
+ code-block fallback), and copyable code blocks with language tags. Raw
50
+ HTML never renders (model output is untrusted); URLs pass a safe default
51
+ transform with an override for app schemes (mentions, citations). KaTeX
52
+ CSS joins `styles.css` with fonts shipped in `dist/fonts`; base chat
53
+ typography is scoped to `[data-as="chat-markdown"]` so it survives app
54
+ preflight. First markdown/math/diagram dependencies in the package —
55
+ isolated behind the `chat-markdown` subpath; apps that don't import it
56
+ bundle nothing extra.
57
+
58
+ - [`2220f90`](https://github.com/neuronection/assistant-ui/commit/2220f9077ba1a85d9427e1b00ef02e6441f7ecb7) Thanks [@constLiakos](https://github.com/constLiakos)! - chat surface hosts (plan 11 L6): `ChatPanel` — the composed host behind
59
+ the family's three chat shapes (`page` / `sidebar` / `bubble` variants,
60
+ header/banner/transcript/composer/footer slots); `ChatDrawer` — the
61
+ resizable sidepanel on Radix Dialog (focus trap, Escape, drag +
62
+ keyboard resize on a `role="separator"` handle, full-screen below the
63
+ breakpoint); `ChatLauncher` — the floating bubble (aria-expanded
64
+ launcher, anchored non-modal panel, unread badge). One assembly, three
65
+ surfaces — completing the shared chat layer's module set.
66
+
67
+ ### Patch Changes
68
+
69
+ - [`6503f87`](https://github.com/neuronection/assistant-ui/commit/6503f8734ca9c21441eb7ffc2e7bbcaaabffa56e) Thanks [@constLiakos](https://github.com/constLiakos)! - SettingsShell: the responsive two-pane columns now live in component CSS
70
+ (`[data-as='settings-shell']`, one column → four at `64rem`) instead of
71
+ `grid-cols-1 lg:grid-cols-4` utilities. Host apps compile their own Tailwind
72
+ utilities after the library stylesheet, so any app that generates an
73
+ unconditional `.grid-cols-1` overrode the media-query rule and forced the
74
+ section nav to stack on top of the content at every viewport width. The shell
75
+ no longer carries collidable grid utilities, so the side-by-side layout holds
76
+ regardless of app CSS; intentional `className` column overrides still win.
77
+
78
+ ## 0.23.0
79
+
80
+ ### Minor Changes
81
+
82
+ - [`9be7c37`](https://github.com/neuronection/assistant-ui/commit/9be7c37787b25b658ff01573d13b9c540a9e6c67) Thanks [@constLiakos](https://github.com/constLiakos)! - RichTextEditor becomes hostable by full apps: `extensions` is now a **full
83
+ override** of the built-in `[StarterKit, Markdown]` set (apps declare their
84
+ complete extension set), and three composition props land — `contentClassName`
85
+ (merged onto the editable region), `onReady` (editor instance on create,
86
+ `null` on destroy — the app handle for commands and event wiring), and
87
+ `headingLevels` (one toggle per level; `labels.heading` is now
88
+ `(level) => string`, default `Heading ${level}`). History buttons now reflect
89
+ undo/redo availability and disable while there is nothing to undo/redo. Also
90
+ fixes a spurious mount-time `onValueChange`: the editable-state effect no
91
+ longer calls `setEditable` when it is already correct (tiptap v3 emits an
92
+ update event from `setEditable`, which surfaced the parsed value back to the
93
+ app on mount).
94
+
3
95
  ## 0.22.0
4
96
 
5
97
  ### Minor Changes
package/README.md CHANGED
@@ -88,6 +88,12 @@ Visual reference: [gallery](https://neuronection.github.io/assistant-ui/).
88
88
  | [`error-banner`](./docs/components/error-banner.md) / [`undo-notice`](./docs/components/undo-notice.md) / [`empty-state`](./docs/components/empty-state.md) / [`spinner`](./docs/components/spinner.md) | presentational feedback: alert banner with `action` slot · undo toast · `EmptyState` · `Spinner` | [stories](https://neuronection.github.io/assistant-ui/?story=feedback--errors) |
89
89
  | [`info-button`](./docs/components/info-button.md) / [`field-label`](./docs/components/field-label.md) / [`copy-button`](./docs/components/copy-button.md) / [`breadcrumbs`](./docs/components/breadcrumbs.md) | `InfoButton` · `FieldLabel` · `CopyButton` (clipboard + copied state) · `Breadcrumbs` (SPA links via `linkComponent`) | [stories](https://neuronection.github.io/assistant-ui/?story=phase2--copy-buttons) |
90
90
  | [`ai-button`](./docs/components/ai-button.md) / [`ai-actions-dropdown`](./docs/components/ai-actions-dropdown.md) / [`ai-magic-fill`](./docs/components/ai-magic-fill.md) | AI affordances: ask-with-suggestions (controlled open, icon-only mode) · action menu + custom prompt · describe-in-words fill modal — API calls stay app-side | [stories](https://neuronection.github.io/assistant-ui/?story=ai-patterns--ai-buttons) |
91
+ | [`chat-core`](./docs/components/chat-core.md) | `useChatStream` (transport-injected live-turn state machine), `liveTurnReducer`, `ChatMessageView`, family `ChatStreamEvent` vocabulary, branch-tree utils (`buildBranchTree`, `walkActivePath`, `variantInfo`) | [stories](https://neuronection.github.io/assistant-ui/?story=chat-core--chat-core-story) |
92
+ | [`chat-markdown`](./docs/components/chat-markdown.md) | `MarkdownSurface` (read-only streaming markdown: GFM + KaTeX + lazy mermaid + copyable code blocks; no raw HTML) · `MarkdownCodeBlock` · `MermaidDiagram` | [stories](https://neuronection.github.io/assistant-ui/?story=chat-markdown--default) |
93
+ | [`chat-message`](./docs/components/chat-message.md) / [`chat-reasoning`](./docs/components/chat-reasoning.md) / [`chat-tool-card`](./docs/components/chat-tool-card.md) | `ChatMessage` (bubble: actions row, variant switcher, edit-and-resend, error/interrupted states) · `ChatReasoning` (collapsible thinking block) · `ChatToolCard` (tool observation: status, duration, args/result) | [stories](https://neuronection.github.io/assistant-ui/?story=chat-message--assistant) |
94
+ | [`chat-composer`](./docs/components/chat-composer.md) | `ChatComposer` — auto-growing IME-safe input with send/stop states, toolbar/attachment/suggestion slots, drag-drop + paste wiring | [stories](https://neuronection.github.io/assistant-ui/?story=chat-composer--default) |
95
+ | [`chat-transcript`](./docs/components/chat-transcript.md) / [`chat-branch-tree`](./docs/components/chat-branch-tree.md) / [`chat-session-list`](./docs/components/chat-session-list.md) | `ChatTranscript` (log semantics, polite announcements, stick-to-bottom + jump pill, optional virtualization) · `ChatBranchTree` (OpenWebUI-style branch rail, keyboard tree nav) · `ChatSessionList` (fuzzy search, date groups, row actions) | [stories](https://neuronection.github.io/assistant-ui/?story=chat-surfaces--transcript) |
96
+ | [`chat-panel`](./docs/components/chat-panel.md) / [`chat-drawer`](./docs/components/chat-drawer.md) / [`chat-launcher`](./docs/components/chat-launcher.md) | the three chat surfaces from one assembly — `ChatPanel` host (`page` \| `sidebar` \| `bubble`) · `ChatDrawer` (resizable sidepanel on Radix Dialog, keyboard resize) · `ChatLauncher` (floating bubble → anchored panel, badge) | [stories](https://neuronection.github.io/assistant-ui/?story=chat-surfaces--transcript) |
91
97
  | [`flow-status`](./docs/components/flow-status.md) | `FlowStatusCard` (multi-step AI-flow progress from the family event vocabulary: per-node status, current-step emphasis, progress summary, error + retryable, controlled retry/cancel/resume, `detail` slot for HITL cards) | [stories](https://neuronection.github.io/assistant-ui/?story=flow-status--running) |
92
98
  | [`settings-shell`](./docs/components/settings-shell.md) / [`provider-form`](./docs/components/provider-form.md) / [`connection-test-row`](./docs/components/connection-test-row.md) | `SettingsShell` (controlled two-pane nav) · `ProviderForm` (write-only API-key field) · `ConnectionTestRow` (idle/testing/ok/fail + latency, `inline` variant + meta slot) | [stories](https://neuronection.github.io/assistant-ui/?story=settings-trio--provider-form-story) |
93
99
  | [`sidebar-nav`](./docs/components/sidebar-nav.md) | `SidebarNav` (family-standard vertical nav: groups + sections, badges, controlled active id, pinned secondary items, optional collapsed icon rail with hover flyouts, header/footer slots) | [stories](https://neuronection.github.io/assistant-ui/?story=sidebar-nav--groups-story) |
@@ -116,6 +122,9 @@ Guides (`docs/guides/`):
116
122
  - [AI settings surfaces](./docs/guides/ai-settings.md) — the providers →
117
123
  models → tasks recipe (`ProviderForm`, `ConnectionTestRow`,
118
124
  `ModelRegistry`, `TaskAssignmentPicker`) with real app call-sites
125
+ - [Chat surfaces](./docs/guides/chat-surfaces.md) — the bubble/sidepanel/
126
+ page assembly from the chat modules: transport adapters, the live tail,
127
+ branching (versioning) contract, composer slots
119
128
 
120
129
  Per-component reference (`docs/components/<module>.md`): purpose, import
121
130
  line, props table, controlled contract, i18n contract, snippets,
package/dist/about.js CHANGED
@@ -1,3 +1,3 @@
1
- export { AboutCard, AboutFooterLine, AboutLinkList, AboutNote, AboutPanel, FamilyBadge, SponsorCard, TechChips } from './chunk-INMAUGBK.js';
1
+ export { AboutCard, AboutFooterLine, AboutLinkList, AboutNote, AboutPanel, FamilyBadge, SponsorCard, TechChips } from './chunk-OH7AJ3WY.js';
2
2
  //# sourceMappingURL=about.js.map
3
3
  //# sourceMappingURL=about.js.map
@@ -1,3 +1,3 @@
1
- export { AiMagicFill } from './chunk-EODV6JK7.js';
1
+ export { AiMagicFill } from './chunk-5QTHDB3D.js';
2
2
  //# sourceMappingURL=ai-magic-fill.js.map
3
3
  //# sourceMappingURL=ai-magic-fill.js.map
@@ -0,0 +1,45 @@
1
+ import * as React from 'react';
2
+ import { LucideIcon } from 'lucide-react';
3
+ import { b as BranchTree } from './tree-YaIz73vo.js';
4
+ import './types-DZwzmyKE.js';
5
+
6
+ interface ChatBranchTreeIcons {
7
+ user: LucideIcon;
8
+ assistant: LucideIcon;
9
+ fork: LucideIcon;
10
+ }
11
+ interface ChatBranchTreeLabels {
12
+ tree: string;
13
+ user: string;
14
+ assistant: string;
15
+ forked: (count: number) => string;
16
+ }
17
+ interface ChatBranchTreeNode {
18
+ id: string;
19
+ role: 'user' | 'assistant' | 'system';
20
+ excerpt?: string;
21
+ parentId: string | null;
22
+ activeChildId: string | null;
23
+ childIds: string[];
24
+ }
25
+ interface ChatBranchTreeProps {
26
+ /** From `buildBranchTree` / `linearTree` (chat-core). */
27
+ tree: BranchTree;
28
+ /** Override the pointer-walk active set (e.g. while a select is pending). */
29
+ activeIds?: Set<string>;
30
+ /** Click = flip one pointer (family `select` endpoint, level-flip semantics). */
31
+ onSelect?: (nodeId: string) => void;
32
+ maxExcerpt?: number;
33
+ icons?: Partial<ChatBranchTreeIcons>;
34
+ labels?: Partial<ChatBranchTreeLabels>;
35
+ className?: string;
36
+ }
37
+ /**
38
+ * The OpenWebUI-style conversation tree rail (study's `BranchTreePanel`,
39
+ * family branching contract): recursive commit-graph rows — filled dots on
40
+ * the active path, hollow dots for hidden variants, fork badges, excerpts.
41
+ * `role="tree"` with roving-tabindex keyboard navigation.
42
+ */
43
+ declare const ChatBranchTree: React.ForwardRefExoticComponent<ChatBranchTreeProps & React.RefAttributes<HTMLDivElement>>;
44
+
45
+ export { ChatBranchTree, type ChatBranchTreeIcons, type ChatBranchTreeLabels, type ChatBranchTreeNode, type ChatBranchTreeProps };
@@ -0,0 +1,3 @@
1
+ export { ChatBranchTree } from './chunk-HQIYSW2D.js';
2
+ //# sourceMappingURL=chat-branch-tree.js.map
3
+ //# sourceMappingURL=chat-branch-tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chat-branch-tree.js"}
@@ -0,0 +1,50 @@
1
+ import * as React from 'react';
2
+ import { LucideIcon } from 'lucide-react';
3
+
4
+ interface ChatComposerLabels {
5
+ send: string;
6
+ stop: string;
7
+ placeholder: string;
8
+ ariaLabel: string;
9
+ dropFiles: string;
10
+ }
11
+ interface ChatComposerIcons {
12
+ send: LucideIcon;
13
+ stop: LucideIcon;
14
+ }
15
+ interface ChatComposerProps {
16
+ value: string;
17
+ onValueChange: (value: string) => void;
18
+ /** Enter / Send — IME-safe (composition and keyCode 229 are ignored). */
19
+ onSubmit: () => void;
20
+ /** A turn is in flight — renders the stop control when `onStop` is provided. */
21
+ sending?: boolean;
22
+ onStop?: () => void;
23
+ disabled?: boolean;
24
+ placeholder?: string;
25
+ ariaLabel?: string;
26
+ /** Auto-grow cap before the textarea scrolls. Default 8. */
27
+ maxRows?: number;
28
+ /** Leading slot inside the input row (attach menu, equation, draw…). */
29
+ toolbarStart?: React.ReactNode;
30
+ /** Trailing slot inside the input row (dictation, tools…). */
31
+ toolbarEnd?: React.ReactNode;
32
+ /** Attachment rail above the input (usually `FileQueue` / chips). */
33
+ attachments?: React.ReactNode;
34
+ /** Suggestion chips / context strip above everything. */
35
+ suggestions?: React.ReactNode;
36
+ /** Drag-drop + paste wiring for file attachments. */
37
+ onAttachFiles?: (files: File[]) => void;
38
+ labels?: Partial<ChatComposerLabels>;
39
+ icons?: Partial<ChatComposerIcons>;
40
+ textareaRef?: React.Ref<HTMLTextAreaElement>;
41
+ className?: string;
42
+ }
43
+ /**
44
+ * The family chat input: auto-growing IME-safe textarea, send/stop
45
+ * states, attachment/dictation/toolbar slots, drag-drop + paste file
46
+ * wiring. Presentational + controlled; transports stay app-side.
47
+ */
48
+ declare const ChatComposer: React.ForwardRefExoticComponent<ChatComposerProps & React.RefAttributes<HTMLFormElement>>;
49
+
50
+ export { ChatComposer, type ChatComposerIcons, type ChatComposerLabels, type ChatComposerProps };
@@ -0,0 +1,3 @@
1
+ export { ChatComposer } from './chunk-743FJDRA.js';
2
+ //# sourceMappingURL=chat-composer.js.map
3
+ //# sourceMappingURL=chat-composer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chat-composer.js"}
@@ -0,0 +1,154 @@
1
+ import { b as ChatError } from './types-DZwzmyKE.js';
2
+ export { a as ChatAttachmentView, c as ChatMessageStatus, d as ChatMessageVariants, e as ChatMessageView, C as ChatRole } from './types-DZwzmyKE.js';
3
+ export { B as BranchNode, a as BranchNodeInput, b as BranchTree, c as activePathSet, d as buildBranchTree, l as linearTree, v as variantInfo, w as walkActivePath } from './tree-YaIz73vo.js';
4
+
5
+ interface FlowStepInfo {
6
+ id: string;
7
+ label?: string;
8
+ }
9
+ /**
10
+ * Family streaming vocabulary (guidelines/ai-features.md §5), extended with
11
+ * the `tool_call` observation event. Transports map their wire format
12
+ * (SSE named events, WS topic payloads) onto these shapes app-side; the
13
+ * reducer tolerates unknown `event` values by ignoring them.
14
+ */
15
+ type ChatStreamEvent = {
16
+ event: 'flow_started';
17
+ flow: string;
18
+ run_id?: string;
19
+ steps?: FlowStepInfo[];
20
+ } | {
21
+ event: 'node_started';
22
+ node: string;
23
+ label?: string;
24
+ run_id?: string;
25
+ } | {
26
+ event: 'node_finished';
27
+ node: string;
28
+ label?: string;
29
+ outcome: 'done' | 'failed' | 'interrupted';
30
+ run_id?: string;
31
+ } | {
32
+ event: 'delta';
33
+ text: string;
34
+ kind?: 'text' | 'reasoning';
35
+ run_id?: string;
36
+ } | {
37
+ event: 'tool_call';
38
+ id: string;
39
+ name: string;
40
+ title?: string;
41
+ status: 'running' | 'done' | 'failed';
42
+ args?: string;
43
+ result?: string;
44
+ durationMs?: number;
45
+ run_id?: string;
46
+ } | {
47
+ event: 'interrupt';
48
+ payload: unknown;
49
+ run_id?: string;
50
+ } | {
51
+ event: 'flow_finished';
52
+ result_ref?: string;
53
+ summary?: string;
54
+ run_id?: string;
55
+ } | {
56
+ event: 'flow_failed';
57
+ code: string;
58
+ message: string;
59
+ retryable: boolean;
60
+ run_id?: string;
61
+ };
62
+
63
+ type LiveTurnStatus = 'idle' | 'pending' | 'streaming' | 'interrupted' | 'done' | 'error';
64
+ interface LiveNodeState {
65
+ id: string;
66
+ label?: string;
67
+ status: 'pending' | 'running' | 'done' | 'failed' | 'interrupted';
68
+ }
69
+ interface LiveToolCall {
70
+ id: string;
71
+ name: string;
72
+ title?: string;
73
+ status: 'running' | 'done' | 'failed';
74
+ args?: string;
75
+ result?: string;
76
+ durationMs?: number;
77
+ }
78
+ /**
79
+ * Ephemeral state of the in-flight assistant turn. `text`/`reasoning` are
80
+ * `null` until the first delta (study's "not streaming yet" sentinel);
81
+ * `interrupted` is a resumable pause (HITL) unless `stopped` marks a user
82
+ * cancel; `stopped`/`done`/`error` are terminal for event intake.
83
+ */
84
+ interface LiveTurnState {
85
+ status: LiveTurnStatus;
86
+ text: string | null;
87
+ reasoning: string | null;
88
+ toolCalls: LiveToolCall[];
89
+ nodes: LiveNodeState[];
90
+ error: ChatError | null;
91
+ interruptPayload: unknown | null;
92
+ runId: string | null;
93
+ stopped: boolean;
94
+ startedAt: number | null;
95
+ finishedAt: number | null;
96
+ }
97
+ type LiveTurnAction = {
98
+ type: 'send';
99
+ at: number;
100
+ } | {
101
+ type: 'event';
102
+ event: ChatStreamEvent;
103
+ at?: number;
104
+ } | {
105
+ type: 'stop';
106
+ at: number;
107
+ } | {
108
+ type: 'reset';
109
+ };
110
+ declare const initialLiveTurnState: LiveTurnState;
111
+ /**
112
+ * Pure state machine for one streamed assistant turn — the fixture-testable
113
+ * core behind `useChatStream` (same role career's `chatFlow.ts` plays for
114
+ * `FlowStatusCard`). Unknown event names are ignored (additive contract).
115
+ */
116
+ declare function liveTurnReducer(state: LiveTurnState, action: LiveTurnAction): LiveTurnState;
117
+
118
+ interface ChatStreamTransport {
119
+ /** Enqueue/send a user turn. Resolves when accepted; errors surface as a failed turn. */
120
+ send(input: {
121
+ text: string;
122
+ }): Promise<void>;
123
+ /** Subscribe to the session's stream events; returns an unsubscribe function. */
124
+ subscribe(handlers: {
125
+ onEvent: (event: ChatStreamEvent) => void;
126
+ }): () => void;
127
+ /** Best-effort cancel of the in-flight turn (backend stop endpoint). */
128
+ stop?(): Promise<void>;
129
+ }
130
+ interface UseChatStreamOptions {
131
+ transport: ChatStreamTransport;
132
+ /** Delta coalescing window. Default 33 ms (study's rAF-scale budget). */
133
+ flushMs?: number;
134
+ /** Watchdog for a turn that never terminates. Default 90 000 ms. */
135
+ timeoutMs?: number;
136
+ }
137
+ interface UseChatStreamResult extends LiveTurnState {
138
+ /** The live turn, or `null` when idle — hand to the transcript's `live` slot. */
139
+ live: LiveTurnState | null;
140
+ /** Returns false and does nothing for blank input or while a turn is active. */
141
+ send(text: string): Promise<boolean>;
142
+ stop(): Promise<void>;
143
+ reset(): void;
144
+ }
145
+ /**
146
+ * Transport-injected live-turn state machine for chat surfaces: send →
147
+ * pending → streaming (coalesced text/reasoning deltas, tool calls, node
148
+ * progress) → done / error / interrupted. Persists nothing — the app owns
149
+ * sessions, messages and the branching endpoints; after a terminal state
150
+ * the app refetches and calls `reset()`.
151
+ */
152
+ declare function useChatStream(options: UseChatStreamOptions): UseChatStreamResult;
153
+
154
+ export { ChatError, type ChatStreamEvent, type ChatStreamTransport, type FlowStepInfo, type LiveNodeState, type LiveToolCall, type LiveTurnAction, type LiveTurnState, type LiveTurnStatus, type UseChatStreamOptions, type UseChatStreamResult, initialLiveTurnState, liveTurnReducer, useChatStream };
@@ -0,0 +1,4 @@
1
+ export { initialLiveTurnState, liveTurnReducer, useChatStream } from './chunk-6GNLY2EB.js';
2
+ export { activePathSet, buildBranchTree, linearTree, variantInfo, walkActivePath } from './chunk-Z4IBQ53C.js';
3
+ //# sourceMappingURL=chat-core.js.map
4
+ //# sourceMappingURL=chat-core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chat-core.js"}
@@ -0,0 +1,32 @@
1
+ import * as React from 'react';
2
+
3
+ interface ChatDrawerProps {
4
+ open: boolean;
5
+ onOpenChange: (open: boolean) => void;
6
+ /** The sidepanel content — usually `ChatPanel variant="sidebar"`. */
7
+ panel: React.ReactNode;
8
+ side?: 'right' | 'left';
9
+ /** Controlled width in px (persist app-side). Default 480. */
10
+ width?: number;
11
+ onWidthChange?: (width: number) => void;
12
+ minWidth?: number;
13
+ maxWidth?: number;
14
+ resizable?: boolean;
15
+ closeLabel?: string;
16
+ resizeLabel?: string;
17
+ /** Accessible dialog name (visually hidden). Default "Chat". */
18
+ title?: string;
19
+ /** Below this viewport width the drawer goes full-screen. Default 768. */
20
+ fullScreenBreakpointPx?: number;
21
+ container?: HTMLElement | null;
22
+ overlayClassName?: string;
23
+ className?: string;
24
+ }
25
+ /**
26
+ * The resizable chat sidepanel (health's `AIDrawer` + study's resizable
27
+ * sidebar, family-standard): portal overlay on Radix Dialog (focus trap,
28
+ * Escape), drag + keyboard resize, full-screen below the breakpoint.
29
+ */
30
+ declare const ChatDrawer: React.ForwardRefExoticComponent<ChatDrawerProps & React.RefAttributes<HTMLDivElement>>;
31
+
32
+ export { ChatDrawer, type ChatDrawerProps };
@@ -0,0 +1,3 @@
1
+ export { ChatDrawer } from './chunk-X3C2FBMR.js';
2
+ //# sourceMappingURL=chat-drawer.js.map
3
+ //# sourceMappingURL=chat-drawer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chat-drawer.js"}
@@ -0,0 +1,28 @@
1
+ import * as React from 'react';
2
+ import { LucideIcon } from 'lucide-react';
3
+
4
+ interface ChatLauncherProps {
5
+ /** The anchored panel body — usually `ChatPanel variant="bubble"`. */
6
+ panel: React.ReactNode;
7
+ open?: boolean;
8
+ defaultOpen?: boolean;
9
+ onOpenChange?: (open: boolean) => void;
10
+ position?: 'bottom-right' | 'bottom-left';
11
+ label?: string;
12
+ closeLabel?: string;
13
+ icon?: LucideIcon;
14
+ closeIcon?: LucideIcon;
15
+ /** Unread / activity badge. */
16
+ badge?: number | string;
17
+ container?: HTMLElement | null;
18
+ panelClassName?: string;
19
+ className?: string;
20
+ }
21
+ /**
22
+ * The floating chat bubble (career's `ChatWidget` launcher,
23
+ * family-standard): fixed launcher button opening an anchored, non-modal
24
+ * panel. `aria-expanded` wiring, Escape closes while focus is inside.
25
+ */
26
+ declare const ChatLauncher: React.ForwardRefExoticComponent<ChatLauncherProps & React.RefAttributes<HTMLButtonElement>>;
27
+
28
+ export { ChatLauncher, type ChatLauncherProps };
@@ -0,0 +1,3 @@
1
+ export { ChatLauncher } from './chunk-RPLEI6LQ.js';
2
+ //# sourceMappingURL=chat-launcher.js.map
3
+ //# sourceMappingURL=chat-launcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chat-launcher.js"}
@@ -0,0 +1,64 @@
1
+ import * as React from 'react';
2
+ import { Components, UrlTransform } from 'react-markdown';
3
+
4
+ interface MarkdownCodeBlockLabels {
5
+ copy: string;
6
+ code: string;
7
+ }
8
+ interface MarkdownCodeBlockProps {
9
+ code: string;
10
+ language?: string;
11
+ showLanguage?: boolean;
12
+ labels?: Partial<MarkdownCodeBlockLabels>;
13
+ className?: string;
14
+ }
15
+ /**
16
+ * Standalone fenced-code surface: mono block, optional language tag, hover
17
+ * copy. Plain by design — no highlighting engine bundled (apps may wrap or
18
+ * slot their own renderer through `MarkdownSurface.components`).
19
+ */
20
+ declare const MarkdownCodeBlock: React.ForwardRefExoticComponent<MarkdownCodeBlockProps & React.RefAttributes<HTMLDivElement>>;
21
+
22
+ type MarkdownComponents = Components;
23
+
24
+ interface MarkdownSurfaceProps {
25
+ /** Markdown source (model output is untrusted — raw HTML never renders). */
26
+ value: string;
27
+ /** Live turn: defers mermaid to the final render (streaming floods break diagrams). */
28
+ streaming?: boolean;
29
+ gfm?: boolean;
30
+ math?: boolean;
31
+ /** Render ```mermaid fences as diagrams (forced off while `streaming`). */
32
+ mermaid?: boolean;
33
+ mermaidTheme?: 'neutral' | 'default' | 'dark' | 'forest';
34
+ /** Per-key overrides of the default renderers (mentions, citations, links…). */
35
+ components?: MarkdownComponents;
36
+ urlTransform?: UrlTransform;
37
+ showCodeLanguage?: boolean;
38
+ labels?: Partial<MarkdownCodeBlockLabels>;
39
+ className?: string;
40
+ }
41
+ /**
42
+ * The family's read-only streaming markdown surface: GFM tables, KaTeX math
43
+ * (error-tolerant while streaming), lazily-imported mermaid diagrams, and
44
+ * copyable code blocks with language tags. Raw HTML is never rendered
45
+ * (no `rehype-raw`) — model output is untrusted input (ai-features §7).
46
+ */
47
+ declare const MarkdownSurface: React.NamedExoticComponent<MarkdownSurfaceProps & React.RefAttributes<HTMLDivElement>>;
48
+
49
+ interface MermaidDiagramProps {
50
+ code: string;
51
+ theme?: 'neutral' | 'default' | 'dark' | 'forest';
52
+ labels?: {
53
+ diagram?: string;
54
+ };
55
+ className?: string;
56
+ }
57
+ /**
58
+ * Lazily-rendered mermaid diagram (dynamic `import('mermaid')`, strict
59
+ * security). Falls back to the plain code block when rendering fails —
60
+ * study-assistant's proven behavior.
61
+ */
62
+ declare const MermaidDiagram: React.ForwardRefExoticComponent<MermaidDiagramProps & React.RefAttributes<HTMLDivElement>>;
63
+
64
+ export { MarkdownCodeBlock, type MarkdownCodeBlockLabels, type MarkdownCodeBlockProps, type MarkdownComponents, MarkdownSurface, type MarkdownSurfaceProps, MermaidDiagram, type MermaidDiagramProps };
@@ -0,0 +1,3 @@
1
+ export { MarkdownCodeBlock, MarkdownSurface, MermaidDiagram } from './chunk-DZBTJZZV.js';
2
+ //# sourceMappingURL=chat-markdown.js.map
3
+ //# sourceMappingURL=chat-markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chat-markdown.js"}