@ai-matrx/chat 0.3.33 → 0.4.2

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 +46 -0
  2. package/dist/agents/addressing/useAgentHref.js +4 -1
  3. package/dist/agents/api/submit-tool-results.js +11 -1
  4. package/dist/agents/components/ambient-assistant/intelligence-places.js +2 -2
  5. package/dist/agents/components/chat/intelligence-places.js +7 -7
  6. package/dist/agents/components/chat/useCanvasScopedToConversation.js +1 -1
  7. package/dist/agents/components/inputs/smart-input/RunToolPicker.js +7 -13
  8. package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPill.js +3 -2
  9. package/dist/agents/components/inputs/smart-input/composer/useComposerAgent.js +5 -5
  10. package/dist/agents/components/inputs/smart-input/composer/useComposerAgentFilter.js +3 -2
  11. package/dist/agents/components/messages-display/AgentConversationDisplay.js +4 -1
  12. package/dist/agents/components/run-controls/RunConfigOverrides.js +10 -16
  13. package/dist/agents/components/run-controls/panels/shared.d.ts +1 -1
  14. package/dist/agents/components/shared/AgentConversationColumn.js +3 -2
  15. package/dist/agents/components/working-document/workingDocumentSurface.d.ts +1 -1
  16. package/dist/agents/hooks/useAgentModelLabel.js +4 -3
  17. package/dist/agents/hooks/useDiffEnrichment.js +3 -5
  18. package/dist/agents/hooks/useModelControls.d.ts +5 -161
  19. package/dist/agents/identity/model-catalog.d.ts +37 -0
  20. package/dist/agents/identity/model-catalog.js +105 -0
  21. package/dist/agents/redux/agent-definition/selectors.d.ts +237 -237
  22. package/dist/agents/redux/agent-definition/thunks.d.ts +1 -1
  23. package/dist/agents/redux/agent-settings/agentSettingsSlice.d.ts +1 -1
  24. package/dist/agents/redux/agent-settings/agentSettingsSlice.js +4 -6
  25. package/dist/agents/redux/agent-settings/selectors.d.ts +13 -152
  26. package/dist/agents/redux/agent-settings/selectors.js +0 -39
  27. package/dist/agents/redux/agent-settings/useNormalizedControls.d.ts +8 -0
  28. package/dist/agents/redux/agent-settings/useNormalizedControls.js +24 -0
  29. package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +50 -50
  30. package/dist/agents/redux/agent-shortcuts/selectors.d.ts +147 -147
  31. package/dist/agents/redux/conversation-history/selectors.d.ts +16 -16
  32. package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +2 -2
  33. package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +54 -54
  34. package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +14 -14
  35. package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +5 -5
  36. package/dist/agents/redux/execution-system/host-conversations/conversation-abilities.d.ts +12 -0
  37. package/dist/agents/redux/execution-system/host-conversations/conversation-abilities.js +25 -0
  38. package/dist/agents/redux/execution-system/host-conversations/host-conversation.thunks.d.ts +50 -0
  39. package/dist/agents/redux/execution-system/host-conversations/host-conversation.thunks.js +367 -0
  40. package/dist/agents/redux/execution-system/host-conversations/host-conversations.selectors.d.ts +28 -0
  41. package/dist/agents/redux/execution-system/host-conversations/host-conversations.selectors.js +41 -0
  42. package/dist/agents/redux/execution-system/host-conversations/host-conversations.slice.d.ts +43 -0
  43. package/dist/agents/redux/execution-system/host-conversations/host-conversations.slice.js +38 -0
  44. package/dist/agents/redux/execution-system/host-conversations/source-registry.d.ts +9 -0
  45. package/dist/agents/redux/execution-system/host-conversations/source-registry.js +15 -0
  46. package/dist/agents/redux/execution-system/host-conversations/useHostConversation.d.ts +4 -0
  47. package/dist/agents/redux/execution-system/host-conversations/useHostConversation.js +24 -0
  48. package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +3 -3
  49. package/dist/agents/redux/execution-system/instance-resources/default-remark-durability.d.ts +22 -0
  50. package/dist/agents/redux/execution-system/instance-resources/default-remark-durability.js +164 -0
  51. package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +8 -8
  52. package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +5 -5
  53. package/dist/agents/redux/execution-system/instance-user-input/composer-draft-store.js +20 -0
  54. package/dist/agents/redux/execution-system/instance-user-input/useComposerDraftRestore.js +2 -1
  55. package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +7 -7
  56. package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +1 -1
  57. package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +7 -7
  58. package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +1 -1
  59. package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +14 -14
  60. package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +2 -1
  61. package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +4 -3
  62. package/dist/agents/redux/execution-system/thunks/load-conversation.thunk.js +6 -0
  63. package/dist/agents/redux/execution-system/thunks/load-older-messages.thunk.js +12 -0
  64. package/dist/agents/redux/execution-system/thunks/process-stream.js +5 -3
  65. package/dist/agents/redux/execution-system/thunks/resolve-base-url.js +1 -1
  66. package/dist/agents/redux/execution-system/thunks/smart-execute.thunk.js +43 -0
  67. package/dist/agents/redux/execution-system/utils/continuation-body.d.ts +1 -0
  68. package/dist/agents/redux/execution-system/utils/continuation-body.js +2 -1
  69. package/dist/agents/redux/model-registry.d.ts +6 -4
  70. package/dist/agents/redux/model-registry.js +23 -5
  71. package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +1 -1
  72. package/dist/agents/redux/tools/tools.selectors.d.ts +1 -1
  73. package/dist/agents/resources/default-picker-items.d.ts +17 -0
  74. package/dist/agents/resources/default-picker-items.js +48 -0
  75. package/dist/agents/runtime/generation-job.js +4 -7
  76. package/dist/agents/runtime/get-model-capabilities.js +3 -3
  77. package/dist/agents/types/instance.types.d.ts +2 -1
  78. package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +2 -2
  79. package/dist/cx-chat/components/SsrSidebarChats.js +1 -1
  80. package/dist/cx-chat/components/sidebar/SidebarUserFooter.js +1 -1
  81. package/dist/host/app-identity.d.ts +20 -0
  82. package/dist/host/app-identity.js +21 -0
  83. package/dist/host/bare-host-chrome.d.ts +14 -0
  84. package/dist/host/bare-host-chrome.js +44 -0
  85. package/dist/host/configure.d.ts +9 -1
  86. package/dist/host/configure.js +44 -8
  87. package/dist/host/content-ir-slots.d.ts +5 -1
  88. package/dist/host/content-ir-slots.js +5 -1
  89. package/dist/host/contract.d.ts +39 -2
  90. package/dist/host/db-types.d.ts +375 -10
  91. package/dist/host/defaults/navigation-hooks.d.ts +2 -0
  92. package/dist/host/defaults/navigation-hooks.js +7 -1
  93. package/dist/host/defaults/navigation.d.ts +4 -3
  94. package/dist/host/defaults/navigation.js +38 -7
  95. package/dist/host/defaults/org.d.ts +12 -4
  96. package/dist/host/defaults/org.js +39 -1
  97. package/dist/host/defaults/workspace-gate.d.ts +16 -0
  98. package/dist/host/defaults/workspace-gate.js +88 -0
  99. package/dist/host/diagnostics.d.ts +7 -2
  100. package/dist/host/diagnostics.js +6 -0
  101. package/dist/host/identity.js +2 -1
  102. package/dist/host/index.d.ts +5 -2
  103. package/dist/host/index.js +21 -1
  104. package/dist/host/no-database.d.ts +38 -0
  105. package/dist/host/no-database.js +107 -0
  106. package/dist/host/react.d.ts +1 -0
  107. package/dist/host/react.js +25 -2
  108. package/dist/host/registered-source.js +2 -2
  109. package/dist/host/source.d.ts +109 -0
  110. package/dist/host/source.js +86 -0
  111. package/dist/host/ui-slots.d.ts +8 -8
  112. package/dist/host/ui-slots.js +5 -3
  113. package/dist/mandates/useMandate.js +13 -0
  114. package/dist/public-chat/components/PublicMessageOptionsMenu.js +1 -1
  115. package/dist/store/create-chat-store.d.ts +4 -4
  116. package/dist/store/middlewares.d.ts +5 -5
  117. package/dist/store/slices.d.ts +1 -1
  118. package/dist/store/slices.js +4 -3
  119. package/dist/surfaces/redux/selectors.d.ts +2 -2
  120. package/dist/testing/turn-harness.d.ts +35 -0
  121. package/dist/testing/turn-harness.js +85 -0
  122. package/dist/tool-call-visualization/intelligence-places.js +1 -1
  123. package/dist/tool-call-visualization/redux/selectors.d.ts +1 -1
  124. package/dist/voice-agent/intelligence-places.js +6 -6
  125. package/package.json +9 -6
  126. package/dist/agents/model-registry/modelRegistrySlice.d.ts +0 -691
  127. package/dist/agents/model-registry/modelRegistrySlice.js +0 -574
  128. package/dist/host/model-class.d.ts +0 -33
  129. package/dist/host/model-class.js +0 -21
package/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # @ai-matrx/chat
2
2
 
3
+ ## 0.4.2
4
+ ### P29a round 2 (a bare host is a real app)
5
+
6
+ - **Front door = the real screens.** `FRONT_DOOR` now names `agents/components/chat/ChatNewClient` and
7
+ `ChatConversationRoom`; the `cx-chat` demo screens are out. The default navigation port is
8
+ CLIENT-SIDE (history API + a notify event; same-origin `Link` clicks move the history, no page load);
9
+ `@ai-matrx/chat/host/react` exports `useRouter`/`usePathname`/`useSearchParams`/`Link` over the host's
10
+ navigation port. `check:front-door:canary` scans the canary.
11
+ - **A host names itself.** `ChatHost.app = { sourceApp, sourceFeature? }` stamps `source_app` /
12
+ `source_feature` on every send; absent = the neutral `chat` producer (said once), never matrx-frontend.
13
+ matrx-frontend sets `app: { sourceApp: "matrx-frontend" }` explicitly. Both names must be registered
14
+ with the server.
15
+ - **The model picker is the agents package's own** (`@ai-matrx/agents/models/react`); `ModelListDropdown` is
16
+ no longer a slot. A bare host's `BareHostChrome` mounts the catalog + favorites over `host.db`.
17
+ - **Unsent chips persist server-side in a bare host** (`default-remark-durability`: `block_state_set` /
18
+ `block_state_list_staged` / `block_state_dismiss_chip`), registered by `<ChatProvider>` for a private store.
19
+ - **Stand-ins report quietly.** An unregistered optional slot is one `console.info` line, once; only a
20
+ registration the package cannot run without (`SLOT_CANNOT_RUN`) warns and reaches diagnostics.
21
+ A bare host also gets the associations service (working document + scratchpad restore) from its own store.
22
+
23
+ ## 0.4.1
24
+
25
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
26
+ `git diff npm/chat/v0.4.0..npm/chat/v0.4.1 -- apps/shared/chat`).
27
+ No source changes intended and no consumer action required.
28
+
29
+ ## 0.4.0
30
+
31
+ Agent core B3 + the B2 tail — every piece of agent and model state has one holder:
32
+
33
+ - **The model registry slice is retired.** `modelRegistry` is gone from `chatReducers`; model records
34
+ (options, full records with controls, pinned-class configs, class labels, identities) live in the core
35
+ model catalog (`@ai-matrx/agents/models` 0.52+, `catalog.records`), bound once per page by
36
+ `agents/identity/model-catalog` (`getModelCatalog`, `getModelRecords`, `readModelRecords`,
37
+ `useModelRecords`, `useModelRecord`, `useModelLabel`, `useModelLabelWithClass`, `useModelClassLabels`,
38
+ `useModelClassControls`). `agents/redux/model-registry` re-exports the core selectors, which take the
39
+ records state. `agents/model-registry/modelRegistrySlice` and the `host/model-class` port are deleted;
40
+ `selectNormalizedControls` / `selectEffectiveModelName` became `useNormalizedControls(agentId)`
41
+ (`agents/redux/agent-settings/useNormalizedControls`).
42
+ - **The run tier is never copied onto the agent record**: selectors complete the record from the core run
43
+ tier store at read time (`agents/redux/agent-definition/run-tier-record`); a field the record read itself wins.
44
+ - G3 `check:one-holder`: the model part and the run-tier projection are hard bans (self-tested).
45
+ - Intelligence places name the package's real paths (`apps/shared/chat/src/...`).
46
+ - **Consumer action:** host — make `getModelCatalog()` return chat's instance, hydrate shell model rows with
47
+ `getModelRecords().hydrate(...)`, drop `registerChatModelClassHooks`, repoint `modelRegistrySlice` imports.
48
+
3
49
  ## 0.3.33
4
50
 
5
51
  - **Opening a chat never asks for an organization.** `launchAgentExecution` asks before opening only
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { useContext, useEffect, useState, useSyncExternalStore } from "react";
3
3
  import { ReactReduxContext } from "react-redux";
4
+ import { ChatStoreContext } from "../../store/context.js";
4
5
  import {
5
6
  agentDoorFor,
6
7
  agentGoHref,
@@ -15,7 +16,9 @@ import { selectIsAdmin } from "../../host/identity.js";
15
16
  const noSubscribe = () => () => {
16
17
  };
17
18
  function useAgentAddressViewer() {
18
- const store = useContext(ReactReduxContext)?.store;
19
+ const chatStore = useContext(ChatStoreContext)?.store;
20
+ const hostStore = useContext(ReactReduxContext)?.store;
21
+ const store = chatStore ?? hostStore;
19
22
  const read = () => store ? selectIsAdmin(store.getState()) : void 0;
20
23
  const isAdmin = useSyncExternalStore(
21
24
  store ? store.subscribe : noSubscribe,
@@ -1,3 +1,5 @@
1
+ import { selectHostConversation } from "../redux/execution-system/host-conversations/host-conversations.selectors.js";
2
+ import { answerHostAsk } from "../redux/execution-system/host-conversations/host-conversation.thunks.js";
1
3
  import { callApi } from "../../host/server/call-api.js";
2
4
  import { toast } from "../../host/notify.js";
3
5
  import { formatDurationMs } from "@ai-matrx/kit/format";
@@ -232,7 +234,7 @@ async function failLifecycleForCalls(dispatch, getState, conversationId, results
232
234
  }
233
235
  }
234
236
  const submitToolResult = (pending) => {
235
- return (dispatch) => {
237
+ return (dispatch, getState) => {
236
238
  dispatch(settleClientToolCall(pending));
237
239
  if (!pending.is_error && nonErrorOutputReadsAsFailure(pending.output)) {
238
240
  console.error(
@@ -240,6 +242,14 @@ const submitToolResult = (pending) => {
240
242
  );
241
243
  }
242
244
  const { conversationId, ...rest } = pending;
245
+ if (selectHostConversation(conversationId)(getState())) {
246
+ void answerHostAsk(conversationId, rest.call_id, rest).catch((error) => {
247
+ toast.error("Your answer did not reach this chat", {
248
+ description: error instanceof Error ? error.message : String(error)
249
+ });
250
+ });
251
+ return;
252
+ }
243
253
  const bucket = queue.get(conversationId) ?? [];
244
254
  bucket.push(rest);
245
255
  queue.set(conversationId, bucket);
@@ -3,14 +3,14 @@ const K = MANDATE_KEYS;
3
3
  const AMBIENT_PLACES = {
4
4
  feature: "ambient",
5
5
  label: "Ambient assistant",
6
- roots: ["packages/chat/src/agents/components/ambient-assistant"],
6
+ roots: ["apps/shared/chat/src/agents/components/ambient-assistant"],
7
7
  places: [
8
8
  {
9
9
  id: "page-guidance",
10
10
  label: "Any page",
11
11
  trigger: "The page assistant (where a module has none of its own)",
12
12
  mandateKeys: [K.ambient__page_guidance],
13
- sources: ["packages/chat/src/agents/components/ambient-assistant/ambientAssistantMandates.ts"]
13
+ sources: ["apps/shared/chat/src/agents/components/ambient-assistant/ambientAssistantMandates.ts"]
14
14
  },
15
15
  {
16
16
  id: "listen",
@@ -15,7 +15,7 @@ const CHAT_PLACES = {
15
15
  feature: "chat",
16
16
  label: "Chat",
17
17
  aliases: { DEFAULT_NEW_CHAT_MANDATE_KEY },
18
- roots: ["packages/chat/src/agents/components/chat", "app/(core)/chat"],
18
+ roots: ["apps/shared/chat/src/agents/components/chat", "app/(core)/chat"],
19
19
  places: [
20
20
  {
21
21
  id: "new",
@@ -25,9 +25,9 @@ const CHAT_PLACES = {
25
25
  mandateKeys: [K.chat__default_new_chat],
26
26
  sources: [
27
27
  "app/(core)/chat/new/page.tsx",
28
- "packages/chat/src/agents/components/chat/ChatNewClient.tsx",
29
- "packages/chat/src/agents/components/chat/ChatNewHeader.tsx",
30
- "packages/chat/src/agents/components/chat/NewChatGreeting.tsx"
28
+ "apps/shared/chat/src/agents/components/chat/ChatNewClient.tsx",
29
+ "apps/shared/chat/src/agents/components/chat/ChatNewHeader.tsx",
30
+ "apps/shared/chat/src/agents/components/chat/NewChatGreeting.tsx"
31
31
  ]
32
32
  },
33
33
  {
@@ -46,8 +46,8 @@ const CHAT_PLACES = {
46
46
  mandateKeys: [K.chat__default_new_chat],
47
47
  sources: [
48
48
  "app/(core)/chat/[conversationId]/page.tsx",
49
- "packages/chat/src/agents/components/chat/ChatConversationRoom.tsx",
50
- "packages/chat/src/agents/components/chat/ChatRoomClient.tsx"
49
+ "apps/shared/chat/src/agents/components/chat/ChatConversationRoom.tsx",
50
+ "apps/shared/chat/src/agents/components/chat/ChatRoomClient.tsx"
51
51
  ]
52
52
  },
53
53
  {
@@ -69,7 +69,7 @@ const CHAT_PLACES = {
69
69
  K.chat__response_mode_data,
70
70
  K.chat__response_mode_brainstorm
71
71
  ],
72
- sources: ["packages/chat/src/cx-chat/components/agent/local-agents.ts"]
72
+ sources: ["apps/shared/chat/src/cx-chat/components/agent/local-agents.ts"]
73
73
  }
74
74
  ]
75
75
  };
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { useEffect } from "react";
3
- import { useStore } from "react-redux";
3
+ import { useAppStore as useStore } from "../../../store/hooks.js";
4
4
  import { useOptionalCanvas } from "@ai-matrx/canvas/react";
5
5
  import { selectCanvasIsHydrated } from "@ai-matrx/canvas";
6
6
  function canvasItemConversation(item, conversationOfMessage) {
@@ -30,18 +30,14 @@ import {
30
30
  } from "../../../redux/agent-definition/selectors.js";
31
31
  import { fetchAgentRunControls } from "../../../redux/agent-definition/thunks.js";
32
32
  import { selectAgentIdFromInstance } from "../../../redux/execution-system/conversations/conversations.selectors.js";
33
- import {
34
- selectAllModels,
35
- selectModelFullyLoaded,
36
- fetchModelById
37
- } from "../../../model-registry/modelRegistrySlice.js";
33
+ import { selectAllModels, selectModelFullyLoaded } from "@ai-matrx/agents/models";
38
34
  import {
39
35
  useModelControls,
40
36
  supportsTools
41
37
  } from "../../../hooks/useModelControls.js";
42
38
  import { selectInstanceOverrideState } from "../../../redux/execution-system/instance-model-overrides/instance-model-overrides.selectors.js";
43
39
  import { effectiveOfferingPin } from "../../../redux/execution-system/instance-model-overrides/offering-pin.js";
44
- import { useModelClassControls } from "../../../../host/model-class.js";
40
+ import { getModelRecords, useModelClassControls, useModelRecords } from "../../../identity/model-catalog.js";
45
41
  import { selectBuilderAdvancedSettings } from "../../../redux/execution-system/instance-ui-state/instance-ui-state.selectors.js";
46
42
  import { setBuilderAdvancedSettings } from "../../../redux/execution-system/instance-ui-state/instance-ui-state.slice.js";
47
43
  import { DEFAULT_BUILDER_ADVANCED_SETTINGS } from "../../../types/instance.types.js";
@@ -73,16 +69,14 @@ function RunToolPicker({ conversationId }) {
73
69
  selectInstanceOverrideState(conversationId)
74
70
  );
75
71
  const effectiveModelId = overrideState?.overrides?.model ?? overrideState?.baseSettings?.model ?? "";
76
- const models = useAppSelector(selectAllModels);
77
- const modelIsFull = useAppSelector(
78
- (s) => selectModelFullyLoaded(s, effectiveModelId)
79
- );
80
- const modelRegistryLoading = useAppSelector((s) => s.modelRegistry.isLoading);
72
+ const models = useModelRecords(selectAllModels);
73
+ const modelIsFull = useModelRecords((s) => selectModelFullyLoaded(s, effectiveModelId));
74
+ const modelRegistryLoading = useModelRecords((s) => s.isLoading);
81
75
  useEffect(() => {
82
76
  if (effectiveModelId && !modelIsFull && !modelRegistryLoading) {
83
- void dispatch(fetchModelById(effectiveModelId));
77
+ void getModelRecords().loadModel(effectiveModelId);
84
78
  }
85
- }, [effectiveModelId, modelIsFull, modelRegistryLoading, dispatch]);
79
+ }, [effectiveModelId, modelIsFull, modelRegistryLoading]);
86
80
  const classControls = useModelClassControls(
87
81
  effectiveModelId,
88
82
  effectiveOfferingPin(overrideState)
@@ -21,7 +21,8 @@ import {
21
21
  import { useSessionKnob } from "../../../../../host/prefs-react.js";
22
22
  import { knobRefusalSentence, setKnobOverride } from "../../../../../host/prefs.js";
23
23
  import { CHAT_DEFAULT_MODEL_KNOB } from "../../../../../ui/chat-default-model-knob.js";
24
- import { selectModelLabelWithClass } from "../../../../model-registry/modelRegistrySlice.js";
24
+ import { selectModelLabelWithClass } from "@ai-matrx/agents/models";
25
+ import { useModelRecords } from "../../../../identity/model-catalog.js";
25
26
  import {
26
27
  ComposerMenuDivider,
27
28
  ComposerMenuHelp,
@@ -173,7 +174,7 @@ function ChatPresetsPanel({
173
174
  const personalModelId = typeof personalModel === "string" && personalModel.trim() ? personalModel : null;
174
175
  const overrideState = useAppSelector(selectInstanceOverrideState(conversationId));
175
176
  const pinnedOfferingId = effectiveOfferingPin(overrideState);
176
- const personalModelLabel = useAppSelector((s) => selectModelLabelWithClass(s, personalModelId, pinnedOfferingId)) ?? null;
177
+ const personalModelLabel = useModelRecords((s) => selectModelLabelWithClass(s, personalModelId, pinnedOfferingId)) ?? null;
177
178
  const onSelectAgent = agentControl?.onSelectAgent;
178
179
  const agentFilter = useComposerAgentFilter(conversationId);
179
180
  if (!onSelectAgent) {
@@ -12,9 +12,9 @@ import { selectInstanceOverrideState } from "../../../../redux/execution-system/
12
12
  import {
13
13
  selectModelLabelById,
14
14
  selectModelLabelWithClass
15
- } from "../../../../model-registry/modelRegistrySlice.js";
15
+ } from "@ai-matrx/agents/models";
16
16
  import { useModelOptions } from "../../../../../host/ui-slots.js";
17
- import { useModelClassLabels } from "../../../../../host/model-class.js";
17
+ import { useModelClassLabels, useModelRecords } from "../../../../identity/model-catalog.js";
18
18
  import { useEffectiveClassPin } from "../../../../redux/execution-system/instance-model-overrides/useEffectiveClassPin.js";
19
19
  import { ensureAgentCatalog, useAgentName } from "../../../../identity/agent-identity.js";
20
20
  const CHAT_AGENT_TAG = "chat-agent";
@@ -49,14 +49,14 @@ function useComposerAgent(conversationId) {
49
49
  const classPins = useEffectiveClassPin(conversationId);
50
50
  const effectivePin = classPins.effectivePin ?? null;
51
51
  const agentOwnPin = classPins.basePin ?? null;
52
- const effectiveModelLabel = useAppSelector((state) => selectModelLabelWithClass(state, effectiveModelId, effectivePin)) ?? null;
52
+ const effectiveModelLabel = useModelRecords((state) => selectModelLabelWithClass(state, effectiveModelId, effectivePin)) ?? null;
53
53
  const agentOwnModelId = useAgentOwnModelId(conversationId);
54
- const agentModelLabel = useAppSelector((state) => selectModelLabelWithClass(state, agentOwnModelId, agentOwnPin)) ?? null;
54
+ const agentModelLabel = useModelRecords((state) => selectModelLabelWithClass(state, agentOwnModelId, agentOwnPin)) ?? null;
55
55
  const { mandate: customMandate } = useMandate(MANDATE_KEYS.chat__default_new_chat, { optional: true });
56
56
  const customAgentId = customMandate?.agentId ?? null;
57
57
  const rows = useAgentCatalogRows();
58
58
  const presetRows = rows.filter(isPresetRow);
59
- const modelLabels = useAppSelector(
59
+ const modelLabels = useModelRecords(
60
60
  (state) => presetRows.map((row) => selectModelLabelById(state, row.modelId) ?? null).join("\0")
61
61
  ).split("\0");
62
62
  const presets = presetRows.map((row, index) => ({
@@ -1,12 +1,13 @@
1
1
  "use client";
2
2
  import { useAppSelector } from "../../../../../store/hooks.js";
3
3
  import { selectBuilderAdvancedSettings } from "../../../../redux/execution-system/instance-ui-state/instance-ui-state.selectors.js";
4
- import { selectAllModels } from "../../../../model-registry/modelRegistrySlice.js";
4
+ import { selectAllModels } from "@ai-matrx/agents/models";
5
+ import { useModelRecords } from "../../../../identity/model-catalog.js";
5
6
  import { readOutputTypes } from "./output-selection.js";
6
7
  import { agentOutputFilterSpec, modelMakesAny, modelOutputModalities } from "./agent-output-filter.js";
7
8
  function useComposerAgentFilter(conversationId) {
8
9
  const settings = useAppSelector(selectBuilderAdvancedSettings(conversationId));
9
- const models = useAppSelector(selectAllModels);
10
+ const models = useModelRecords(selectAllModels);
10
11
  const spec = agentOutputFilterSpec(readOutputTypes(settings?.outputTypes));
11
12
  if (!spec) return void 0;
12
13
  const outputsById = new Map(models.map((model) => [model.id, modelOutputModalities(model.capabilities)]));
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useConversationAbilities } from "../../redux/execution-system/host-conversations/conversation-abilities.js";
3
4
  import { useEffect, useMemo, useRef, useState } from "react";
4
5
  import { useAppDispatch, useAppSelector } from "../../../store/hooks.js";
5
6
  import { loadConversation } from "../../redux/execution-system/thunks/load-conversation.thunk.js";
@@ -101,9 +102,11 @@ function AgentConversationDisplay({
101
102
  () => setFindOpen(true),
102
103
  displayGroups.length > 0
103
104
  );
105
+ const { database: canPin } = useConversationAbilities();
104
106
  useEffect(() => {
107
+ if (!canPin) return;
105
108
  void hydratePinnedMessages(messages.map((m) => m.id));
106
- }, [messages]);
109
+ }, [messages, canPin]);
107
110
  const [findHistory, setFindHistory] = useState({
108
111
  state: "loading",
109
112
  loaded: 0
@@ -8,12 +8,10 @@ import { useAppDispatch, useAppSelector, useAppStore } from "../../../store/hook
8
8
  import {
9
9
  selectAllModels,
10
10
  selectModelFullyLoaded,
11
- fetchModelById,
12
- retryModelDetail,
13
11
  selectModelDetailError
14
- } from "../../model-registry/modelRegistrySlice.js";
12
+ } from "@ai-matrx/agents/models";
15
13
  import { useModelControls } from "../../hooks/useModelControls.js";
16
- import { useModelClassControls } from "../../../host/model-class.js";
14
+ import { getModelRecords, useModelClassControls, useModelRecords } from "../../identity/model-catalog.js";
17
15
  import {
18
16
  selectInstanceOverrideState,
19
17
  selectSettingsOverridesForApi
@@ -88,7 +86,7 @@ function RunConfigOverrides({
88
86
  const overrideState = useAppSelector(
89
87
  selectInstanceOverrideState(conversationId)
90
88
  );
91
- const models = useAppSelector(selectAllModels);
89
+ const models = useModelRecords(selectAllModels);
92
90
  const overrideJson = useAppSelector(
93
91
  (state) => JSON.stringify(
94
92
  selectSettingsOverridesForApi(conversationId)(state) ?? {},
@@ -133,18 +131,14 @@ function RunConfigOverrides({
133
131
  const effectiveOffering = removals.includes("offering_id") ? nullDefaults?.offering_id : overrides.offering_id ?? base.offering_id;
134
132
  const pinnedOfferingId = typeof effectiveOffering === "string" && effectiveOffering ? effectiveOffering : void 0;
135
133
  const modelChoiceOverridden = "model" in overrides || "offering_id" in overrides || removals.includes("offering_id");
136
- const isFull = useAppSelector(
137
- (s) => selectModelFullyLoaded(s, effectiveModelId)
138
- );
139
- const modelDetailError = useAppSelector(
140
- (s) => selectModelDetailError(s, effectiveModelId)
141
- );
142
- const registryLoading = useAppSelector((s) => s.modelRegistry.isLoading);
134
+ const isFull = useModelRecords((s) => selectModelFullyLoaded(s, effectiveModelId));
135
+ const modelDetailError = useModelRecords((s) => selectModelDetailError(s, effectiveModelId));
136
+ const registryLoading = useModelRecords((s) => s.isLoading);
143
137
  useEffect(() => {
144
138
  if (effectiveModelId && !isFull && !registryLoading) {
145
- dispatch(fetchModelById(effectiveModelId));
139
+ void getModelRecords().loadModel(effectiveModelId);
146
140
  }
147
- }, [dispatch, effectiveModelId, isFull, registryLoading]);
141
+ }, [effectiveModelId, isFull, registryLoading]);
148
142
  const classControls = useModelClassControls(effectiveModelId, pinnedOfferingId);
149
143
  const { normalizedControls } = useModelControls(
150
144
  models,
@@ -194,8 +188,8 @@ function RunConfigOverrides({
194
188
  {
195
189
  variant: "outline",
196
190
  onClick: () => {
197
- dispatch(retryModelDetail(effectiveModelId));
198
- void dispatch(fetchModelById(effectiveModelId));
191
+ getModelRecords().retryModel(effectiveModelId);
192
+ void getModelRecords().loadModel(effectiveModelId);
199
193
  },
200
194
  children: "Retry"
201
195
  }
@@ -64,8 +64,8 @@ export declare function makeSelectConversationRequests(conversationId: string):
64
64
  proposedDirectives: import("../../../redux/proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
65
65
  agentSettings: import("../../../redux/agent-settings/types.js").AgentSettingsState;
66
66
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
67
- modelRegistry: import("../../../model-registry/modelRegistrySlice.js").ModelRegistryState;
68
67
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
68
+ hostConversations: import("../../../redux/execution-system/host-conversations/host-conversations.slice.js").HostConversationsState;
69
69
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => ActiveRequest[]) & {
70
70
  clearCache: () => void;
71
71
  resultsCount: () => number;
@@ -26,6 +26,7 @@ import {
26
26
  } from "../../redux/execution-system/messages/messages.slice.js";
27
27
  import { selectStreamPhase } from "../../redux/execution-system/selectors/aggregate.selectors.js";
28
28
  import { selectShowCreatorPanel } from "../../../host/prefs.js";
29
+ import { ConversationAbilitiesProvider } from "../../redux/execution-system/host-conversations/conversation-abilities.js";
29
30
  import {
30
31
  TranscriptAudienceProvider
31
32
  } from "./transcript-audience.js";
@@ -202,7 +203,7 @@ function AgentConversationColumn({
202
203
  }, []);
203
204
  const edgeScroll = constrainWidth && edgeToEdgeScroll;
204
205
  const centerWrap = edgeScroll ? cn(ASSISTANT_MESSAGE_COLUMN_CLASS, ASSISTANT_MESSAGE_COLUMN_INSET_CLASS) : "contents";
205
- return /* @__PURE__ */ jsx(TranscriptAudienceProvider, { audience, children: /* @__PURE__ */ jsxs(
206
+ return /* @__PURE__ */ jsx(ConversationAbilitiesProvider, { conversationId: displayId, children: /* @__PURE__ */ jsx(TranscriptAudienceProvider, { audience, children: /* @__PURE__ */ jsxs(
206
207
  "div",
207
208
  {
208
209
  className: cn(
@@ -347,7 +348,7 @@ function AgentConversationColumn({
347
348
  )
348
349
  ]
349
350
  }
350
- ) });
351
+ ) }) });
351
352
  }
352
353
  export {
353
354
  AgentConversationColumn
@@ -20,7 +20,7 @@ export declare function surfaceNameForKind(kind: WorkingDocumentKind): string;
20
20
  export declare function sourceFeatureForKind(kind: WorkingDocumentKind): SourceFeature;
21
21
  /** `UnifiedAgentContextMenu` prop bundle for a document kind. */
22
22
  export declare function workingDocumentContextMenuProps(kind: WorkingDocumentKind): {
23
- sourceFeature: "action_request_continuation" | "action_request_credential" | "action_request_one_time_code" | "action_request_park" | "action_request_resolve" | "admin" | "agent" | "agent-app" | "agent-builder" | "agent-comparison" | "agent-factory" | "agent-generator" | "agent-runner" | "agent-service" | "agent-studio" | "agent_blocks" | "agent_call" | "agent_factory.copy_probe" | "agent_factory.tool_probe" | "agent_flow_v1" | "agent_foundry_v1" | "agent_run" | "agent_structure_builder" | "agent_tool" | "agent_usage_sync" | "agents-other" | "ai-results" | "ai_judge" | "analysis-studio" | "auto_ingest" | "auto_ingest_ner" | "background_agent" | "billing" | "browser_handoff_delegate" | "browser_handoff_resolve" | "browser_session_health" | "builtin_agent" | "builtin_categorize" | "canvas" | "chat" | "claude-code" | "clean_pdf_extracted_content" | "client-unmapped" | "cloud_browser.local_login_learning" | "cms" | "code-editor" | "codex" | "coding_session_bridge.backfill" | "coding_session_native" | "coding_session_reply" | "communications.sms" | "conductor" | "content-extractor" | "content_plan_acceptance" | "content_plan_cms_fill" | "content_plan_cms_fill_preview" | "content_plan_deepen" | "content_plan_generate" | "content_processing" | "content_processing.research_landing" | "content_processing.transcript_landing" | "content_processing_upload_hook" | "context-parity" | "context_compare_answer" | "context_follow_listener" | "context_summary" | "conversation" | "conversation_context" | "conversation_crash_recovery" | "conversation_fork" | "conversation_resume" | "coverage" | "crawl_run" | "crm" | "crm.media_list_refresh" | "crm.media_list_research" | "crm.party_kind" | "crm.personalization" | "cursor" | "deep_research_v1" | "deferred_claim_recovery" | "dictionary" | "distillation_coherence" | "doc_verify" | "documents" | "education-analytics" | "education-assessment" | "education-fastfire" | "education-flashcards" | "education-ingest" | "education-media-reconcile" | "education-mindmap" | "education-planner" | "education-tutor" | "education_card_image_generator" | "education_card_image_prompt_writer" | "education_card_image_qc_judge" | "education_card_image_rot" | "education_card_image_web_source" | "education_card_images" | "education_study_pack" | "education_study_pack_v2" | "endpoint_family_sweep" | "external_url_change" | "files" | "fork_and_run" | "google_workspace.approval_replay" | "group_chat_cadence" | "hindsight" | "hindsight/crystallization" | "hindsight/wire_replay" | "hindsight_replay" | "hindsight_replay_worker" | "hindsight_shadow_recompilation" | "hr" | "human_decisions" | "image-studio" | "incident-assurance" | "internal" | "judge" | "kg_clustering_namer" | "legal" | "local_proxy" | "mandate_candidate_review" | "mandates.batch_lane" | "manual" | "marketing" | "masterwork" | "masterwork_audition_elicitation_vanilla" | "masterwork_audition_outcome_vanilla" | "masterwork_audition_unfolding_vanilla" | "masterwork_audition_vanilla" | "masterwork_bench_a2" | "masterwork_bench_extract" | "masterwork_bench_judge" | "masterwork_bench_panel" | "masterwork_build" | "masterwork_recovery" | "media_catalog" | "media_heal" | "meet:after_meeting_workflow" | "mermaid-workbench" | "messages" | "ner" | "news_monitor" | "notes" | "notify_listener" | "outcome_attribution" | "outreach" | "page_extraction" | "page_extraction_retry" | "pdf-cleaner" | "pdf-extractor" | "pdf-widgets" | "personal-staff" | "personal_staff_workspace_listener" | "platform_checks" | "platform_checks_drain" | "podcasts" | "print" | "product_capture_intake" | "product_capture_research" | "projects" | "prompt" | "proof_run:content_plan_family_grounding" | "proof_run:news_self_validating" | "provenance" | "provider_outage" | "rag" | "rag-search" | "rag.page_clean" | "rag_chunk_contextualizer" | "rag_hyde_generator" | "rag_pdf_page_cleaner" | "rag_query_expander" | "reachability" | "realtime" | "realtime_tool" | "registry_ingestion.pass" | "request_snapshot_blob" | "reroute" | "research" | "research_condenser_1" | "research_condenser_2" | "research_refresh_dispatch" | "row_history" | "scanner" | "scheduled" | "schema_coerce" | "scraper" | "scratchpad" | "screen_tool_run" | "seo" | "seo.engine_schedule_dispatcher" | "seo.keyword_place_backfill" | "seo.page_analysis" | "seo.rank_schedule" | "seo_analysis_sweep" | "seo_keyword_research" | "server-door" | "server-run" | "sharing" | "sms-assistant" | "sms-outbound" | "socket_compat" | "source_intelligence" | "staff-inbox-driver" | "suggestion_sweep" | "summarize_content" | "sweep_listener" | "system" | "tasks" | "test.agent_factory.intake" | "tool-call-visualization" | "tool-testing" | "transcription" | "udt" | "vision_interview" | "vision_interview_tracker" | "voice-agent" | "vscode" | "web-capture" | "web_crawl_crash_resume" | "web_crawl_schedule_dispatch" | "web_research" | "web_url_announce" | "whole_value_follower" | "workflow_decision_fallback" | "workflow_extract_sweep" | "workflow_holder_proof" | "workflow_node_test" | "workflow_plan_assist" | "workflow_recovery_advisor" | "workflow_recovery_push" | "workflow_recovery_resolve" | "workflow_run" | "workflow_run_assists" | "workflow_worker" | "working-document" | "youtube_research_processing" | "youtube_transcription";
23
+ sourceFeature: "action_request_continuation" | "action_request_credential" | "action_request_one_time_code" | "action_request_park" | "action_request_resolve" | "admin" | "agent" | "agent-app" | "agent-builder" | "agent-comparison" | "agent-factory" | "agent-generator" | "agent-runner" | "agent-service" | "agent-studio" | "agent_blocks" | "agent_call" | "agent_factory.copy_probe" | "agent_factory.tool_probe" | "agent_flow_v1" | "agent_foundry_v1" | "agent_run" | "agent_structure_builder" | "agent_tool" | "agent_usage_sync" | "agents-other" | "ai-results" | "ai_judge" | "analysis-studio" | "auto_ingest" | "auto_ingest_ner" | "background_agent" | "billing" | "browser_handoff_delegate" | "browser_handoff_resolve" | "browser_session_health" | "builtin_agent" | "builtin_categorize" | "canvas" | "chat" | "chat-canary" | "claude-code" | "clean_pdf_extracted_content" | "client-unmapped" | "cloud_browser.local_login_learning" | "cms" | "code-editor" | "codex" | "coding_session_bridge.backfill" | "coding_session_native" | "coding_session_reply" | "communications.sms" | "conductor" | "content-extractor" | "content_plan_acceptance" | "content_plan_cms_fill" | "content_plan_cms_fill_preview" | "content_plan_deepen" | "content_plan_generate" | "content_processing" | "content_processing.research_landing" | "content_processing.transcript_landing" | "content_processing_upload_hook" | "context-parity" | "context_compare_answer" | "context_follow_listener" | "context_summary" | "conversation" | "conversation_context" | "conversation_crash_recovery" | "conversation_fork" | "conversation_resume" | "coverage" | "crawl_run" | "crm" | "crm.media_list_refresh" | "crm.media_list_research" | "crm.party_kind" | "crm.personalization" | "cursor" | "deep_research_v1" | "deferred_claim_recovery" | "dictionary" | "distillation_coherence" | "doc_verify" | "documents" | "education-analytics" | "education-assessment" | "education-fastfire" | "education-flashcards" | "education-ingest" | "education-media-reconcile" | "education-mindmap" | "education-planner" | "education-tutor" | "education_card_image_generator" | "education_card_image_prompt_writer" | "education_card_image_qc_judge" | "education_card_image_rot" | "education_card_image_web_source" | "education_card_images" | "education_study_pack" | "education_study_pack_v2" | "endpoint_family_sweep" | "external_url_change" | "files" | "fork_and_run" | "google_workspace.approval_replay" | "group_chat_cadence" | "hindsight" | "hindsight/crystallization" | "hindsight/wire_replay" | "hindsight_replay" | "hindsight_replay_worker" | "hindsight_shadow_recompilation" | "hr" | "human_decisions" | "image-studio" | "incident-assurance" | "internal" | "judge" | "kg_clustering_namer" | "legal" | "local_proxy" | "mandate_candidate_review" | "mandates.batch_lane" | "manual" | "marketing" | "masterwork" | "masterwork_audition_elicitation_vanilla" | "masterwork_audition_outcome_vanilla" | "masterwork_audition_unfolding_vanilla" | "masterwork_audition_vanilla" | "masterwork_bench_a2" | "masterwork_bench_extract" | "masterwork_bench_judge" | "masterwork_bench_panel" | "masterwork_build" | "masterwork_recovery" | "media_catalog" | "media_heal" | "meet:after_meeting_workflow" | "mermaid-workbench" | "messages" | "ner" | "news_monitor" | "notes" | "notify_listener" | "outcome_attribution" | "outreach" | "page_extraction" | "page_extraction_retry" | "pdf-cleaner" | "pdf-extractor" | "pdf-widgets" | "personal-staff" | "personal_staff_workspace_listener" | "platform_checks" | "platform_checks_drain" | "podcasts" | "print" | "product_capture_intake" | "product_capture_research" | "projects" | "prompt" | "proof_run:content_plan_family_grounding" | "proof_run:news_self_validating" | "provenance" | "provider_outage" | "rag" | "rag-search" | "rag.page_clean" | "rag_chunk_contextualizer" | "rag_hyde_generator" | "rag_pdf_page_cleaner" | "rag_query_expander" | "reachability" | "realtime" | "realtime_tool" | "registry_ingestion.pass" | "request_snapshot_blob" | "reroute" | "research" | "research_condenser_1" | "research_condenser_2" | "research_refresh_dispatch" | "row_history" | "scanner" | "scheduled" | "schema_coerce" | "scraper" | "scratchpad" | "screen_tool_run" | "seo" | "seo.engine_schedule_dispatcher" | "seo.keyword_place_backfill" | "seo.page_analysis" | "seo.rank_schedule" | "seo_analysis_sweep" | "seo_keyword_research" | "server-door" | "server-run" | "sharing" | "sms-assistant" | "sms-outbound" | "socket_compat" | "source_intelligence" | "staff-inbox-driver" | "suggestion_sweep" | "summarize_content" | "sweep_listener" | "system" | "tasks" | "test.agent_factory.intake" | "tool-call-visualization" | "tool-testing" | "transcription" | "udt" | "vision_interview" | "vision_interview_tracker" | "voice-agent" | "vscode" | "web-capture" | "web_crawl_crash_resume" | "web_crawl_schedule_dispatch" | "web_research" | "web_url_announce" | "whole_value_follower" | "workflow_decision_fallback" | "workflow_extract_sweep" | "workflow_holder_proof" | "workflow_node_test" | "workflow_plan_assist" | "workflow_recovery_advisor" | "workflow_recovery_push" | "workflow_recovery_resolve" | "workflow_run" | "workflow_run_assists" | "workflow_worker" | "working-document" | "youtube_research_processing" | "youtube_transcription";
24
24
  surfaceName: string;
25
25
  isEditable: true;
26
26
  enabledPlacements: ("ai-action" | "content-block" | "quick-action")[];
@@ -7,8 +7,8 @@ import {
7
7
  import {
8
8
  selectModelLabelById,
9
9
  selectModelLabelWithClass
10
- } from "../model-registry/modelRegistrySlice.js";
11
- import { useModelClassLabels } from "../../host/model-class.js";
10
+ } from "@ai-matrx/agents/models";
11
+ import { useModelClassLabels, useModelLabel, useModelRecords } from "../identity/model-catalog.js";
12
12
  import { useAgentSummaryRow } from "../identity/agent-identity.js";
13
13
  function useAgentModelLabel(agentId) {
14
14
  useModelClassLabels();
@@ -21,7 +21,8 @@ function useAgentModelLabel(agentId) {
21
21
  );
22
22
  const modelId = ownModelId ?? summary?.modelId ?? null;
23
23
  const offeringId = ownOfferingId !== void 0 ? ownOfferingId : summary?.offeringId;
24
- const label = useAppSelector(
24
+ useModelLabel(modelId);
25
+ const label = useModelRecords(
25
26
  (state) => offeringId === void 0 ? selectModelLabelById(state, modelId) : selectModelLabelWithClass(state, modelId, offeringId)
26
27
  );
27
28
  return { modelId, offeringId, label };
@@ -6,15 +6,13 @@ import {
6
6
  selectToolIdentityMap
7
7
  } from "../redux/tools/tools.selectors.js";
8
8
  import { selectMcpCatalog } from "../redux/mcp/mcp.slice.js";
9
- import { selectModelIdentityMap } from "../model-registry/modelRegistrySlice.js";
9
+ import { useModelRecords } from "../identity/model-catalog.js";
10
10
  function useDiffEnrichment() {
11
11
  const allTools = useAppSelector(selectAllTools);
12
12
  const toolIdentities = useAppSelector(selectToolIdentityMap);
13
13
  const mcpCatalog = useAppSelector(selectMcpCatalog);
14
- const modelEntities = useAppSelector(
15
- (state) => state.modelRegistry.entities
16
- );
17
- const modelIdentities = useAppSelector(selectModelIdentityMap);
14
+ const modelEntities = useModelRecords((s) => s.entities);
15
+ const modelIdentities = useModelRecords((s) => s.identityById);
18
16
  return useMemo(
19
17
  () => ({
20
18
  resolveModelId: (id) => {