@ai-matrx/chat 0.4.0 → 0.4.7

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 (226) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/dist/agent-copy/RichCopySplit.d.ts +17 -0
  3. package/dist/agent-copy/RichCopySplit.js +34 -0
  4. package/dist/agents/addressing/useAgentHref.js +4 -1
  5. package/dist/agents/api/submit-tool-results.js +11 -1
  6. package/dist/agents/components/agent-widgets/chat-assistant/AssistantMessageCard.js +1 -1
  7. package/dist/agents/components/chat/ConversationRecordsChip.js +1 -1
  8. package/dist/agents/components/chat/useCanvasScopedToConversation.js +1 -1
  9. package/dist/agents/components/context-items/bodies/WorkingDocumentBody.d.ts +5 -2
  10. package/dist/agents/components/context-items/bodies/WorkingDocumentBody.js +6 -1
  11. package/dist/agents/components/context-policies-display/ContextValueBody.js +1 -1
  12. package/dist/agents/components/context-preview/ContextCompareView.js +1 -1
  13. package/dist/agents/components/custom-agent/CustomAgentWindow.js +1 -1
  14. package/dist/agents/components/inputs/smart-input/AgentTextarea.d.ts +6 -1
  15. package/dist/agents/components/inputs/smart-input/AgentTextarea.js +2 -2
  16. package/dist/agents/components/inputs/smart-input/ComposerToolsNotice.d.ts +1 -0
  17. package/dist/agents/components/inputs/smart-input/ComposerToolsNotice.js +5 -0
  18. package/dist/agents/components/inputs/smart-input/ConversationContextRail.d.ts +5 -1
  19. package/dist/agents/components/inputs/smart-input/ConversationContextRail.js +6 -1
  20. package/dist/agents/components/inputs/smart-input/InboxQueueStrip.d.ts +6 -1
  21. package/dist/agents/components/inputs/smart-input/InboxQueueStrip.js +6 -1
  22. package/dist/agents/components/inputs/smart-input/InputActionButtons.js +8 -6
  23. package/dist/agents/components/inputs/smart-input/SmartInputFileDropTarget.d.ts +5 -1
  24. package/dist/agents/components/inputs/smart-input/SmartInputFileDropTarget.js +8 -1
  25. package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPill.js +2 -2
  26. package/dist/agents/components/inputs/smart-input/composer/ComposerChipsRow.d.ts +5 -2
  27. package/dist/agents/components/inputs/smart-input/composer/ComposerChipsRow.js +6 -1
  28. package/dist/agents/components/inputs/smart-input/composer/ComposerMetaRow.d.ts +6 -8
  29. package/dist/agents/components/inputs/smart-input/composer/ComposerMetaRow.js +13 -1
  30. package/dist/agents/components/inputs/smart-input/composer/useOutputShapeCatalog.d.ts +1 -1
  31. package/dist/agents/components/inputs/smart-input/composer/useOutputShapeCatalog.js +1 -1
  32. package/dist/agents/components/live-run/LiveRunDisplay.js +1 -1
  33. package/dist/agents/components/live-run/RunSetDisplay.js +1 -1
  34. package/dist/agents/components/memory/components/AgentMemoryAllView.js +1 -1
  35. package/dist/agents/components/messages-display/AgentConversationDisplay.js +4 -1
  36. package/dist/agents/components/messages-display/assistant/AgentAssistantMessage.d.ts +1 -0
  37. package/dist/agents/components/messages-display/assistant/AgentAssistantMessage.js +4 -3
  38. package/dist/agents/components/messages-display/assistant/AgentEmptyMessageDisplay.js +1 -1
  39. package/dist/agents/components/messages-display/assistant/AssistantMessageFooter.d.ts +2 -2
  40. package/dist/agents/components/messages-display/assistant/AssistantMessageFooter.js +4 -7
  41. package/dist/agents/components/messages-display/assistant/InPlaceAnswerEditor.js +2 -2
  42. package/dist/agents/components/messages-display/citations/MessageSourcesRow.js +1 -1
  43. package/dist/agents/components/messages-display/rich-document/chat-message-source.d.ts +2 -0
  44. package/dist/agents/components/messages-display/rich-document/chat-message-source.js +41 -0
  45. package/dist/agents/components/messages-display/rich-document/chatMessageActions.d.ts +31 -0
  46. package/dist/agents/components/messages-display/rich-document/chatMessageActions.js +39 -0
  47. package/dist/agents/components/messages-display/user/AgentUserMessage.d.ts +1 -0
  48. package/dist/agents/components/messages-display/user/AgentUserMessage.js +7 -4
  49. package/dist/agents/components/messages-display/user/CollabNoteMessage.js +1 -1
  50. package/dist/agents/components/messages-display/user/UserActionBar.js +49 -39
  51. package/dist/agents/components/run-controls/panels/shared.d.ts +1 -0
  52. package/dist/agents/components/shared/AgentConversationColumn.js +3 -2
  53. package/dist/agents/components/working-document/WorkingDocumentEditor.d.ts +1 -1
  54. package/dist/agents/components/working-document/WorkingDocumentPanel.js +2 -1
  55. package/dist/agents/components/working-document/workingDocumentSurface.d.ts +1 -1
  56. package/dist/agents/identity/model-catalog.js +5 -3
  57. package/dist/agents/identity/run-tier-store.js +3 -0
  58. package/dist/agents/redux/agent-definition/cache-bust-middleware.js +2 -0
  59. package/dist/agents/redux/agent-definition/selectors.d.ts +237 -0
  60. package/dist/agents/redux/agent-settings/agentSettingsSlice.d.ts +0 -4
  61. package/dist/agents/redux/agent-settings/agentSettingsSlice.js +12 -5
  62. package/dist/agents/redux/agent-settings/selectors.d.ts +12 -0
  63. package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +50 -0
  64. package/dist/agents/redux/agent-shortcuts/selectors.d.ts +147 -0
  65. package/dist/agents/redux/conversation-history/selectors.d.ts +16 -0
  66. package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +2 -0
  67. package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +54 -0
  68. package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +14 -0
  69. package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +5 -0
  70. package/dist/agents/redux/execution-system/host-conversations/conversation-abilities.d.ts +12 -0
  71. package/dist/agents/redux/execution-system/host-conversations/conversation-abilities.js +25 -0
  72. package/dist/agents/redux/execution-system/host-conversations/host-conversation.thunks.d.ts +53 -0
  73. package/dist/agents/redux/execution-system/host-conversations/host-conversation.thunks.js +412 -0
  74. package/dist/agents/redux/execution-system/host-conversations/host-conversations.selectors.d.ts +28 -0
  75. package/dist/agents/redux/execution-system/host-conversations/host-conversations.selectors.js +41 -0
  76. package/dist/agents/redux/execution-system/host-conversations/host-conversations.slice.d.ts +43 -0
  77. package/dist/agents/redux/execution-system/host-conversations/host-conversations.slice.js +38 -0
  78. package/dist/agents/redux/execution-system/host-conversations/source-registry.d.ts +9 -0
  79. package/dist/agents/redux/execution-system/host-conversations/source-registry.js +15 -0
  80. package/dist/agents/redux/execution-system/host-conversations/useHostConversation.d.ts +4 -0
  81. package/dist/agents/redux/execution-system/host-conversations/useHostConversation.js +24 -0
  82. package/dist/agents/redux/execution-system/inbox/inbox-turn-end.middleware.js +2 -1
  83. package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +3 -0
  84. package/dist/agents/redux/execution-system/instance-resources/default-remark-durability.d.ts +22 -0
  85. package/dist/agents/redux/execution-system/instance-resources/default-remark-durability.js +164 -0
  86. package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +8 -0
  87. package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +5 -0
  88. package/dist/agents/redux/execution-system/instance-ui-state/run-configuration-persist.js +2 -0
  89. package/dist/agents/redux/execution-system/instance-user-input/composer-draft-store.js +20 -0
  90. package/dist/agents/redux/execution-system/instance-user-input/useComposerDraftRestore.js +2 -1
  91. package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +7 -0
  92. package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +1 -0
  93. package/dist/agents/redux/execution-system/messages/messages.selectors.js +1 -1
  94. package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +7 -0
  95. package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +1 -0
  96. package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +14 -0
  97. package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +8 -1
  98. package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +2 -1
  99. package/dist/agents/redux/execution-system/thunks/load-conversation.thunk.js +6 -0
  100. package/dist/agents/redux/execution-system/thunks/load-older-messages.thunk.js +12 -0
  101. package/dist/agents/redux/execution-system/thunks/process-stream.js +6 -4
  102. package/dist/agents/redux/execution-system/thunks/resolve-base-url.js +1 -1
  103. package/dist/agents/redux/execution-system/thunks/smart-execute.thunk.js +43 -0
  104. package/dist/agents/redux/execution-system/utils/assemble-cx-content-blocks.js +2 -1
  105. package/dist/agents/redux/execution-system/utils/continuation-body.d.ts +1 -0
  106. package/dist/agents/redux/execution-system/utils/continuation-body.js +2 -1
  107. package/dist/agents/redux/execution-system/utils/inbound-render-block.d.ts +8 -0
  108. package/dist/agents/redux/execution-system/utils/inbound-render-block.js +17 -2
  109. package/dist/agents/redux/execution-system/utils/normalize-content-blocks.js +1 -1
  110. package/dist/agents/redux/execution-system/utils/progress-data-block.d.ts +11 -0
  111. package/dist/agents/redux/execution-system/utils/progress-data-block.js +37 -0
  112. package/dist/agents/redux/execution-system/utils/stream-block-accumulator.js +10 -8
  113. package/dist/agents/redux/mcp/mcp.slice.js +15 -7
  114. package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +1 -0
  115. package/dist/agents/redux/tools/tools.selectors.d.ts +1 -0
  116. package/dist/agents/redux/tools/tools.thunks.js +3 -0
  117. package/dist/agents/resources/default-picker-items.d.ts +17 -0
  118. package/dist/agents/resources/default-picker-items.js +48 -0
  119. package/dist/agents/runtime-reconnect/ServerOperationBanner.d.ts +6 -1
  120. package/dist/agents/runtime-reconnect/ServerOperationBanner.js +6 -1
  121. package/dist/agents/types/instance.types.d.ts +2 -1
  122. package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +2 -0
  123. package/dist/agents/ui-first-tools/ui/ApprovalCard.js +1 -1
  124. package/dist/agents/ui-first-tools/ui/AskCard.js +1 -1
  125. package/dist/agents/ui-first-tools/ui/lists/TaskPanel.js +1 -1
  126. package/dist/conversation/hooks/useDomCapturePrint.js +1 -1
  127. package/dist/conversation/utils/markdown-print.js +1 -1
  128. package/dist/cx-chat/components/SsrSidebarChats.js +1 -1
  129. package/dist/cx-chat/components/messages/AssistantMessage.js +3 -5
  130. package/dist/cx-chat/components/sidebar/SidebarUserFooter.js +1 -1
  131. package/dist/cx-conversation/AssistantMessage.js +3 -5
  132. package/dist/host/app-data-slots.d.ts +85 -0
  133. package/dist/host/app-data-slots.js +42 -0
  134. package/dist/host/app-identity.d.ts +20 -0
  135. package/dist/host/app-identity.js +21 -0
  136. package/dist/host/bare-host-chrome.d.ts +14 -0
  137. package/dist/host/bare-host-chrome.js +45 -0
  138. package/dist/host/configure.d.ts +9 -1
  139. package/dist/host/configure.js +44 -8
  140. package/dist/host/contract.d.ts +39 -2
  141. package/dist/host/db-types.d.ts +99 -1
  142. package/dist/host/defaults/navigation-hooks.d.ts +2 -0
  143. package/dist/host/defaults/navigation-hooks.js +7 -1
  144. package/dist/host/defaults/navigation.d.ts +4 -3
  145. package/dist/host/defaults/navigation.js +38 -7
  146. package/dist/host/defaults/org.d.ts +12 -4
  147. package/dist/host/defaults/org.js +39 -1
  148. package/dist/host/defaults/prefs.d.ts +11 -0
  149. package/dist/host/defaults/prefs.js +43 -0
  150. package/dist/host/defaults/workspace-gate.d.ts +16 -0
  151. package/dist/host/defaults/workspace-gate.js +89 -0
  152. package/dist/host/diagnostics.d.ts +7 -2
  153. package/dist/host/diagnostics.js +6 -0
  154. package/dist/host/identity.js +2 -1
  155. package/dist/host/index.d.ts +6 -3
  156. package/dist/host/index.js +23 -2
  157. package/dist/host/no-database.d.ts +38 -0
  158. package/dist/host/no-database.js +107 -0
  159. package/dist/host/react.d.ts +1 -0
  160. package/dist/host/react.js +40 -2
  161. package/dist/host/registered-source.js +2 -2
  162. package/dist/host/source.d.ts +130 -0
  163. package/dist/host/source.js +86 -0
  164. package/dist/host/ui-slots.d.ts +9 -31
  165. package/dist/host/ui-slots.js +5 -37
  166. package/dist/mandates/useMandate.js +13 -0
  167. package/dist/public-chat/components/PublicMessageOptionsMenu.js +3 -2
  168. package/dist/store/create-chat-store.d.ts +4 -2
  169. package/dist/store/middlewares.d.ts +5 -0
  170. package/dist/store/slices.d.ts +1 -0
  171. package/dist/store/slices.js +4 -1
  172. package/dist/surfaces/redux/selectors.d.ts +2 -0
  173. package/dist/surfaces/redux/surfaceConfigSlice.js +2 -0
  174. package/dist/surfaces/redux/userStateSlice.js +3 -1
  175. package/dist/surfaces/runtime/agent-offer.js +1 -1
  176. package/dist/surfaces/runtime/surface-writeback.js +1 -1
  177. package/dist/testing/turn-harness.d.ts +35 -0
  178. package/dist/testing/turn-harness.js +85 -0
  179. package/dist/tool-call-visualization/db-renderer/fetchToolRendererRow.js +2 -0
  180. package/dist/tool-call-visualization/redux/selectors.d.ts +1 -0
  181. package/dist/tool-call-visualization/renderers/agent-call/AgentCallInline.js +1 -1
  182. package/dist/tool-call-visualization/renderers/agent-call/CollabCallCard.js +1 -1
  183. package/dist/tool-call-visualization/renderers/fs/FsInline.js +1 -1
  184. package/dist/tool-call-visualization/renderers/random-wheel/RandomWheelInline.js +1 -1
  185. package/dist/tool-call-visualization/renderers/research/ResearchOverlay.js +4 -4
  186. package/dist/tool-call-visualization/renderers/research/SubagentReportBlock.js +2 -2
  187. package/dist/tool-call-visualization/renderers/scrape/ScrapeOverlay.js +1 -1
  188. package/dist/tool-call-visualization/renderers/search/SearchInline.js +1 -1
  189. package/dist/tool-call-visualization/renderers/search/SearchOverlay.js +1 -1
  190. package/dist/tool-call-visualization/renderers/sql/SqlInline.js +1 -1
  191. package/dist/tool-call-visualization/result-fields/KeyValueGrid.js +1 -1
  192. package/dist/tool-call-visualization/result-fields/ResultMarkdown.js +1 -1
  193. package/dist/tool-call-visualization/result-fields/ResultValue.js +1 -1
  194. package/dist/tool-call-visualization/surface-write/SurfaceWriteDiff.js +1 -1
  195. package/dist/ui/AudioOutputBlockSkeleton.d.ts +17 -0
  196. package/dist/ui/AudioOutputBlockSkeleton.js +78 -0
  197. package/dist/ui/chat-protocol-from-stream.d.ts +60 -0
  198. package/dist/ui/chat-protocol-from-stream.js +135 -0
  199. package/dist/ui/markdown-stream/EnhancedChatMarkdown.d.ts +59 -0
  200. package/dist/ui/markdown-stream/EnhancedChatMarkdown.js +1108 -0
  201. package/dist/ui/markdown-stream/MarkdownStream.d.ts +88 -0
  202. package/dist/ui/markdown-stream/MarkdownStream.js +14 -0
  203. package/dist/ui/markdown-stream/MarkdownStreamImpl.d.ts +4 -0
  204. package/dist/ui/markdown-stream/MarkdownStreamImpl.js +86 -0
  205. package/dist/ui/markdown-stream/StreamAwareChatMarkdown.d.ts +58 -0
  206. package/dist/ui/markdown-stream/StreamAwareChatMarkdown.js +294 -0
  207. package/dist/ui/markdown-stream/internal-handlers/AgentCallChildTrace.d.ts +22 -0
  208. package/dist/ui/markdown-stream/internal-handlers/AgentCallChildTrace.js +128 -0
  209. package/dist/ui/markdown-stream/internal-handlers/InlineAssistantError.d.ts +3 -0
  210. package/dist/ui/markdown-stream/internal-handlers/InlineAssistantError.js +26 -0
  211. package/dist/ui/markdown-stream/internal-handlers/InlineThinkingSlot.d.ts +14 -0
  212. package/dist/ui/markdown-stream/internal-handlers/InlineThinkingSlot.js +23 -0
  213. package/dist/ui/markdown-stream/internal-handlers/ToolHandlers.d.ts +42 -0
  214. package/dist/ui/markdown-stream/internal-handlers/ToolHandlers.js +109 -0
  215. package/dist/ui/markdown-stream/useBoundAgentOutputSchema.d.ts +2 -0
  216. package/dist/ui/markdown-stream/useBoundAgentOutputSchema.js +33 -0
  217. package/dist/window-panels/windows/agents/AgentAssistantMarkdownDebugWindow.js +1 -1
  218. package/package.json +10 -5
  219. package/dist/host/content-ir-slots.d.ts +0 -231
  220. package/dist/host/content-ir-slots.js +0 -131
  221. package/dist/host/markdown-slots.d.ts +0 -53
  222. package/dist/host/markdown-slots.js +0 -32
  223. package/dist/host/rich-document-slots.d.ts +0 -123
  224. package/dist/host/rich-document-slots.js +0 -36
  225. package/dist/utils/content-ir/report-kind-at-raw-renderer.d.ts +0 -19
  226. package/dist/utils/content-ir/report-kind-at-raw-renderer.js +0 -32
@@ -12,7 +12,9 @@
12
12
  * port (identity → diagnostics, server → identity + org) always reaches the
13
13
  * resolved one — the host's override when it gave one.
14
14
  */
15
- import type { ChatHost, ChatRoutes, ResolvedChatHost } from "./contract.js";
15
+ import type { ChatAppIdentity, ChatHost, ChatRoutes, ResolvedChatHost } from "./contract.js";
16
+ /** What a host that names no `app` is called: the neutral registered producer, never matrx-frontend. */
17
+ export declare const DEFAULT_CHAT_APP: ChatAppIdentity;
16
18
  /** The platform's production addresses — the default `routes`. */
17
19
  export declare const DEFAULT_CHAT_ROUTES: ChatRoutes;
18
20
  export declare function resolveChatHost(host: ChatHost): ResolvedChatHost;
@@ -22,6 +24,12 @@ export declare function configureChat(host: ChatHost): ResolvedChatHost;
22
24
  export declare function onChatHostConfigured(listener: () => void): () => void;
23
25
  /** The configured host. Throws `ChatHostNotConfiguredError` (with the remedy) when there is none. */
24
26
  export declare function getChatHost(): ResolvedChatHost;
27
+ /**
28
+ * False when the configured host gave a message `source` and no `db` (the db is the stand-in).
29
+ * The branch every global database read takes FIRST (G-DOOR). Unconfigured: true — the read
30
+ * then fails loudly on the missing host, as before.
31
+ */
32
+ export declare function chatHostHasDatabase(): boolean;
25
33
  /** True once `configureChat` (or `<ChatProvider>` in a browser) has run. */
26
34
  export declare function isChatHostConfigured(): boolean;
27
35
  /** Test-only: forget the configured host. */
@@ -8,7 +8,7 @@ import {
8
8
  isChatSourceApp
9
9
  } from "./defaults/diagnostics.js";
10
10
  import { createDbIdentity } from "./defaults/identity.js";
11
- import { createNoPickerOrg } from "./defaults/org.js";
11
+ import { createStoredOrg } from "./defaults/org.js";
12
12
  import { createDefaultServer } from "./defaults/server.js";
13
13
  import { createDefaultServerApi } from "./defaults/server-api.js";
14
14
  import { createDomNotifier } from "./defaults/notify.js";
@@ -19,6 +19,14 @@ import { createDbCatalogGetter } from "./defaults/catalog.js";
19
19
  import { createDefaultChrome } from "./defaults/chrome.js";
20
20
  import { createDbFeedback } from "./defaults/feedback.js";
21
21
  import { createUnhostedCanvas } from "./defaults/canvas.js";
22
+ import { SIGNED_OUT_IDENTITY } from "./defaults/identity.js";
23
+ import {
24
+ NO_DATABASE_CODE_PREFIX,
25
+ createConsoleDiagnostics,
26
+ createNoDatabaseStandIn,
27
+ createNoServerApi
28
+ } from "./no-database.js";
29
+ const DEFAULT_CHAT_APP = Object.freeze({ sourceApp: "chat" });
22
30
  const DEFAULT_CHAT_ROUTES = Object.freeze({
23
31
  workflowStudio: "https://workflows.aimatrx.com"
24
32
  });
@@ -41,24 +49,41 @@ const PORTS = [
41
49
  const EMPTY_REGISTRATIONS = Object.freeze({});
42
50
  function assertDb(host) {
43
51
  const db = host?.db;
44
- if (!db) throw new ChatHostInvalidError("`db` is missing");
52
+ if (!db) {
53
+ if (host?.source) return;
54
+ throw new ChatHostInvalidError("`db` is missing (pass `db`, or a message `source`)");
55
+ }
45
56
  if (typeof db.rpc !== "function" || typeof db.from !== "function" || !db.auth) {
46
57
  throw new ChatHostInvalidError(
47
58
  "`db` is not a Supabase client (no auth/rpc/from)"
48
59
  );
49
60
  }
50
61
  }
62
+ const SOURCE_ONLY_IDENTITY = Object.freeze({
63
+ current: () => SOURCE_ONLY_IDENTITY_VALUE,
64
+ subscribe: () => () => {
65
+ },
66
+ getAccessToken: async () => null
67
+ });
68
+ const SOURCE_ONLY_IDENTITY_VALUE = Object.freeze({ ...SIGNED_OUT_IDENTITY, authReady: true });
51
69
  function resolveChatHost(host) {
52
70
  assertDb(host);
53
- const { db } = host;
71
+ const hasDatabase = Boolean(host.db);
72
+ const reportNoDatabase = (feature) => {
73
+ ref.diagnostics.capture(new Error(`no database: ${feature}`), {
74
+ area: "host-source",
75
+ code: `${NO_DATABASE_CODE_PREFIX}${feature}`
76
+ });
77
+ };
78
+ const db = host.db ?? createNoDatabaseStandIn(reportNoDatabase);
54
79
  const overridden = new Set(
55
80
  PORTS.filter((name) => host[name] !== void 0)
56
81
  );
57
82
  const ref = {};
58
- const diagnostics = host.diagnostics ?? createLogClientErrorDiagnostics(db, { sourceApp: host.sourceApp });
83
+ const diagnostics = host.diagnostics ?? (hasDatabase ? createLogClientErrorDiagnostics(db, { sourceApp: host.sourceApp }) : createConsoleDiagnostics());
59
84
  const notify = host.notify ?? createDomNotifier();
60
- const identity = host.identity ?? createDbIdentity(db, () => ref.diagnostics);
61
- const org = host.org ?? createNoPickerOrg(
85
+ const identity = host.identity ?? (hasDatabase ? createDbIdentity(db, () => ref.diagnostics) : SOURCE_ONLY_IDENTITY);
86
+ const org = host.org ?? createStoredOrg(
62
87
  () => ref.notify,
63
88
  () => ref.diagnostics
64
89
  );
@@ -68,7 +93,10 @@ function resolveChatHost(host) {
68
93
  );
69
94
  const server = {
70
95
  ...serverPort,
71
- api: serverPort.api ?? defaultServerApi(() => ref)
96
+ api: serverPort.api ?? (hasDatabase || host.server ? defaultServerApi(() => ref) : createNoServerApi(
97
+ reportNoDatabase,
98
+ defaultServerApi(() => ref)
99
+ ))
72
100
  };
73
101
  const prefs = host.prefs ?? createWebPrefs();
74
102
  const navigation = host.navigation ?? createWindowNavigation();
@@ -81,7 +109,10 @@ function resolveChatHost(host) {
81
109
  );
82
110
  Object.assign(ref, {
83
111
  db,
112
+ hasDatabase,
113
+ source: host.source ?? null,
84
114
  sourceApp: isChatSourceApp(host.sourceApp) ? host.sourceApp : null,
115
+ app: host.app ?? DEFAULT_CHAT_APP,
85
116
  identity,
86
117
  org,
87
118
  server,
@@ -106,7 +137,7 @@ function defaultServerApi(host) {
106
137
  let configured = null;
107
138
  function configureChat(host) {
108
139
  if (configured?.host === host) return configured.resolved;
109
- if (configured && configured.host.db !== host.db) {
140
+ if (configured && configured.host.db && host.db && configured.host.db !== host.db) {
110
141
  announceOnce(
111
142
  "configure-replaced-db",
112
143
  "configureChat was called again with a different `db`; the newest host replaces the first. Configure the chat host once per page."
@@ -131,6 +162,9 @@ function getChatHost() {
131
162
  if (!configured) throw new ChatHostNotConfiguredError();
132
163
  return configured.resolved;
133
164
  }
165
+ function chatHostHasDatabase() {
166
+ return configured ? configured.resolved.hasDatabase : true;
167
+ }
134
168
  function isChatHostConfigured() {
135
169
  return configured !== null;
136
170
  }
@@ -138,8 +172,10 @@ function _resetChatHostForTests() {
138
172
  configured = null;
139
173
  }
140
174
  export {
175
+ DEFAULT_CHAT_APP,
141
176
  DEFAULT_CHAT_ROUTES,
142
177
  _resetChatHostForTests,
178
+ chatHostHasDatabase,
143
179
  configureChat,
144
180
  getChatHost,
145
181
  isChatHostConfigured,
@@ -24,6 +24,7 @@ import type { CanvasJson } from "@ai-matrx/canvas";
24
24
  import type { ChatCanvasTabKind } from "./canvas-tabs.js";
25
25
  import type { ChatWindowOpeners } from "./window-openers.js";
26
26
  import type { DefaultChatServerApi, DefaultChatServerTypes } from "./defaults/server-api.js";
27
+ import type { ChatMessageSource } from "./source.js";
27
28
  /**
28
29
  * The connection contract (R10). Authenticated, RLS applies. Typed with the
29
30
  * package's own `ChatDatabase` (`./db-types`, generated: the schemas the
@@ -89,6 +90,11 @@ export interface ChatOrgPort {
89
90
  * Never picks one on the person's behalf.
90
91
  */
91
92
  require(reason: string, options?: ChatOrgRequireOptions): Promise<string>;
93
+ /**
94
+ * The person picked an organization in the package's own picker (the bare-host
95
+ * `WorkspaceGate`). Absent on a host that brings its own picker (matrx-frontend).
96
+ */
97
+ choose?(org: ChatOrganization): void;
92
98
  }
93
99
  /**
94
100
  * The host's server client and its types, REGISTERED by module augmentation —
@@ -718,15 +724,39 @@ export interface ChatCanvasPort {
718
724
  useOpeners(): ChatCanvasOpeners;
719
725
  useTab(tab: ChatCanvasTabRef): ChatCanvasTab;
720
726
  }
727
+ /** How a host names itself on the conversations it starts. */
728
+ export interface ChatAppIdentity {
729
+ /** `chat.conversation.source_app` — a producer registered with the server. */
730
+ sourceApp: string;
731
+ /** `source_feature` for every conversation this app starts; absent keeps each screen's own. */
732
+ sourceFeature?: string;
733
+ }
721
734
  export interface ChatHost {
722
- /** R10 connection contract — the ONLY required value. Authenticated, RLS applies. */
723
- db: ChatDb;
735
+ /**
736
+ * R10 connection contract. Authenticated, RLS applies. Required unless `source` is given: a
737
+ * host with no database gets the no-database stand-in (`./no-database`), which refuses and
738
+ * says so per feature.
739
+ */
740
+ db?: ChatDb;
741
+ /**
742
+ * A host-owned message source (`./source`, HOST-OWNED-SOURCE-PLAN §2.2): conversations bound
743
+ * to it (`useHostConversation`) load, stream and send through the host, never a database.
744
+ * Both may be given; at least one is required.
745
+ */
746
+ source?: ChatMessageSource;
724
747
  /**
725
748
  * Which client this is, for the platform errors system (`log_client_error`'s
726
749
  * closed `p_source_app` list). Absent or off the list: diagnostics stay on the
727
750
  * console and say so once.
728
751
  */
729
752
  sourceApp?: ChatSourceApp;
753
+ /**
754
+ * What this app calls itself on the conversations it starts (`source_app`, and when given a
755
+ * `source_feature` that replaces the per-screen one). Both must be registered with the server
756
+ * (`source_attribution`). Absent: the neutral app `chat` and each screen's own feature — a host
757
+ * that is not matrx-frontend never labels its rows as the main app's.
758
+ */
759
+ app?: ChatAppIdentity;
730
760
  /** Default: from db.auth (getSession + onAuthStateChange); admin level from admin.admins. */
731
761
  identity?: ChatIdentityPort;
732
762
  /** Default: no active org; `require` refuses loudly (never auto-picks). */
@@ -765,8 +795,15 @@ export interface ChatHost {
765
795
  export type ChatPortName = "identity" | "org" | "server" | "notify" | "diagnostics" | "prefs" | "navigation" | "windows" | "catalog" | "registry" | "chrome" | "feedback" | "routes" | "canvas";
766
796
  /** Every port present. `overridden` names the ports the host supplied itself. */
767
797
  export interface ResolvedChatHost {
798
+ /** The host's client, or the no-database stand-in when it gave only a `source`. */
768
799
  db: ChatDb;
800
+ /** False when `db` is the stand-in. */
801
+ hasDatabase: boolean;
802
+ /** The host's message source, or null. */
803
+ source: ChatMessageSource | null;
769
804
  sourceApp: ChatSourceApp | null;
805
+ /** The app's identity on the conversations it starts (`DEFAULT_CHAT_APP` when the host gave none). */
806
+ app: ChatAppIdentity;
770
807
  identity: ChatIdentityPort;
771
808
  org: ChatOrgPort;
772
809
  server: ResolvedChatServerPort;
@@ -7156,6 +7156,13 @@ export type ChatDatabase = {
7156
7156
  referencedRelation: "user_request_summary";
7157
7157
  referencedColumns: ["id"];
7158
7158
  },
7159
+ {
7160
+ foreignKeyName: "fk_cx_tool_call_parent";
7161
+ columns: ["parent_call_id"];
7162
+ isOneToOne: false;
7163
+ referencedRelation: "_tool_call_facts";
7164
+ referencedColumns: ["tool_call_id"];
7165
+ },
7159
7166
  {
7160
7167
  foreignKeyName: "fk_cx_tool_call_parent";
7161
7168
  columns: ["parent_call_id"];
@@ -7559,6 +7566,48 @@ export type ChatDatabase = {
7559
7566
  };
7560
7567
  };
7561
7568
  Views: {
7569
+ _tool_call_facts: {
7570
+ Row: {
7571
+ after_trim: number | null;
7572
+ agent_id: string | null;
7573
+ chars_refetched_same_data: number | null;
7574
+ conversation_id: string | null;
7575
+ created_at: string | null;
7576
+ gap_calls: number | null;
7577
+ gap_secs: number | null;
7578
+ is_repeat: number | null;
7579
+ new_data: number | null;
7580
+ output_chars: number | null;
7581
+ person_id: string | null;
7582
+ same_data: number | null;
7583
+ tool_call_id: string | null;
7584
+ tool_name: string | null;
7585
+ unknown_data: number | null;
7586
+ };
7587
+ Relationships: [
7588
+ {
7589
+ foreignKeyName: "cx_tool_call_conversation_id_fkey";
7590
+ columns: ["conversation_id"];
7591
+ isOneToOne: false;
7592
+ referencedRelation: "admin_conversation_summary";
7593
+ referencedColumns: ["id"];
7594
+ },
7595
+ {
7596
+ foreignKeyName: "cx_tool_call_conversation_id_fkey";
7597
+ columns: ["conversation_id"];
7598
+ isOneToOne: false;
7599
+ referencedRelation: "conversation";
7600
+ referencedColumns: ["id"];
7601
+ },
7602
+ {
7603
+ foreignKeyName: "cx_tool_call_conversation_id_fkey";
7604
+ columns: ["conversation_id"];
7605
+ isOneToOne: false;
7606
+ referencedRelation: "conversation_summary";
7607
+ referencedColumns: ["id"];
7608
+ }
7609
+ ];
7610
+ };
7562
7611
  admin_conversation_summary: {
7563
7612
  Row: {
7564
7613
  conversation_type: string | null;
@@ -30382,6 +30431,14 @@ export type ChatDatabase = {
30382
30431
  Args: never;
30383
30432
  Returns: Json;
30384
30433
  };
30434
+ drill_def__tool_refetch: {
30435
+ Args: never;
30436
+ Returns: Json;
30437
+ };
30438
+ drill_def__user_acquisition: {
30439
+ Args: never;
30440
+ Returns: Json;
30441
+ };
30385
30442
  drill_def__workflow_runs: {
30386
30443
  Args: never;
30387
30444
  Returns: Json;
@@ -51548,7 +51605,30 @@ export type ChatDatabase = {
51548
51605
  };
51549
51606
  };
51550
51607
  Views: {
51551
- [_ in never]: never;
51608
+ _acquisition_facts: {
51609
+ Row: {
51610
+ blocked: boolean | null;
51611
+ campaign: string | null;
51612
+ converted_at: string | null;
51613
+ cost: number | null;
51614
+ created_at: string | null;
51615
+ guest_id: string | null;
51616
+ identity_id: string | null;
51617
+ identity_state: string | null;
51618
+ landing_host: string | null;
51619
+ landing_path: string | null;
51620
+ person_id: string | null;
51621
+ referrer: string | null;
51622
+ referrer_host: string | null;
51623
+ referrer_state: string | null;
51624
+ requests: number | null;
51625
+ traffic_kind: string | null;
51626
+ utm_campaign: string | null;
51627
+ utm_medium: string | null;
51628
+ utm_source: string | null;
51629
+ };
51630
+ Relationships: [];
51631
+ };
51552
51632
  };
51553
51633
  Functions: {
51554
51634
  _set_own_organization_choice: {
@@ -51558,6 +51638,20 @@ export type ChatDatabase = {
51558
51638
  };
51559
51639
  Returns: string;
51560
51640
  };
51641
+ acquisition_host_is_local: {
51642
+ Args: {
51643
+ p_host: string;
51644
+ };
51645
+ Returns: boolean;
51646
+ };
51647
+ acquisition_traffic_kind: {
51648
+ Args: {
51649
+ p_landing_host: string;
51650
+ p_referrer: string;
51651
+ p_user_agent: string;
51652
+ };
51653
+ Returns: string;
51654
+ };
51561
51655
  admin_account_facts: {
51562
51656
  Args: never;
51563
51657
  Returns: {
@@ -51633,6 +51727,10 @@ export type ChatDatabase = {
51633
51727
  Args: never;
51634
51728
  Returns: number;
51635
51729
  };
51730
+ my_organization_choices: {
51731
+ Args: never;
51732
+ Returns: Json;
51733
+ };
51636
51734
  my_organization_vault_access: {
51637
51735
  Args: {
51638
51736
  p_organization_id: string;
@@ -1,3 +1,5 @@
1
1
  import type { ChatSearchParams } from "../contract.js";
2
+ /** Fired after the default port moves the address with the history API (no page load). */
3
+ export declare const CHAT_NAVIGATED_EVENT = "ai-matrx-chat:navigated";
2
4
  export declare function useWindowPathname(): string;
3
5
  export declare function useWindowSearchParams(): ChatSearchParams;
@@ -1,11 +1,16 @@
1
1
  "use client";
2
2
  import { useSyncExternalStore } from "react";
3
3
  const hasWindow = () => typeof window !== "undefined";
4
+ const CHAT_NAVIGATED_EVENT = "ai-matrx-chat:navigated";
4
5
  function subscribeToHistory(listener) {
5
6
  if (!hasWindow()) return () => {
6
7
  };
7
8
  window.addEventListener("popstate", listener);
8
- return () => window.removeEventListener("popstate", listener);
9
+ window.addEventListener(CHAT_NAVIGATED_EVENT, listener);
10
+ return () => {
11
+ window.removeEventListener("popstate", listener);
12
+ window.removeEventListener(CHAT_NAVIGATED_EVENT, listener);
13
+ };
9
14
  }
10
15
  function useWindowPathname() {
11
16
  return useSyncExternalStore(
@@ -32,6 +37,7 @@ function useWindowSearchParams() {
32
37
  return paramsFor(search);
33
38
  }
34
39
  export {
40
+ CHAT_NAVIGATED_EVENT,
35
41
  useWindowPathname,
36
42
  useWindowSearchParams
37
43
  };
@@ -1,7 +1,8 @@
1
1
  /**
2
- * Default navigation port: full page loads through `window.location`, links as
3
- * plain anchors, the path and query read from `window.location` (kept current
4
- * across back/forward). matrx-frontend overrides with the package's Next
2
+ * Default navigation port: CLIENT-SIDE navigation through the history API (no page load, the
3
+ * mounted chat keeps its state), links as anchors that navigate the same way, the path and query
4
+ * read from `window.location` (kept current across back/forward and the port's own moves). An
5
+ * address on another origin is a real page load. matrx-frontend overrides with the package's Next
5
6
  * binding (`next/navigation`).
6
7
  */
7
8
  import type { ChatNavigationPort } from "../contract.js";
@@ -1,18 +1,49 @@
1
1
  import { createElement } from "react";
2
- import { useWindowPathname, useWindowSearchParams } from "./navigation-hooks.js";
3
- function PlainLink({ prefetch, replace, scroll, ...anchor }) {
2
+ import { CHAT_NAVIGATED_EVENT, useWindowPathname, useWindowSearchParams } from "./navigation-hooks.js";
3
+ const hasWindow = () => typeof window !== "undefined";
4
+ function sameOriginAddress(href) {
5
+ if (!hasWindow()) return null;
6
+ try {
7
+ const url = new URL(href, window.location.href);
8
+ return url.origin === window.location.origin ? url.pathname + url.search + url.hash : null;
9
+ } catch {
10
+ return null;
11
+ }
12
+ }
13
+ function move(href, mode) {
14
+ if (!hasWindow()) return;
15
+ const address = sameOriginAddress(href);
16
+ if (address === null) {
17
+ if (mode === "push") window.location.assign(href);
18
+ else window.location.replace(href);
19
+ return;
20
+ }
21
+ if (mode === "push") window.history.pushState(null, "", address);
22
+ else window.history.replaceState(null, "", address);
23
+ window.dispatchEvent(new Event(CHAT_NAVIGATED_EVENT));
24
+ }
25
+ function PlainLink({ prefetch, replace, scroll, onClick, ...anchor }) {
4
26
  void prefetch;
5
- void replace;
6
27
  void scroll;
7
- return createElement("a", anchor);
28
+ return createElement("a", {
29
+ ...anchor,
30
+ onClick: (event) => {
31
+ onClick?.(event);
32
+ const href = typeof anchor.href === "string" ? anchor.href : null;
33
+ if (event.defaultPrevented || !href || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || anchor.target && anchor.target !== "_self" || sameOriginAddress(href) === null) {
34
+ return;
35
+ }
36
+ event.preventDefault();
37
+ move(href, replace ? "replace" : "push");
38
+ }
39
+ });
8
40
  }
9
- const hasWindow = () => typeof window !== "undefined";
10
41
  const windowRouter = {
11
42
  push(href) {
12
- if (hasWindow()) window.location.assign(href);
43
+ move(href, "push");
13
44
  },
14
45
  replace(href) {
15
- if (hasWindow()) window.location.replace(href);
46
+ move(href, "replace");
16
47
  },
17
48
  back() {
18
49
  if (hasWindow()) window.history.back();
@@ -1,8 +1,16 @@
1
1
  /**
2
- * Default org port. A bare host has no organization picker, and the platform
3
- * rule is hold-and-set — never auto-pick. So: no active org, and `require`
4
- * refuses with a named, remedied error that is also shown and recorded.
5
- * A host with a picker (matrx-frontend) overrides this port.
2
+ * Org ports for a host that brings no organization port of its own.
3
+ *
4
+ * `createStoredOrg` (the default): the person picks in the package's own
5
+ * `WorkspaceGate` picker (`./workspace-gate.tsx`, memberships read over `db`),
6
+ * the choice is remembered on this device, and `require` resolves it. Nothing is
7
+ * ever picked on the person's behalf (hold-and-set); with no choice yet `require`
8
+ * refuses exactly like `createNoPickerOrg`, and the gate shows the picker.
9
+ * `createNoPickerOrg`: never an organization — for a host that must not write.
10
+ * A host with its own picker (matrx-frontend) overrides the port.
6
11
  */
7
12
  import type { ChatDiagnosticsPort, ChatNotifyPort, ChatOrgPort } from "../contract.js";
8
13
  export declare function createNoPickerOrg(notify: () => ChatNotifyPort, diagnostics: () => ChatDiagnosticsPort): ChatOrgPort;
14
+ /** Where the bare-host choice is remembered (this device only). */
15
+ export declare const CHAT_ACTIVE_ORG_STORAGE_KEY = "matrx-chat:active-organization";
16
+ export declare function createStoredOrg(notify: () => ChatNotifyPort, diagnostics: () => ChatDiagnosticsPort): ChatOrgPort;
@@ -18,6 +18,44 @@ function createNoPickerOrg(notify, diagnostics) {
18
18
  }
19
19
  };
20
20
  }
21
+ const CHAT_ACTIVE_ORG_STORAGE_KEY = "matrx-chat:active-organization";
22
+ function readStored() {
23
+ try {
24
+ if (typeof window === "undefined" || !window.localStorage) return null;
25
+ const raw = window.localStorage.getItem(CHAT_ACTIVE_ORG_STORAGE_KEY);
26
+ if (!raw) return null;
27
+ const parsed = JSON.parse(raw);
28
+ return typeof parsed.id === "string" ? { id: parsed.id, name: parsed.name ?? null } : null;
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+ function createStoredOrg(notify, diagnostics) {
34
+ const refuse = createNoPickerOrg(notify, diagnostics);
35
+ let active = readStored();
36
+ const listeners = /* @__PURE__ */ new Set();
37
+ return {
38
+ active: () => active,
39
+ subscribe(listener) {
40
+ listeners.add(listener);
41
+ return () => listeners.delete(listener);
42
+ },
43
+ require(reason, options) {
44
+ if (active) return Promise.resolve(active.id);
45
+ return refuse.require(reason, options);
46
+ },
47
+ choose(org) {
48
+ active = { id: org.id, name: org.name };
49
+ try {
50
+ window.localStorage?.setItem(CHAT_ACTIVE_ORG_STORAGE_KEY, JSON.stringify(active));
51
+ } catch {
52
+ }
53
+ for (const listener of [...listeners]) listener();
54
+ }
55
+ };
56
+ }
21
57
  export {
22
- createNoPickerOrg
58
+ CHAT_ACTIVE_ORG_STORAGE_KEY,
59
+ createNoPickerOrg,
60
+ createStoredOrg
23
61
  };
@@ -23,3 +23,14 @@ export declare const PREFERENCE_FIELDS: Readonly<Record<string, keyof ChatPrefer
23
23
  export declare function createUnhostedKnobs(): ChatKnobsPort;
24
24
  export declare const CHAT_PREFS_PREFIX = "ai-matrx-chat:";
25
25
  export declare function createWebPrefs(): ChatPrefsPort;
26
+ /**
27
+ * A prefs port the HOST keeps (HOST-OWNED-SOURCE-PLAN §2.2 "Drafts"): a page whose origin
28
+ * changes between launches (a local host on a new port, a desktop window) cannot keep drafts in
29
+ * web storage. The host reads its saved values once (`initial`) and receives every change
30
+ * (`persist`, `null` = removed) to write where it keeps them — a file, an IPC store. Reads are
31
+ * synchronous from memory, so the first render already sees the saved draft.
32
+ */
33
+ export declare function createHostKeptPrefs(options: {
34
+ initial: Readonly<Record<string, string>>;
35
+ persist: (key: string, value: string | null) => void;
36
+ }): ChatPrefsPort;
@@ -168,11 +168,54 @@ function createWebPrefs() {
168
168
  };
169
169
  return port;
170
170
  }
171
+ function createHostKeptPrefs(options) {
172
+ const memory = new Map(Object.entries(options.initial));
173
+ const listeners = /* @__PURE__ */ new Set();
174
+ const emit = (key) => {
175
+ for (const listener of listeners) listener(key);
176
+ };
177
+ const write = (key, value) => {
178
+ try {
179
+ options.persist(key, value);
180
+ } catch (error) {
181
+ announceOnce(
182
+ "prefs-host-write-failed",
183
+ `The host could not save a chat preference or draft (${error instanceof Error ? error.message : String(error)}); it is kept for this session.`
184
+ );
185
+ }
186
+ };
187
+ const port = {
188
+ get: (key) => memory.get(key) ?? null,
189
+ set(key, value) {
190
+ if (memory.get(key) === value) return;
191
+ memory.set(key, value);
192
+ write(key, value);
193
+ emit(key);
194
+ },
195
+ remove(key) {
196
+ if (!memory.has(key)) return;
197
+ memory.delete(key);
198
+ write(key, null);
199
+ emit(key);
200
+ },
201
+ subscribe(listener) {
202
+ listeners.add(listener);
203
+ return () => {
204
+ listeners.delete(listener);
205
+ };
206
+ },
207
+ knob: (key, fallback) => parseKnob(memory.get(key) ?? null, fallback),
208
+ knobs: createUnhostedKnobs(),
209
+ snapshot: () => Object.fromEntries(memory)
210
+ };
211
+ return port;
212
+ }
171
213
  export {
172
214
  CHAT_PREFS_PREFIX,
173
215
  DEFAULT_CHAT_PREFERENCES,
174
216
  PREFERENCE_FIELDS,
175
217
  applyPreferenceWrite,
218
+ createHostKeptPrefs,
176
219
  createUnhostedKnobs,
177
220
  createWebPrefs
178
221
  };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The bare-host `WorkspaceGate`: when a surface is blocked on "no organization chosen",
3
+ * the same area lists the organizations the person belongs to (read over `host.db`) and
4
+ * picking one makes it active (`host.org.choose`). Nothing is picked for the person.
5
+ * A host with its own picker (matrx-frontend) registers its own gate.
6
+ */
7
+ import { type ReactNode } from "react";
8
+ export interface DefaultWorkspaceGateProps {
9
+ blocked: boolean;
10
+ sentence: string;
11
+ description?: string;
12
+ children?: ReactNode;
13
+ compact?: boolean;
14
+ className?: string;
15
+ }
16
+ export declare function DefaultWorkspaceGate({ blocked, sentence, description, children, className }: DefaultWorkspaceGateProps): import("react").JSX.Element;