@ai-matrx/chat 0.7.29 → 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 +12 -0
- package/dist/agents/components/inputs/smart-input/useConversationDisplayRows.d.ts +8 -9
- package/dist/agents/components/inputs/smart-input/useConversationDisplayRows.js +80 -5
- package/dist/agents/hooks/useComposerStructuredRun.d.ts +20 -0
- package/dist/agents/hooks/useComposerStructuredRun.js +75 -0
- package/dist/agents/redux/execution-system/instance-variable-values/bound-variable.selectors.js +2 -0
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.slice.d.ts +12 -1
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.slice.js +11 -0
- package/dist/agents/redux/execution-system/utils/host-turn.d.ts +9 -0
- package/dist/agents/redux/execution-system/utils/host-turn.js +25 -0
- package/dist/context/sources/scopes.d.ts +1 -1
- package/dist/host/contract.d.ts +6 -0
- package/dist/messenger/MessengerRail.js +1 -1
- package/dist/messenger/agents/AgentsMessenger.js +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
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
|
+
|
|
9
|
+
## 0.7.30
|
|
10
|
+
|
|
11
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
12
|
+
`git diff npm/chat/v0.7.29..npm/chat/v0.7.30 -- apps/shared/chat`).
|
|
13
|
+
No source changes intended and no consumer action required.
|
|
14
|
+
|
|
3
15
|
## 0.7.29
|
|
4
16
|
### the agents messenger
|
|
5
17
|
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
import { type ResolvedContextRow } from "@ai-matrx/agents/context";
|
|
2
|
+
import type { ChatRootState } from "../../../../store/root-state.js";
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* platform.associations edges `AttachedDocumentChips` lists, and the connector
|
|
6
|
-
* resources (repos, Google files, synced records) the attachments handle has
|
|
7
|
-
* read (`selectConversationAttachmentsEntry`, no second fetch). An attachment
|
|
8
|
-
* detached since the last receipt drops out at once; one attached since then
|
|
9
|
-
* shows at once, its size unknown until the next receipt.
|
|
4
|
+
* What the host's context sources (the page the person is on, for a browser host) would add to
|
|
5
|
+
* the next turn, read now and again whenever a source says it changed, the window regains focus,
|
|
6
|
+
* or the conversation changes. A host without sources reads `{}` once and never again.
|
|
10
7
|
*/
|
|
11
|
-
|
|
8
|
+
export declare function useHostContextPreview(conversationId: string): Record<string, unknown>;
|
|
9
|
+
/** The host's would-be context as rows, each under the person's saved rule; keys already shown stay as they are. */
|
|
10
|
+
export declare function hostContextRows(state: ChatRootState, conversationId: string, shown: readonly ResolvedContextRow[], hostContext: Readonly<Record<string, unknown>>): ResolvedContextRow[];
|
|
12
11
|
export declare function useConversationDisplayRows(conversationId: string, mandateKillSwitch: boolean): ResolvedContextRow[];
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_SURFACE_KEY,
|
|
5
|
+
resolveContextRow
|
|
6
|
+
} from "@ai-matrx/agents/context";
|
|
7
|
+
import { humanizeIdentifier } from "@ai-matrx/kit/text-case";
|
|
2
8
|
import { useAppSelector, useAppStore } from "../../../../store/hooks.js";
|
|
3
9
|
import { useConversationMaterialized } from "../../../hooks/useConversationMaterialized.js";
|
|
4
10
|
import { useContainerLinks } from "@ai-matrx/associations/react";
|
|
5
11
|
import { attachmentContextKey } from "@ai-matrx/agents/context";
|
|
6
12
|
import {
|
|
13
|
+
previewHostTurnContext,
|
|
14
|
+
subscribeHostContextChanges
|
|
15
|
+
} from "../../../redux/execution-system/utils/host-turn.js";
|
|
16
|
+
import { resolveClientSurface } from "../../../redux/execution-system/utils/build-tool-injection.js";
|
|
17
|
+
import { selectSavedContextRuleRows } from "../../../redux/execution-system/context-rules/context-rules.thunks.js";
|
|
18
|
+
import {
|
|
19
|
+
selectContextInlineCap,
|
|
7
20
|
DOCUMENT_ATTACHMENT_PREFIXES,
|
|
8
21
|
RESOURCE_ATTACHMENT_PREFIXES,
|
|
9
22
|
durableAttachmentKey,
|
|
@@ -18,6 +31,51 @@ import {
|
|
|
18
31
|
useAttachedDocumentFileNames
|
|
19
32
|
} from "../resources/attached-documents.js";
|
|
20
33
|
import { selectOrganizationId } from "../../../../host/org.js";
|
|
34
|
+
function useHostContextPreview(conversationId) {
|
|
35
|
+
const store = useAppStore();
|
|
36
|
+
const [preview, setPreview] = useState({});
|
|
37
|
+
const latest = useRef(0);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
let live = true;
|
|
40
|
+
const read = () => {
|
|
41
|
+
const ticket = ++latest.current;
|
|
42
|
+
void previewHostTurnContext(store.getState(), conversationId).then(
|
|
43
|
+
(context) => {
|
|
44
|
+
if (live && ticket === latest.current) setPreview(context);
|
|
45
|
+
},
|
|
46
|
+
() => void 0
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
read();
|
|
50
|
+
const off = subscribeHostContextChanges(read);
|
|
51
|
+
const onFocus = () => read();
|
|
52
|
+
window.addEventListener("focus", onFocus);
|
|
53
|
+
return () => {
|
|
54
|
+
live = false;
|
|
55
|
+
off();
|
|
56
|
+
window.removeEventListener("focus", onFocus);
|
|
57
|
+
};
|
|
58
|
+
}, [store, conversationId]);
|
|
59
|
+
return preview;
|
|
60
|
+
}
|
|
61
|
+
function hostContextRows(state, conversationId, shown, hostContext) {
|
|
62
|
+
const keys = Object.keys(hostContext);
|
|
63
|
+
if (keys.length === 0) return [];
|
|
64
|
+
const have = new Set(shown.map((row) => row.key));
|
|
65
|
+
const saved = selectSavedContextRuleRows(state);
|
|
66
|
+
const cap = selectContextInlineCap(state, conversationId);
|
|
67
|
+
const primarySurface = resolveClientSurface(state, conversationId) ?? null;
|
|
68
|
+
return keys.filter((key) => !have.has(key) && hostContext[key] !== void 0).map((key) => {
|
|
69
|
+
const source = {
|
|
70
|
+
key,
|
|
71
|
+
label: humanizeIdentifier(key) || key,
|
|
72
|
+
surfaceKey: DEFAULT_SURFACE_KEY,
|
|
73
|
+
origin: "page",
|
|
74
|
+
value: hostContext[key]
|
|
75
|
+
};
|
|
76
|
+
return resolveContextRow(source, saved, cap, primarySurface);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
21
79
|
function useConversationDisplayRows(conversationId, mandateKillSwitch) {
|
|
22
80
|
const store = useAppStore();
|
|
23
81
|
const rows = useAppSelector(selectDisplayContextRows(conversationId, mandateKillSwitch));
|
|
@@ -55,11 +113,28 @@ function useConversationDisplayRows(conversationId, mandateKillSwitch) {
|
|
|
55
113
|
key: attachmentContextKey(row.provider, row.resource_ref),
|
|
56
114
|
label: row.display_name
|
|
57
115
|
})) : null;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
116
|
+
const reconciled = reconcileDurableAttachments(
|
|
117
|
+
store.getState(),
|
|
118
|
+
conversationId,
|
|
119
|
+
rows,
|
|
120
|
+
[
|
|
121
|
+
{ prefixes: DOCUMENT_ATTACHMENT_PREFIXES, items: documents },
|
|
122
|
+
{ prefixes: RESOURCE_ATTACHMENT_PREFIXES, items: resources }
|
|
123
|
+
]
|
|
124
|
+
);
|
|
125
|
+
const hostContext = useHostContextPreview(conversationId);
|
|
126
|
+
return useMemo(() => {
|
|
127
|
+
const extra = hostContextRows(
|
|
128
|
+
store.getState(),
|
|
129
|
+
conversationId,
|
|
130
|
+
reconciled,
|
|
131
|
+
hostContext
|
|
132
|
+
);
|
|
133
|
+
return extra.length === 0 ? reconciled : [...reconciled, ...extra];
|
|
134
|
+
}, [store, conversationId, reconciled, hostContext]);
|
|
62
135
|
}
|
|
63
136
|
export {
|
|
64
|
-
|
|
137
|
+
hostContextRows,
|
|
138
|
+
useConversationDisplayRows,
|
|
139
|
+
useHostContextPreview
|
|
65
140
|
};
|
|
@@ -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
|
+
};
|
package/dist/agents/redux/execution-system/instance-variable-values/bound-variable.selectors.js
CHANGED
|
@@ -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">,
|
|
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,
|
|
@@ -37,6 +37,15 @@ export declare function resetLatchedTurns(): void;
|
|
|
37
37
|
* keeps what the start latched (a resume whose start predates this page load latches then).
|
|
38
38
|
*/
|
|
39
39
|
export declare function collectHostTurnContribution(state: ChatRootState, conversationId: string, phase: ChatHostTurnPhase): Promise<ChatHostTurnContribution | null>;
|
|
40
|
+
/**
|
|
41
|
+
* What the host's context sources would add to the NEXT turn's `context`, read for display (the
|
|
42
|
+
* composer's context chip). Same sources, same bounded wait, same merge as a real send, but
|
|
43
|
+
* nothing is latched. A source that is slow or throws contributes no rows here (the skip is
|
|
44
|
+
* announced through diagnostics like any other).
|
|
45
|
+
*/
|
|
46
|
+
export declare function previewHostTurnContext(state: ChatRootState, conversationId: string): Promise<Record<string, unknown>>;
|
|
47
|
+
/** Subscribe to every context source's "my answer may have changed" signal; returns one unsubscribe. */
|
|
48
|
+
export declare function subscribeHostContextChanges(onChange: () => void): () => void;
|
|
40
49
|
/**
|
|
41
50
|
* Merge the host's context entries under what the request already carries: a key the person
|
|
42
51
|
* or the agent set always wins. Returns the original object when the host adds nothing.
|
|
@@ -93,6 +93,29 @@ async function collectHostTurnContribution(state, conversationId, phase) {
|
|
|
93
93
|
}
|
|
94
94
|
return contribution;
|
|
95
95
|
}
|
|
96
|
+
async function previewHostTurnContext(state, conversationId) {
|
|
97
|
+
if (!isChatHostConfigured()) return {};
|
|
98
|
+
const sources = getChatHost().registry.contextSources ?? [];
|
|
99
|
+
if (sources.length === 0) return {};
|
|
100
|
+
const input = {
|
|
101
|
+
conversationId,
|
|
102
|
+
agentId: agentIdOf(state, conversationId),
|
|
103
|
+
phase: "start"
|
|
104
|
+
};
|
|
105
|
+
const merged = mergeContributions(
|
|
106
|
+
await Promise.all(sources.map((source) => askSource(source, input)))
|
|
107
|
+
);
|
|
108
|
+
return merged?.context ?? {};
|
|
109
|
+
}
|
|
110
|
+
function subscribeHostContextChanges(onChange) {
|
|
111
|
+
if (!isChatHostConfigured()) return () => void 0;
|
|
112
|
+
const offs = (getChatHost().registry.contextSources ?? []).flatMap(
|
|
113
|
+
(source) => source.subscribe ? [source.subscribe(onChange)] : []
|
|
114
|
+
);
|
|
115
|
+
return () => {
|
|
116
|
+
for (const off of offs) off();
|
|
117
|
+
};
|
|
118
|
+
}
|
|
96
119
|
function mergeHostTurnContext(existing, hostContext) {
|
|
97
120
|
if (!hostContext) return existing;
|
|
98
121
|
const keys = Object.keys(hostContext);
|
|
@@ -113,7 +136,9 @@ export {
|
|
|
113
136
|
devicePermissionModeKey,
|
|
114
137
|
getLatchedTurn,
|
|
115
138
|
mergeHostTurnContext,
|
|
139
|
+
previewHostTurnContext,
|
|
116
140
|
readDevicePermissionMode,
|
|
117
141
|
resetLatchedTurns,
|
|
142
|
+
subscribeHostContextChanges,
|
|
118
143
|
writeDevicePermissionMode
|
|
119
144
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Scopes (user-authored dimensions: organization, project, task, scope types and their
|
|
5
5
|
* values, the active scope selection) are a platform primitive the chat package READS to
|
|
6
|
-
* build what an agent receives. Until
|
|
6
|
+
* build what an agent receives. Until the data/records packages own scope reading (scopes package deleted 2026-10-09), the host hands
|
|
7
7
|
* them over through ONE registration, `registerChatScopes({...})`, keyed by the export names
|
|
8
8
|
* that package will publish — so P17s3 swaps this module's import specifier for
|
|
9
9
|
* `@ai-matrx/scopes` and deletes this file, with no call-site change.
|
package/dist/host/contract.d.ts
CHANGED
|
@@ -873,6 +873,12 @@ export interface ChatContextSource {
|
|
|
873
873
|
/** Stable id, for diagnostics. */
|
|
874
874
|
id: string;
|
|
875
875
|
contribute(input: ChatHostTurnInput): Promise<ChatHostTurnContribution | null>;
|
|
876
|
+
/**
|
|
877
|
+
* Tell the package this source's answer may have changed (the page navigated, the person
|
|
878
|
+
* switched tabs), so the composer's context chip re-reads it. Returns the unsubscribe. Absent:
|
|
879
|
+
* the chip reads the source when the conversation opens and when the window regains focus.
|
|
880
|
+
*/
|
|
881
|
+
subscribe?(onChange: () => void): () => void;
|
|
876
882
|
}
|
|
877
883
|
export interface ChatRoutingPort {
|
|
878
884
|
policy(conversationId: string): ChatRoutingPolicy;
|
|
@@ -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-
|
|
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) :
|
|
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.
|
|
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",
|
|
@@ -4718,12 +4718,12 @@
|
|
|
4718
4718
|
"zod": "^4.6.5",
|
|
4719
4719
|
"@ai-matrx/associations": "latest",
|
|
4720
4720
|
"@ai-matrx/browser-audio": "latest",
|
|
4721
|
-
"@ai-matrx/alchemy": "latest",
|
|
4722
4721
|
"@ai-matrx/canvas": "latest",
|
|
4723
4722
|
"@ai-matrx/content-ir": "latest",
|
|
4724
4723
|
"@ai-matrx/content-ir-react": "latest",
|
|
4724
|
+
"@ai-matrx/alchemy": "latest",
|
|
4725
4725
|
"@ai-matrx/data": "latest",
|
|
4726
|
-
"@ai-matrx/
|
|
4726
|
+
"@ai-matrx/agents": "latest",
|
|
4727
4727
|
"@ai-matrx/design-system": "latest",
|
|
4728
4728
|
"@ai-matrx/icons": "latest",
|
|
4729
4729
|
"@ai-matrx/kit": "latest",
|
|
@@ -4735,7 +4735,7 @@
|
|
|
4735
4735
|
"@ai-matrx/records-ui": "latest",
|
|
4736
4736
|
"@ai-matrx/rich-content": "latest",
|
|
4737
4737
|
"@ai-matrx/rich-editor": "latest",
|
|
4738
|
-
"@ai-matrx/
|
|
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": "
|
|
4857
|
+
"gitHead": "49f70431f3ef0317f82a1e22f628cf521e448058"
|
|
4858
4858
|
}
|