@ai-matrx/chat 0.6.6 → 0.7.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 (248) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +1 -1
  3. package/dist/agents/components/agent-widgets/AgentChatHistorySidebar.js +16 -55
  4. package/dist/agents/components/chat/chat-door.d.ts +67 -0
  5. package/dist/agents/components/chat/chat-door.js +100 -0
  6. package/dist/agents/components/conversation-history/AgentConversationList.d.ts +83 -0
  7. package/dist/agents/components/conversation-history/AgentConversationList.js +252 -0
  8. package/dist/agents/components/conversation-history/ConversationArchiveSection.d.ts +5 -1
  9. package/dist/agents/components/conversation-history/ConversationArchiveSection.js +22 -4
  10. package/dist/agents/components/conversation-history/ConversationHistorySidebar.js +19 -65
  11. package/dist/agents/components/inputs/input-components/TextareaInput.js +2 -0
  12. package/dist/agents/components/inputs/input-components/VariableInputComponent.js +7 -6
  13. package/dist/agents/components/inputs/smart-input/ConversationCompanionPills.d.ts +3 -0
  14. package/dist/agents/components/inputs/smart-input/ConversationCompanionPills.js +40 -0
  15. package/dist/agents/components/inputs/smart-input/ConversationContextRail.js +6 -29
  16. package/dist/agents/components/inputs/smart-input/DeviceToolsModeRow.d.ts +3 -0
  17. package/dist/agents/components/inputs/smart-input/DeviceToolsModeRow.js +35 -0
  18. package/dist/agents/components/inputs/smart-input/InboxQueueStrip.js +0 -8
  19. package/dist/agents/components/inputs/smart-input/RunToolPicker.js +15 -11
  20. package/dist/agents/components/inputs/smart-input/composer/ComposerPlusMenu.js +22 -0
  21. package/dist/agents/components/inputs/smart-input/rail-pill.d.ts +35 -0
  22. package/dist/agents/components/inputs/smart-input/rail-pill.js +30 -0
  23. package/dist/agents/components/inputs/variable-input-variations/AgentVariableForm.js +52 -48
  24. package/dist/agents/components/run-controls/panels/shared.d.ts +1 -1
  25. package/dist/agents/components/shared/AgentModeController.js +3 -2
  26. package/dist/agents/components/shell/AgentRunSidebarMenu.js +15 -54
  27. package/dist/agents/components/working-document/documents-workspace/DocumentsListRail.js +1 -2
  28. package/dist/agents/engine.d.ts +15 -0
  29. package/dist/agents/engine.js +17 -0
  30. package/dist/agents/hooks/useModelControls.js +3 -175
  31. package/dist/agents/redux/agent-definition/selectors.d.ts +237 -237
  32. package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +50 -50
  33. package/dist/agents/redux/agent-shortcuts/selectors.d.ts +147 -147
  34. package/dist/agents/redux/conversation-history/thunks.js +6 -18
  35. package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +1 -73
  36. package/dist/agents/redux/conversation-list/conversation-list.selectors.js +2 -36
  37. package/dist/agents/redux/conversation-list/conversation-list.slice.d.ts +7 -22
  38. package/dist/agents/redux/conversation-list/conversation-list.slice.js +7 -62
  39. package/dist/agents/redux/conversation-list/conversation-list.thunks.d.ts +0 -25
  40. package/dist/agents/redux/conversation-list/conversation-list.thunks.js +2 -58
  41. package/dist/agents/redux/conversation-list/conversation-list.types.d.ts +0 -5
  42. package/dist/agents/redux/conversation-list/conversation-rows.d.ts +16 -0
  43. package/dist/agents/redux/conversation-list/conversation-rows.js +24 -0
  44. package/dist/agents/redux/conversation-list/conversation-trash.thunks.d.ts +1 -0
  45. package/dist/agents/redux/conversation-list/conversation-trash.thunks.js +13 -18
  46. package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +54 -54
  47. package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +14 -14
  48. package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +5 -5
  49. package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +3 -3
  50. package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +8 -8
  51. package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +5 -5
  52. package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +7 -7
  53. package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +1 -1
  54. package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +7 -7
  55. package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +1 -1
  56. package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +14 -14
  57. package/dist/agents/redux/execution-system/thunks/create-instance.thunk.d.ts +10 -1
  58. package/dist/agents/redux/execution-system/thunks/create-instance.thunk.js +114 -265
  59. package/dist/agents/redux/execution-system/thunks/dispatch-matrx-extend-tool.thunk.js +18 -2
  60. package/dist/agents/redux/execution-system/thunks/dispatch-surface-client-tool.thunk.js +10 -28
  61. package/dist/agents/redux/execution-system/thunks/dispatch-surface-write.thunk.js +10 -25
  62. package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +20 -0
  63. package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +6 -1
  64. package/dist/agents/redux/execution-system/thunks/notify-and-play-dispatcher.d.ts +58 -0
  65. package/dist/agents/redux/execution-system/thunks/notify-and-play-dispatcher.js +62 -0
  66. package/dist/agents/redux/execution-system/thunks/post-delegated-tool-outcome.d.ts +23 -0
  67. package/dist/agents/redux/execution-system/thunks/post-delegated-tool-outcome.js +37 -0
  68. package/dist/agents/redux/execution-system/thunks/resume-instance.thunk.js +10 -2
  69. package/dist/agents/redux/execution-system/utils/build-tool-injection.d.ts +7 -0
  70. package/dist/agents/redux/execution-system/utils/build-tool-injection.js +18 -6
  71. package/dist/agents/redux/execution-system/utils/host-turn.d.ts +45 -0
  72. package/dist/agents/redux/execution-system/utils/host-turn.js +119 -0
  73. package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +1 -1
  74. package/dist/agents/scribe-tools/dispatcher/dispatch-scribe-tool.thunk.d.ts +50 -20
  75. package/dist/agents/scribe-tools/dispatcher/dispatch-scribe-tool.thunk.js +9 -101
  76. package/dist/agents/types/tool-injection.types.d.ts +18 -2
  77. package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +2 -2
  78. package/dist/agents/ui-first-tools/redux/pending-asks.slice.d.ts +2 -1
  79. package/dist/agents/ui-first-tools/redux/resolve-asks-with-input.thunk.js +1 -1
  80. package/dist/agents/ui-first-tools/tools/ask-response.d.ts +29 -0
  81. package/dist/agents/ui-first-tools/tools/ask-response.js +15 -0
  82. package/dist/agents/ui-first-tools/tools/schemas.d.ts +3 -25
  83. package/dist/agents/ui-first-tools/tools/schemas.js +1 -12
  84. package/dist/agents/ui-first-tools/ui/ApprovalCard.js +1 -1
  85. package/dist/agents/ui-first-tools/ui/AskWizard.d.ts +1 -1
  86. package/dist/agents/ui-first-tools/ui/AskWizard.js +1 -1
  87. package/dist/cx-chat/_legacy-stubs.d.ts +5 -5
  88. package/dist/cx-chat/components/SsrSidebarChats.js +13 -15
  89. package/dist/cx-chat/components/messages/UserMessage.d.ts +2 -2
  90. package/dist/cx-chat/types/conversation.d.ts +6 -6
  91. package/dist/cx-chat/utils/buildContentBlocksForSave.d.ts +1 -1
  92. package/dist/cx-chat/utils/cx-content-converter.d.ts +1 -1
  93. package/dist/host/bare-host-chrome.js +9 -3
  94. package/dist/host/composer-extensions.d.ts +75 -0
  95. package/dist/host/composer-extensions.js +92 -0
  96. package/dist/host/configure.js +1 -0
  97. package/dist/host/contract.d.ts +105 -13
  98. package/dist/host/defaults/confirm.d.ts +15 -0
  99. package/dist/host/defaults/confirm.js +25 -0
  100. package/dist/host/defaults/files-ui.d.ts +85 -0
  101. package/dist/host/defaults/files-ui.js +158 -0
  102. package/dist/host/defaults/gates.d.ts +27 -0
  103. package/dist/host/defaults/gates.js +72 -0
  104. package/dist/host/defaults/media-client.d.ts +15 -0
  105. package/dist/host/defaults/media-client.js +40 -0
  106. package/dist/host/defaults/voice.d.ts +81 -0
  107. package/dist/host/defaults/voice.js +239 -0
  108. package/dist/host/device-tool-handoff.d.ts +26 -0
  109. package/dist/host/device-tool-handoff.js +45 -0
  110. package/dist/host/index.d.ts +1 -0
  111. package/dist/host/index.js +4 -1
  112. package/dist/host/microphone.d.ts +11 -0
  113. package/dist/host/microphone.js +17 -0
  114. package/dist/host/ui-slots.d.ts +29 -74
  115. package/dist/host/ui-slots.js +40 -42
  116. package/dist/store/create-chat-store.d.ts +2 -2
  117. package/dist/store/middlewares.d.ts +5 -5
  118. package/dist/store/slices.d.ts +1 -1
  119. package/dist/surfaces/redux/selectors.d.ts +2 -2
  120. package/dist/tool-call-visualization/components/ToolCallVisualization.js +3 -2
  121. package/dist/tool-call-visualization/configured-rows/ConfiguredRowRenderer.d.ts +15 -0
  122. package/dist/tool-call-visualization/configured-rows/ConfiguredRowRenderer.js +36 -0
  123. package/dist/tool-call-visualization/configured-rows/ConfiguredToolRow.d.ts +40 -0
  124. package/dist/tool-call-visualization/configured-rows/ConfiguredToolRow.js +296 -0
  125. package/dist/tool-call-visualization/configured-rows/CopyToolButton.d.ts +23 -0
  126. package/dist/tool-call-visualization/configured-rows/CopyToolButton.js +62 -0
  127. package/dist/tool-call-visualization/configured-rows/ToolProgressView.d.ts +23 -0
  128. package/dist/tool-call-visualization/configured-rows/ToolProgressView.js +147 -0
  129. package/dist/tool-call-visualization/configured-rows/field-components.d.ts +15 -0
  130. package/dist/tool-call-visualization/configured-rows/field-components.js +244 -0
  131. package/dist/tool-call-visualization/configured-rows/helpers.d.ts +39 -0
  132. package/dist/tool-call-visualization/configured-rows/helpers.js +110 -0
  133. package/dist/tool-call-visualization/configured-rows/register.d.ts +25 -0
  134. package/dist/tool-call-visualization/configured-rows/register.js +51 -0
  135. package/dist/tool-call-visualization/configured-rows/registries.d.ts +27 -0
  136. package/dist/tool-call-visualization/configured-rows/registries.js +14 -0
  137. package/dist/tool-call-visualization/configured-rows/to-row-entry.d.ts +8 -0
  138. package/dist/tool-call-visualization/configured-rows/to-row-entry.js +38 -0
  139. package/dist/tool-call-visualization/configured-rows/transforms.d.ts +14 -0
  140. package/dist/tool-call-visualization/configured-rows/transforms.js +30 -0
  141. package/dist/tool-call-visualization/configured-rows/types.d.ts +140 -0
  142. package/dist/tool-call-visualization/redux/selectors.d.ts +1 -1
  143. package/dist/tool-call-visualization/registry/registry.d.ts +1 -1
  144. package/dist/tool-call-visualization/registry/registry.js +8 -1
  145. package/dist/tool-call-visualization/types.d.ts +1 -1
  146. package/dist/ui/chat-protocol-types.d.ts +0 -1
  147. package/dist/ui/ownership.d.ts +25 -0
  148. package/dist/ui/ownership.js +18 -0
  149. package/dist/voice-agent/audio/audioCapture.js +11 -6
  150. package/dist/window-panels/windows/agents/AgentRunHistoryWindow.d.ts +1 -2
  151. package/dist/window-panels/windows/agents/AgentRunHistoryWindow.js +21 -181
  152. package/package.json +4585 -123
  153. package/dist/agents/components/agent-widgets/chat-assistant/AssistantMessageCard.d.ts +0 -7
  154. package/dist/agents/components/agent-widgets/chat-assistant/AssistantMessageCard.js +0 -33
  155. package/dist/agents/components/agent-widgets/chat-assistant/StatusCard.d.ts +0 -6
  156. package/dist/agents/components/agent-widgets/chat-assistant/StatusCard.js +0 -21
  157. package/dist/agents/components/agent-widgets/chat-assistant/UserMessageCard.d.ts +0 -6
  158. package/dist/agents/components/agent-widgets/chat-assistant/UserMessageCard.js +0 -11
  159. package/dist/agents/components/agent-widgets/chat-assistant/VariableInputCard.d.ts +0 -12
  160. package/dist/agents/components/agent-widgets/chat-assistant/VariableInputCard.js +0 -7
  161. package/dist/agents/components/agent-widgets/execution-gates/PreExecutionCard.d.ts +0 -4
  162. package/dist/agents/components/agent-widgets/execution-gates/PreExecutionCard.js +0 -81
  163. package/dist/agents/components/run/run-sidebar/SidebarHeader.d.ts +0 -21
  164. package/dist/agents/components/run/run-sidebar/SidebarHeader.js +0 -50
  165. package/dist/agents/components/run-controls/AdvancedRunSettings/index.d.ts +0 -6
  166. package/dist/agents/components/run-controls/AdvancedRunSettings/index.js +0 -32
  167. package/dist/agents/components/run-controls/RunSettingsModal.d.ts +0 -5
  168. package/dist/agents/components/run-controls/RunSettingsModal.js +0 -22
  169. package/dist/agents/components/shell/AgentBuildSidebarExtras.d.ts +0 -6
  170. package/dist/agents/components/shell/AgentBuildSidebarExtras.js +0 -30
  171. package/dist/agents/constants/agent-system-competitors.d.ts +0 -9
  172. package/dist/agents/constants/agent-system-competitors.js +0 -125
  173. package/dist/agents/hooks/message-crud/useMessageActions.d.ts +0 -29
  174. package/dist/agents/hooks/message-crud/useMessageActions.js +0 -119
  175. package/dist/agents/hooks/useConversationPendingCalls.d.ts +0 -30
  176. package/dist/agents/hooks/useConversationPendingCalls.js +0 -42
  177. package/dist/agents/model-registry/model-classes.d.ts +0 -1
  178. package/dist/agents/model-registry/model-classes.js +0 -1
  179. package/dist/agents/redux/conversation-history/index.d.ts +0 -18
  180. package/dist/agents/redux/conversation-history/index.js +0 -4
  181. package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.thunks.d.ts +0 -38
  182. package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.thunks.js +0 -42
  183. package/dist/agents/redux/execution-system/message-crud/server/compact-turns.thunk.d.ts +0 -58
  184. package/dist/agents/redux/execution-system/message-crud/server/compact-turns.thunk.js +0 -50
  185. package/dist/agents/redux/execution-system/message-crud/server/fork-and-run-server.thunk.d.ts +0 -76
  186. package/dist/agents/redux/execution-system/message-crud/server/fork-and-run-server.thunk.js +0 -101
  187. package/dist/agents/redux/execution-system/thunks/attach-workflow-run.d.ts +0 -38
  188. package/dist/agents/redux/execution-system/thunks/attach-workflow-run.js +0 -25
  189. package/dist/agents/redux/execution-system/utils/source-slice-helpers.d.ts +0 -45
  190. package/dist/agents/redux/execution-system/utils/source-slice-helpers.js +0 -50
  191. package/dist/agents/runtime/realtime/launchRealtimeSession.thunk.d.ts +0 -25
  192. package/dist/agents/runtime/realtime/launchRealtimeSession.thunk.js +0 -15
  193. package/dist/agents/services/agentService.d.ts +0 -12
  194. package/dist/agents/services/agentService.js +0 -92
  195. package/dist/agents/utils/escape-code-fences.d.ts +0 -15
  196. package/dist/agents/utils/escape-code-fences.js +0 -9
  197. package/dist/agents/utils/normalize-managed-options.d.ts +0 -30
  198. package/dist/agents/utils/normalize-managed-options.js +0 -29
  199. package/dist/agents/utils/processedDocumentContext.d.ts +0 -51
  200. package/dist/agents/utils/processedDocumentContext.js +0 -51
  201. package/dist/agents/utils/variable-validation.d.ts +0 -28
  202. package/dist/agents/utils/variable-validation.js +0 -54
  203. package/dist/cx-chat/components/ChatConversationSkeleton.d.ts +0 -9
  204. package/dist/cx-chat/components/ChatConversationSkeleton.js +0 -45
  205. package/dist/cx-chat/components/ChatPanelBackButton.d.ts +0 -1
  206. package/dist/cx-chat/components/ChatPanelBackButton.js +0 -26
  207. package/dist/cx-chat/components/messages/MessageErrorBoundary.d.ts +0 -20
  208. package/dist/cx-chat/components/messages/MessageErrorBoundary.js +0 -40
  209. package/dist/cx-chat/components/variable-inputs/CheckboxGroupInput.d.ts +0 -14
  210. package/dist/cx-chat/components/variable-inputs/CheckboxGroupInput.js +0 -160
  211. package/dist/cx-chat/components/variable-inputs/NumberInput.d.ts +0 -15
  212. package/dist/cx-chat/components/variable-inputs/NumberInput.js +0 -79
  213. package/dist/cx-chat/components/variable-inputs/RadioGroupInput.d.ts +0 -14
  214. package/dist/cx-chat/components/variable-inputs/RadioGroupInput.js +0 -125
  215. package/dist/cx-chat/components/variable-inputs/SelectInput.d.ts +0 -14
  216. package/dist/cx-chat/components/variable-inputs/SelectInput.js +0 -92
  217. package/dist/cx-chat/components/variable-inputs/TextareaInput.d.ts +0 -14
  218. package/dist/cx-chat/components/variable-inputs/TextareaInput.js +0 -46
  219. package/dist/cx-chat/components/variable-inputs/ToggleInput.d.ts +0 -14
  220. package/dist/cx-chat/components/variable-inputs/ToggleInput.js +0 -46
  221. package/dist/cx-chat/hooks/useChatPersistence.d.ts +0 -28
  222. package/dist/cx-chat/hooks/useChatPersistence.js +0 -180
  223. package/dist/cx-chat/hooks/useInstanceBootstrap.d.ts +0 -1
  224. package/dist/cx-chat/hooks/useInstanceBootstrap.js +0 -115
  225. package/dist/cx-chat/types/content.d.ts +0 -184
  226. package/dist/cx-chat/types/content.js +0 -91
  227. package/dist/cx-chat/types/cx-tables.d.ts +0 -176
  228. package/dist/cx-chat/utils/settings-diff.d.ts +0 -13
  229. package/dist/cx-chat/utils/settings-diff.js +0 -25
  230. package/dist/public-chat/components/AgentSelector.d.ts +0 -22
  231. package/dist/public-chat/components/AgentSelector.js +0 -80
  232. package/dist/public-chat/components/GuidedVariableInputs.d.ts +0 -25
  233. package/dist/public-chat/components/GuidedVariableInputs.js +0 -623
  234. package/dist/public-chat/components/PublicVariableInputs.d.ts +0 -29
  235. package/dist/public-chat/components/PublicVariableInputs.js +0 -172
  236. package/dist/public-chat/types/content.d.ts +0 -184
  237. package/dist/public-chat/types/content.js +0 -91
  238. package/dist/tool-call-visualization/renderers/_shared-entity/EntityOpenActions.d.ts +0 -15
  239. package/dist/tool-call-visualization/renderers/_shared-entity/EntityOpenActions.js +0 -31
  240. package/dist/tool-call-visualization/utils/toolCallBlockToLifecycleEntry.d.ts +0 -24
  241. package/dist/tool-call-visualization/utils/toolCallBlockToLifecycleEntry.js +0 -26
  242. package/dist/ui/AudioOutputBlockSkeleton.d.ts +0 -17
  243. package/dist/ui/AudioOutputBlockSkeleton.js +0 -78
  244. package/dist/ui/lazy/PublicChatVariableInputs.d.ts +0 -2
  245. package/dist/ui/lazy/PublicChatVariableInputs.js +0 -16
  246. package/dist/utils/xml/readXmlTag.d.ts +0 -12
  247. package/dist/utils/xml/readXmlTag.js +0 -66
  248. /package/dist/{cx-chat/types/cx-tables.js → tool-call-visualization/configured-rows/types.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,8 +1,42 @@
1
1
  # @ai-matrx/chat
2
2
 
3
+ ## 0.7.0
4
+ ### BREAKING: the exports map is explicit (no wildcards)
5
+
6
+ - `exports` lists every public module by name (`scripts/public-modules.json`, ~900 subpaths + `./host` + `./host/react`);
7
+ the 22 `./<domain>/*` wildcards are gone. A module that no consumer imports is no longer addressable from outside the
8
+ package (the tarball still carries it for the modules that import it). `node scripts/sync-public-surface.mjs --write`
9
+ adds what the sibling repos import; `--check` (`pnpm check:public-surface`, part of `check:package`) fails on a wildcard,
10
+ a listed module with no source, a FRONT_DOOR entry that is not listed, or an in-repo import the map does not export.
11
+ matrx-frontend's `check:chat-public-subpaths` reports a real-but-unexported module as `NOT_EXPORTED`.
12
+ - New stable door `@ai-matrx/chat/agents/engine` (`createInstanceFull`, `destroyInstance`, `patchConversation`, `loadConversation`,
13
+ `smartExecute`, `cancelExecution`, `setUserInputText`, `selectIsExecuting`, `selectLatestRequestStatus`): a host that drives one
14
+ conversation by hand no longer deep-imports the redux internals. FRONT_DOOR now also names the host extension points the
15
+ extension and desktop use (ui-slots, composer-extensions, tool-renderer registry, coding-session reply door, ChatHistorySidebar,
16
+ ChatPanel, CredentialCaptureCard).
17
+ - 36 modules nothing imported (and nothing in the package used) are deleted.
18
+ - The package's own `@ai-matrx/chat/<sub>` self-imports in `src/` resolve through this same map, so they count as consumers:
19
+ 16 self-imported modules (`ui/checkbox`, `ui/tabs`, `ui/aspect-ratio-options`, …) were missing and every bundler build of the
20
+ package failed (workflow-studio's vite build, AI Dream release 2026-10-08). `check:public-surface` and `--write` now include them.
21
+
3
22
  ## 0.6.6
4
23
  ### Unreleased
5
24
 
25
+ - **Configured tool rows** `@ai-matrx/chat/tool-call-visualization/configured-rows/{register,registries,transforms,ConfiguredToolRow,...}`:
26
+ one config-driven row (verb per phase, icon per action, result fields) any host registers its tools into with
27
+ `registerConfiguredToolRenderers(configs | { names, load }, { namePrefixes, stripPrefix })`. New renderer chrome
28
+ `"row"`: the shell draws the renderer directly in every phase. Hosts add icons (`registerRowIcons`), transforms
29
+ (`registerRowTransforms`) and field components (`registerRowFieldComponents`); a config never pulls the whole lucide set.
30
+ `AskUserResponse` / `EMPTY_ASK_RESPONSE` live in `ui-first-tools/tools/ask-response` (no zod); the research overlay tabs load lazily.
31
+
32
+ - **Host door** `@ai-matrx/chat/agents/components/chat/chat-door` (`chatDoor`, `createChatDoor`): a host's own code,
33
+ outside every React tree, puts text in the open composer's draft, opens a conversation, starts a new chat, sends a
34
+ message to an agent/mandate with named variables, and reads the open conversation id. Work asked before the chat
35
+ mounts is held, then delivered; it is refused out loud (`ChatDoorNotReadyError`) if the chat never mounts.
36
+ - **`ChatHost.microphone`** (`ChatMicrophonePort.requestPermission`): a host that cannot show the browser's
37
+ microphone prompt where the chat lives (an extension side panel) obtains the grant elsewhere; the voice capture
38
+ retries once after it resolves `true` (`withMicrophoneGrant`, exported from `/host`). Default none — unchanged.
39
+
6
40
  - **One "Archived" place for every conversation list** (Arman, 2026-10-08). The separate "Archived (N)" toggle
7
41
  and the "Trash" disclosure are gone; `ConversationArchiveSection` (was `ConversationTrashSection`) is the one
8
42
  closed-by-default section at the foot of `ConversationHistorySidebar`, listing archived AND deleted
package/README.md CHANGED
@@ -4,7 +4,7 @@ The one AI Matrx **person ↔ agent** chat. (For person ↔ person threads, use
4
4
  [`@ai-matrx/messaging`](https://www.npmjs.com/package/@ai-matrx/messaging).)
5
5
 
6
6
  One chat, one renderer. The package is the whole chat (running agents, conversations, tool calls,
7
- streaming, context, surfaces, voice) as per-module subpaths over a host contract whose only required
7
+ streaming, context, surfaces, voice) as explicit per-module subpaths (no wildcards: `scripts/public-modules.json`) over a host contract whose only required
8
8
  value is a `db`.
9
9
 
10
10
  ## Install
@@ -1,17 +1,18 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { useEffect, useState } from "react";
4
- import { ArchivedDisclosure } from "@ai-matrx/design-system";
3
+ import { useEffect } from "react";
5
4
  import { useAppDispatch, useAppSelector } from "../../../store/hooks.js";
6
5
  import { ScrollArea } from "@ai-matrx/design-system";
7
6
  import { Loader2, MessageSquare, AlertCircle } from "lucide-react";
8
7
  import { selectInstanceAgentId } from "../../redux/execution-system/instance-ui-state/instance-ui-state.selectors.js";
9
8
  import { fetchAgentConversations } from "../../redux/conversation-list/conversation-list.thunks.js";
10
9
  import { makeSelectAgentConversations } from "../../redux/conversation-list/conversation-list.selectors.js";
11
- import { ItemRow } from "../../../host/ui-slots.js";
12
- import { buildConversationMenu } from "../conversation-actions/conversationActionRegistry.js";
13
- import { renameConversation } from "../../redux/conversation-list/conversation-row-actions.thunks.js";
10
+ import {
11
+ ConversationListRow,
12
+ agentRunHref
13
+ } from "../conversation-history/AgentConversationList.js";
14
14
  import { ErrorAlchemyMenu } from "../../../host/ui-slots.js";
15
+ import { ConversationArchiveSection } from "../conversation-history/ConversationArchiveSection.js";
15
16
  const IDLE_CONVERSATIONS = {
16
17
  status: "idle",
17
18
  conversations: [],
@@ -27,7 +28,6 @@ function AgentChatHistorySidebar({
27
28
  const { status, conversations, archived, error } = useAppSelector(
28
29
  (state) => selectConversations ? selectConversations(state) : IDLE_CONVERSATIONS
29
30
  );
30
- const [showArchived, setShowArchived] = useState(false);
31
31
  useEffect(() => {
32
32
  if (!agentId) return;
33
33
  if (status === "idle") {
@@ -53,46 +53,29 @@ function AgentChatHistorySidebar({
53
53
  ConversationRow,
54
54
  {
55
55
  conv,
56
- agentId,
57
- dispatch
56
+ agentId
58
57
  },
59
58
  conv.conversationId
60
- )),
61
- agentId && /* @__PURE__ */ jsx(
62
- ArchivedDisclosure,
63
- {
64
- count: archived.length,
65
- open: showArchived,
66
- onOpenChange: setShowArchived,
67
- className: "mx-1 mt-1",
68
- children: archived.map((conv) => /* @__PURE__ */ jsx(
69
- ConversationRow,
70
- {
71
- conv,
72
- agentId,
73
- dispatch
74
- },
75
- conv.conversationId
76
- ))
77
- }
78
- )
79
- ] }) })
59
+ ))
60
+ ] }) }),
61
+ agentId && /* @__PURE__ */ jsx(ConversationArchiveSection, { agentIds: [agentId] })
80
62
  ] });
81
63
  }
82
64
  function ConversationRow({
83
65
  conv,
84
- agentId,
85
- dispatch
66
+ agentId
86
67
  }) {
87
68
  const date = conv.updatedAt ? new Date(conv.updatedAt).toLocaleDateString(void 0, {
88
69
  month: "short",
89
70
  day: "numeric"
90
71
  }) : null;
91
- const href = `/agents/go/${agentId}/run?conversationId=${conv.conversationId}`;
92
72
  const secondary = [`${conv.messageCount} msg`, date].filter(Boolean).join(" \xB7 ");
93
73
  return /* @__PURE__ */ jsx(
94
- ItemRow,
74
+ ConversationListRow,
95
75
  {
76
+ conv,
77
+ href: agentRunHref(agentId, conv.conversationId),
78
+ linkRow: true,
96
79
  sourceFeature: "conversation",
97
80
  entity: {
98
81
  type: "conversation",
@@ -100,29 +83,7 @@ function ConversationRow({
100
83
  title: conv.title || "Untitled"
101
84
  },
102
85
  className: "mx-1",
103
- size: "sm",
104
- label: conv.title || "Untitled",
105
- secondaryLabel: secondary || void 0,
106
- href,
107
- menu: () => buildConversationMenu({
108
- conversationId: conv.conversationId,
109
- title: conv.title,
110
- isFavorite: conv.isFavorite ?? false,
111
- isArchived: conv.status === "archived",
112
- excludeFromKg: conv.excludeFromKg ?? false,
113
- href,
114
- dispatch
115
- }),
116
- rename: {
117
- value: conv.title ?? "",
118
- emptyFallback: "Untitled",
119
- onCommit: (next) => void dispatch(
120
- renameConversation({
121
- conversationId: conv.conversationId,
122
- title: next
123
- })
124
- )
125
- }
86
+ secondaryLabel: secondary || void 0
126
87
  }
127
88
  );
128
89
  }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * THE HOST DOOR — what a host's OWN code (outside every React tree, often before the chat has
3
+ * mounted) can ask of the chat: put words in the composer, open a conversation, start a new chat,
4
+ * send a message to an agent, read which conversation is open. A browser extension's right-click
5
+ * menu, a desktop app's deep link and a web page's "ask about this" button all use it.
6
+ *
7
+ * It rebuilds nothing: the draft goes through `appendToComposerDraft` (the same door a tool's "use
8
+ * this path" takes), a conversation opens through the host's navigation port, and a send is the
9
+ * one `launchAgentExecution`. Work asked of it before the chat exists is HELD and delivered the
10
+ * moment `<ChatProvider>` has mounted — never dropped, never run against a half-built store.
11
+ */
12
+ import type { ChatNavigationPort } from "../../../host/contract.js";
13
+ import { type ChatStoreSingleton } from "../../../store/store-singleton.js";
14
+ import type { AnyMandateKey } from "@ai-matrx/agents/mandates";
15
+ import type { ManagedAgentOptions } from "../../types/instance.types.js";
16
+ /** A message to send: to an agent (or the agent a mandate resolves to), with named variables. */
17
+ export interface ChatDoorSend {
18
+ /** The words the person would have typed. */
19
+ text: string;
20
+ agentId?: string;
21
+ mandateKey?: AnyMandateKey;
22
+ /** Agent variables by NAME. Structured information goes here, never inside `text`. */
23
+ variables?: Record<string, unknown>;
24
+ /** Continue THIS conversation (a heartbeat or a reopened thread); absent starts a new one. */
25
+ conversationId?: string | null;
26
+ }
27
+ /** The part of a navigation port the door moves; `address` is the memory port's own current address. */
28
+ export type ChatDoorNavigation = Pick<ChatNavigationPort, "push"> & {
29
+ address?(): string;
30
+ };
31
+ /** What the door reads from the world. Tests hand it fakes; the default reads the live host. */
32
+ export interface ChatDoorEnv {
33
+ /** The host's navigation port, or null while no chat is mounted. */
34
+ navigation(): ChatDoorNavigation | null;
35
+ /** The chat store, or null while no chat is mounted. */
36
+ store(): ChatStoreSingleton | null;
37
+ /** Runs one launch against the store. */
38
+ launch(options: ManagedAgentOptions, store: ChatStoreSingleton): Promise<{
39
+ conversationId: string;
40
+ }>;
41
+ /** The page's own address when the host's navigation port names none. */
42
+ pageAddress(): string;
43
+ }
44
+ export interface ChatDoor {
45
+ /** The conversation the chat shows now, or null (new-chat screen, history, no chat yet). */
46
+ currentConversationId(): string | null;
47
+ openConversation(conversationId: string): Promise<void>;
48
+ startNewChat(): Promise<void>;
49
+ /** Add `text` to the open composer's draft on its own line; nothing is sent. Held until a composer exists. */
50
+ putTextInDraft(text: string): Promise<void>;
51
+ /** Send `message` to an agent and show the conversation. Resolves with the conversation id. */
52
+ sendMessage(message: ChatDoorSend): Promise<{
53
+ conversationId: string;
54
+ }>;
55
+ }
56
+ export interface ChatDoorOptions {
57
+ /** How often held work re-checks that the chat has mounted. */
58
+ pollMs?: number;
59
+ /** How long held work waits for the chat to mount before it is refused out loud. */
60
+ timeoutMs?: number;
61
+ }
62
+ export declare class ChatDoorNotReadyError extends Error {
63
+ constructor();
64
+ }
65
+ export declare function createChatDoor(env: ChatDoorEnv, options?: ChatDoorOptions): ChatDoor;
66
+ /** The door over the live host and store. */
67
+ export declare const chatDoor: ChatDoor;
@@ -0,0 +1,100 @@
1
+ import { getChatHost, isChatHostConfigured } from "../../../host/configure.js";
2
+ import { getStoreSingleton } from "../../../store/store-singleton.js";
3
+ import { appendToComposerDraft } from "../../redux/execution-system/instance-user-input/append-to-composer-draft.thunk.js";
4
+ const CONVERSATION_ADDRESS = /^\/chat\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[/?#]|$)/i;
5
+ class ChatDoorNotReadyError extends Error {
6
+ constructor() {
7
+ super("The chat is not open, so this request could not be delivered to it.");
8
+ this.name = "ChatDoorNotReadyError";
9
+ }
10
+ }
11
+ function createChatDoor(env, options = {}) {
12
+ const pollMs = options.pollMs ?? 100;
13
+ const timeoutMs = options.timeoutMs ?? 3e4;
14
+ const whenReady = () => new Promise((resolve, reject) => {
15
+ const started = Date.now();
16
+ const check = () => {
17
+ const navigation = env.navigation();
18
+ const store = env.store();
19
+ if (navigation && store) return resolve({ navigation, store });
20
+ if (Date.now() - started >= timeoutMs) return reject(new ChatDoorNotReadyError());
21
+ setTimeout(check, pollMs);
22
+ };
23
+ check();
24
+ });
25
+ const addressOf = (navigation) => navigation.address ? navigation.address() : env.pageAddress();
26
+ const conversationIn = (address) => CONVERSATION_ADDRESS.exec(address)?.[1]?.toLowerCase() ?? null;
27
+ const composerConversation = (navigation, store) => {
28
+ const open = conversationIn(addressOf(navigation));
29
+ if (open) return open;
30
+ const focus = store.getState().conversationFocus;
31
+ const key = focus?.lastSurfaceKey;
32
+ return key && focus.bySurface[key]?.input || null;
33
+ };
34
+ return {
35
+ currentConversationId() {
36
+ const navigation = env.navigation();
37
+ return navigation ? conversationIn(addressOf(navigation)) : null;
38
+ },
39
+ async openConversation(conversationId) {
40
+ const { navigation } = await whenReady();
41
+ navigation.push(`/chat/${conversationId}`);
42
+ },
43
+ async startNewChat() {
44
+ const { navigation } = await whenReady();
45
+ navigation.push("/chat/new");
46
+ },
47
+ async putTextInDraft(text) {
48
+ if (!text) return;
49
+ const { navigation, store } = await whenReady();
50
+ const started = Date.now();
51
+ for (; ; ) {
52
+ const conversationId = composerConversation(navigation, store);
53
+ if (conversationId) {
54
+ store.dispatch(appendToComposerDraft(conversationId, text));
55
+ return;
56
+ }
57
+ if (Date.now() - started >= timeoutMs) throw new ChatDoorNotReadyError();
58
+ await new Promise((r) => setTimeout(r, pollMs));
59
+ }
60
+ },
61
+ async sendMessage(message) {
62
+ const { navigation, store } = await whenReady();
63
+ if (!message.agentId && !message.mandateKey) {
64
+ throw new Error("sendMessage needs an agentId or a mandateKey");
65
+ }
66
+ const result = await env.launch(
67
+ {
68
+ ...message.agentId ? { agentId: message.agentId } : {},
69
+ ...message.mandateKey ? { mandateKey: message.mandateKey } : {},
70
+ ...message.conversationId ? { conversationId: message.conversationId } : {},
71
+ surfaceKey: `chat-door:${message.agentId ?? message.mandateKey}`,
72
+ sourceFeature: "agent-runner",
73
+ config: { displayMode: "direct", autoRun: true },
74
+ runtime: {
75
+ userInput: message.text,
76
+ ...message.variables && Object.keys(message.variables).length > 0 ? { variables: message.variables } : {}
77
+ },
78
+ onConversationCreated: (conversationId) => navigation.push(`/chat/${conversationId}`)
79
+ },
80
+ store
81
+ );
82
+ return { conversationId: result.conversationId };
83
+ }
84
+ };
85
+ }
86
+ const chatDoor = createChatDoor({
87
+ // A navigation port that keeps its own address (the memory port) names the open conversation.
88
+ navigation: () => isChatHostConfigured() ? getChatHost().navigation : null,
89
+ store: () => getStoreSingleton(),
90
+ async launch(options, store) {
91
+ const { launchAgentExecution } = await import("../../redux/execution-system/thunks/launch-agent-execution.thunk.js");
92
+ return store.dispatch(launchAgentExecution(options)).unwrap();
93
+ },
94
+ pageAddress: () => typeof window === "undefined" ? "/" : window.location.pathname + window.location.search
95
+ });
96
+ export {
97
+ ChatDoorNotReadyError,
98
+ chatDoor,
99
+ createChatDoor
100
+ };
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The ONE agent conversation list — loader hook, row, version groups.
3
+ *
4
+ * Every "the runs of this agent" panel (the agent-run history window, the
5
+ * advanced-editor History tab, the agent chat history sidebar, the run sidebar
6
+ * menu) used to carry its own copy of: resolve the canonical agent id → read
7
+ * the per-agent cache → fetch when idle → group by version → draw an `ItemRow`
8
+ * with the conversation menu and inline rename. Variants are props now:
9
+ * `sourceFeature`, `href`, `trailing`, `secondaryLabel`, `surfaceKey`.
10
+ */
11
+ import { type ReactNode } from "react";
12
+ import type { ItemRowProps } from "../../../ui/item-types.js";
13
+ import type { ConversationListItem, ConversationListLoadStatus } from "../../redux/conversation-list/conversation-list.types.js";
14
+ import { type ConversationMenuContext } from "../conversation-actions/conversationActionRegistry.js";
15
+ /** "10:42 AM" today · "Yesterday" · "3d ago" · "Oct 8". */
16
+ export declare function formatConversationDate(iso: string | null): string;
17
+ export interface ConversationVersionGroup {
18
+ versionNumber: number;
19
+ conversations: ConversationListItem[];
20
+ }
21
+ /** Highest version first; within a version, newest first. */
22
+ export declare function groupConversationsByVersion(conversations: ConversationListItem[]): ConversationVersionGroup[];
23
+ export declare function agentRunHref(agentId: string, conversationId: string): string;
24
+ export interface AgentConversationListState {
25
+ canonicalAgentId: string | null;
26
+ agentName: string | null;
27
+ status: ConversationListLoadStatus;
28
+ error: string | null;
29
+ fetchedAt: string | null;
30
+ conversations: ConversationListItem[];
31
+ archived: ConversationListItem[];
32
+ versionGroups: ConversationVersionGroup[];
33
+ archivedGroups: ConversationVersionGroup[];
34
+ }
35
+ /**
36
+ * Resolve the agent, read its cached conversation list, and fetch it once when
37
+ * the cache is idle. Pass `null` for "no agent chosen yet".
38
+ */
39
+ export declare function useAgentConversationList(agentId: string | null | undefined): AgentConversationListState;
40
+ export interface ConversationListRowProps {
41
+ conv: ConversationListItem;
42
+ /** Runner link for new-tab / copy-link; also handed to the menu. */
43
+ href: string;
44
+ /** `ItemRow` source feature (drives the row's context-menu family). */
45
+ sourceFeature: ItemRowProps["sourceFeature"];
46
+ active?: boolean;
47
+ onOpen?: () => void;
48
+ openInPlace?: boolean;
49
+ /** Whether the row is a link (`href` on the row) or only a click target. */
50
+ linkRow?: boolean;
51
+ size?: ItemRowProps["size"];
52
+ /** Menu surface key, when the host has one. */
53
+ surfaceKey?: string;
54
+ /** Attach-To entity (omit for hosts whose menu already carries Share). */
55
+ entity?: ItemRowProps["entity"];
56
+ /** The row's owning agent, handed to the menu as a door. */
57
+ agent?: {
58
+ id: string;
59
+ name: string | null;
60
+ };
61
+ /** Source provenance context for the menu. */
62
+ source?: ConversationMenuContext["source"];
63
+ /** Overrides `conv.isFavorite` (a host that overlays pins itself). */
64
+ isFavorite?: boolean;
65
+ /** Label for a conversation with no title. */
66
+ untitled?: string;
67
+ kebabAriaLabel?: string;
68
+ /** Called after a rename or menu mutation lands (the host re-reads). */
69
+ onMutationSuccess?: () => void;
70
+ secondaryLabel?: string;
71
+ leading?: ReactNode;
72
+ trailing?: ReactNode;
73
+ className?: string;
74
+ }
75
+ export declare function ConversationListRow({ conv, href, sourceFeature, active, onOpen, openInPlace, linkRow, size, surfaceKey, entity, agent, source, isFavorite, untitled, kebabAriaLabel, onMutationSuccess, secondaryLabel, leading, trailing, className, }: ConversationListRowProps): import("react").JSX.Element;
76
+ /** Version groups (newest version open) + the one "Archived" section (archived + deleted). */
77
+ export declare function AgentVersionGroupedList({ agentId, list, selectedId, onSelect, sourceFeature, }: {
78
+ agentId: string;
79
+ list: Pick<AgentConversationListState, "versionGroups">;
80
+ selectedId: string | null;
81
+ onSelect: (id: string) => void;
82
+ sourceFeature: ItemRowProps["sourceFeature"];
83
+ }): import("react").JSX.Element;
@@ -0,0 +1,252 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useMemo, useState } from "react";
4
+ import { ChevronDown, ChevronRight, MessageSquare } from "lucide-react";
5
+ import { Button } from "@ai-matrx/design-system/controls";
6
+ import { ItemRow } from "../../../host/ui-slots.js";
7
+ import { useAppDispatch, useAppSelector } from "../../../store/hooks.js";
8
+ import { selectAgentById } from "../../redux/agent-definition/selectors.js";
9
+ import { fetchAgentConversations } from "../../redux/conversation-list/conversation-list.thunks.js";
10
+ import { makeSelectAgentConversations } from "../../redux/conversation-list/conversation-list.selectors.js";
11
+ import { renameConversation } from "../../redux/conversation-list/conversation-row-actions.thunks.js";
12
+ import { ConversationArchiveSection } from "./ConversationArchiveSection.js";
13
+ import {
14
+ buildConversationMenu
15
+ } from "../conversation-actions/conversationActionRegistry.js";
16
+ function formatConversationDate(iso) {
17
+ if (!iso) return "";
18
+ const d = new Date(iso);
19
+ const now = /* @__PURE__ */ new Date();
20
+ const diffDays = Math.floor((now.getTime() - d.getTime()) / 864e5);
21
+ if (diffDays === 0)
22
+ return d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
23
+ if (diffDays === 1) return "Yesterday";
24
+ if (diffDays < 7) return `${diffDays}d ago`;
25
+ return d.toLocaleDateString([], { month: "short", day: "numeric" });
26
+ }
27
+ function groupConversationsByVersion(conversations) {
28
+ const map = /* @__PURE__ */ new Map();
29
+ for (const conv of conversations) {
30
+ const v = conv.agentVersionNumber ?? 0;
31
+ const group = map.get(v);
32
+ if (group) group.push(conv);
33
+ else map.set(v, [conv]);
34
+ }
35
+ return Array.from(map.entries()).sort(([a], [b]) => b - a).map(([versionNumber, convs]) => ({
36
+ versionNumber,
37
+ conversations: [...convs].sort(
38
+ (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
39
+ )
40
+ }));
41
+ }
42
+ function agentRunHref(agentId, conversationId) {
43
+ return `/agents/go/${agentId}/run?conversationId=${conversationId}`;
44
+ }
45
+ function useAgentConversationList(agentId) {
46
+ const dispatch = useAppDispatch();
47
+ const agentName = useAppSelector(
48
+ (state) => agentId ? selectAgentById(state, agentId)?.name ?? null : null
49
+ );
50
+ const canonicalAgentId = useAppSelector((state) => {
51
+ if (!agentId) return null;
52
+ const agent = selectAgentById(state, agentId);
53
+ return agent?.parentAgentId ?? agent?.id ?? agentId;
54
+ });
55
+ const selectConversations = useMemo(
56
+ () => canonicalAgentId ? makeSelectAgentConversations(canonicalAgentId, null) : null,
57
+ [canonicalAgentId]
58
+ );
59
+ const entry = useAppSelector(
60
+ (state) => selectConversations ? selectConversations(state) : null
61
+ );
62
+ const status = entry?.status ?? "idle";
63
+ const conversations = entry?.conversations ?? EMPTY;
64
+ const archived = entry?.archived ?? EMPTY;
65
+ useEffect(() => {
66
+ if (canonicalAgentId && status === "idle") {
67
+ dispatch(
68
+ fetchAgentConversations({
69
+ agentId: canonicalAgentId,
70
+ versionFilter: null
71
+ })
72
+ );
73
+ }
74
+ }, [canonicalAgentId, status, dispatch]);
75
+ const versionGroups = useMemo(
76
+ () => groupConversationsByVersion(conversations),
77
+ [conversations]
78
+ );
79
+ const archivedGroups = useMemo(
80
+ () => groupConversationsByVersion(archived),
81
+ [archived]
82
+ );
83
+ return {
84
+ canonicalAgentId,
85
+ agentName,
86
+ status,
87
+ error: entry?.error ?? null,
88
+ fetchedAt: entry?.fetchedAt ?? null,
89
+ conversations,
90
+ archived,
91
+ versionGroups,
92
+ archivedGroups
93
+ };
94
+ }
95
+ const EMPTY = [];
96
+ function ConversationListRow({
97
+ conv,
98
+ href,
99
+ sourceFeature,
100
+ active,
101
+ onOpen,
102
+ openInPlace,
103
+ linkRow = false,
104
+ size = "sm",
105
+ surfaceKey,
106
+ entity,
107
+ agent,
108
+ source,
109
+ isFavorite,
110
+ untitled = "Untitled",
111
+ kebabAriaLabel,
112
+ onMutationSuccess,
113
+ secondaryLabel,
114
+ leading,
115
+ trailing,
116
+ className
117
+ }) {
118
+ const dispatch = useAppDispatch();
119
+ const title = conv.title?.trim() || untitled;
120
+ return /* @__PURE__ */ jsx(
121
+ ItemRow,
122
+ {
123
+ sourceFeature,
124
+ entity,
125
+ className,
126
+ size,
127
+ label: title,
128
+ secondaryLabel,
129
+ href: linkRow ? href : void 0,
130
+ active,
131
+ onOpen,
132
+ openInPlace,
133
+ leading,
134
+ kebabAriaLabel,
135
+ menu: () => buildConversationMenu({
136
+ conversationId: conv.conversationId,
137
+ title: conv.title,
138
+ isFavorite: isFavorite ?? conv.isFavorite ?? false,
139
+ isArchived: conv.status === "archived",
140
+ excludeFromKg: conv.excludeFromKg ?? false,
141
+ href,
142
+ ...surfaceKey ? { surfaceKey } : {},
143
+ ...agent ? { agent } : {},
144
+ ...source ? { source } : {},
145
+ ...onMutationSuccess ? { onMutationSuccess } : {},
146
+ dispatch
147
+ }),
148
+ rename: {
149
+ value: conv.title ?? "",
150
+ emptyFallback: untitled,
151
+ onCommit: async (next) => {
152
+ const result = await dispatch(
153
+ renameConversation({
154
+ conversationId: conv.conversationId,
155
+ title: next
156
+ })
157
+ );
158
+ if (renameConversation.fulfilled.match(result)) {
159
+ onMutationSuccess?.();
160
+ }
161
+ }
162
+ },
163
+ trailing
164
+ }
165
+ );
166
+ }
167
+ function VersionGroupRow({
168
+ group,
169
+ agentId,
170
+ selectedId,
171
+ onSelect,
172
+ defaultOpen,
173
+ sourceFeature
174
+ }) {
175
+ const [open, setOpen] = useState(defaultOpen);
176
+ const hasActive = group.conversations.some(
177
+ (c) => c.conversationId === selectedId
178
+ );
179
+ return /* @__PURE__ */ jsxs("div", { children: [
180
+ /* @__PURE__ */ jsxs(
181
+ Button,
182
+ {
183
+ variant: "quiet",
184
+ pressed: hasActive,
185
+ icon: open ? /* @__PURE__ */ jsx(ChevronDown, {}) : /* @__PURE__ */ jsx(ChevronRight, {}),
186
+ onClick: () => setOpen((v) => !v),
187
+ className: "w-full",
188
+ children: [
189
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-semibold text-muted-foreground uppercase tracking-wide flex-1 min-w-0 truncate", children: group.versionNumber ? `Version ${group.versionNumber}` : "Latest" }),
190
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground/60 shrink-0 ml-1", children: group.conversations.length })
191
+ ]
192
+ }
193
+ ),
194
+ open && /* @__PURE__ */ jsx("div", { className: "pl-2", children: group.conversations.map((conv) => {
195
+ const date = formatConversationDate(conv.updatedAt);
196
+ return /* @__PURE__ */ jsx(
197
+ ConversationListRow,
198
+ {
199
+ conv,
200
+ href: agentRunHref(agentId, conv.conversationId),
201
+ sourceFeature,
202
+ active: conv.conversationId === selectedId,
203
+ onOpen: () => onSelect(conv.conversationId),
204
+ trailing: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-[10px] text-muted-foreground/70", children: [
205
+ /* @__PURE__ */ jsx(MessageSquare, { className: "w-2.5 h-2.5 shrink-0" }),
206
+ conv.messageCount,
207
+ date ? ` \xB7 ${date}` : ""
208
+ ] })
209
+ },
210
+ conv.conversationId
211
+ );
212
+ }) })
213
+ ] });
214
+ }
215
+ function AgentVersionGroupedList({
216
+ agentId,
217
+ list,
218
+ selectedId,
219
+ onSelect,
220
+ sourceFeature
221
+ }) {
222
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
223
+ list.versionGroups.map((group, i) => /* @__PURE__ */ jsx(
224
+ VersionGroupRow,
225
+ {
226
+ group,
227
+ agentId,
228
+ selectedId,
229
+ onSelect,
230
+ defaultOpen: i === 0,
231
+ sourceFeature
232
+ },
233
+ group.versionNumber
234
+ )),
235
+ /* @__PURE__ */ jsx(
236
+ ConversationArchiveSection,
237
+ {
238
+ agentIds: [agentId],
239
+ onOpen: onSelect,
240
+ className: "mt-1"
241
+ }
242
+ )
243
+ ] });
244
+ }
245
+ export {
246
+ AgentVersionGroupedList,
247
+ ConversationListRow,
248
+ agentRunHref,
249
+ formatConversationDate,
250
+ groupConversationsByVersion,
251
+ useAgentConversationList
252
+ };