@ai-matrx/chat 0.3.11 → 0.3.19

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 (129) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/dist/agent-copy/export.d.ts +10 -2
  3. package/dist/agent-copy/export.js +3 -2
  4. package/dist/agents/components/agent-widgets/chat-assistant/CompactAssistantInput.js +1 -1
  5. package/dist/agents/components/debug/SandboxFileViewer.js +1 -3
  6. package/dist/agents/components/inputs/AgentVariablesInline.js +1 -1
  7. package/dist/agents/components/inputs/smart-input/AgentTextarea.js +1 -1
  8. package/dist/agents/components/inputs/smart-input/InputActionButtons.js +1 -1
  9. package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPeek.js +6 -6
  10. package/dist/agents/components/messages-display/TranscriptIntegrityCopyButton.js +4 -4
  11. package/dist/agents/components/messages-display/user/UserActionBar.js +3 -18
  12. package/dist/agents/components/run/AgentRunHeader.js +1 -2
  13. package/dist/agents/components/shared/AgentConversationColumn.js +1 -1
  14. package/dist/agents/components/shared/AgentHeader.js +1 -2
  15. package/dist/agents/components/shared/AgentHeaderMobile.js +1 -2
  16. package/dist/agents/components/working-document/DocumentLinkPicker.d.ts +1 -1
  17. package/dist/agents/components/working-document/WorkingDocumentPanel.js +1 -1
  18. package/dist/agents/components/working-document/documents-workspace/DocumentsListRail.js +2 -2
  19. package/dist/agents/components/working-document/documents-workspace/DocumentsWorkspace.js +2 -2
  20. package/dist/agents/hooks/useInstanceInputUndoRedo.d.ts +1 -1
  21. package/dist/agents/hooks/useInstanceInputUndoRedo.js +1 -1
  22. package/dist/agents/hooks/useWorkingDocument.js +7 -6
  23. package/dist/agents/model-registry/model-classes.d.ts +1 -43
  24. package/dist/agents/model-registry/model-classes.js +1 -40
  25. package/dist/agents/model-registry/parse.d.ts +1 -88
  26. package/dist/agents/model-registry/parse.js +1 -246
  27. package/dist/agents/prompt-preview/PromptPreviewContent.js +1 -3
  28. package/dist/agents/redux/agent-definition/selectors.d.ts +8 -8
  29. package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +14 -0
  30. package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.js +30 -0
  31. package/dist/agents/redux/execution-system/client-capabilities/desktop-native.provider.js +10 -1
  32. package/dist/agents/redux/execution-system/instance-working-document/cx-working-document.service.d.ts +18 -16
  33. package/dist/agents/redux/execution-system/instance-working-document/cx-working-document.service.js +101 -52
  34. package/dist/agents/redux/execution-system/instance-working-document/instance-working-document.slice.d.ts +2 -2
  35. package/dist/agents/redux/execution-system/instance-working-document/instance-working-document.thunks.d.ts +1 -1
  36. package/dist/agents/redux/execution-system/instance-working-document/scratchpad.thunks.d.ts +1 -1
  37. package/dist/agents/redux/execution-system/message-crud/refetch-single-message.thunk.js +5 -0
  38. package/dist/agents/redux/execution-system/thunks/process-stream.js +2 -2
  39. package/dist/agents/redux/execution-system/utils/stream-block-accumulator.d.ts +14 -0
  40. package/dist/agents/redux/execution-system/utils/stream-block-accumulator.js +28 -0
  41. package/dist/agents/utils/platform-keys.d.ts +15 -0
  42. package/dist/agents/utils/platform-keys.js +69 -0
  43. package/dist/context/sources/scopes.d.ts +1 -1
  44. package/dist/cx-chat/components/user-input/ConversationInput.js +1 -1
  45. package/dist/cx-conversation/ConversationInput.js +1 -1
  46. package/dist/host/db-types.d.ts +23242 -23071
  47. package/dist/host/ui-slots.d.ts +50 -64
  48. package/dist/host/ui-slots.js +12 -52
  49. package/dist/public-chat/components/GuidedVariableInputs.js +1 -1
  50. package/dist/public-chat/components/PublicVariableInputs.js +1 -1
  51. package/dist/react.cjs +11 -23
  52. package/dist/react.cjs.map +1 -1
  53. package/dist/react.js +11 -23
  54. package/dist/react.js.map +1 -1
  55. package/dist/surfaces/manifests/_conversation-document.manifest.js +1 -1
  56. package/dist/tool-call-visualization/registry/registry.js +13 -0
  57. package/dist/ui/composer/useTouchOnlyDevice.js +1 -1
  58. package/dist/ui/skills-types.d.ts +1 -275
  59. package/dist/ui/skills-types.js +1 -0
  60. package/dist/voice-agent/components/VoiceDebugPanel.js +1 -3
  61. package/package.json +60 -34
  62. package/dist/agents/components/run/run-sidebar/AgentRunsSidebar.d.ts +0 -15
  63. package/dist/agents/components/run/run-sidebar/AgentRunsSidebar.js +0 -201
  64. package/dist/agents/components/run-controls/AgentExecutionTestModal.d.ts +0 -36
  65. package/dist/agents/components/run-controls/AgentExecutionTestModal.js +0 -440
  66. package/dist/agents/components/run-controls/AgentLauncherSidebarTester.d.ts +0 -6
  67. package/dist/agents/components/run-controls/AgentLauncherSidebarTester.js +0 -127
  68. package/dist/agents/components/run-controls/AgentWidgetInvokerTester.d.ts +0 -6
  69. package/dist/agents/components/run-controls/AgentWidgetInvokerTester.js +0 -84
  70. package/dist/agents/components/run-controls/CreatorRunPanel.d.ts +0 -22
  71. package/dist/agents/components/run-controls/CreatorRunPanel.js +0 -108
  72. package/dist/agents/components/run-controls/CreatorRunTabContent.d.ts +0 -30
  73. package/dist/agents/components/run-controls/CreatorRunTabContent.js +0 -319
  74. package/dist/agents/components/run-controls/PayloadTab.d.ts +0 -5
  75. package/dist/agents/components/run-controls/PayloadTab.js +0 -388
  76. package/dist/agents/components/run-controls/TesterSettingsPanel.d.ts +0 -71
  77. package/dist/agents/components/run-controls/TesterSettingsPanel.js +0 -470
  78. package/dist/agents/components/shared/AgentOptionsMenu.d.ts +0 -8
  79. package/dist/agents/components/shared/AgentOptionsMenu.js +0 -776
  80. package/dist/agents/components/shared/AgentPeekDuplicateButton.d.ts +0 -8
  81. package/dist/agents/components/shared/AgentPeekDuplicateButton.js +0 -66
  82. package/dist/agents/components/shared/AgentSaveStatus.d.ts +0 -7
  83. package/dist/agents/components/shared/AgentSaveStatus.js +0 -128
  84. package/dist/agents/components/shared/AgentSaveTapButton.d.ts +0 -18
  85. package/dist/agents/components/shared/AgentSaveTapButton.js +0 -105
  86. package/dist/agents/components/shared/useAgentSaveAction.d.ts +0 -33
  87. package/dist/agents/components/shared/useAgentSaveAction.js +0 -179
  88. package/dist/agents/components/shell/AgentsListHeader.d.ts +0 -1
  89. package/dist/agents/components/shell/AgentsListHeader.js +0 -69
  90. package/dist/agents/components/undo-history/AgentEditHistory.d.ts +0 -9
  91. package/dist/agents/components/undo-history/AgentEditHistory.js +0 -244
  92. package/dist/agents/components/unused/AgentSharedHeader.d.ts +0 -3
  93. package/dist/agents/components/unused/AgentSharedHeader.js +0 -134
  94. package/dist/agents/components/widgets/AgentWidgetsPage.d.ts +0 -11
  95. package/dist/agents/components/widgets/AgentWidgetsPage.js +0 -571
  96. package/dist/agents/components/widgets/WidgetVariableInputs.d.ts +0 -8
  97. package/dist/agents/components/widgets/WidgetVariableInputs.js +0 -80
  98. package/dist/agents/components/widgets/build-widget-launch.d.ts +0 -70
  99. package/dist/agents/components/widgets/build-widget-launch.js +0 -90
  100. package/dist/agents/hooks/useAgentAutoSave.d.ts +0 -1
  101. package/dist/agents/hooks/useAgentAutoSave.js +0 -127
  102. package/dist/agents/hooks/useAgentBuilderWriteHandlers.d.ts +0 -9
  103. package/dist/agents/hooks/useAgentBuilderWriteHandlers.js +0 -102
  104. package/dist/agents/hooks/useAgentDuplicateFlow.d.ts +0 -25
  105. package/dist/agents/hooks/useAgentDuplicateFlow.js +0 -133
  106. package/dist/agents/hooks/useAgentUndoRedo.d.ts +0 -31
  107. package/dist/agents/hooks/useAgentUndoRedo.js +0 -134
  108. package/dist/agents/hooks/useAgentUsages.d.ts +0 -17
  109. package/dist/agents/hooks/useAgentUsages.js +0 -36
  110. package/dist/agents/hooks/useDriftAlerts.d.ts +0 -11
  111. package/dist/agents/hooks/useDriftAlerts.js +0 -36
  112. package/dist/agents/hooks/useDriftReport.d.ts +0 -20
  113. package/dist/agents/hooks/useDriftReport.js +0 -34
  114. package/dist/agents/lifecycle/useAgentLifecycleActions.d.ts +0 -17
  115. package/dist/agents/lifecycle/useAgentLifecycleActions.js +0 -63
  116. package/dist/agents/message-flags/useMessageFlags.d.ts +0 -8
  117. package/dist/agents/message-flags/useMessageFlags.js +0 -68
  118. package/dist/agents/services/agent-definition-snapshot.service.d.ts +0 -15
  119. package/dist/agents/services/agent-definition-snapshot.service.js +0 -20
  120. package/dist/agents/surface-catalog-profile.d.ts +0 -96
  121. package/dist/agents/surface-catalog-profile.js +0 -79
  122. package/dist/cx-chat/hooks/useAgentBootstrap.d.ts +0 -1
  123. package/dist/cx-chat/hooks/useAgentBootstrap.js +0 -110
  124. package/dist/host/builder-door.d.ts +0 -61
  125. package/dist/host/builder-door.js +0 -25
  126. package/dist/next/lazy/CreatorRunPanel.d.ts +0 -1
  127. package/dist/next/lazy/CreatorRunPanel.js +0 -11
  128. package/dist/ui/composer/composerSubmit.d.ts +0 -50
  129. package/dist/ui/composer/composerSubmit.js +0 -32
package/CHANGELOG.md CHANGED
@@ -1,5 +1,88 @@
1
1
  # @ai-matrx/chat
2
2
 
3
+ ## 0.3.19 — 2026-10-07
4
+ ### Working documents fix-up
5
+
6
+ - `host/db-types.ts` regenerated: it now carries the `content` schema the working-document service reads (0.3.18 failed its own type-check without it); `workbench` dropped (no longer read).
7
+
8
+ ## 0.3.18 — 2026-10-07 (not published: type-check failed)
9
+ ### Working documents and scratchpads live in the content store (cleanup C5c)
10
+
11
+ - `cx-working-document.service` reads and writes `content.document` (types `working_document` / `scratch`; text in `body`) instead of the retired `workbench.working_documents`; links are `document` → `conversation` associations; version history reads `content.version_list` / `version_get` / `version_restore`. Exported `WORKING_DOCUMENT_ENTITY` (`"document"`) and `workingDocumentTypeIds()`; `WORKING_DOCUMENT_TOKEN` is removed.
12
+ - Share buttons, row entities and the view-vs-edit gate name the `document` entity; the live editor subscribes to `content.document`.
13
+ - Consumer action: none for UI imports; a host that passed `"working_document"` as an entity or resource type for these documents passes `"document"`.
14
+
15
+ ### The composer key rule lives in kit
16
+
17
+ - `@ai-matrx/chat/ui/composer/composerSubmit` is gone; the rule moved unchanged to `@ai-matrx/kit/composer-keys`
18
+ (Applets' reply box needs it and cannot depend on chat).
19
+ - Consumer action: repoint `@ai-matrx/chat/ui/composer/composerSubmit` imports to `@ai-matrx/kit/composer-keys`.
20
+
21
+ ## 0.3.17 — 2026-10-07
22
+ ### The agent builder leaves chat (AGENT-CORE-PLAN B1)
23
+
24
+ - Removed (now in matrx-frontend `features/agents`): `agents/hooks/{useAgentAutoSave, useAgentBuilderWriteHandlers, useAgentUndoRedo, useAgentDuplicateFlow, useAgentUsages, useDriftAlerts, useDriftReport}`, `agents/lifecycle/useAgentLifecycleActions`, `agents/components/shared/{useAgentSaveAction, AgentOptionsMenu, AgentSaveTapButton, AgentSaveStatus, AgentPeekDuplicateButton}`, `agents/components/undo-history/AgentEditHistory`, `agents/components/shell/AgentsListHeader`, `agents/components/widgets/*`, the creator/tester panels in `agents/components/run-controls/` (`CreatorRunPanel`, `CreatorRunTabContent`, `TesterSettingsPanel`, `AgentExecutionTestModal`, `AgentLauncherSidebarTester`, `AgentWidgetInvokerTester`, `PayloadTab`), `agents/services/agent-definition-snapshot.service`, `agents/message-flags/useMessageFlags`, `agents/surface-catalog-profile`, `next/lazy/CreatorRunPanel`, and `host/builder-door` (retired: chat no longer calls a builder write). Dead files deleted: `cx-chat/hooks/useAgentBootstrap`, `agents/components/run/run-sidebar/AgentRunsSidebar`, `agents/components/unused/AgentSharedHeader`.
25
+ - New contribution slots in `host/ui-slots` (absent when unregistered): `AgentOptionsMenu`, `AgentSaveStatus`, `AgentSaveTapButton`, `AgentPeekDuplicateButton`, `CreatorRunPanel`. Removed slots: the 14 usages/drift thunks and selectors, `useAgentChangeReach`, `AgentSettingsModal`, `SystemInstructionEditor`.
26
+ - The platform helpers (`getPlatform`, `isMacLike`, `isTouchDevice`, undo/redo hints) live at `agents/utils/platform-keys`.
27
+ - The composer's agent peek reads the run tier (`fetchAgentRunTier`), never the full definition.
28
+ - `agents/model-registry/parse`, `agents/model-registry/model-classes` and `ui/skills-types` re-export `@ai-matrx/agents/models` / `/skills`.
29
+ - Guard G2 `check:no-builder-tier` (in `check:package`): builder-tier symbols in chat are shrink-only; only the agent-definition slice/thunks remain (B2).
30
+
31
+ **Consumer action:** register the five new slots with the builder's components (`registerChatUi`), drop `registerBuilderDoor` and the removed slot registrations, and import the moved modules from the app.
32
+
33
+ ### Message actions copy through the kit door (AP-2 A2)
34
+
35
+ - `ChatMessageActions` "Copy" / "Copy as markdown" write through kit `copyText` (async write + textarea fallback, never throws) instead of a raw `navigator.clipboard.writeText`; "Copied" shows only when the words landed, and a refusal is told once through the host notifier with its remedy.
36
+
37
+ **Consumer action:** none.
38
+
39
+ ## 0.3.16 — 2026-10-07
40
+ ### Every subpath resolves for `require` too (P27)
41
+
42
+ - Each `exports` entry gains a `default` condition naming the same ESM file, so a CommonJS caller
43
+ (matrx-frontend's tsx-run scripts such as `check-surface-drift`, Node >= 22 `require(esm)`) resolves
44
+ `@ai-matrx/chat/<domain>/<module>` instead of throwing `ERR_PACKAGE_PATH_NOT_EXPORTED`.
45
+ `verify-modules-tarball` now proves every public subpath resolves through `require` as well.
46
+ - `host/db-types.ts` regenerated from matrx-frontend's current schema (the scope/context tables SCOPES-W3
47
+ retired are gone from `context`).
48
+ - Consumer action: none.
49
+
50
+ ## 0.3.15 — 2026-10-07
51
+ ### The Export menu's .csv download is formula-guarded (AP-2)
52
+
53
+ - `csvExportItem` (the Export menu's `.csv` DOWNLOAD) is always formula-guarded: a person opens it in a spreadsheet, so `=HYPERLINK(...)` arrives as text.
54
+ - `rowsToCsv(rows, columns?, { spreadsheetSafe? })` is guarded by default; pass `{ spreadsheetSafe: false }` only where an AI or a parser reads the text.
55
+
56
+ **Consumer action:** none. A caller that feeds `rowsToCsv` text to an AI passes `{ spreadsheetSafe: false }`.
57
+
58
+ ## 0.3.14 — 2026-10-07
59
+ ### Re-sync before matrx-frontend consumes the published package (P27)
60
+
61
+ - Carries every matrx-frontend `packages/chat` edit after `f0b5af6a6a`: the `CopySplit` host slot (split
62
+ Copy on the person's own message), JSON extraction reading the bytes behind a split wrapper
63
+ (`stream-block-accumulator`, active-request selectors, `process-stream`), agent-copy export, and
64
+ `host/db-types.ts` regenerated from the frontend's current schema (SCOPES-W3 moved the scope tables to
65
+ `deprecated`; `ContextItemRow` reads them there).
66
+ - Consumer action: none.
67
+
68
+ ## 0.3.13 — 2026-10-07
69
+ ### No signed-in-only reads for a signed-out visitor (Applets L4)
70
+
71
+ - `refetchSingleMessage` makes no `chat.message` read for a signed-out visitor (anon holds no grant; a
72
+ guest run on `/p/<slug>` answered eight 42501s per run) and never retries a refusal — the bounded
73
+ durable read waits on lag, not on an error.
74
+ - The desktop-presence warm waits for the chat host (`onChatHostConfigured`): it loaded before
75
+ `<ChatProvider>` rendered and announced "No chat host is configured" on every `/p` load.
76
+ - Consumer action: none.
77
+
78
+ ## 0.3.12 — 2026-10-07
79
+ ### One copy, one toast (AP-2)
80
+
81
+ - Sandbox file viewer, transcript integrity report, prompt preview and voice debug copies passed their
82
+ success words to the notifying `useClipboard` hook instead of toasting a second time after the kit's
83
+ own "Text copied to clipboard!".
84
+ - Consumer action: none.
85
+
3
86
  ## 0.3.11 — 2026-10-07
4
87
  ### Re-sync before matrx-frontend consumes the published package (P27)
5
88
 
@@ -25,11 +25,19 @@ export interface ExportItem {
25
25
  export declare function exportFilename(base: string, extension: string): string;
26
26
  export declare function jsonExportItem(data: unknown | (() => unknown), label?: string): ExportItem;
27
27
  export declare function textExportItem(content: string | (() => string), label: string, extension?: string): ExportItem;
28
- /** Rows → CSV (Alchemy's one writer). Columns: explicit list, or the union of keys across rows. */
28
+ /**
29
+ * Rows → CSV (Alchemy's one writer). Columns: explicit list, or the union of keys across rows.
30
+ * `spreadsheetSafe` defaults ON (kit `spreadsheetSafeByDefault`: a .csv is opened in a
31
+ * spreadsheet, so formula-looking text gets a leading `'`). Pass `{ spreadsheetSafe: false }` ONLY
32
+ * where an AI or a parser reads the text — never for a file a person downloads.
33
+ */
29
34
  export declare function rowsToCsv(rows: Array<Record<string, unknown>>, columns?: Array<{
30
35
  key: string;
31
36
  header: string;
32
- }>): string;
37
+ }>, options?: {
38
+ spreadsheetSafe?: boolean;
39
+ }): string;
40
+ /** The Export menu's .csv DOWNLOAD — a person opens it in a spreadsheet, so it is always formula-guarded. */
33
41
  export declare function csvExportItem(rows: Array<Record<string, unknown>> | (() => Array<Record<string, unknown>>), label?: string, columns?: Array<{
34
42
  key: string;
35
43
  header: string;
@@ -35,14 +35,15 @@ function textExportItem(content, label, extension = "txt") {
35
35
  })
36
36
  };
37
37
  }
38
- function rowsToCsv(rows, columns) {
38
+ function rowsToCsv(rows, columns, options = {}) {
39
39
  const cols = columns ?? [...new Set(rows.flatMap((row) => Object.keys(row)))].map((key) => ({
40
40
  key,
41
41
  header: key
42
42
  }));
43
43
  return toDelimitedText(
44
44
  cols.map((c) => c.header),
45
- rows.map((row) => cols.map((c) => row[c.key] ?? null))
45
+ rows.map((row) => cols.map((c) => row[c.key] ?? null)),
46
+ options.spreadsheetSafe === void 0 ? {} : { spreadsheetSafe: options.spreadsheetSafe }
46
47
  );
47
48
  }
48
49
  function csvExportItem(rows, label = "CSV", columns) {
@@ -36,7 +36,7 @@ import { useTouchOnlyDevice } from "../../../../ui/composer/useTouchOnlyDevice.j
36
36
  import {
37
37
  composerKeyIntent,
38
38
  intentTakesTheKey
39
- } from "../../../../ui/composer/composerSubmit.js";
39
+ } from "@ai-matrx/kit/composer-keys";
40
40
  function CompactAssistantInput({
41
41
  conversationId
42
42
  }) {
@@ -5,7 +5,6 @@ import { toast as copyToast } from "../../../host/notify.js";
5
5
  import { Button } from "@ai-matrx/design-system/controls";
6
6
  import { useCallback, useEffect, useRef, useState } from "react";
7
7
  import { FileText, Loader2, RefreshCw, Copy, Check } from "lucide-react";
8
- import { toast } from "../../../host/notify.js";
9
8
  import { createSandboxFilesystemAdapter } from "../../../host/ui-slots.js";
10
9
  import { ErrorAlchemyMenu } from "../../../host/ui-slots.js";
11
10
  function SandboxFileViewer({
@@ -49,9 +48,8 @@ function SandboxFileViewer({
49
48
  }, [initialPath, sandboxRowId, load]);
50
49
  const handleCopy = async () => {
51
50
  if (content == null) return;
52
- if (!await copyText(content)) return;
51
+ if (!await copyText(content, "File contents copied")) return;
53
52
  setCopied(true);
54
- toast.success("File contents copied");
55
53
  setTimeout(() => setCopied(false), 1500);
56
54
  };
57
55
  return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
@@ -38,7 +38,7 @@ import {
38
38
  } from "../../utils/table-variable.js";
39
39
  import { RowChoicesButton } from "./RowChoicesButton.js";
40
40
  import { isControlVariable } from "@ai-matrx/agents";
41
- import { enterSendsHere } from "../../../ui/composer/composerSubmit.js";
41
+ import { enterSendsHere } from "@ai-matrx/kit/composer-keys";
42
42
  import { Button } from "@ai-matrx/design-system/controls";
43
43
  function AgentVariablesInline({
44
44
  conversationId,
@@ -27,7 +27,7 @@ import { focusUnlessTypingElsewhere } from "../../../../utils/dom/focus-guard.js
27
27
  import {
28
28
  composerKeyIntent,
29
29
  intentTakesTheKey
30
- } from "../../../../ui/composer/composerSubmit.js";
30
+ } from "@ai-matrx/kit/composer-keys";
31
31
  import { readVerticalChrome, snapToLineGrid } from "./textarea-line-grid.js";
32
32
  import { useInstanceInputUndoRedo } from "../../../hooks/useInstanceInputUndoRedo.js";
33
33
  import { ComposerDraftNotice } from "./ComposerDraftNotice.js";
@@ -36,7 +36,7 @@ import {
36
36
  smartExecute,
37
37
  cancelExecution
38
38
  } from "../../../redux/execution-system/thunks/smart-execute.thunk.js";
39
- import { isMacLike } from "../../../hooks/useAgentUndoRedo.js";
39
+ import { isMacLike } from "../../../utils/platform-keys.js";
40
40
  import { MicDeviceMenu } from "../../../../host/ui-slots.js";
41
41
  import { Button, SplitButton } from "@ai-matrx/design-system/controls";
42
42
  import { cn } from "@ai-matrx/design-system";
@@ -3,17 +3,17 @@ import { jsx } from "react/jsx-runtime";
3
3
  import { useEffect } from "react";
4
4
  import { AgentDetailCard, useAgentCatalogState } from "@ai-matrx/agents/catalog/react";
5
5
  import { useAppDispatch, useAppSelector } from "../../../../../store/hooks.js";
6
- import { selectAgentById, selectAgentReadyForBuilder } from "../../../../redux/agent-definition/selectors.js";
7
- import { fetchFullAgent } from "../../../../redux/agent-definition/thunks.js";
8
- import { AgentPeekDuplicateButton } from "../../../shared/AgentPeekDuplicateButton.js";
6
+ import { selectAgentById, selectAgentReadyForExecution } from "../../../../redux/agent-definition/selectors.js";
7
+ import { fetchAgentRunTier } from "../../../../redux/agent-definition/thunks.js";
8
+ import { AgentPeekDuplicateButton } from "../../../../../host/ui-slots.js";
9
9
  function ComposerAgentPeek({ agentId, onDone }) {
10
10
  const dispatch = useAppDispatch();
11
11
  const row = useAgentCatalogState((state) => state.byId[agentId]);
12
12
  const record = useAppSelector((state) => selectAgentById(state, agentId));
13
- const isReady = useAppSelector((state) => selectAgentReadyForBuilder(state, agentId));
13
+ const isReady = useAppSelector((state) => selectAgentReadyForExecution(state, agentId));
14
14
  useEffect(() => {
15
- if (!isReady) void dispatch(fetchFullAgent(agentId)).unwrap().catch(() => void 0);
16
- }, [dispatch, agentId, isReady]);
15
+ if (!row && !isReady) void dispatch(fetchAgentRunTier(agentId)).unwrap().catch(() => void 0);
16
+ }, [dispatch, agentId, isReady, row]);
17
17
  const agent = row ?? (record ? {
18
18
  id: record.id,
19
19
  name: record.name,
@@ -8,7 +8,6 @@ import { Stethoscope } from "lucide-react";
8
8
  import { useAppSelector, useAppStore } from "../../../store/hooks.js";
9
9
  import { selectMessageCount } from "../../redux/execution-system/messages/messages.selectors.js";
10
10
  import { selectStreamPhase } from "../../redux/execution-system/selectors/aggregate.selectors.js";
11
- import { toast } from "../../../host/notify.js";
12
11
  import { useDebugContext } from "../../../host/prefs-react.js";
13
12
  import {
14
13
  buildTranscriptIntegrityReport,
@@ -67,10 +66,11 @@ function TranscriptIntegrityCopyButtonInner({
67
66
  pathname,
68
67
  effectiveVisibleGroupLimit
69
68
  });
70
- if (!await copyText(formatTranscriptIntegrityReport(report))) return;
71
- toast.success(
69
+ if (!await copyText(
70
+ formatTranscriptIntegrityReport(report),
72
71
  report.anomalies.length === 0 ? "Transcript report copied \u2014 no anomalies detected" : `Transcript report copied \u2014 ${report.anomalies.length} anomal${report.anomalies.length === 1 ? "y" : "ies"} flagged`
73
- );
72
+ ))
73
+ return;
74
74
  };
75
75
  return /* @__PURE__ */ jsx(
76
76
  Button,
@@ -2,7 +2,7 @@
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { RegistryActionMenu, buildChatMessageActions, useDocumentDialogsHost } from "../../../../host/rich-document-slots.js";
4
4
  import { useState, Suspense, useCallback } from "react";
5
- import { Copy, Check, Edit, Send, MoreHorizontal, Pin, PinOff, Loader2 } from "lucide-react";
5
+ import { Edit, Send, MoreHorizontal, Pin, PinOff, Loader2 } from "lucide-react";
6
6
  import {
7
7
  togglePinnedMessage,
8
8
  usePendingPinMessageIds,
@@ -12,8 +12,7 @@ import {
12
12
  TapTargetButtonForGroup,
13
13
  TapTargetButtonGroup
14
14
  } from "@ai-matrx/tap-target";
15
- import { copyRichContent } from "../../../../host/ui-slots.js";
16
- import { SpeakerButton } from "../../../../host/ui-slots.js";
15
+ import { CopySplit, SpeakerButton } from "../../../../host/ui-slots.js";
17
16
  import { useAppDispatch, useAppSelector, useAppStore } from "../../../../store/hooks.js";
18
17
  import { useOpenFullScreenMarkdownEditorBridge } from "../../../../host/window-openers.js";
19
18
  import { selectMessagePosition } from "../../../redux/execution-system/messages/messages.selectors.js";
@@ -69,7 +68,6 @@ function UserActionBar({
69
68
  const dispatch = useAppDispatch();
70
69
  const store = useAppStore();
71
70
  const openEditor = useOpenFullScreenMarkdownEditorBridge();
72
- const [isCopied, setIsCopied] = useState(false);
73
71
  const isPinned = usePinnedMessageIds().has(messageId);
74
72
  const pinPending = usePendingPinMessageIds().has(messageId);
75
73
  const [showOptionsMenu, setShowOptionsMenu] = useState(false);
@@ -82,12 +80,6 @@ function UserActionBar({
82
80
  const showOptions = useAppSelector(
83
81
  selectShowUserMessageOptions(conversationId)
84
82
  );
85
- const handleCopy = async () => {
86
- if (await copyRichContent(content, "default", { toast: false })) {
87
- setIsCopied(true);
88
- setTimeout(() => setIsCopied(false), 2e3);
89
- }
90
- };
91
83
  const handleEditAction = useCallback(
92
84
  (actionId, newContent) => routeUserEditAction(dispatch, {
93
85
  actionId,
@@ -183,14 +175,7 @@ function UserActionBar({
183
175
  const canFork = (messagePosition ?? 0) > 0;
184
176
  return /* @__PURE__ */ jsxs(Fragment, { children: [
185
177
  /* @__PURE__ */ jsxs(TapTargetButtonGroup, { surface: "solid", children: [
186
- /* @__PURE__ */ jsx(
187
- TapTargetButtonForGroup,
188
- {
189
- onClick: handleCopy,
190
- ariaLabel: "Copy message",
191
- icon: isCopied ? /* @__PURE__ */ jsx(Check, { className: "w-4 h-4 text-blue-500 dark:text-blue-400" }) : /* @__PURE__ */ jsx(Copy, { className: "w-4 h-4 text-muted-foreground" })
192
- }
193
- ),
178
+ /* @__PURE__ */ jsx(CopySplit, { text: content, label: "Copy message" }),
194
179
  /* @__PURE__ */ jsx(SpeakerButton, { text: content, variant: "group" }),
195
180
  /* @__PURE__ */ jsx(
196
181
  TapTargetButtonForGroup,
@@ -1,7 +1,6 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { AgentModeController } from "../shared/AgentModeController.js";
3
- import { AgentSaveStatus } from "../shared/AgentSaveStatus.js";
4
- import { AgentOptionsMenu } from "../shared/AgentOptionsMenu.js";
3
+ import { AgentSaveStatus, AgentOptionsMenu } from "../../../host/ui-slots.js";
5
4
  import { ReviewAnswersLink } from "../../../host/ui-slots.js";
6
5
  import { AgentSelectorIsland } from "../shared/AgentSelectorIsland.js";
7
6
  import { ChevronLeftTapButton } from "@ai-matrx/tap-target/buttons";
@@ -7,7 +7,7 @@ import {
7
7
  useEffect,
8
8
  useLayoutEffect
9
9
  } from "react";
10
- import { CreatorRunPanel } from "../../../next/lazy/CreatorRunPanel.js";
10
+ import { CreatorRunPanel } from "../../../host/ui-slots.js";
11
11
  import { ArrowDown } from "lucide-react";
12
12
  import { motion } from "motion/react";
13
13
  import { AgentConversationDisplay } from "../messages-display/AgentConversationDisplay.js";
@@ -1,8 +1,7 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { AgentSelectorIsland } from "./AgentSelectorIsland.js";
3
3
  import { AgentModeController } from "./AgentModeController.js";
4
- import { AgentSaveStatus } from "./AgentSaveStatus.js";
5
- import { AgentOptionsMenu } from "./AgentOptionsMenu.js";
4
+ import { AgentSaveStatus, AgentOptionsMenu } from "../../../host/ui-slots.js";
6
5
  import { AgentReferenceCopyButton } from "./AgentReferenceCopyButton.js";
7
6
  import { AgentHeaderMobile } from "./AgentHeaderMobile.js";
8
7
  import { ReviewAnswersLink } from "../../../host/ui-slots.js";
@@ -28,8 +28,7 @@ import {
28
28
  import { cn } from "@ai-matrx/design-system";
29
29
  import { useIsMobile } from "@ai-matrx/kit/media-query";
30
30
  import { HeaderActionsSlot, usePhonePageActions } from "../../../host/chrome.js";
31
- import { AgentOptionsMenu } from "./AgentOptionsMenu.js";
32
- import { AgentSaveTapButton } from "./AgentSaveTapButton.js";
31
+ import { AgentOptionsMenu, AgentSaveTapButton } from "../../../host/ui-slots.js";
33
32
  import {
34
33
  MODES,
35
34
  deriveAgentMode,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * DocumentLinkPicker — pick an existing document (working / scratch) of the
3
3
  * current user to LINK this conversation to. Powers cross-conversation sharing:
4
- * both conversations then point at the same `cx_working_documents` row, so
4
+ * both conversations then point at the same `content.document` row, so
5
5
  * edits round-trip to all of them.
6
6
  *
7
7
  * Desktop: Popover. Mobile: BottomSheet (nested pickers must not use Popover).
@@ -284,7 +284,7 @@ function WorkingDocumentPanel({
284
284
  materialized && binding.kind === "cx_working_document" && !!binding.id && /* @__PURE__ */ jsx(
285
285
  ShareButton,
286
286
  {
287
- resourceType: "working_document",
287
+ resourceType: "document",
288
288
  resourceId: binding.id,
289
289
  resourceName: title || docTitleFallback,
290
290
  variant: "ghost",
@@ -126,10 +126,10 @@ function DocumentsListRail({
126
126
  {
127
127
  sourceFeature: "working-document",
128
128
  entity: {
129
- type: "working_document",
129
+ type: "document",
130
130
  id: d.id,
131
131
  title: label,
132
- resourceType: "working_document"
132
+ resourceType: "document"
133
133
  },
134
134
  size: "sm",
135
135
  active: isActive,
@@ -392,10 +392,10 @@ function DocumentsWorkspace({
392
392
  // has not materialized yet has no id, so it resolves to null and
393
393
  // the entity actions hide rather than target the wrong record.
394
394
  [CONTEXT_MENU_ENTITY_KEY]: tab.documentId ? {
395
- type: "working_document",
395
+ type: "document",
396
396
  id: tab.documentId,
397
397
  title,
398
- resourceType: "working_document"
398
+ resourceType: "document"
399
399
  } : null
400
400
  };
401
401
  },
@@ -1,4 +1,4 @@
1
- import { type Platform } from "./useAgentUndoRedo.js";
1
+ import { type Platform } from "../utils/platform-keys.js";
2
2
  interface UseInstanceInputUndoRedoOptions {
3
3
  conversationId: string | null;
4
4
  /**
@@ -12,7 +12,7 @@ import {
12
12
  getUndoShortcutHint,
13
13
  getRedoShortcutHint,
14
14
  getPlatform
15
- } from "./useAgentUndoRedo.js";
15
+ } from "../utils/platform-keys.js";
16
16
  function useInstanceInputUndoRedo({
17
17
  conversationId,
18
18
  scope,
@@ -84,7 +84,7 @@ const wdChannels = /* @__PURE__ */ new Map();
84
84
  const workingDocChannel = defineChannelNamespace({
85
85
  namespace: "cx-working-doc",
86
86
  parts: ["documentId"],
87
- description: "workbench.working_documents row for one working document"
87
+ description: "content.document row for one chat working document"
88
88
  });
89
89
  function subscribeWorkingDocRow(documentId, listenerKey, onRow) {
90
90
  let entry = wdChannels.get(documentId);
@@ -98,15 +98,16 @@ function subscribeWorkingDocRow(documentId, listenerKey, onRow) {
98
98
  postgresChanges: [
99
99
  {
100
100
  event: "*",
101
- schema: "workbench",
102
- table: "working_documents",
101
+ schema: "content",
102
+ table: "document",
103
103
  filter: `id=eq.${documentId}`,
104
104
  rowId: (row) => typeof row.id === "string" ? row.id : void 0,
105
- fingerprint: (row) => JSON.stringify([row.content ?? null, row.title ?? null, row.version ?? null]),
105
+ fingerprint: (row) => JSON.stringify([row.body ?? null, row.title ?? null, row.version ?? null]),
106
106
  onChange: ({ payload, row }) => {
107
107
  if (payload.eventType === "DELETE") return;
108
108
  if (!row) return;
109
- fanOut(row);
109
+ const r = row;
110
+ fanOut({ ...r, content: r.body ?? r.content });
110
111
  }
111
112
  }
112
113
  ],
@@ -374,7 +375,7 @@ function useWorkingDocument(conversationId, kind = DEFAULT_DOC_KIND) {
374
375
  const conflictRef = useRef(conflict);
375
376
  conflictRef.current = conflict;
376
377
  const docAccess = useAccess(
377
- kind === "working" && binding.kind === "cx_working_document" && binding.id && materialized ? "working_document" : void 0,
378
+ kind === "working" && binding.kind === "cx_working_document" && binding.id && materialized ? "document" : void 0,
378
379
  kind === "working" && binding.kind === "cx_working_document" && binding.id && materialized ? binding.id : void 0
379
380
  );
380
381
  const viewOnly = !docAccess.loading && docAccess.exists && docAccess.level === "view" && !docAccess.isOwner;
@@ -1,43 +1 @@
1
- /**
2
- * A model's CLASSES — the serving endpoints it is offered through ("Matrx Fast",
3
- * "Matrx Lightning", ...). Two classes of one model are different products, so
4
- * wherever a surface names the model an agent or run USES, a model with several
5
- * classes is named with its class: "Qwen3.8 27B · Matrx Lightning".
6
- *
7
- * Same grouping as the picker (`collapseTiersByClass` in useModelCatalog): one
8
- * class per endpoint (or brand when the endpoint is unknown), preferred
9
- * (lowest-priority) first. Every offering — including ones collapsed into a
10
- * class — maps to its class, so any stored `offering_id` resolves.
11
- */
12
- export type ModelOfferingRow = {
13
- model_id: string | null;
14
- offering_id: string | null;
15
- served_via: string | null;
16
- served_via_endpoint_id: string | null;
17
- priority: number | null;
18
- };
19
- export type ModelClassEntry = {
20
- /** Public Matrx brand of the serving endpoint — never a vendor name. */
21
- servedVia: string;
22
- endpointId: string | null;
23
- /** The class's preferred offering (what the picker pins). */
24
- offeringId: string;
25
- };
26
- export type ModelClassIndex = {
27
- /** modelId → its classes, preferred first. */
28
- classesByModelId: Record<string, ModelClassEntry[]>;
29
- /** offeringId → { modelId, index into classesByModelId[modelId] }. */
30
- classOfOffering: Record<string, {
31
- modelId: string;
32
- classIndex: number;
33
- }>;
34
- };
35
- export declare function buildModelClassIndex(rows: ModelOfferingRow[]): ModelClassIndex;
36
- /**
37
- * The class name to show beside a model, or undefined when the model has a
38
- * single class (nothing to tell apart). A pin names its class; no pin (or a
39
- * pin of another model) means the server runs the preferred class.
40
- */
41
- export declare function modelClassName(index: ModelClassIndex | null | undefined, modelId: string | null | undefined, offeringId: string | null | undefined): string | undefined;
42
- /** "Model · Class" when the model has several classes, else the model name. */
43
- export declare function withModelClass(modelLabel: string, className: string | undefined): string;
1
+ export * from "@ai-matrx/agents/models";
@@ -1,40 +1 @@
1
- function buildModelClassIndex(rows) {
2
- const classesByModelId = {};
3
- const classOfOffering = {};
4
- const sorted = [...rows].sort(
5
- (a, b) => (a.priority ?? 100) - (b.priority ?? 100)
6
- );
7
- for (const r of sorted) {
8
- if (!r.model_id || !r.offering_id) continue;
9
- const list = classesByModelId[r.model_id] ??= [];
10
- let classIndex = list.findIndex(
11
- (c) => c.endpointId && r.served_via_endpoint_id ? c.endpointId === r.served_via_endpoint_id : c.servedVia === (r.served_via ?? "")
12
- );
13
- if (classIndex === -1) {
14
- list.push({
15
- servedVia: r.served_via ?? "",
16
- endpointId: r.served_via_endpoint_id,
17
- offeringId: r.offering_id
18
- });
19
- classIndex = list.length - 1;
20
- }
21
- classOfOffering[r.offering_id] = { modelId: r.model_id, classIndex };
22
- }
23
- return { classesByModelId, classOfOffering };
24
- }
25
- function modelClassName(index, modelId, offeringId) {
26
- if (!index || !modelId) return void 0;
27
- const classes = index.classesByModelId[modelId];
28
- if (!classes || classes.length < 2) return void 0;
29
- const pinned = offeringId ? index.classOfOffering[offeringId] : void 0;
30
- const entry = pinned && pinned.modelId === modelId ? classes[pinned.classIndex] : classes[0];
31
- return entry?.servedVia || void 0;
32
- }
33
- function withModelClass(modelLabel, className) {
34
- return className ? `${modelLabel} \xB7 ${className}` : modelLabel;
35
- }
36
- export {
37
- buildModelClassIndex,
38
- modelClassName,
39
- withModelClass
40
- };
1
+ export * from "@ai-matrx/agents/models";
@@ -1,88 +1 @@
1
- import { type ModelCapabilities } from "@ai-matrx/agents/models";
2
- /** Identifies the model whose capabilities are being parsed, for loud reporting. */
3
- export interface CapabilitiesParseContext {
4
- modelId?: string;
5
- modelName?: string;
6
- }
7
- /**
8
- * Validate the canonical `{input, output, features, interaction,
9
- * multilingual}` object. Anything that is not that object — including `null`
10
- * for an unsaved row — yields the text-only turn-based default.
11
- *
12
- * Pass `context` (model id/name) wherever available — it's what makes the
13
- * unknown-value scream actionable.
14
- */
15
- export declare function parseCapabilities(raw: unknown, context?: CapabilitiesParseContext): ModelCapabilities;
16
- /**
17
- * The persistence/API boundary for `ai.model_definition.capabilities`.
18
- *
19
- * Unlike `parseCapabilities`, which is intentionally a resilient display
20
- * reader, this refuses a corrupt or provider-shaped value. A Supabase JSONB
21
- * column has no application vocabulary enforcement: accepting aliases here
22
- * would make them durable and leak them back out through another reader.
23
- */
24
- export declare function requireCanonicalCapabilities(raw: unknown, context?: CapabilitiesParseContext): ModelCapabilities;
25
- /**
26
- * Flat audit-shaped record. Re-exported here for callers that want the
27
- * derived projection without importing from the audit module.
28
- */
29
- export type AuditCapabilitiesRecord = Partial<{
30
- text_input: boolean;
31
- text_output: boolean;
32
- image_input: boolean;
33
- image_output: boolean;
34
- audio_input: boolean;
35
- audio_output: boolean;
36
- video_input: boolean;
37
- document_input: boolean;
38
- code_execution: boolean;
39
- function_calling: boolean;
40
- streaming: boolean;
41
- vision: boolean;
42
- web_search: boolean;
43
- json_mode: boolean;
44
- structured_output: boolean;
45
- system_prompt: boolean;
46
- multi_turn: boolean;
47
- embeddings: boolean;
48
- fine_tuning: boolean;
49
- batch_api: boolean;
50
- }>;
51
- /**
52
- * Project the canonical shape onto the flat audit record so existing
53
- * audit consumers see the same view they always have.
54
- */
55
- export declare function toAuditRecord(caps: ModelCapabilities): AuditCapabilitiesRecord;
56
- /**
57
- * Merge an edited flat audit record back INTO the canonical capabilities
58
- * object — the write-side inverse of `toAuditRecord`. This exists because
59
- * writing the flat 20-boolean projection over the column destroys
60
- * `interaction` / `multilingual` / non-text output / the extended feature
61
- * vocabulary (the exact silent-drop class TASK-003 killed on the read side).
62
- *
63
- * Rules:
64
- * - Starts from the RAW stored object (arrays cloned) — every key and every
65
- * array member the editor doesn't model is preserved VERBATIM, including
66
- * values outside the FE vocabulary.
67
- * - Only flags whose edited value DIFFERS from the current projection are
68
- * applied (as an add/remove on the owning array), so an untouched Save is
69
- * a byte-for-byte no-op: `merge(raw, toAuditRecord(parse(raw))) === raw`.
70
- * - A flag with no canonical mapping is never written.
71
- */
72
- export declare function mergeAuditRecordIntoCapabilities(raw: unknown, edited: AuditCapabilitiesRecord, context?: CapabilitiesParseContext): Record<string, unknown>;
73
- export { CONTENT_TYPES, FEATURE_KEYS, INTERACTION_MODES, DEFAULT_CAPABILITIES, } from "@ai-matrx/agents/models";
74
- export type { ContentType, FeatureKey, InteractionMode, ModelCapabilities, } from "@ai-matrx/agents/models";
75
- /**
76
- * Every value in `raw` that is outside the canonical vocabulary, as
77
- * human-readable lines. Empty array = the object is canonical.
78
- *
79
- * The admin detail panel writes `capabilities` straight to Supabase, so it
80
- * does NOT pass the server's write guard
81
- * (`matrx_ai/providers/capability_vocabulary.py`, which the agent `sql`/`db_*`
82
- * tools and `scripts/set_model_capabilities.py` go through). This is that
83
- * door's lock. It REFUSES rather than normalizes on purpose: the alias table
84
- * lives server-side and forking it into the browser is how the vocabulary
85
- * came apart in the first place. A hand-edit that means a real new capability
86
- * belongs in BOTH vocabulary lists first.
87
- */
88
- export declare function findNonCanonicalCapabilityValues(raw: unknown): string[];
1
+ export * from "@ai-matrx/agents/models";