@ai-matrx/chat 0.7.6 → 0.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/agents/api/fetch-pending-calls.js +4 -3
  3. package/dist/agents/api/submit-tool-results.js +3 -6
  4. package/dist/agents/components/chat/begin-fresh-chat.js +2 -2
  5. package/dist/agents/components/inputs/smart-input/composer/ComposerSplash.js +2 -3
  6. package/dist/agents/components/inputs/smart-input/composer/useComposerMode.js +4 -2
  7. package/dist/agents/components/live-run/LiveRunDisplay.d.ts +7 -1
  8. package/dist/agents/components/live-run/LiveRunDisplay.js +3 -1
  9. package/dist/agents/components/messages-display/AgentConversationDisplay.js +1 -1
  10. package/dist/agents/components/messages-display/assistant/AgentEmptyMessageDisplay.js +4 -4
  11. package/dist/agents/components/messages-display/assistant/AssistantNoAnswer.js +1 -1
  12. package/dist/agents/components/messages-display/assistant/BreathingOrb.js +1 -1
  13. package/dist/agents/components/messages-display/assistant/InPlaceAnswerEditor.js +1 -1
  14. package/dist/agents/components/messages-display/citations/MessageSourcesRow.js +1 -1
  15. package/dist/agents/components/messages-display/conversation-tools/ConversationFindBar.js +4 -4
  16. package/dist/agents/components/messages-display/message-options/EditHistoryDialog.js +7 -7
  17. package/dist/agents/components/messages-display/user/AgentUserMessage.js +4 -4
  18. package/dist/agents/components/messages-display/user/CollabNoteMessage.js +2 -2
  19. package/dist/agents/components/messages-display/user/FirstTurnVariables.js +3 -3
  20. package/dist/agents/components/messages-display/user/PendingSendMessage.js +4 -4
  21. package/dist/agents/components/messages-display/user/RemarksTranscriptView.js +7 -7
  22. package/dist/agents/components/messages-display/user/ResourceAttachmentTile.js +9 -9
  23. package/dist/agents/components/messages-display/user/ResourceEditableToggleSamples.js +4 -4
  24. package/dist/agents/components/messages-display/user/UserActionBar.js +3 -3
  25. package/dist/agents/components/messages-display/user/UserMessageAttachmentStyleComparison.js +12 -12
  26. package/dist/agents/components/messages-display/user/UserMessageChipsDemo.js +19 -19
  27. package/dist/agents/components/messages-display/user/UserMessageHybridTileSamples.js +22 -22
  28. package/dist/agents/components/run/AgentRunnerPage.js +4 -4
  29. package/dist/agents/components/run/AssistantError.js +1 -1
  30. package/dist/agents/components/run/AssistantWarning.js +1 -1
  31. package/dist/agents/components/run/GenerationJobCard.js +5 -5
  32. package/dist/agents/components/run/IncompleteNote.js +1 -1
  33. package/dist/agents/components/run/RunJobWorkingLine.js +1 -1
  34. package/dist/agents/components/shared/AgentConversationColumn.js +1 -1
  35. package/dist/agents/components/shared/AgentHeaderMobile.js +6 -6
  36. package/dist/agents/components/shared/AgentModeController.js +1 -1
  37. package/dist/agents/components/shared/AutoInjectionSwitch.js +6 -6
  38. package/dist/agents/components/shared/DesktopFilterPanel.js +8 -8
  39. package/dist/agents/components/smart/AgentRunner.js +1 -1
  40. package/dist/agents/components/smart/CreateWithAiTabs.js +1 -1
  41. package/dist/agents/redux/agent-definition/agent-cache-bust-request.js +7 -7
  42. package/dist/agents/redux/execution-system/context-rules/receipt-check.js +2 -2
  43. package/dist/agents/redux/execution-system/inbox/inbox.thunks.d.ts +2 -2
  44. package/dist/agents/redux/execution-system/inbox/inbox.thunks.js +7 -15
  45. package/dist/agents/redux/execution-system/observational-memory/fetch-memory-cost.thunk.d.ts +1 -1
  46. package/dist/agents/redux/execution-system/observational-memory/fetch-memory-cost.thunk.js +7 -4
  47. package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +1 -114
  48. package/dist/agents/redux/execution-system/selectors/aggregate.selectors.js +28 -43
  49. package/dist/agents/redux/execution-system/thunks/call-conversation-api.d.ts +44 -0
  50. package/dist/agents/redux/execution-system/thunks/call-conversation-api.js +78 -0
  51. package/dist/agents/redux/execution-system/thunks/continue-agent-json.d.ts +41 -0
  52. package/dist/agents/redux/execution-system/thunks/continue-agent-json.js +66 -0
  53. package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.d.ts +20 -0
  54. package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +9 -2
  55. package/dist/agents/redux/execution-system/thunks/launch-agent-execution.thunk.js +4 -6
  56. package/dist/agents/redux/execution-system/thunks/notify-and-play-dispatcher.d.ts +1 -5
  57. package/dist/agents/redux/execution-system/thunks/notify-and-play-dispatcher.js +2 -1
  58. package/dist/agents/redux/execution-system/thunks/resolve-base-url.js +7 -17
  59. package/dist/agents/redux/execution-system/thunks/settle-after-stop.thunk.js +2 -2
  60. package/dist/agents/redux/execution-system/thunks/smart-execute.thunk.js +3 -3
  61. package/dist/agents/redux/execution-system/utils/continuation-body.d.ts +8 -2
  62. package/dist/agents/redux/execution-system/utils/continuation-body.js +3 -3
  63. package/dist/agents/redux/execution-system/utils/required-organization.d.ts +18 -0
  64. package/dist/agents/redux/execution-system/utils/required-organization.js +14 -10
  65. package/dist/agents/services/mcp-connections.service.js +5 -8
  66. package/dist/agents/ui-first-tools/dispatcher/dispatch-ui-first-tool.thunk.js +2 -1
  67. package/dist/host/defaults/files-host.js +11 -1
  68. package/dist/host/defaults/server-api.d.ts +1 -15
  69. package/dist/host/defaults/server-api.js +0 -21
  70. package/dist/host/defaults/server.d.ts +2 -1
  71. package/dist/host/defaults/server.js +8 -6
  72. package/dist/host/request-headers.d.ts +26 -0
  73. package/dist/host/request-headers.js +15 -0
  74. package/dist/host/server/call-api.d.ts +0 -13
  75. package/dist/host/server/call-api.js +0 -2
  76. package/dist/host/server/matrx-transport.d.ts +0 -1
  77. package/dist/host/server/matrx-transport.js +0 -2
  78. package/dist/store/root-state.d.ts +4 -21
  79. package/dist/surfaces/hooks/useSurfaceConfig.js +2 -1
  80. package/dist/surfaces/runtime/surface-feedback.js +2 -2
  81. package/dist/tool-call-visualization/components/ArtifactResultBar.js +4 -4
  82. package/dist/tool-call-visualization/components/ChatResultColumn.d.ts +1 -1
  83. package/dist/tool-call-visualization/components/ToolCallBatch.js +2 -2
  84. package/dist/tool-call-visualization/components/ToolCallVisualization.js +5 -5
  85. package/dist/tool-call-visualization/components/ToolTabBodies.js +12 -12
  86. package/dist/tool-call-visualization/components/ToolUpdatesOverlay.js +4 -4
  87. package/dist/tool-call-visualization/configured-rows/ConfiguredToolRow.js +8 -8
  88. package/dist/tool-call-visualization/configured-rows/CopyToolButton.js +1 -1
  89. package/dist/tool-call-visualization/configured-rows/ToolProgressView.js +7 -7
  90. package/dist/tool-call-visualization/configured-rows/field-components.js +6 -6
  91. package/dist/tool-call-visualization/registry/GenericRenderer.js +4 -4
  92. package/dist/tool-call-visualization/renderers/_shared-entity/EmptyResultCard.js +1 -1
  93. package/dist/tool-call-visualization/renderers/_shared-entity/EntityCard.js +5 -5
  94. package/dist/tool-call-visualization/renderers/_shared-entity/PartPeekPopover.js +2 -2
  95. package/dist/tool-call-visualization/renderers/_shared-entity/ToolGlyph.js +1 -1
  96. package/dist/tool-call-visualization/renderers/_shared-entity/ToolResultCard.js +6 -6
  97. package/dist/tool-call-visualization/renderers/agent-call/AgentCallInline.js +5 -5
  98. package/dist/tool-call-visualization/renderers/agent-call/CollabCallCard.js +4 -4
  99. package/dist/tool-call-visualization/renderers/agent-call/ImageGenerationResult.js +1 -1
  100. package/dist/tool-call-visualization/renderers/ask/AskInline.js +3 -3
  101. package/dist/tool-call-visualization/renderers/ask-person/AskPersonInline.js +2 -2
  102. package/dist/tool-call-visualization/renderers/cloud-browser/CloudBrowserRunCard.js +5 -5
  103. package/dist/tool-call-visualization/renderers/ctx/CtxBatchInline.js +3 -3
  104. package/dist/tool-call-visualization/renderers/ctx/CtxGetInline.js +2 -2
  105. package/dist/tool-call-visualization/renderers/ctx/CtxItemCard.js +3 -3
  106. package/dist/tool-call-visualization/renderers/ctx/CtxPatchInline.js +6 -6
  107. package/dist/tool-call-visualization/renderers/dictionary/DictEntryList.js +12 -12
  108. package/dist/tool-call-visualization/renderers/dictionary/DictionaryOverlay.js +5 -5
  109. package/dist/tool-call-visualization/renderers/fs/FsInline.js +7 -7
  110. package/dist/tool-call-visualization/renderers/news-api/NewsInline.js +17 -17
  111. package/dist/tool-call-visualization/renderers/news-api/NewsOverlay.js +12 -12
  112. package/dist/tool-call-visualization/renderers/random-wheel/RandomWheelInline.js +34 -34
  113. package/dist/tool-call-visualization/renderers/records/RecordsInline.js +1 -1
  114. package/dist/tool-call-visualization/renderers/research/ResearchInline.js +10 -10
  115. package/dist/tool-call-visualization/renderers/research/ResearchOverlay.js +19 -19
  116. package/dist/tool-call-visualization/renderers/research/SubagentReportBlock.js +11 -11
  117. package/dist/tool-call-visualization/renderers/scrape/ScrapeInline.js +18 -18
  118. package/dist/tool-call-visualization/renderers/scrape/ScrapeOverlay.js +17 -17
  119. package/dist/tool-call-visualization/renderers/search/SearchInline.js +30 -30
  120. package/dist/tool-call-visualization/renderers/search/SearchOverlay.js +40 -40
  121. package/dist/tool-call-visualization/renderers/shell/ShellInline.js +3 -3
  122. package/dist/tool-call-visualization/renderers/skill/SkillInline.js +5 -5
  123. package/dist/tool-call-visualization/renderers/sql/DbSchemaInline.js +7 -7
  124. package/dist/tool-call-visualization/renderers/sql/SqlInline.js +4 -4
  125. package/dist/tool-call-visualization/renderers/workbook/WorkbookGrid.js +4 -4
  126. package/dist/tool-call-visualization/renderers/workbook/WorkbookInline.js +2 -2
  127. package/dist/tool-call-visualization/renderers/workbook/WorkbookOverlay.js +7 -7
  128. package/dist/tool-call-visualization/renderers/working-document/PatchDiffInline.js +3 -3
  129. package/dist/tool-call-visualization/result-fields/EmptyResult.js +1 -1
  130. package/dist/tool-call-visualization/result-fields/KeyValueGrid.js +9 -9
  131. package/dist/tool-call-visualization/result-fields/ResultFile.js +4 -4
  132. package/dist/tool-call-visualization/result-fields/ResultJson.js +1 -1
  133. package/dist/tool-call-visualization/result-fields/ResultMedia.js +2 -2
  134. package/dist/tool-call-visualization/result-fields/ResultScalar.js +2 -2
  135. package/dist/tool-call-visualization/result-fields/ResultTable.js +10 -10
  136. package/dist/tool-call-visualization/result-fields/ResultValue.js +7 -7
  137. package/dist/tool-call-visualization/result-fields/ShortId.js +3 -3
  138. package/dist/tool-call-visualization/result-fields/ToolErrorCard.js +4 -4
  139. package/dist/tool-call-visualization/result-fields/UrlChips.js +3 -3
  140. package/dist/tool-call-visualization/surface-write/SurfaceWriteDiff.js +2 -2
  141. package/dist/tool-call-visualization/surface-write/SurfaceWriteStress.js +1 -1
  142. package/dist/tool-call-visualization/window-panel/ToolCallWindowPanel.js +9 -9
  143. package/dist/ui/mandates-storage/mandateStorage.d.ts +36 -0
  144. package/dist/ui/mandates-storage/shortcutStorage.d.ts +9 -0
  145. package/dist/ui/markdown-stream/EnhancedChatMarkdown.js +22 -0
  146. package/dist/ui/markdown-stream/MarkdownStreamImpl.js +3 -3
  147. package/dist/ui/markdown-stream/StreamTextFallback.d.ts +6 -0
  148. package/dist/ui/markdown-stream/StreamTextFallback.js +23 -0
  149. package/dist/ui/markdown-stream/merge-thinking-across-hidden.d.ts +19 -0
  150. package/dist/ui/markdown-stream/merge-thinking-across-hidden.js +21 -0
  151. package/package.json +12 -7
@@ -45,7 +45,7 @@ function RadioSelect({
45
45
  onClick: () => onChange(opt.value),
46
46
  className: cn(
47
47
  "flex items-center gap-2 px-3 py-1.5 rounded-md text-sm transition-colors text-left",
48
- value === opt.value ? "bg-primary/10 text-primary-ink font-medium" : "text-muted-foreground hover:bg-muted hover:text-foreground"
48
+ value === opt.value ? "bg-primary/10 text-primary-ink font-medium" : "text-[color:var(--mx-chat-text-secondary,hsl(var(--muted-foreground)))] hover:bg-[var(--mx-chat-fill,hsl(var(--muted)))] hover:text-[color:var(--mx-chat-text,hsl(var(--foreground)))]"
49
49
  ),
50
50
  children: [
51
51
  /* @__PURE__ */ jsx(
@@ -86,7 +86,7 @@ function MultiSelectChips({
86
86
  };
87
87
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
88
88
  items.length > 5 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 px-2 h-7 rounded-md bg-muted/50 border border-border/50", children: [
89
- /* @__PURE__ */ jsx(Search, { className: "h-3 w-3 text-muted-foreground shrink-0" }),
89
+ /* @__PURE__ */ jsx(Search, { className: "h-3 w-3 text-[color:var(--mx-chat-text-secondary,hsl(var(--muted-foreground)))] shrink-0" }),
90
90
  /* @__PURE__ */ jsx(
91
91
  "input",
92
92
  {
@@ -94,7 +94,7 @@ function MultiSelectChips({
94
94
  placeholder: searchPlaceholder,
95
95
  value: searchQ,
96
96
  onChange: (e) => setSearchQ(e.target.value),
97
- className: "flex-1 bg-transparent text-xs text-foreground placeholder:text-muted-foreground/50 outline-none"
97
+ className: "flex-1 bg-transparent text-xs text-[color:var(--mx-chat-text,hsl(var(--foreground)))] placeholder:text-muted-foreground/50 outline-none"
98
98
  }
99
99
  ),
100
100
  searchQ && /* @__PURE__ */ jsx(Button, { variant: "quiet", icon: /* @__PURE__ */ jsx(X, {}), "aria-label": "Clear search", onClick: () => setSearchQ("") })
@@ -107,7 +107,7 @@ function MultiSelectChips({
107
107
  return /* @__PURE__ */ jsx(Chip, { asChild: true, pressed: isSelected, label: item, children: /* @__PURE__ */ jsx("button", { type: "button", onClick: () => toggle(item) }) }, item);
108
108
  })
109
109
  ] }) }),
110
- filtered.length === 0 && searchQ && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "No matches" })
110
+ filtered.length === 0 && searchQ && /* @__PURE__ */ jsx("p", { className: "text-xs text-[color:var(--mx-chat-text-secondary,hsl(var(--muted-foreground)))]", children: "No matches" })
111
111
  ] });
112
112
  }
113
113
  function FilterSection({
@@ -117,7 +117,7 @@ function FilterSection({
117
117
  }) {
118
118
  return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
119
119
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
120
- /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-foreground uppercase tracking-wider", children: label }),
120
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-[color:var(--mx-chat-text,hsl(var(--foreground)))] uppercase tracking-wider", children: label }),
121
121
  active && /* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-primary" })
122
122
  ] }),
123
123
  children
@@ -194,7 +194,7 @@ function DesktopFilterPanel({
194
194
  maxHeight: "var(--radix-popover-content-available-height, calc(100dvh - 120px))"
195
195
  },
196
196
  children: [
197
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-2.5 border-b border-border shrink-0", children: [
197
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-2.5 border-b border-[color:var(--mx-chat-border,hsl(var(--border)))] shrink-0", children: [
198
198
  /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Filters & Sort" }),
199
199
  activeFilterCount > 0 && /* @__PURE__ */ jsx(Button, { variant: "quiet", tone: "primary", icon: /* @__PURE__ */ jsx(RotateCcw, {}), onClick: resetFilters, children: "Reset all" })
200
200
  ] }),
@@ -267,7 +267,7 @@ function DesktopFilterPanel({
267
267
  {
268
268
  className: cn(
269
269
  "w-8 h-[18px] rounded-full relative transition-colors shrink-0",
270
- favoritesFirst ? "bg-primary" : "bg-muted border border-border"
270
+ favoritesFirst ? "bg-primary" : "bg-[var(--mx-chat-fill,hsl(var(--muted)))] border border-[color:var(--mx-chat-border,hsl(var(--border)))]"
271
271
  ),
272
272
  children: /* @__PURE__ */ jsx(
273
273
  "span",
@@ -280,7 +280,7 @@ function DesktopFilterPanel({
280
280
  )
281
281
  }
282
282
  ),
283
- /* @__PURE__ */ jsx("span", { className: "text-foreground", children: "Pin favorites to top" })
283
+ /* @__PURE__ */ jsx("span", { className: "text-[color:var(--mx-chat-text,hsl(var(--foreground)))]", children: "Pin favorites to top" })
284
284
  ]
285
285
  }
286
286
  ) })
@@ -130,7 +130,7 @@ function AgentRunnerFrame({
130
130
  {
131
131
  className: `relative mx-auto h-full w-full max-w-[800px] overflow-hidden bg-background ${className}`,
132
132
  children: [
133
- showTitle && title && /* @__PURE__ */ jsx("div", { className: "absolute top-0 left-0 right-0 z-10 px-4 py-2 border-b border-border bg-background", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground truncate", children: title }) }),
133
+ showTitle && title && /* @__PURE__ */ jsx("div", { className: "absolute top-0 left-0 right-0 z-10 px-4 py-2 border-b border-[color:var(--mx-chat-border,hsl(var(--border)))] bg-background", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[color:var(--mx-chat-text,hsl(var(--foreground)))] truncate", children: title }) }),
134
134
  /* @__PURE__ */ jsx(
135
135
  "div",
136
136
  {
@@ -71,7 +71,7 @@ function CreateWithAiTabs({
71
71
  };
72
72
  return /* @__PURE__ */ jsxs("div", { className: cn("flex h-full min-h-0 flex-col", className), children: [
73
73
  /* @__PURE__ */ jsx("div", { className: cn("flex-shrink-0 px-1 pb-3", headerClassName), children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
74
- /* @__PURE__ */ jsxs("div", { className: "inline-flex w-full items-center gap-1 rounded-lg bg-muted p-1", children: [
74
+ /* @__PURE__ */ jsxs("div", { className: "inline-flex w-full items-center gap-1 rounded-lg bg-[var(--mx-chat-fill,hsl(var(--muted)))] p-1", children: [
75
75
  /* @__PURE__ */ jsx(
76
76
  ModeButton,
77
77
  {
@@ -1,4 +1,4 @@
1
- import { applyOrganizationContextHeader } from "../../../host/server/organization-context.js";
1
+ import { chatRequestHeaders } from "../../../host/request-headers.js";
2
2
  import { selectResolvedBaseUrl } from "../../../host/server/api-config.js";
3
3
  import { selectAccessToken, selectFingerprintId } from "../../../host/identity.js";
4
4
  import { selectOrganizationId } from "../../../host/org.js";
@@ -17,7 +17,6 @@ function resolveAgentCacheBustBackend(state) {
17
17
  const accessToken = selectAccessToken(state);
18
18
  const fingerprintId = selectFingerprintId(state);
19
19
  if (accessToken) {
20
- headers["Authorization"] = `Bearer ${accessToken}`;
21
20
  const organizationId = selectOrganizationId(state);
22
21
  if (!organizationId) {
23
22
  console.warn(
@@ -27,13 +26,14 @@ function resolveAgentCacheBustBackend(state) {
27
26
  }
28
27
  return {
29
28
  baseUrl: trimmedBase,
30
- headers: applyOrganizationContextHeader(headers, organizationId)
29
+ // THE ONE HEADER BUILDER (host/request-headers.ts).
30
+ headers: { ...headers, ...chatRequestHeaders({ accessToken, fingerprintId: null }, organizationId) }
31
31
  };
32
32
  }
33
- if (fingerprintId) {
34
- headers["X-Fingerprint-ID"] = fingerprintId;
35
- }
36
- return { baseUrl: trimmedBase, headers };
33
+ return {
34
+ baseUrl: trimmedBase,
35
+ headers: { ...headers, ...chatRequestHeaders({ accessToken: null, fingerprintId }, null) }
36
+ };
37
37
  }
38
38
  async function postInvalidateAgentCache(baseUrl, agentId, headers, options) {
39
39
  const response = await sendMatrxRequest(
@@ -5,6 +5,7 @@ import {
5
5
  import { setContextReceipt } from "../instance-context/instance-context.slice.js";
6
6
  import { captureError } from "../../../../host/diagnostics.js";
7
7
  import { toast } from "../../../../host/notify.js";
8
+ import { selectIsAdmin } from "../../../../host/identity.js";
8
9
  function toContextReceiptRow(row) {
9
10
  const out = {
10
11
  key: row.key,
@@ -101,8 +102,7 @@ function recordContextReceipt(dispatch, getState, args) {
101
102
  requestId,
102
103
  level: "high"
103
104
  });
104
- const auth = getState().userAuth;
105
- if (auth?.isAdmin && auth.adminLaneOpen) {
105
+ if (selectIsAdmin(getState())) {
106
106
  console.error("[context-rules] receipt mismatch", { conversationId, requestId, mismatches, receipt });
107
107
  toast.warning(`Context mismatch: ${summary}`.slice(0, 140));
108
108
  }
@@ -10,8 +10,8 @@
10
10
  * anywhere else; bypassing the funnel forfeits the optimistic card +
11
11
  * `injection_consumed` delivery handshake.
12
12
  *
13
- * All four calls ride `callApi` (auth, base-url resolution, org/project
14
- * scope injection, error capture) against the generated endpoint types.
13
+ * All four calls ride THE CONVERSATION DOOR (`callConversationApi`): the turn's own server,
14
+ * credential and organization, so a mid-run message can never go where the run is not.
15
15
  */
16
16
  import type { ChatDispatch, ChatRootState } from "../../../../store/root-state.js";
17
17
  import { type InboxItemKind, type InboxItemMode } from "./inbox.slice.js";
@@ -1,5 +1,5 @@
1
1
  import { createAsyncThunk } from "@reduxjs/toolkit";
2
- import { callApi } from "../../../../host/server/call-api.js";
2
+ import { callConversationApi } from "../thunks/call-conversation-api.js";
3
3
  import { toast } from "../../../../host/notify.js";
4
4
  import {
5
5
  addInboxItem,
@@ -55,10 +55,9 @@ const enqueueInboxMessage = createAsyncThunk(
55
55
  })
56
56
  );
57
57
  const result = await dispatch(
58
- callApi({
58
+ callConversationApi(conversationId, {
59
59
  path: "/ai/conversations/{conversation_id}/inbox",
60
60
  method: "POST",
61
- pathParams: { conversation_id: conversationId },
62
61
  expectedErrorStatuses: [404],
63
62
  body: {
64
63
  kind,
@@ -116,13 +115,10 @@ const retractInboxItem = createAsyncThunk(
116
115
  return "retracted";
117
116
  }
118
117
  const result = await dispatch(
119
- callApi({
118
+ callConversationApi(conversationId, {
120
119
  path: "/ai/conversations/{conversation_id}/inbox/{injection_id}",
121
120
  method: "DELETE",
122
- pathParams: {
123
- conversation_id: conversationId,
124
- injection_id: injectionId
125
- }
121
+ pathParams: { injection_id: injectionId }
126
122
  })
127
123
  );
128
124
  if (result.error && result.error.status === 409) {
@@ -150,13 +146,10 @@ const editInboxItem = createAsyncThunk(
150
146
  return;
151
147
  }
152
148
  const result = await dispatch(
153
- callApi({
149
+ callConversationApi(conversationId, {
154
150
  path: "/ai/conversations/{conversation_id}/inbox/{injection_id}",
155
151
  method: "PATCH",
156
- pathParams: {
157
- conversation_id: conversationId,
158
- injection_id: injectionId
159
- },
152
+ pathParams: { injection_id: injectionId },
160
153
  body: { text }
161
154
  })
162
155
  );
@@ -178,10 +171,9 @@ const editInboxItem = createAsyncThunk(
178
171
  );
179
172
  const hydrateInbox = createAsyncThunk("conversationInbox/hydrate", async ({ conversationId }, { dispatch }) => {
180
173
  const result = await dispatch(
181
- callApi({
174
+ callConversationApi(conversationId, {
182
175
  path: "/ai/conversations/{conversation_id}/inbox",
183
176
  method: "GET",
184
- pathParams: { conversation_id: conversationId },
185
177
  queryParams: { status: "pending" }
186
178
  })
187
179
  );
@@ -13,7 +13,7 @@
13
13
  * captures that as a typed error on the slice and never throws.
14
14
  */
15
15
  import type { ChatRootState } from "../../../../store/root-state.js";
16
- import { type MemoryCostSummary } from "../../../../host/server/call-api.js";
16
+ import type { MemoryCostSummary } from "../../../../host/server/call-api.js";
17
17
  interface FetchMemoryCostArgs {
18
18
  conversationId: string;
19
19
  signal?: AbortSignal;
@@ -1,7 +1,5 @@
1
1
  import { createAsyncThunk } from "@reduxjs/toolkit";
2
- import {
3
- callConversationMemoryCost
4
- } from "../../../../host/server/call-api.js";
2
+ import { callConversationApi } from "../thunks/call-conversation-api.js";
5
3
  import {
6
4
  setCostFetchStatus,
7
5
  setCostSummary
@@ -11,7 +9,12 @@ const fetchMemoryCost = createAsyncThunk(
11
9
  async ({ conversationId, signal }, { dispatch, rejectWithValue }) => {
12
10
  dispatch(setCostFetchStatus({ conversationId, status: "loading" }));
13
11
  const result = await dispatch(
14
- callConversationMemoryCost(conversationId, { signal })
12
+ // THE CONVERSATION DOOR: the turn's own server, credential and organization.
13
+ callConversationApi(conversationId, {
14
+ path: "/ai/conversations/{conversation_id}/memory_cost",
15
+ method: "GET",
16
+ ...signal ? { signal } : {}
17
+ })
15
18
  );
16
19
  if (result.error || !result.data) {
17
20
  const message = result.error?.message ?? "Failed to fetch memory cost.";
@@ -362,120 +362,7 @@ export declare const selectIsInstanceReady: (conversationId: string) => ((state:
362
362
  * Usage — stabilize selector identity with `useMemo`:
363
363
  * `useMemo(() => makeSelectAssembledRequest(conversationId), [conversationId])`.
364
364
  */
365
- export declare function makeSelectAssembledRequest(conversationId: string): ((state: {
366
- voiceAgent: import("../../../../voice-agent/types.js").VoiceAgentState;
367
- agentDefinition: import("../../../types/agent-definition.types.js").AgentDefinitionSliceState;
368
- conversationList: import("../../conversation-list/conversation-list.types.js").ConversationListState;
369
- conversationHistory: import("../../conversation-history/types.js").ConversationHistoryState;
370
- agentShortcut: import("../../agent-shortcuts/types.js").AgentShortcutSliceState;
371
- agentShortcutCategory: import("../../agent-shortcut-categories/types.js").AgentShortcutCategorySliceState;
372
- surfaceUserState: import("../../../../surfaces/redux/userStateSlice.js").SurfaceUserStateSlice;
373
- conversations: import("../conversations/conversations.slice.js").ConversationsState;
374
- chatIncognito: import("../../chat/chat-incognito.slice.js").ChatIncognitoState;
375
- chatRoute: import("../../chat/chat-route.slice.js").ChatRouteState;
376
- instanceModelOverrides: import("../instance-model-overrides/instance-model-overrides.slice.js").InstanceModelOverridesState;
377
- instanceInputCapabilities: import("../instance-input-capabilities/instance-input-capabilities.slice.js").InstanceInputCapabilitiesState;
378
- instanceVariableValues: import("../instance-variable-values/instance-variable-values.slice.js").InstanceVariableValuesState;
379
- instanceResources: import("../instance-resources/instance-resources.slice.js").InstanceResourcesState;
380
- instanceContext: import("../instance-context/instance-context.slice.js").InstanceContextState;
381
- instanceWorkingDocument: import("../instance-working-document/instance-working-document.slice.js").InstanceWorkingDocumentSliceState;
382
- instanceUserInput: import("../instance-user-input/instance-user-input.slice.js").InstanceUserInputSliceState;
383
- instanceClientTools: import("../instance-client-tools/instance-client-tools.slice.js").InstanceClientToolsState;
384
- pendingAsks: import("../../../ui-first-tools/redux/pending-asks.slice.js").PendingAsksState;
385
- conversationInbox: import("../inbox/inbox.slice.js").ConversationInboxState;
386
- agentLists: import("../../../ui-first-tools/redux/agent-lists.slice.js").AgentListsState;
387
- instanceUIState: import("../instance-ui-state/instance-ui-state.slice.js").InstanceUIStateSlice;
388
- activeTools: import("../active-tools/active-tools.slice.js").ActiveToolsState;
389
- activeRequests: import("../active-requests/active-requests.slice.js").ActiveRequestsState;
390
- runSets: import("../run-sets/run-sets.slice.js").RunSetsState;
391
- messages: import("../messages/messages.slice.js").MessagesState;
392
- observability: import("../observability/observability.slice.js").ObservabilityState;
393
- contextState: import("../context-state/context-state.slice.js").ContextStateSliceState;
394
- observationalMemory: import("../observational-memory/observational-memory.slice.js").ObservationalMemoryState;
395
- cacheBypass: import("../message-crud/cache-bypass.slice.js").CacheBypassState;
396
- conversationFocus: import("../conversation-focus/conversation-focus.slice.js").ConversationFocusState;
397
- surfaces: import("../../surfaces/surfaces.slice.js").SurfacesState;
398
- surfacesCatalog: import("../../../../surfaces/redux/surfacesCatalogSlice.js").SurfacesCatalogSliceState;
399
- agentSurfaceBindings: import("../../../../surfaces/redux/agentSurfaceBindingsSlice.js").AgentSurfaceBindingsSliceState;
400
- surfaceConfig: import("../../../../surfaces/redux/surfaceConfigSlice.js").SurfaceConfigSliceState;
401
- agentAssistantMarkdownDraft: import("../../agent-assistant-markdown-draft.slice.js").AgentAssistantMarkdownDraftState;
402
- mcp: import("../../mcp/mcp.slice.js").McpSliceState;
403
- proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
404
- conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
405
- chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
406
- hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
407
- } & import("../../../../store/root-state.js").ChatHostReadSlices) => AssembledAgentStartRequest | null) & {
408
- clearCache: () => void;
409
- resultsCount: () => number;
410
- resetResultsCount: () => void;
411
- } & {
412
- resultFunc: (resultFuncArgs_0: import("../conversations/conversations.slice.js").ConversationsState, resultFuncArgs_1: import("../instance-ui-state/instance-ui-state.slice.js").InstanceUIStateSlice, resultFuncArgs_2: import("../instance-user-input/instance-user-input.slice.js").InstanceUserInputSliceState, resultFuncArgs_3: import("../instance-resources/instance-resources.slice.js").InstanceResourcesState, resultFuncArgs_4: import("../instance-variable-values/instance-variable-values.slice.js").InstanceVariableValuesState, resultFuncArgs_5: import("../instance-model-overrides/instance-model-overrides.slice.js").InstanceModelOverridesState, resultFuncArgs_6: import("../instance-context/instance-context.slice.js").InstanceContextState, resultFuncArgs_7: import("../instance-client-tools/instance-client-tools.slice.js").InstanceClientToolsState, resultFuncArgs_8: {
413
- organization_id?: string | null;
414
- } | undefined, resultFuncArgs_9: import("../../../../store/chat-host.slice.js").ChatHostState, resultFuncArgs_10: import("../../../types/agent-definition.types.js").AgentDefinitionSliceState, resultFuncArgs_11: import("../../../../surfaces/redux/userStateSlice.js").SurfaceUserStateSlice, resultFuncArgs_12: import("../messages/messages.slice.js").MessagesState, resultFuncArgs_13: {
415
- id: string | null;
416
- email?: string | null;
417
- isAnonymous?: boolean;
418
- accessToken?: string | null;
419
- isAdmin?: boolean;
420
- adminLaneOpen?: boolean;
421
- adminLevel?: string | null;
422
- } | undefined, resultFuncArgs_14: {
423
- fingerprintId?: string | null;
424
- userMetadata?: {
425
- fullName?: string | null;
426
- name?: string | null;
427
- preferredUsername?: string | null;
428
- } | null;
429
- } | undefined) => AssembledAgentStartRequest | null;
430
- memoizedResultFunc: ((resultFuncArgs_0: import("../conversations/conversations.slice.js").ConversationsState, resultFuncArgs_1: import("../instance-ui-state/instance-ui-state.slice.js").InstanceUIStateSlice, resultFuncArgs_2: import("../instance-user-input/instance-user-input.slice.js").InstanceUserInputSliceState, resultFuncArgs_3: import("../instance-resources/instance-resources.slice.js").InstanceResourcesState, resultFuncArgs_4: import("../instance-variable-values/instance-variable-values.slice.js").InstanceVariableValuesState, resultFuncArgs_5: import("../instance-model-overrides/instance-model-overrides.slice.js").InstanceModelOverridesState, resultFuncArgs_6: import("../instance-context/instance-context.slice.js").InstanceContextState, resultFuncArgs_7: import("../instance-client-tools/instance-client-tools.slice.js").InstanceClientToolsState, resultFuncArgs_8: {
431
- organization_id?: string | null;
432
- } | undefined, resultFuncArgs_9: import("../../../../store/chat-host.slice.js").ChatHostState, resultFuncArgs_10: import("../../../types/agent-definition.types.js").AgentDefinitionSliceState, resultFuncArgs_11: import("../../../../surfaces/redux/userStateSlice.js").SurfaceUserStateSlice, resultFuncArgs_12: import("../messages/messages.slice.js").MessagesState, resultFuncArgs_13: {
433
- id: string | null;
434
- email?: string | null;
435
- isAnonymous?: boolean;
436
- accessToken?: string | null;
437
- isAdmin?: boolean;
438
- adminLaneOpen?: boolean;
439
- adminLevel?: string | null;
440
- } | undefined, resultFuncArgs_14: {
441
- fingerprintId?: string | null;
442
- userMetadata?: {
443
- fullName?: string | null;
444
- name?: string | null;
445
- preferredUsername?: string | null;
446
- } | null;
447
- } | undefined) => AssembledAgentStartRequest | null) & {
448
- clearCache: () => void;
449
- resultsCount: () => number;
450
- resetResultsCount: () => void;
451
- };
452
- lastResult: () => AssembledAgentStartRequest | null;
453
- dependencies: [(s: ChatRootState) => import("../conversations/conversations.slice.js").ConversationsState, (s: ChatRootState) => import("../instance-ui-state/instance-ui-state.slice.js").InstanceUIStateSlice, (s: ChatRootState) => import("../instance-user-input/instance-user-input.slice.js").InstanceUserInputSliceState, (s: ChatRootState) => import("../instance-resources/instance-resources.slice.js").InstanceResourcesState, (s: ChatRootState) => import("../instance-variable-values/instance-variable-values.slice.js").InstanceVariableValuesState, (s: ChatRootState) => import("../instance-model-overrides/instance-model-overrides.slice.js").InstanceModelOverridesState, (s: ChatRootState) => import("../instance-context/instance-context.slice.js").InstanceContextState, (s: ChatRootState) => import("../instance-client-tools/instance-client-tools.slice.js").InstanceClientToolsState, (s: ChatRootState) => {
454
- organization_id?: string | null;
455
- } | undefined, (s: ChatRootState) => import("../../../../store/chat-host.slice.js").ChatHostState, (s: ChatRootState) => import("../../../types/agent-definition.types.js").AgentDefinitionSliceState, (s: ChatRootState) => import("../../../../surfaces/redux/userStateSlice.js").SurfaceUserStateSlice, (s: ChatRootState) => import("../messages/messages.slice.js").MessagesState, (s: ChatRootState) => {
456
- id: string | null;
457
- email?: string | null;
458
- isAnonymous?: boolean;
459
- accessToken?: string | null;
460
- isAdmin?: boolean;
461
- adminLaneOpen?: boolean;
462
- adminLevel?: string | null;
463
- } | undefined, (s: ChatRootState) => {
464
- fingerprintId?: string | null;
465
- userMetadata?: {
466
- fullName?: string | null;
467
- name?: string | null;
468
- preferredUsername?: string | null;
469
- } | null;
470
- } | undefined];
471
- recomputations: () => number;
472
- resetRecomputations: () => void;
473
- dependencyRecomputations: () => number;
474
- resetDependencyRecomputations: () => void;
475
- } & {
476
- memoize: typeof import("reselect").weakMapMemoize;
477
- argsMemoize: typeof import("reselect").weakMapMemoize;
478
- };
365
+ export declare function makeSelectAssembledRequest(conversationId: string): (state: ChatRootState) => AssembledAgentStartRequest | null;
479
366
  /** @deprecated Use {@link makeSelectAssembledRequest}; same underlying factory (alias). */
480
367
  export declare const selectAssembledRequest: typeof makeSelectAssembledRequest;
481
368
  /**
@@ -11,6 +11,7 @@ import {
11
11
  selectShowAutoClearToggle
12
12
  } from "../instance-ui-state/instance-ui-state.selectors.js";
13
13
  import { assembleRequest } from "../thunks/execute-instance.thunk.js";
14
+ import { selectAppContext } from "../../../../context/sources/scopes.js";
14
15
  import {
15
16
  contextItemBindingOf,
16
17
  isCustomDataBinding
@@ -170,49 +171,33 @@ const selectIsInstanceReady = (conversationId) => {
170
171
  return selector;
171
172
  };
172
173
  function makeSelectAssembledRequest(conversationId) {
173
- return createSelector(
174
- [
175
- (s) => s.conversations,
176
- (s) => s.instanceUIState,
177
- (s) => s.instanceUserInput,
178
- (s) => s.instanceResources,
179
- (s) => s.instanceVariableValues,
180
- (s) => s.instanceModelOverrides,
181
- (s) => s.instanceContext,
182
- (s) => s.instanceClientTools,
183
- (s) => s.appContext,
184
- // Identity, active org and the person's preferences (P7/P8): the package's own host slice.
185
- (s) => s.chatHost,
186
- // The context door (buildRequestContext) reads these too: the agent's
187
- // policies + kill switch, the person's saved context rules, whether this
188
- // is the first turn, and who is signed in (first-turn system values).
189
- (s) => s.agentDefinition,
190
- (s) => s.surfaceUserState,
191
- (s) => s.messages,
192
- (s) => s.userAuth,
193
- (s) => s.userProfile
194
- ],
195
- (conversations, instanceUIState, instanceUserInput, instanceResources, instanceVariableValues, instanceModelOverrides, instanceContext, instanceClientTools, appContext, chatHost, agentDefinition, surfaceUserState, messages, userAuth, userProfile) => {
196
- const state = {
197
- conversations,
198
- instanceUIState,
199
- instanceUserInput,
200
- instanceResources,
201
- instanceVariableValues,
202
- instanceModelOverrides,
203
- instanceContext,
204
- instanceClientTools,
205
- appContext,
206
- chatHost,
207
- agentDefinition,
208
- surfaceUserState,
209
- messages,
210
- userAuth,
211
- userProfile
212
- };
213
- return assembleRequest(state, conversationId);
214
- }
215
- );
174
+ const inputs = [
175
+ (s) => s.conversations,
176
+ (s) => s.instanceUIState,
177
+ (s) => s.instanceUserInput,
178
+ (s) => s.instanceResources,
179
+ (s) => s.instanceVariableValues,
180
+ (s) => s.instanceModelOverrides,
181
+ (s) => s.instanceContext,
182
+ (s) => s.instanceClientTools,
183
+ (s) => selectAppContext(s),
184
+ (s) => s.chatHost,
185
+ // The context door (buildRequestContext) reads these too: the agent's
186
+ // policies + kill switch, the person's saved context rules, whether this
187
+ // is the first turn.
188
+ (s) => s.agentDefinition,
189
+ (s) => s.surfaceUserState,
190
+ (s) => s.messages
191
+ ];
192
+ let lastInputs = null;
193
+ let lastResult = null;
194
+ return (state) => {
195
+ const current = inputs.map((read) => read(state));
196
+ if (lastInputs && current.every((value, i) => value === lastInputs[i])) return lastResult;
197
+ lastInputs = current;
198
+ lastResult = assembleRequest(state, conversationId);
199
+ return lastResult;
200
+ };
216
201
  }
217
202
  const selectAssembledRequest = makeSelectAssembledRequest;
218
203
  const selectInstanceSummary = (conversationId) => createSelector(
@@ -0,0 +1,44 @@
1
+ /**
2
+ * THE CONVERSATION DOOR for every JSON request that names a conversation (Audit B family 8).
3
+ *
4
+ * A turn resolves where it goes and what it carries in `resolveBackendForConversation`: the
5
+ * conversation's channel (global / sandbox override / local engine / EC2-dedicated, under the
6
+ * confidential-routing rule), THE ONE header builder and THE ORG RULE. Until 2026-10-08 the calls
7
+ * that ride beside a turn on the same conversation — the inbox, tool results, pending calls,
8
+ * memory cost, cancel — went through the host's general `callApi` instead: another base URL (no
9
+ * sandbox / local override), another organization precedence (the tab's selection, not the
10
+ * conversation's), and in one host no session at all (the inbox sent without auth). This door
11
+ * makes them the turn's twin: same resolver, so the same server, credential and organization.
12
+ *
13
+ * Result shape and error classification are the shared pipeline's (`executeMatrxCall`,
14
+ * `normalizeMatrxError` in `@ai-matrx/agents/matrx`) — the same `{ data } | { error }` the call
15
+ * sites already read from `callApi`. Guard: `__tests__/conversation-calls-name-the-turns-org.test.ts`.
16
+ */
17
+ import { type MatrxCancelResponse, type MatrxCallResult, type MatrxQueryParams } from "@ai-matrx/agents/matrx";
18
+ import type { ChatRootState } from "../../../../store/root-state.js";
19
+ export type ConversationCallMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
20
+ export interface ConversationCallConfig {
21
+ /** Path template; `{conversation_id}` is filled from the door's conversation. */
22
+ path: string;
23
+ method: ConversationCallMethod;
24
+ /** Other path parameters (never `conversation_id`). */
25
+ pathParams?: Record<string, string>;
26
+ queryParams?: MatrxQueryParams;
27
+ body?: unknown;
28
+ signal?: AbortSignal;
29
+ /** HTTP statuses this call site handles as expected outcomes (not logged as failures). */
30
+ expectedErrorStatuses?: readonly number[];
31
+ connectTimeoutMs?: number;
32
+ totalTimeoutMs?: number | null;
33
+ }
34
+ type AnyDispatch = (action: never) => unknown;
35
+ /** Send one JSON request on `conversationId`'s own channel, credential and organization. */
36
+ export declare function callConversationApi<T = unknown>(conversationId: string, config: ConversationCallConfig): (dispatch: AnyDispatch, getState: () => ChatRootState) => Promise<MatrxCallResult<T>>;
37
+ /**
38
+ * Stop (or interrupt) one server run of `conversationId` on the conversation's own channel,
39
+ * credential and organization — never the tab's. `seenSeq` is the last wire `stream_seq` the page
40
+ * APPLIED before Stop; the server cuts the stopped answer there, so the saved text never outgrows
41
+ * the screen.
42
+ */
43
+ export declare function cancelConversationRun(conversationId: string, requestId: string, mode?: "cancel" | "interrupt", seenSeq?: number): (dispatch: AnyDispatch, getState: () => ChatRootState) => Promise<MatrxCallResult<MatrxCancelResponse>>;
44
+ export {};
@@ -0,0 +1,78 @@
1
+ import {
2
+ cancelAgentRun,
3
+ buildMatrxRequestBody,
4
+ buildMatrxRequestUrl,
5
+ executeMatrxCall,
6
+ normalizeMatrxError,
7
+ resolveEndpointPath
8
+ } from "@ai-matrx/agents/matrx";
9
+ import { selectEndpointOverrideConfig } from "../../../../host/server/api-config.js";
10
+ import { conversationRequestOrganizationId } from "../utils/required-organization.js";
11
+ import { resolveBackendForConversation } from "./resolve-base-url.js";
12
+ import { createMatrxTransportForConversation } from "./matrx-transport-for-conversation.js";
13
+ function callConversationApi(conversationId, config) {
14
+ return async (_dispatch, getState) => {
15
+ try {
16
+ const state = getState();
17
+ const backend = resolveBackendForConversation(state, conversationId);
18
+ if (!backend) {
19
+ return {
20
+ error: {
21
+ type: "network_error",
22
+ message: "No AI Matrx server is configured for this conversation. The request was not sent."
23
+ }
24
+ };
25
+ }
26
+ const organizationId = conversationRequestOrganizationId(state, conversationId);
27
+ const path = resolveEndpointPath(config.path, selectEndpointOverrideConfig(state));
28
+ const result = await executeMatrxCall({
29
+ url: buildMatrxRequestUrl(
30
+ backend.baseUrl,
31
+ path,
32
+ { ...config.pathParams ?? {}, conversation_id: conversationId },
33
+ config.queryParams
34
+ ),
35
+ method: config.method,
36
+ headers: { ...backend.headers, Accept: "application/json" },
37
+ body: buildMatrxRequestBody(
38
+ config.body,
39
+ organizationId ? { organization_id: organizationId } : {}
40
+ ),
41
+ ...config.signal ? { signal: config.signal } : {},
42
+ ...config.connectTimeoutMs !== void 0 ? { connectTimeoutMs: config.connectTimeoutMs } : {},
43
+ ...config.totalTimeoutMs !== void 0 ? { totalTimeoutMs: config.totalTimeoutMs } : {}
44
+ });
45
+ const status = result.error?.status;
46
+ if (result.error && !(status !== void 0 && config.expectedErrorStatuses?.includes(status))) {
47
+ console.warn(`[conversation-call] ${config.method} ${config.path} failed`, {
48
+ conversationId,
49
+ channel: backend.channel,
50
+ error: result.error
51
+ });
52
+ }
53
+ return result;
54
+ } catch (error) {
55
+ return { error: normalizeMatrxError(error) };
56
+ }
57
+ };
58
+ }
59
+ function cancelConversationRun(conversationId, requestId, mode = "cancel", seenSeq) {
60
+ return async (_dispatch, getState) => {
61
+ try {
62
+ const base = createMatrxTransportForConversation(getState, conversationId, {
63
+ source: "matrxTransport:cancel"
64
+ });
65
+ const transport = seenSeq === void 0 ? base : {
66
+ fetch: (path, init) => base.fetch(`${path}${path.includes("?") ? "&" : "?"}seen_seq=${seenSeq}`, init)
67
+ };
68
+ const data = await cancelAgentRun(transport, requestId, { mode });
69
+ return { data, requestId: data.request_id };
70
+ } catch (error) {
71
+ return { error: normalizeMatrxError(error) };
72
+ }
73
+ };
74
+ }
75
+ export {
76
+ callConversationApi,
77
+ cancelConversationRun
78
+ };
@@ -0,0 +1,41 @@
1
+ /**
2
+ * continueAgentJson — the NEXT turn of a conversation whose first turn ran headlessly
3
+ * (`runHeadlessAgentJson` with `keepInstance`), waited on exactly like the first.
4
+ *
5
+ * ONE CONVERSATION, MANY ROUNDS. A surface that builds something with an agent and then keeps
6
+ * talking about it (the Applet builder: build → automatic fix round → "Change it" → the person's
7
+ * replies) continues THAT conversation instead of starting a new one per round, so the person can
8
+ * read and answer it in one place and the agent sees every earlier round.
9
+ *
10
+ * A turn is either the person's words (`userInput` — only what a human typed, THE USER-INPUT LAW)
11
+ * or a turn the host writes (`hostTurn` — an activation line + which feature wrote it; never quoted
12
+ * as the person). Structured content for the turn rides `context` (named entries on the instance —
13
+ * a `null` value removes the key), never the message.
14
+ *
15
+ * It reuses THE machinery: `executeInstance` sends the continuation (`POST /ai/conversations/{id}`),
16
+ * `adoptHeadlessAgentJson` waits on it (polling, settle window, one result rule, the persistence
17
+ * seam). A conversation not in this tab yet (a refresh) is read first through `loadConversation`.
18
+ * Never throws: resolves a structured result, exactly like `runHeadlessAgentJson`.
19
+ */
20
+ import type { ChatDispatch, ChatRootState } from "../../../../store/root-state.js";
21
+ import type { RequestInitiation } from "../../../types/instance.types.js";
22
+ import { type HostTurnInput } from "./execute-instance.thunk.js";
23
+ import { type AdoptedAgentJsonOptions, type HeadlessAgentJsonResult } from "./run-headless-agent-json.js";
24
+ export interface ContinueAgentJsonOptions extends Pick<AdoptedAgentJsonOptions, "surfaceKey" | "timeoutMs" | "pollIntervalMs" | "settleMs" | "expect" | "onResult" | "signal" | "failureMessages"> {
25
+ conversationId: string;
26
+ /** What the person typed for this turn. Exclusive with `hostTurn`. */
27
+ userInput?: string;
28
+ /** A turn the host writes (the person said nothing). Exclusive with `userInput`. */
29
+ hostTurn?: HostTurnInput;
30
+ /** Per-turn named context: each key is written on the instance; `null` removes it. */
31
+ context?: Record<string, unknown>;
32
+ /** "user" when the person pressed send; "auto" for a host-started round. Default by turn kind. */
33
+ initiation?: RequestInitiation;
34
+ /** Fires the instant the turn's request exists (a live view binds to it). */
35
+ onRequestId?: (requestId: string) => void;
36
+ /** Keep the instance after the turn (the live view owns teardown). Default true. */
37
+ keepInstance?: boolean;
38
+ }
39
+ /** Which of the two turn kinds this is — exactly one, or a sentence why not. */
40
+ export declare function continuationTurnProblem(opts: Pick<ContinueAgentJsonOptions, "userInput" | "hostTurn">): string | null;
41
+ export declare function continueAgentJson(dispatch: ChatDispatch, getState: () => ChatRootState, opts: ContinueAgentJsonOptions): Promise<HeadlessAgentJsonResult>;