@ai-matrx/chat 0.7.30 → 0.7.31

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,11 @@
1
1
  # @ai-matrx/chat
2
2
 
3
+ ## 0.7.31
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/chat/v0.7.30..npm/chat/v0.7.31 -- apps/shared/chat`).
7
+ No source changes intended and no consumer action required.
8
+
3
9
  ## 0.7.30
4
10
 
5
11
  Automatic changed-only republish (docs/metadata drift since the last tag — see
@@ -0,0 +1,20 @@
1
+ import { type HeadlessAgentJsonResult } from "../redux/execution-system/thunks/run-headless-agent-json.js";
2
+ export interface ComposerStructuredRunOptions<T> {
3
+ /** The conversation the page launched and the composer sends. */
4
+ conversationId: string | null | undefined;
5
+ /** Stable surface key (telemetry, the same key the launcher used). */
6
+ surfaceKey: string;
7
+ /** Variables the page supplies whole — hidden from the form, still sent. */
8
+ pageOwnedVariables?: readonly string[];
9
+ /** Narrow the extracted value; throw for an unusable answer. */
10
+ coerce: (value: unknown, result: HeadlessAgentJsonResult) => T;
11
+ /** The answer, once a sent run finishes and extracts. */
12
+ onResult: (answer: T, requestId: string) => void;
13
+ /** The run failed or its answer could not be used. */
14
+ onError: (message: string, requestId: string) => void;
15
+ /** A run the composer just sent (the page shows its own progress). */
16
+ onStart?: (requestId: string) => void;
17
+ }
18
+ export declare function useComposerStructuredRun<T>({ conversationId, surfaceKey, pageOwnedVariables, coerce, onResult, onError, onStart, }: ComposerStructuredRunOptions<T>): {
19
+ running: boolean;
20
+ };
@@ -0,0 +1,75 @@
1
+ "use client";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { useAppDispatch, useAppSelector, useAppStore } from "../../store/hooks.js";
4
+ import { selectLatestRequestId } from "../redux/execution-system/selectors/aggregate.selectors.js";
5
+ import { setPageOwnedVariableNames } from "../redux/execution-system/instance-variable-values/instance-variable-values.slice.js";
6
+ import {
7
+ adoptHeadlessAgentJson
8
+ } from "../redux/execution-system/thunks/run-headless-agent-json.js";
9
+ function useComposerStructuredRun({
10
+ conversationId,
11
+ surfaceKey,
12
+ pageOwnedVariables,
13
+ coerce,
14
+ onResult,
15
+ onError,
16
+ onStart
17
+ }) {
18
+ const dispatch = useAppDispatch();
19
+ const store = useAppStore();
20
+ const [running, setRunning] = useState(false);
21
+ const latest = useAppSelector(
22
+ (state) => conversationId ? selectLatestRequestId(conversationId)(state) : void 0
23
+ );
24
+ const seen = useRef({
25
+ conversationId: null,
26
+ ids: /* @__PURE__ */ new Set()
27
+ });
28
+ const callbacks = useRef({ coerce, onResult, onError, onStart });
29
+ useEffect(() => {
30
+ callbacks.current = { coerce, onResult, onError, onStart };
31
+ });
32
+ const ownedKey = (pageOwnedVariables ?? []).join("\0");
33
+ useEffect(() => {
34
+ if (!conversationId || !ownedKey) return;
35
+ dispatch(setPageOwnedVariableNames({ conversationId, names: ownedKey.split("\0") }));
36
+ }, [dispatch, conversationId, ownedKey]);
37
+ useEffect(() => {
38
+ if (!conversationId) return;
39
+ if (seen.current.conversationId !== conversationId) {
40
+ seen.current = { conversationId, ids: new Set(latest ? [latest] : []) };
41
+ return;
42
+ }
43
+ if (!latest || seen.current.ids.has(latest)) return;
44
+ seen.current.ids.add(latest);
45
+ const requestId = latest;
46
+ setRunning(true);
47
+ callbacks.current.onStart?.(requestId);
48
+ void adoptHeadlessAgentJson(dispatch, store.getState, {
49
+ requestId,
50
+ conversationId,
51
+ surfaceKey,
52
+ expect: "json",
53
+ keepInstance: true
54
+ }).then((result) => {
55
+ if (!result.success) {
56
+ callbacks.current.onError(
57
+ [result.error, result.errorDetail].filter(Boolean).join(" \u2014 ") || "The run returned no answer.",
58
+ requestId
59
+ );
60
+ return;
61
+ }
62
+ try {
63
+ callbacks.current.onResult(callbacks.current.coerce(result.data, result), requestId);
64
+ } catch (err) {
65
+ callbacks.current.onError(err instanceof Error ? err.message : String(err), requestId);
66
+ }
67
+ }).catch((err) => {
68
+ callbacks.current.onError(err instanceof Error ? err.message : String(err), requestId);
69
+ }).finally(() => setRunning(false));
70
+ }, [dispatch, store, conversationId, latest, surfaceKey]);
71
+ return { running };
72
+ }
73
+ export {
74
+ useComposerStructuredRun
75
+ };
@@ -53,7 +53,9 @@ const selectVisibleInputDefinitions = (conversationId) => {
53
53
  (entry, items) => {
54
54
  if (!entry || entry.definitions.length === 0) return EMPTY_DEFS;
55
55
  const effective = applyInheritedComponents(entry.definitions, items);
56
+ const pageOwned = entry.pageOwnedNames ?? [];
56
57
  const visible = effective.filter((d) => {
58
+ if (pageOwned.includes(d.name)) return false;
57
59
  if (isCustomDataBinding(d.binding)) return false;
58
60
  if (!isBound(d)) return true;
59
61
  return isEmptyVal(entry.scopeValues[d.name]);
@@ -62,6 +62,14 @@ export interface InstanceVariableValuesEntry {
62
62
  * the name leaves this list: it is now genuinely hers.
63
63
  */
64
64
  hostValueNames: string[];
65
+ /**
66
+ * Variables the PAGE supplies whole and the person never edits (an
67
+ * organization's facts, the tables a builder may reuse, today's date): they
68
+ * ship with the run like any value, but the variable form never draws them
69
+ * as fields — only the variables the person fills appear (Arman, 2026-10-09:
70
+ * "variables are the stars of the show"). Absent = none.
71
+ */
72
+ pageOwnedNames?: string[];
65
73
  /** Immutable payload rendered only with the first submitted user turn. */
66
74
  submittedFirstTurnValues: Record<string, unknown> | null;
67
75
  submittedFirstTurnHostValueNames: string[];
@@ -86,7 +94,10 @@ export declare const initInstanceVariables: import("@reduxjs/toolkit").ActionCre
86
94
  }, "instanceVariableValues/setUserVariableValues">, setHostVariableValues: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
87
95
  conversationId: string;
88
96
  values: Record<string, unknown>;
89
- }, "instanceVariableValues/setHostVariableValues">, restoreVariableValues: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
97
+ }, "instanceVariableValues/setHostVariableValues">, setPageOwnedVariableNames: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
98
+ conversationId: string;
99
+ names: string[];
100
+ }, "instanceVariableValues/setPageOwnedVariableNames">, restoreVariableValues: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
90
101
  conversationId: string;
91
102
  values: Record<string, unknown>;
92
103
  /** The subset of `values` the host wired. Omitted = all of it is hers. */
@@ -78,6 +78,15 @@ const instanceVariableValuesSlice = createSlice({
78
78
  }
79
79
  entry.hostValueNames = names;
80
80
  },
81
+ /**
82
+ * Name the variables this page supplies whole (see `pageOwnedNames`): the
83
+ * form hides them; their values still ship.
84
+ */
85
+ setPageOwnedVariableNames(state, action) {
86
+ const entry = state.byConversationId[action.payload.conversationId];
87
+ if (!entry) return;
88
+ entry.pageOwnedNames = [...new Set(action.payload.names)];
89
+ },
81
90
  /**
82
91
  * Put back a set of ALREADY-RESOLVED values TOGETHER WITH THEIR AUTHORSHIP.
83
92
  *
@@ -259,6 +268,7 @@ const {
259
268
  setUserVariableValue,
260
269
  setUserVariableValues,
261
270
  setHostVariableValues,
271
+ setPageOwnedVariableNames,
262
272
  restoreVariableValues,
263
273
  stampSubmittedFirstTurnValues,
264
274
  clearSubmittedFirstTurnValues,
@@ -287,6 +297,7 @@ export {
287
297
  resetUserVariableValues,
288
298
  restoreVariableValues,
289
299
  setHostVariableValues,
300
+ setPageOwnedVariableNames,
290
301
  setRuntimeVariableResourcePolicy,
291
302
  setScopeVariableValues,
292
303
  setUserVariableValue,
@@ -139,7 +139,7 @@ function MessengerRail({
139
139
  "data-collapsed": collapsed ? "true" : "false",
140
140
  className: cn(
141
141
  "flex h-full shrink-0 flex-col border-r border-border bg-muted/40 py-2 transition-[width] duration-150",
142
- collapsed ? "w-16 px-2" : "w-36 px-2",
142
+ collapsed ? "w-16 px-2" : "w-40 px-2",
143
143
  className
144
144
  ),
145
145
  children: [
@@ -307,7 +307,7 @@ function useAgentsMessengerSource(options = {}) {
307
307
  id: agentRowId(row.agentId),
308
308
  name: nameOf(row.agentId),
309
309
  avatar: { kind: "monogram" },
310
- preview: row.latest ? threadTitle(row.latest) : seatOf(row.agentId) ? STARTER_LABEL : void 0,
310
+ preview: row.latest ? threadTitle(row.latest) : void 0,
311
311
  time: relativeDate(row.latest?.updatedAt),
312
312
  pinned: row.pinned,
313
313
  searchText: info.get(row.agentId)?.description ?? void 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/chat",
3
- "version": "0.7.30",
3
+ "version": "0.7.31",
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 explicit per-module subpaths @ai-matrx/chat/<domain>/<module> (no wildcards: scripts/public-modules.json) over a host contract (/host, /host/react) whose only required value is a db. One chat, one renderer: the old kernel entries (., /external-store, /matrx, /react, /tools, styles.css, tokens.css) are retired.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -4716,14 +4716,14 @@
4716
4716
  "server-only": "^0.0.1",
4717
4717
  "uuid": "^14.0.2",
4718
4718
  "zod": "^4.6.5",
4719
- "@ai-matrx/alchemy": "latest",
4720
4719
  "@ai-matrx/associations": "latest",
4721
4720
  "@ai-matrx/browser-audio": "latest",
4722
- "@ai-matrx/agents": "latest",
4723
4721
  "@ai-matrx/canvas": "latest",
4724
4722
  "@ai-matrx/content-ir": "latest",
4725
4723
  "@ai-matrx/content-ir-react": "latest",
4724
+ "@ai-matrx/alchemy": "latest",
4726
4725
  "@ai-matrx/data": "latest",
4726
+ "@ai-matrx/agents": "latest",
4727
4727
  "@ai-matrx/design-system": "latest",
4728
4728
  "@ai-matrx/icons": "latest",
4729
4729
  "@ai-matrx/kit": "latest",
@@ -4731,11 +4731,11 @@
4731
4731
  "@ai-matrx/messaging": "latest",
4732
4732
  "@ai-matrx/print": "latest",
4733
4733
  "@ai-matrx/realtime": "latest",
4734
- "@ai-matrx/diff": "latest",
4735
4734
  "@ai-matrx/records": "latest",
4736
4735
  "@ai-matrx/records-ui": "latest",
4737
4736
  "@ai-matrx/rich-content": "latest",
4738
- "@ai-matrx/rich-editor": "latest"
4737
+ "@ai-matrx/rich-editor": "latest",
4738
+ "@ai-matrx/diff": "latest"
4739
4739
  },
4740
4740
  "devDependencies": {
4741
4741
  "@arethetypeswrong/cli": "^0.18.5",
@@ -4854,5 +4854,5 @@
4854
4854
  "check:side-effects": "node ../scripts/check-side-effects-listed.mjs . && node ../scripts/check-side-effects-listed.mjs --self-test",
4855
4855
  "check:public-surface": "node ./scripts/sync-public-surface.mjs --check && node ./scripts/sync-public-surface.mjs --self-test"
4856
4856
  },
4857
- "gitHead": "95a5e215a7437a241b5588b14653a183c82c240c"
4857
+ "gitHead": "49f70431f3ef0317f82a1e22f628cf521e448058"
4858
4858
  }