@ai-matrx/chat 0.3.32 → 0.3.33

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @ai-matrx/chat
2
2
 
3
+ ## 0.3.33
4
+
5
+ - **Opening a chat never asks for an organization.** `launchAgentExecution` asks before opening only
6
+ when the run starts now or a window/gate opens (`launchAsksForOrganizationBeforeOpen`); an inline
7
+ composer (`/chat/new`) asks at the first send through the same hold-and-set gate.
8
+ - **Reading your own agent-less chat never waits on the active workspace.** `ChatConversationRoom`
9
+ takes `organizationId` (the row's own) and resolves its mandate there.
10
+ Consumer action: pass the conversation row's `organization_id` to `ChatConversationRoom`.
11
+
3
12
  ## 0.3.32
4
13
 
5
14
  Automatic changed-only republish (docs/metadata drift since the last tag — see
@@ -19,8 +19,14 @@ import type { ComposerMode } from "../inputs/smart-input/composer/composer-types
19
19
  * `mandateKey` rides along so the next turn is answered by whoever the
20
20
  * org/user binding says, not by a frozen display identity.
21
21
  */
22
- export declare function ChatConversationRoom({ conversationId, agentId, ownedByMandate, sandboxBinding, composer, }: {
22
+ export declare function ChatConversationRoom({ conversationId, agentId, ownedByMandate, sandboxBinding, composer, organizationId, }: {
23
23
  conversationId: string;
24
+ /**
25
+ * The conversation ROW's own organization. An agent-less room resolves its
26
+ * mandate in THAT organization, so reading your own chat never waits on, or
27
+ * asks for, the active workspace (Arman, 2026-10-07).
28
+ */
29
+ organizationId?: string | null;
24
30
  /** The conversation's own agent, or the SSR-resolved mandate agent, or null. */
25
31
  agentId: string | null;
26
32
  /** True when `agentId` is the mandate's display identity, not the row's. */
@@ -10,7 +10,8 @@ function ChatConversationRoom({
10
10
  agentId,
11
11
  ownedByMandate,
12
12
  sandboxBinding = null,
13
- composer
13
+ composer,
14
+ organizationId = null
14
15
  }) {
15
16
  if (agentId && !ownedByMandate) {
16
17
  return /* @__PURE__ */ jsx(
@@ -39,6 +40,7 @@ function ChatConversationRoom({
39
40
  ChatConversationRoomResolved,
40
41
  {
41
42
  conversationId,
43
+ organizationId,
42
44
  sandboxBinding,
43
45
  composer
44
46
  }
@@ -46,10 +48,14 @@ function ChatConversationRoom({
46
48
  }
47
49
  function ChatConversationRoomResolved({
48
50
  conversationId,
51
+ organizationId,
49
52
  sandboxBinding,
50
53
  composer
51
54
  }) {
52
- const { mandate, loading, error, organizationPending } = useMandate(DEFAULT_NEW_CHAT_MANDATE_KEY);
55
+ const { mandate, loading, error, organizationPending } = useMandate(
56
+ DEFAULT_NEW_CHAT_MANDATE_KEY,
57
+ organizationId ? { organizationId } : {}
58
+ );
53
59
  if (loading) return /* @__PURE__ */ jsx(ChatNewLandingSkeleton, {});
54
60
  if (organizationPending) {
55
61
  return /* @__PURE__ */ jsx(WorkspaceGate, { blocked: true, sentence: "This chat needs a workspace to open.", children: /* @__PURE__ */ jsx(ChatNewLandingSkeleton, {}) });
@@ -41,7 +41,10 @@ import {
41
41
  createManualInstanceNoAgent
42
42
  } from "./create-instance.thunk.js";
43
43
  import { executeInstance } from "./execute-instance.thunk.js";
44
- import { ensureExecutionOrganization } from "../utils/required-organization.js";
44
+ import {
45
+ ensureExecutionOrganization,
46
+ launchAsksForOrganizationBeforeOpen
47
+ } from "../utils/required-organization.js";
45
48
  import {
46
49
  replaceSurfaceVariableValues,
47
50
  setHostVariableValues
@@ -690,7 +693,12 @@ const launchAgentExecution = createAsyncThunk("instances/launch", async (options
690
693
  if (bindingAutoRun !== null && autoRun === void 0) {
691
694
  dispatch(setAutoRun({ conversationId, value: effectiveAutoRun }));
692
695
  }
693
- await ensureExecutionOrganization(getState(), conversationId);
696
+ if (launchAsksForOrganizationBeforeOpen({
697
+ runsNow: effectiveAutoRun,
698
+ opensWindow: effectiveShowPreExecutionGate || Boolean(DISPLAY_MODE_TO_OVERLAY_ID[resolvedDisplayMode])
699
+ })) {
700
+ await ensureExecutionOrganization(getState(), conversationId);
701
+ }
694
702
  if (effectiveShowPreExecutionGate) {
695
703
  const downstreamOverlayId = DISPLAY_MODE_TO_OVERLAY_ID[resolvedDisplayMode];
696
704
  dispatch(
@@ -55,5 +55,19 @@ export declare function executionOrganizationForRequest(state: ChatRootState, co
55
55
  * Throws ONLY `OrganizationSelectionCancelled`, when the person actively
56
56
  * declines. Callers must treat that as "nothing happened".
57
57
  */
58
+ /**
59
+ * Does a LAUNCH ask for the organization before it opens anything?
60
+ *
61
+ * Only when something is about to happen that a later cancel would strand: the
62
+ * run starts now (auto-run), or a window / pre-run gate opens. A launch that
63
+ * only mounts an inline composer — `/chat/new`, a room — asks nothing: opening
64
+ * a chat is never blocked (Arman, 2026-10-07). Its first SEND asks through the
65
+ * same hold-and-set gate (`execute-instance` / `smart-execute` call
66
+ * `ensureExecutionOrganization`), and the turn continues in the chosen one.
67
+ */
68
+ export declare function launchAsksForOrganizationBeforeOpen(launch: {
69
+ runsNow: boolean;
70
+ opensWindow: boolean;
71
+ }): boolean;
58
72
  export declare function ensureExecutionOrganization(state: ChatRootState, conversationId: string): Promise<string | null>;
59
73
  export declare function requireExecutionOrganizationId(state: ChatRootState, conversationId: string): string;
@@ -8,6 +8,9 @@ function executionOrganizationForRequest(state, conversationId) {
8
8
  if (isFingerprintGuestExecution(state)) return void 0;
9
9
  return requireExecutionOrganizationId(state, conversationId);
10
10
  }
11
+ function launchAsksForOrganizationBeforeOpen(launch) {
12
+ return launch.runsNow || launch.opensWindow;
13
+ }
11
14
  async function ensureExecutionOrganization(state, conversationId) {
12
15
  if (isFingerprintGuestExecution(state)) return null;
13
16
  const instance = state.conversations.byConversationId[conversationId];
@@ -49,5 +52,6 @@ export {
49
52
  ensureExecutionOrganization,
50
53
  executionOrganizationForRequest,
51
54
  isFingerprintGuestExecution,
55
+ launchAsksForOrganizationBeforeOpen,
52
56
  requireExecutionOrganizationId
53
57
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/chat",
3
- "version": "0.3.32",
3
+ "version": "0.3.33",
4
4
  "description": "THE one AI Matrx person-to-agent chat system: the full chat (running agents, conversations, tool calls, streaming, context, surfaces, voice) as per-module subpaths @ai-matrx/chat/<domain>/<module> over a host contract (/host, /host/react) whose only required value is a db; plus the kernel compatibility entries (., /external-store, /matrx, /react, /tools, styles.css, tokens.css) until P28.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -226,13 +226,13 @@
226
226
  "server-only": "^0.0.1",
227
227
  "uuid": "^14.0.2",
228
228
  "zod": "^4.6.5",
229
- "@ai-matrx/agents": "latest",
230
- "@ai-matrx/alchemy": "latest",
231
229
  "@ai-matrx/browser-audio": "latest",
230
+ "@ai-matrx/canvas": "latest",
232
231
  "@ai-matrx/content-ir": "latest",
233
- "@ai-matrx/content-ir-react": "latest",
232
+ "@ai-matrx/alchemy": "latest",
233
+ "@ai-matrx/agents": "latest",
234
234
  "@ai-matrx/associations": "latest",
235
- "@ai-matrx/canvas": "latest",
235
+ "@ai-matrx/content-ir-react": "latest",
236
236
  "@ai-matrx/data": "latest",
237
237
  "@ai-matrx/design-system": "latest",
238
238
  "@ai-matrx/diff": "latest",