@ai-matrx/chat 0.4.10 → 0.4.12

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 (115) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/agents/components/context-items/bodies/ContextInputBody.js +1 -1
  3. package/dist/agents/components/context-items/bodies/GenericBody.js +1 -1
  4. package/dist/agents/components/conversation-actions/conversation-verbs.js +1 -1
  5. package/dist/agents/components/inputs/smart-input/RunSkillPicker.js +1 -1
  6. package/dist/agents/components/live-run/LiveRunDisplay.js +1 -1
  7. package/dist/agents/components/live-run/LiveRunProgress.js +1 -1
  8. package/dist/agents/components/live-run/RunSetDisplay.js +1 -1
  9. package/dist/agents/components/messages-display/assistant/AgentAssistantMessage.js +2 -2
  10. package/dist/agents/components/messages-display/assistant/InPlaceAnswerEditor.js +1 -1
  11. package/dist/agents/components/messages-display/conversation-tools/find-in-conversation.js +1 -1
  12. package/dist/agents/components/messages-display/message-options/buildTaskSeedFromMessage.js +1 -1
  13. package/dist/agents/components/messages-display/user/AgentUserMessage.js +1 -1
  14. package/dist/agents/components/messages-display/user/FirstTurnVariables.js +1 -1
  15. package/dist/agents/components/run/AgentStatusIndicator.js +1 -1
  16. package/dist/agents/components/run/RunJobWorkingLine.js +1 -1
  17. package/dist/agents/components/shared/AgentNewRunButton.js +1 -1
  18. package/dist/agents/components/shared/AgentPlanningIndicator.js +1 -1
  19. package/dist/agents/conversation-export/conversation-transfer.js +1 -1
  20. package/dist/agents/conversation-export/document-markdown.js +1 -1
  21. package/dist/agents/hooks/useConversationRoutePromotion.js +1 -1
  22. package/dist/agents/hooks/useModelControls.js +1 -1
  23. package/dist/agents/redux/agent-definition/converters.js +1 -1
  24. package/dist/agents/redux/agent-definition/slice.js +1 -1
  25. package/dist/agents/redux/conversation-list/conversation-list.thunks.js +1 -1
  26. package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.js +1 -1
  27. package/dist/agents/redux/execution-system/instance-context/sync-canvas-item-context.thunk.js +1 -1
  28. package/dist/agents/redux/execution-system/thunks/process-stream.js +1 -1
  29. package/dist/agents/redux/execution-system/thunks/run-ai-stream.d.ts +7 -0
  30. package/dist/agents/redux/execution-system/thunks/run-ai-stream.js +13 -0
  31. package/dist/agents/redux/execution-system/utils/assemble-cx-content-blocks.js +1 -1
  32. package/dist/agents/redux/execution-system/utils/normalize-content-blocks.js +1 -1
  33. package/dist/agents/redux/execution-system/utils/output-contract-guard.js +1 -1
  34. package/dist/agents/redux/execution-system/utils/stream-block-accumulator.js +8 -8
  35. package/dist/agents/utils/canvasItemContext.js +1 -1
  36. package/dist/canvas/workspace/ChatPanelTitleMenu.js +1 -1
  37. package/dist/canvas/workspace/useCanvasWorkspaceConversation.js +1 -1
  38. package/dist/cx-chat/components/SsrSidebarChats.js +1 -1
  39. package/dist/cx-chat/components/core/ChatConversationClient.js +1 -1
  40. package/dist/cx-chat/components/messages/AssistantMessage.js +1 -1
  41. package/dist/cx-chat/hooks/useInstanceBootstrap.js +1 -1
  42. package/dist/cx-conversation/AssistantMessage.js +1 -1
  43. package/dist/mandates/llm-params.d.ts +1 -1
  44. package/dist/mandates/output-contract.js +1 -1
  45. package/dist/mandates/service.d.ts +1 -1
  46. package/dist/mandates/service.js +1 -1
  47. package/dist/mandates/test-run-core.js +1 -1
  48. package/dist/public-chat/components/PublicMessageOptionsMenu.js +1 -1
  49. package/dist/surfaces/services/surface-config.service.js +1 -1
  50. package/dist/tool-call-visualization/components/ToolCallBatch.js +1 -1
  51. package/dist/tool-call-visualization/components/ToolCallVisualization.js +1 -1
  52. package/dist/tool-call-visualization/renderers/agent-call/AgentCallInline.js +1 -1
  53. package/dist/tool-call-visualization/renderers/agent-call/CollabCallCard.js +1 -1
  54. package/dist/tool-call-visualization/renderers/agent-call/collab-subtitle.js +3 -3
  55. package/dist/tool-call-visualization/renderers/skill/SkillInline.js +1 -1
  56. package/dist/tool-call-visualization/result-fields/KeyValueGrid.js +1 -1
  57. package/dist/tool-call-visualization/result-fields/ResultValue.js +1 -1
  58. package/dist/tool-call-visualization/result-fields/shape.js +1 -1
  59. package/dist/tool-call-visualization/utils/cxToolCallToLifecycleEntry.js +2 -2
  60. package/dist/tool-call-visualization/utils/human-copy.js +3 -3
  61. package/dist/ui/mandates-storage/provision-shapes.d.ts +1 -1
  62. package/dist/ui/mandates-storage/provision-shapes.js +1 -1
  63. package/dist/ui/markdown-stream/EnhancedChatMarkdown.js +1 -1
  64. package/dist/ui/treatment-shape.d.ts +1 -1
  65. package/dist/ui/treatment-shape.js +1 -1
  66. package/dist/voice-agent/relay/useVoiceRelaySession.js +1 -1
  67. package/package.json +23 -6
  68. package/dist/agents/hooks/useWarmAgent.d.ts +0 -8
  69. package/dist/agents/hooks/useWarmAgent.js +0 -25
  70. package/dist/agents/utils/artifactId.d.ts +0 -34
  71. package/dist/agents/utils/artifactId.js +0 -15
  72. package/dist/ui/ShimmerText.d.ts +0 -5
  73. package/dist/ui/ShimmerText.js +0 -21
  74. package/dist/ui/addressWithoutNavigating.d.ts +0 -68
  75. package/dist/ui/addressWithoutNavigating.js +0 -60
  76. package/dist/utils/content-ir/decision-answers-ids.d.ts +0 -3
  77. package/dist/utils/content-ir/decision-answers-ids.js +0 -6
  78. package/dist/utils/content-ir/envelope-parity.d.ts +0 -12
  79. package/dist/utils/content-ir/envelope-parity.js +0 -32
  80. package/dist/utils/content-ir/instance-title.d.ts +0 -26
  81. package/dist/utils/content-ir/instance-title.js +0 -39
  82. package/dist/utils/content-ir/kinds/kind-markdown-utils.d.ts +0 -84
  83. package/dist/utils/content-ir/kinds/kind-markdown-utils.js +0 -233
  84. package/dist/utils/content-ir/kinds/kind-value-markdown.d.ts +0 -5
  85. package/dist/utils/content-ir/kinds/kind-value-markdown.js +0 -17
  86. package/dist/utils/content-ir/legacy-quiz-envelope.d.ts +0 -3
  87. package/dist/utils/content-ir/legacy-quiz-envelope.js +0 -45
  88. package/dist/utils/content-ir/surfaces/embedded-kind-json.d.ts +0 -140
  89. package/dist/utils/content-ir/surfaces/embedded-kind-json.js +0 -527
  90. package/dist/utils/content-ir/surfaces/json-kind-signal.d.ts +0 -307
  91. package/dist/utils/content-ir/surfaces/json-kind-signal.js +0 -945
  92. package/dist/utils/content-ir/surfaces/kind-image-alt.d.ts +0 -27
  93. package/dist/utils/content-ir/surfaces/kind-image-alt.js +0 -117
  94. package/dist/utils/content-ir/surfaces/kind-one-line.d.ts +0 -67
  95. package/dist/utils/content-ir/surfaces/kind-one-line.js +0 -209
  96. package/dist/utils/content-ir/surfaces/kind-text-label.d.ts +0 -20
  97. package/dist/utils/content-ir/surfaces/kind-text-label.js +0 -50
  98. package/dist/utils/content-ir/surfaces/kind-text-to-markdown.d.ts +0 -47
  99. package/dist/utils/content-ir/surfaces/kind-text-to-markdown.js +0 -399
  100. package/dist/utils/content-ir/surfaces/markdown-escaped-kind.d.ts +0 -54
  101. package/dist/utils/content-ir/surfaces/markdown-escaped-kind.js +0 -128
  102. package/dist/utils/content-ir/surfaces/quoted-kind-lift.d.ts +0 -61
  103. package/dist/utils/content-ir/surfaces/quoted-kind-lift.js +0 -215
  104. package/dist/utils/inline-decision/decision-options.d.ts +0 -21
  105. package/dist/utils/inline-decision/decision-options.js +0 -32
  106. package/dist/utils/json.d.ts +0 -63
  107. package/dist/utils/json.js +0 -22
  108. package/dist/utils/markdown/plain-title.d.ts +0 -25
  109. package/dist/utils/markdown/plain-title.js +0 -51
  110. package/dist/utils/rendered-find.d.ts +0 -9
  111. package/dist/utils/rendered-find.js +0 -68
  112. package/dist/utils/rich-editor/core/caret-context.d.ts +0 -24
  113. package/dist/utils/rich-editor/core/caret-context.js +0 -73
  114. package/dist/utils/rich-editor/in-place/caret-handoff.d.ts +0 -3
  115. package/dist/utils/rich-editor/in-place/caret-handoff.js +0 -15
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # @ai-matrx/chat
2
2
 
3
+ ## Unreleased
4
+
5
+ - Chat's own message surfaces import `ui/markdown-stream/MarkdownStream` by its default export, so a host test that mocks that module (default only) replaces it everywhere, as it did when it was a slot.
6
+
7
+ ## 0.4.12 — chat keeps no copy of another package's code
8
+
9
+ - Deleted `src/utils/content-ir/**` (14 modules, 4.4k lines): every import now reads
10
+ `@ai-matrx/content-ir/surfaces`, whose versions are the stricter ones (the kind-value-markdown
11
+ registration lives on `globalThis`, so dual loaders share one registration).
12
+ - Deleted nine modules that were byte-identical to their owner and import the owner instead:
13
+ `agents/utils/artifactId`, `ui/ShimmerText`, `ui/addressWithoutNavigating`,
14
+ `utils/inline-decision/decision-options`, `utils/json`, `utils/markdown/plain-title`,
15
+ `utils/rendered-find` → `@ai-matrx/rich-content/utils/…`; `utils/rich-editor/core/caret-context`,
16
+ `utils/rich-editor/in-place/caret-handoff` → `@ai-matrx/rich-editor/…` (one caret hand-off
17
+ state instead of two).
18
+
19
+ Consumer action: replace these specifiers —
20
+ `@ai-matrx/chat/utils/content-ir/**` → `@ai-matrx/content-ir/surfaces` (re-register
21
+ `registerKindValueMarkdown` from there); `@ai-matrx/chat/agents/utils/artifactId` →
22
+ `@ai-matrx/rich-content/utils/lifted/artifactId`; `@ai-matrx/chat/ui/ShimmerText` →
23
+ `@ai-matrx/rich-content/utils/lifted/ShimmerText`; `@ai-matrx/chat/ui/addressWithoutNavigating` →
24
+ `@ai-matrx/rich-content/utils/addressWithoutNavigating`;
25
+ `@ai-matrx/chat/utils/inline-decision/decision-options` → `@ai-matrx/rich-content/utils/decision-options`;
26
+ `@ai-matrx/chat/utils/json` → `@ai-matrx/rich-content/utils/json`;
27
+ `@ai-matrx/chat/utils/markdown/plain-title` → `@ai-matrx/rich-content/utils/plain-title`;
28
+ `@ai-matrx/chat/utils/rendered-find` → `@ai-matrx/rich-content/utils/rendered-find`.
29
+
30
+ ## 0.4.11 — every AI run request reports its client latency
31
+
32
+ - `runAiStream` sends `X-Matrx-Client-Sent-At` (epoch ms of the frozen submission moment) and
33
+ `X-Matrx-Client-Prep-Ms` (submission to fetch dispatch) on every turn and resume request
34
+ (`buildLatencyHeaders`); the server persists one `platform.ai_request_latency` row per request.
35
+ - Forcing test `agents/redux/execution-system/thunks/__tests__/every-ai-run-request-reports-its-client-latency.test.ts`.
36
+
37
+ Consumer action: none.
38
+
3
39
  ## 0.4.10 — a confidential conversation never reaches a cloud target
4
40
 
5
41
  - THE CONFIDENTIAL-ROUTING RULE moves from the frozen kernel (`src/compat`) into the real chat:
@@ -2,7 +2,7 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { humanizeIdentifier } from "@ai-matrx/kit/text-case";
4
4
  import { AnswerValueView } from "../../../../host/ui-slots.js";
5
- import { valueCarriesKind } from "../../../../utils/content-ir/surfaces/json-kind-signal.js";
5
+ import { valueCarriesKind } from "@ai-matrx/content-ir/surfaces";
6
6
  function displayValue(value) {
7
7
  if (typeof value === "string") return value;
8
8
  if (value === null) return "null";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { AnswerValueView } from "../../../../host/ui-slots.js";
4
- import { hasKindKeyAnySpelling, valueCarriesKind } from "../../../../utils/content-ir/surfaces/json-kind-signal.js";
4
+ import { hasKindKeyAnySpelling, valueCarriesKind } from "@ai-matrx/content-ir/surfaces";
5
5
  function carriesKind(value) {
6
6
  return valueCarriesKind(value);
7
7
  }
@@ -7,7 +7,7 @@ import {
7
7
  renameConversation
8
8
  } from "../../redux/conversation-list/conversation-row-actions.thunks.js";
9
9
  import { conversationRenameOpener } from "./rename/conversationRenameOpener.js";
10
- import { conversationTitleText } from "../../../utils/content-ir/surfaces/kind-text-label.js";
10
+ import { conversationTitleText } from "@ai-matrx/content-ir/surfaces";
11
11
  function displayConversationTitle(title) {
12
12
  if (!title) return "Untitled conversation";
13
13
  return title.trim().length > 0 ? conversationTitleText(title) ?? title : "Untitled conversation";
@@ -28,7 +28,7 @@ import {
28
28
  PicksSkeletons
29
29
  } from "./RunPicksSurface.js";
30
30
  import { groupCatalog, toolCategoryLabel } from "./run-tool-catalog.js";
31
- import { catalogProseText } from "../../../../utils/content-ir/surfaces/kind-one-line.js";
31
+ import { catalogProseText } from "@ai-matrx/content-ir/surfaces";
32
32
  function tierForSkill(skillId, config) {
33
33
  if (config.included.includes(skillId)) return "included";
34
34
  if (config.listed.includes(skillId)) return "listed";
@@ -4,7 +4,7 @@ import { useEffect, useRef } from "react";
4
4
  import { Loader2, TriangleAlert, X } from "lucide-react";
5
5
  import { cn } from "@ai-matrx/design-system";
6
6
  import { useAppSelector } from "../../../store/hooks.js";
7
- import { MarkdownStream } from "../../../ui/markdown-stream/MarkdownStream.js";
7
+ import MarkdownStream from "../../../ui/markdown-stream/MarkdownStream.js";
8
8
  import { AgentAssistantMessage } from "../messages-display/assistant/AgentAssistantMessage.js";
9
9
  import { useRetainRequestForViewer } from "../../redux/execution-system/active-requests/useRetainRequestForViewer.js";
10
10
  import {
@@ -5,7 +5,7 @@ import { cn } from "@ai-matrx/design-system";
5
5
  import {
6
6
  honestProgressSummary
7
7
  } from "@ai-matrx/kit/progress";
8
- import { isJsonObject } from "../../../utils/json.js";
8
+ import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
9
9
  const STATUSES = /* @__PURE__ */ new Set([
10
10
  "waiting",
11
11
  "running",
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useAppDispatch, useAppSelector } from "../../../store/hooks.js";
4
- import { MarkdownStream } from "../../../ui/markdown-stream/MarkdownStream.js";
4
+ import MarkdownStream from "../../../ui/markdown-stream/MarkdownStream.js";
5
5
  import { cn } from "@ai-matrx/design-system";
6
6
  import { LiveRunDisplay } from "./LiveRunDisplay.js";
7
7
  import { selectRunSetEntries } from "../../redux/execution-system/run-sets/run-sets.slice.js";
@@ -7,7 +7,7 @@ import {
7
7
  useState,
8
8
  useEffect
9
9
  } from "react";
10
- import { MarkdownStream } from "../../../../ui/markdown-stream/MarkdownStream.js";
10
+ import MarkdownStream from "../../../../ui/markdown-stream/MarkdownStream.js";
11
11
  import "../rich-document/chat-message-source.js";
12
12
  import { RecordAnnotations, annotationRecordOf } from "@ai-matrx/rich-content/host/app-bindings";
13
13
  import { useAppDispatch, useAppSelector } from "../../../../store/hooks.js";
@@ -75,7 +75,7 @@ import { retryConversationTurn } from "../../../redux/execution-system/message-c
75
75
  import { commitInlineContentEdit } from "../../../redux/execution-system/message-crud/commit-inline-edit.thunk.js";
76
76
  import { InPlaceAnswerEditor } from "./InPlaceAnswerEditor.js";
77
77
  import { updateMessageRecord } from "../../../redux/execution-system/messages/messages.slice.js";
78
- import { handInPlaceCaret } from "../../../../utils/rich-editor/in-place/caret-handoff.js";
78
+ import { handInPlaceCaret } from "@ai-matrx/rich-editor/in-place/caret-handoff";
79
79
  import { toast } from "../../../../host/notify.js";
80
80
  import { useDomCapturePrint } from "../../../../conversation/hooks/useDomCapturePrint.js";
81
81
  import { MessageFilesStrip } from "../../../../host/ui-slots.js";
@@ -2,7 +2,7 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useState } from "react";
4
4
  import { Loader2 } from "lucide-react";
5
- import { takeInPlaceCaret } from "../../../../utils/rich-editor/in-place/caret-handoff.js";
5
+ import { takeInPlaceCaret } from "@ai-matrx/rich-editor/in-place/caret-handoff";
6
6
  import { useAppDispatch } from "../../../../store/hooks.js";
7
7
  import { updateMessageRecord } from "../../../redux/execution-system/messages/messages.slice.js";
8
8
  import {
@@ -1,4 +1,4 @@
1
- import { collectRenderedFindRanges, findRenderedTextMatches } from "../../../../utils/rendered-find.js";
1
+ import { collectRenderedFindRanges, findRenderedTextMatches } from "@ai-matrx/rich-content/utils/rendered-find";
2
2
  function findTextMatches(text, query) {
3
3
  return findRenderedTextMatches(text, query.trim());
4
4
  }
@@ -1,5 +1,5 @@
1
1
  import { durableRecordId } from "@ai-matrx/kit/ids";
2
- import { plainTitleFromMarkdown } from "../../../../utils/markdown/plain-title.js";
2
+ import { plainTitleFromMarkdown } from "@ai-matrx/rich-content/utils/plain-title";
3
3
  import { cleanMarkdown } from "@ai-matrx/content-ir/source";
4
4
  import { buildConversationMessageTitle } from "../../../utils/conversation-message-title.js";
5
5
  function buildMessagePreviewLabel(content, maxLength = 160) {
@@ -36,7 +36,7 @@ import {
36
36
  } from "../../../redux/execution-system/instance-variable-values/instance-variable-values.selectors.js";
37
37
  import { MessageAttachmentStrip } from "../MessageAttachmentStrip.js";
38
38
  import { isAttachmentMessagePart } from "../../context-items/normalize.js";
39
- import { MarkdownStream } from "../../../../ui/markdown-stream/MarkdownStream.js";
39
+ import MarkdownStream from "../../../../ui/markdown-stream/MarkdownStream.js";
40
40
  import "../rich-document/chat-message-source.js";
41
41
  import { literalUserText } from "./literal-user-text.js";
42
42
  import { buildVariableDisplayLines } from "../../../utils/variable-display-lines.js";
@@ -11,7 +11,7 @@ import { buildVariableDisplayLines } from "../../../utils/variable-display-lines
11
11
  import { EntityRef } from "../../../../host/ui-slots.js";
12
12
  import { useEntityTitles } from "../../../../host/ui-slots.js";
13
13
  import { AnswerValueView } from "../../../../host/ui-slots.js";
14
- import { isKindJsonText, valueCarriesKind } from "../../../../utils/content-ir/surfaces/json-kind-signal.js";
14
+ import { isKindJsonText, valueCarriesKind } from "@ai-matrx/content-ir/surfaces";
15
15
  function kindCarryingValue(value) {
16
16
  if (!valueCarriesKind(value)) return null;
17
17
  if (typeof value === "string" && isKindJsonText(value)) {
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { ShimmerText } from "../../../ui/ShimmerText.js";
3
+ import { ShimmerText } from "@ai-matrx/rich-content/utils/lifted/ShimmerText";
4
4
  function AgentStatusIndicator({
5
5
  message,
6
6
  compact = false
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useState } from "react";
4
- import { ShimmerText } from "../../../ui/ShimmerText.js";
4
+ import { ShimmerText } from "@ai-matrx/rich-content/utils/lifted/ShimmerText";
5
5
  import { useAppSelector } from "../../../store/hooks.js";
6
6
  import {
7
7
  selectRequestGenerationJob,
@@ -6,7 +6,7 @@ import { useAppDispatch, useAppSelector } from "../../../store/hooks.js";
6
6
  import { startNewConversation } from "../../redux/execution-system/thunks/create-instance.thunk.js";
7
7
  import { PlusTapButton } from "@ai-matrx/tap-target/buttons";
8
8
  import { selectFocusedConversation } from "../../redux/execution-system/conversation-focus/conversation-focus.selectors.js";
9
- import { pushAddressWithoutNavigating } from "../../../ui/addressWithoutNavigating.js";
9
+ import { pushAddressWithoutNavigating } from "@ai-matrx/rich-content/utils/addressWithoutNavigating";
10
10
  function AgentNewRunButton({ surfaceKey }) {
11
11
  const conversationId = useAppSelector(selectFocusedConversation(surfaceKey));
12
12
  const dispatch = useAppDispatch();
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { ShimmerText } from "../../../ui/ShimmerText.js";
3
+ import { ShimmerText } from "@ai-matrx/rich-content/utils/lifted/ShimmerText";
4
4
  function AgentPlanningIndicator({
5
5
  compact = false,
6
6
  label = "Planning..."
@@ -1,6 +1,6 @@
1
1
  import { toast } from "../../host/notify.js";
2
2
  import { unwrapKindEnvelopes } from "@ai-matrx/content-ir/source";
3
- import { kindTextToMarkdown } from "../../utils/content-ir/surfaces/kind-text-to-markdown.js";
3
+ import { kindTextToMarkdown } from "@ai-matrx/content-ir/surfaces";
4
4
  import { extractFlatText } from "../redux/execution-system/messages/messages.selectors.js";
5
5
  import { selectConversationTitle } from "../redux/execution-system/conversations/conversations.selectors.js";
6
6
  import { isMessagePinned } from "../message-pins/pinned-messages-store.js";
@@ -1,5 +1,5 @@
1
1
  import { unwrapKindEnvelopes } from "@ai-matrx/content-ir/source";
2
- import { kindTextToMarkdown } from "../../utils/content-ir/surfaces/kind-text-to-markdown.js";
2
+ import { kindTextToMarkdown } from "@ai-matrx/content-ir/surfaces";
3
3
  function documentMarkdown(markdown) {
4
4
  return kindTextToMarkdown(unwrapKindEnvelopes(markdown));
5
5
  }
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { useEffect, useEffectEvent, useRef } from "react";
3
3
  import { useRouter } from "../../host/navigation.js";
4
- import { replaceAddressWithoutNavigating } from "../../ui/addressWithoutNavigating.js";
4
+ import { replaceAddressWithoutNavigating } from "@ai-matrx/rich-content/utils/addressWithoutNavigating";
5
5
  import { useAppDispatch, useAppSelector, useAppStore } from "../../store/hooks.js";
6
6
  import { waitForConversationPersisted } from "../redux/execution-system/conversations/conversation-persistence.js";
7
7
  import { selectMessageCount } from "../redux/execution-system/messages/messages.selectors.js";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { LLM_PARAMS_KEYS } from "@ai-matrx/agents/generated/llm-enums";
3
3
  import { UI_GATE_KEYS } from "../redux/agent-settings/ui-gates.js";
4
- import { isJsonObject } from "../../utils/json.js";
4
+ import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
5
5
  import { outputFormatControlKey } from "@ai-matrx/agents/models";
6
6
  function supportsTools(normalizedControls) {
7
7
  const normalizedTools = normalizedControls?.tools;
@@ -15,7 +15,7 @@ import { sanitizeAgentToolIds } from "./sanitize-tool-ids.js";
15
15
  import { stripNullish } from "../../../ui/payload.js";
16
16
  import { OrganizationContextError } from "@ai-matrx/agents/matrx";
17
17
  import { parseUiGates } from "../agent-settings/ui-gates.js";
18
- import { isJsonObject } from "../../../utils/json.js";
18
+ import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
19
19
  import {
20
20
  recordAgentDataIssue,
21
21
  recoverAgentDataField
@@ -1,5 +1,5 @@
1
1
  import { createSlice } from "@reduxjs/toolkit";
2
- import { isJsonObject } from "../../../utils/json.js";
2
+ import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
3
3
  import {
4
4
  shouldUpgradeFetchStatus
5
5
  } from "../../types/agent-definition.types.js";
@@ -16,7 +16,7 @@ import {
16
16
  import { CONVERSATION_LIST_PAGE_SIZE } from "./conversation-list.types.js";
17
17
  import { excludeHiddenLane } from "../conversation-history/history-filters.js";
18
18
  import { getUserId, hasBrowserSession } from "../../../host/identity.js";
19
- import { conversationTitleText } from "../../../utils/content-ir/surfaces/kind-text-label.js";
19
+ import { conversationTitleText } from "@ai-matrx/content-ir/surfaces";
20
20
  function resolveCanonicalAgentIdForConversationsFetch(input, state) {
21
21
  const versionFilter = input.versionFilter === void 0 ? null : input.versionFilter;
22
22
  let mapKey;
@@ -5,7 +5,7 @@ import {
5
5
  import { createSelector } from "@reduxjs/toolkit";
6
6
  import { isAnswerKeptWarning } from "./answer-kept-warning.js";
7
7
  import { blockMediaFileId } from "../utils/block-media-identity.js";
8
- import { DECISION_ANSWERS_BLOCK_TYPE } from "../../../../utils/content-ir/decision-answers-ids.js";
8
+ import { DECISION_ANSWERS_BLOCK_TYPE } from "@ai-matrx/content-ir/surfaces";
9
9
  import { decisionAnswersText } from "@ai-matrx/agents/presentation/decision-answers";
10
10
  import {
11
11
  readEnvelope,
@@ -8,7 +8,7 @@ import { applyContextDeltaToContent } from "../instance-working-document/context
8
8
  import { CANVAS_ITEM_UPDATED_EVENT } from "../../../utils/canvas-item-event.js";
9
9
  import { invalidateCanvasItemCache } from "../../../../host/ui-slots.js";
10
10
  import { canvasGetVersionHistory, canvasGetById } from "../../../../host/ui-slots.js";
11
- import { isMaterializedArtifactId } from "../../../utils/artifactId.js";
11
+ import { isMaterializedArtifactId } from "@ai-matrx/rich-content/utils/lifted/artifactId";
12
12
  import { recordUnavailable } from "../../../../host/diagnostics.js";
13
13
  function extractBody(content) {
14
14
  const stored = content;
@@ -187,7 +187,7 @@ import { StreamProfiler } from "../../../../ui/stream-profiler.js";
187
187
  import { makePartialKindStalenessGate } from "@ai-matrx/content-ir/wire";
188
188
  import { prepareInboundRenderBlock } from "../utils/inbound-render-block.js";
189
189
  import { progressDataRenderBlock } from "../utils/progress-data-block.js";
190
- import { DECISION_ANSWERS_BLOCK_TYPE } from "../../../../utils/content-ir/decision-answers-ids.js";
190
+ import { DECISION_ANSWERS_BLOCK_TYPE } from "@ai-matrx/content-ir/surfaces";
191
191
  import { recordContextReceipt } from "../context-rules/receipt-check.js";
192
192
  import { assembleMessageParts } from "../utils/assemble-cx-content-blocks.js";
193
193
  import { materializeMessageArtifacts } from "../../../../host/ui-slots.js";
@@ -201,6 +201,13 @@ export interface UnprocessableErrorClassification {
201
201
  }
202
202
  /** Classify HTTP 422s by server code; message text is legacy fallback only. */
203
203
  export declare function classifyUnprocessableError(errorCode: string | null, serverMessage: string): UnprocessableErrorClassification;
204
+ /**
205
+ * `X-Matrx-Client-Sent-At` (epoch ms of the frozen submission moment) and
206
+ * `X-Matrx-Client-Prep-Ms` (submission → fetch dispatch). `submitAt` is a
207
+ * `performance.now()` stamp, so the epoch time is derived from the monotonic
208
+ * elapsed time — immune to wall-clock steps between submit and dispatch.
209
+ */
210
+ export declare function buildLatencyHeaders(submitAt: number, nowPerf?: number, nowEpoch?: number): Record<string, string>;
204
211
  /**
205
212
  * Retry only after the server explicitly rejected the POST before execution
206
213
  * with `X-Matrx-Drain`. Once that proof exists, brief connection failures are
@@ -180,6 +180,13 @@ function waitForDrainRetry(ms, signal) {
180
180
  signal.addEventListener("abort", onAbort, { once: true });
181
181
  });
182
182
  }
183
+ function buildLatencyHeaders(submitAt, nowPerf = performance.now(), nowEpoch = Date.now()) {
184
+ const prepMs = Math.max(0, nowPerf - submitAt);
185
+ return {
186
+ "X-Matrx-Client-Sent-At": String(Math.round(nowEpoch - prepMs)),
187
+ "X-Matrx-Client-Prep-Ms": String(Math.round(prepMs))
188
+ };
189
+ }
183
190
  async function fetchThroughDeploymentDrain(url, init, signal) {
184
191
  const deadline = Date.now() + DEPLOYMENT_DRAIN_MAX_WAIT_MS;
185
192
  let drainObserved = false;
@@ -299,6 +306,11 @@ async function runAiStreamOnce(args) {
299
306
  );
300
307
  }
301
308
  }
309
+ if (kind !== "rejoin") {
310
+ Object.assign(fetchInit, {
311
+ headers: { ...headers, ...buildLatencyHeaders(submitAt) }
312
+ });
313
+ }
302
314
  response = kind === "rejoin" ? await fetchRejoin(
303
315
  url,
304
316
  fetchInit,
@@ -586,6 +598,7 @@ export {
586
598
  StreamCancelledError,
587
599
  StreamPhaseError,
588
600
  StreamRejoinUnavailableError,
601
+ buildLatencyHeaders,
589
602
  classifyUnprocessableError,
590
603
  fetchThroughDeploymentDrain,
591
604
  parseApiErrorBody,
@@ -9,7 +9,7 @@ import { readEnvelope } from "@ai-matrx/content-ir";
9
9
  import {
10
10
  DECISION_ANSWERS_BLOCK_TYPE,
11
11
  DECISION_ANSWERS_KIND
12
- } from "../../../../utils/content-ir/decision-answers-ids.js";
12
+ } from "@ai-matrx/content-ir/surfaces";
13
13
  function isReasoningEnd(e) {
14
14
  return e.kind === "reasoning_end";
15
15
  }
@@ -4,7 +4,7 @@ import {
4
4
  fromCxAudioPart,
5
5
  fromCxVideoPart
6
6
  } from "@ai-matrx/media/files";
7
- import { DECISION_ANSWERS_BLOCK_TYPE } from "../../../../utils/content-ir/decision-answers-ids.js";
7
+ import { DECISION_ANSWERS_BLOCK_TYPE } from "@ai-matrx/content-ir/surfaces";
8
8
  import { withPerformedScript } from "../../../speech-script/types.js";
9
9
  import { seedPersistedEnvelopeCache } from "@ai-matrx/rich-content/kinds/registry/region-envelope-memo";
10
10
  function normalizeContentBlocks(rawBlocks) {
@@ -3,7 +3,7 @@ import { hasField } from "@ai-matrx/agents/field-flags";
3
3
  import { peekMandateCatalogueEntry } from "../../../../host/ui-slots.js";
4
4
  import { fetchAgentOutputSchemas } from "../../../../mandates/output-contract.js";
5
5
  import { SURFACE_WRITE_TOOL_NAME } from "../../../../surfaces/runtime/surface-writeback.js";
6
- import { isJsonObject } from "../../../../utils/json.js";
6
+ import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
7
7
  import { readAgentName } from "../../../identity/agent-identity.js";
8
8
  function schemaName(schema) {
9
9
  if (!isJsonObject(schema)) return null;
@@ -1,9 +1,9 @@
1
- import { parseDecisionOptionsFromBody } from "../../../../utils/inline-decision/decision-options.js";
2
- import { QuotedKindLift } from "../../../../utils/content-ir/surfaces/quoted-kind-lift.js";
3
- import { canonicalizeCompletedLegacyQuizEnvelope } from "../../../../utils/content-ir/legacy-quiz-envelope.js";
4
- import { envelopeMatchesParsedSource } from "../../../../utils/content-ir/envelope-parity.js";
5
- import { MarkdownEscapedKindJson } from "../../../../utils/content-ir/surfaces/markdown-escaped-kind.js";
6
- import { KindImageAltUnwrap } from "../../../../utils/content-ir/surfaces/kind-image-alt.js";
1
+ import { parseDecisionOptionsFromBody } from "@ai-matrx/rich-content/utils/decision-options";
2
+ import { QuotedKindLift } from "@ai-matrx/content-ir/surfaces";
3
+ import { canonicalizeCompletedLegacyQuizEnvelope } from "@ai-matrx/content-ir/surfaces";
4
+ import { envelopeMatchesParsedSource } from "@ai-matrx/content-ir/surfaces";
5
+ import { MarkdownEscapedKindJson } from "@ai-matrx/content-ir/surfaces";
6
+ import { KindImageAltUnwrap } from "@ai-matrx/content-ir/surfaces";
7
7
  import { FENCE_META_KEY, splitFenceInfo } from "@ai-matrx/content-ir/source";
8
8
  import {
9
9
  hasUnclosedBacktickRun,
@@ -16,7 +16,7 @@ import {
16
16
  kindGrammar,
17
17
  kindObjectProseBreak,
18
18
  bareRegionBreaksIntoProse
19
- } from "../../../../utils/content-ir/surfaces/json-kind-signal.js";
19
+ } from "@ai-matrx/content-ir/surfaces";
20
20
  import {
21
21
  findBalancedXmlClose,
22
22
  initialXmlBalance
@@ -68,7 +68,7 @@ import {
68
68
  import {
69
69
  normalizeRecoveredContainerPiece,
70
70
  splitAroundEmbeddedKindJson
71
- } from "../../../../utils/content-ir/surfaces/embedded-kind-json.js";
71
+ } from "@ai-matrx/content-ir/surfaces";
72
72
  import { captureError } from "../../../../host/diagnostics.js";
73
73
  const isSpecialCodeLanguage = (language) => SPECIAL_CODE_LANGUAGES.includes(language);
74
74
  const envelopeForCompletedXmlRegion = (tag, regionText) => hostSplitterEnvelopes()?.xmlRegion(tag, regionText) ?? null;
@@ -1,4 +1,4 @@
1
- import { isMaterializedArtifactId } from "./artifactId.js";
1
+ import { isMaterializedArtifactId } from "@ai-matrx/rich-content/utils/lifted/artifactId";
2
2
  const CANVAS_ITEM_SOURCE_KIND = "canvas_item";
3
3
  const DESCRIPTION = "A pinned conversation artifact (code or JSON). Read with ctx_get on this key (the artifact UUID). Apply every change with ctx_patch \u2014 edits save as a new version of the same artifact. Do NOT recreate it; extend or edit it.";
4
4
  function isCanvasItemContextKey(key) {
@@ -8,7 +8,7 @@ import { useAppSelector } from "../../store/hooks.js";
8
8
  import { selectConversationTitle } from "../../agents/redux/execution-system/conversations/conversations.selectors.js";
9
9
  import { selectConversationListItemById } from "../../agents/redux/conversation-list/conversation-list.selectors.js";
10
10
  import { conversationRenameOpener } from "../../agents/components/conversation-actions/rename/conversationRenameOpener.js";
11
- import { conversationTitleText } from "../../utils/content-ir/surfaces/kind-text-label.js";
11
+ import { conversationTitleText } from "@ai-matrx/content-ir/surfaces";
12
12
  import { Button, Tile } from "@ai-matrx/design-system/controls";
13
13
  import { ConversationHistorySidebar } from "../../agents/components/conversation-history/ConversationHistorySidebar.js";
14
14
  const PANEL_HISTORY_SCOPE = "chat-panel-menu";
@@ -7,7 +7,7 @@ import { resumeConversation } from "../../agents/redux/execution-system/thunks/r
7
7
  import { useAppDispatch, useAppSelector } from "../../store/hooks.js";
8
8
  import { selectShouldPromptForOrganization } from "../../host/ui-slots.js";
9
9
  import { selectIsCacheOnly } from "../../agents/redux/execution-system/conversations/conversations.selectors.js";
10
- import { replaceAddressWithoutNavigating } from "../../ui/addressWithoutNavigating.js";
10
+ import { replaceAddressWithoutNavigating } from "@ai-matrx/rich-content/utils/addressWithoutNavigating";
11
11
  import { describeLaunchError } from "./describe-launch-error.js";
12
12
  import { selectOrganizationId, ensureOrganizationContext, isOrganizationSelectionCancelled } from "../../host/org.js";
13
13
  function initialRequest(start) {
@@ -37,7 +37,7 @@ const toSidebarItem = (c) => ({
37
37
  status: c.status
38
38
  });
39
39
  const selectSidebarConversations = (state) => selectGlobalConversationList(state);
40
- import { conversationTitleText } from "../../utils/content-ir/surfaces/kind-text-label.js";
40
+ import { conversationTitleText } from "@ai-matrx/content-ir/surfaces";
41
41
  const GROUP_ORDER = ["Today", "Yesterday", "This Week", "This Month", "Older"];
42
42
  function groupByTime(items) {
43
43
  const now = /* @__PURE__ */ new Date();
@@ -24,7 +24,7 @@ import { useComposerMode } from "../../../agents/components/inputs/smart-input/c
24
24
  import { ProposedDirectivesZone } from "../../../host/ui-slots.js";
25
25
  import { ServerOperationBanner } from "../../../agents/runtime-reconnect/ServerOperationBanner.js";
26
26
  import { pushAppHref } from "../../../host/ui-slots.js";
27
- import { replaceAddressWithoutNavigating } from "../../../ui/addressWithoutNavigating.js";
27
+ import { replaceAddressWithoutNavigating } from "@ai-matrx/rich-content/utils/addressWithoutNavigating";
28
28
  import { Button } from "@ai-matrx/design-system/controls";
29
29
  function ChatConversationClient({
30
30
  conversationId,
@@ -13,7 +13,7 @@ import {
13
13
  Save
14
14
  } from "lucide-react";
15
15
  import { Button } from "@ai-matrx/design-system/controls";
16
- import { MarkdownStream } from "../../../ui/markdown-stream/MarkdownStream.js";
16
+ import MarkdownStream from "../../../ui/markdown-stream/MarkdownStream.js";
17
17
  import AudioOutputBlockSkeleton from "../../../ui/AudioOutputBlockSkeleton.js";
18
18
  import { useDomCapturePrint } from "../../../conversation/hooks/useDomCapturePrint.js";
19
19
  import { useAppSelector, useAppDispatch } from "../../../store/hooks.js";
@@ -12,7 +12,7 @@ import { toast } from "../../host/notify.js";
12
12
  import { isNotAuthenticatedError } from "../../host/identity.js";
13
13
  import { isOrganizationSelectionCancelled } from "../../host/org.js";
14
14
  import { DEFAULT_AGENT_ID } from "../components/agent/local-agents.js";
15
- import { replaceAddressWithoutNavigating } from "../../ui/addressWithoutNavigating.js";
15
+ import { replaceAddressWithoutNavigating } from "@ai-matrx/rich-content/utils/addressWithoutNavigating";
16
16
  import { ensureAgentCatalog, isAgentCatalogStale } from "../../agents/identity/agent-identity.js";
17
17
  function parseChatUrl(pathname, searchParams) {
18
18
  const agentPathMatch = pathname.match(/\/demos\/chat\/a\/([^/?]+)/);
@@ -13,7 +13,7 @@ import {
13
13
  Save
14
14
  } from "lucide-react";
15
15
  import { Button } from "@ai-matrx/design-system/controls";
16
- import { MarkdownStream } from "../ui/markdown-stream/MarkdownStream.js";
16
+ import MarkdownStream from "../ui/markdown-stream/MarkdownStream.js";
17
17
  import AudioOutputBlockSkeleton from "../ui/AudioOutputBlockSkeleton.js";
18
18
  import { useDomCapturePrint } from "../conversation/hooks/useDomCapturePrint.js";
19
19
  import { useAppSelector, useAppDispatch } from "../store/hooks.js";
@@ -5,6 +5,6 @@
5
5
  * keys the client run path honours. Field by field, no casts; unknown keys
6
6
  * are dropped LOUDLY (the server's apply_overrides stays the authority).
7
7
  */
8
- import type { JsonObject } from "../utils/json.js";
8
+ import type { JsonObject } from "@ai-matrx/rich-content/utils/json";
9
9
  import type { FeLlmParams } from "../agents/types/agent-api-types.js";
10
10
  export declare function toLlmParams(obj: JsonObject): Partial<FeLlmParams>;
@@ -1,5 +1,5 @@
1
1
  import { createClient } from "../host/db.js";
2
- import { isJsonObject } from "../utils/json.js";
2
+ import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
3
3
  import { hasBrowserSession } from "../host/identity.js";
4
4
  function outputSchemaKeys(outputSchema) {
5
5
  if (!isJsonObject(outputSchema)) return /* @__PURE__ */ new Set();
@@ -1,7 +1,7 @@
1
1
  import type { FeLlmParams } from "../agents/types/agent-api-types.js";
2
2
  import { type OrganizationAdmission } from "../host/server/organization-admission.js";
3
3
  import { type MandateContract } from "@ai-matrx/agents/mandates";
4
- import type { JsonObject } from "../utils/json.js";
4
+ import type { JsonObject } from "@ai-matrx/rich-content/utils/json";
5
5
  import type { AnyMandateKey } from "@ai-matrx/agents/mandates";
6
6
  import { type BindingPresentation } from "../ui/treatment-shape.js";
7
7
  export interface ResolvedMandate {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { createClient } from "../host/db.js";
3
3
  import { getClaimsUser } from "../host/db.js";
4
- import { isJsonObject } from "../utils/json.js";
4
+ import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
5
5
  import { recordUnavailable } from "../host/diagnostics.js";
6
6
  import { apiGet, buildPath } from "../host/server/typed-client.js";
7
7
  import { BackendApiError } from "@ai-matrx/agents/matrx";
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { isJsonObject } from "../utils/json.js";
2
+ import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
3
3
  import { usableServerNotes } from "../ui/usable-server-notes.js";
4
4
  function readMandateRunHolder(result) {
5
5
  if (!isJsonObject(result)) {
@@ -26,7 +26,7 @@ import { useAppSelector as useSelector } from "../../store/hooks.js";
26
26
  import { selectIsAuthenticated } from "../../host/identity.js";
27
27
  import { useAppDispatch } from "../../store/hooks.js";
28
28
  import { openOverlay, CHAT_WINDOWS } from "../../host/windows.js";
29
- import { kindTextToMarkdown } from "../../utils/content-ir/surfaces/kind-text-to-markdown.js";
29
+ import { kindTextToMarkdown } from "@ai-matrx/content-ir/surfaces";
30
30
  import { removeCodeSpans, replaceFences } from "@ai-matrx/content-ir/source";
31
31
  import { selectOrganizationId, ensureOrganizationContext, isOrganizationSelectionCancelled } from "../../host/org.js";
32
32
  import { downloadFile } from "@ai-matrx/kit/download";
@@ -3,7 +3,7 @@ import { storedMandateKey } from "@ai-matrx/agents/mandates";
3
3
  import { createClient } from "../../host/db.js";
4
4
  import { writeOne } from "@ai-matrx/data/db";
5
5
  import { getClaimsUser } from "../../host/db.js";
6
- import { isJsonObject } from "../../utils/json.js";
6
+ import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
7
7
  import { fetchMandatePins } from "../../mandates/service.js";
8
8
  import {
9
9
  getNamespaceHandler,
@@ -4,7 +4,7 @@ import { useEffect, useState } from "react";
4
4
  import { ChevronDown, ChevronRight } from "lucide-react";
5
5
  import { cn } from "@ai-matrx/design-system";
6
6
  import { useAppSelector } from "../../store/hooks.js";
7
- import { ShimmerText } from "../../ui/ShimmerText.js";
7
+ import { ShimmerText } from "@ai-matrx/rich-content/utils/lifted/ShimmerText";
8
8
  import { getToolDisplayName } from "../registry/registry.js";
9
9
  import { DIFF_START_OPEN_KNOB, readSurfaceWrite } from "../surface-write/readSurfaceWrite.js";
10
10
  import { holdsADecision } from "./holdsADecision.js";