@ai-matrx/chat 0.5.16 → 0.5.17
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,9 +1,9 @@
|
|
|
1
1
|
# @ai-matrx/chat
|
|
2
2
|
|
|
3
|
-
## 0.5.
|
|
3
|
+
## 0.5.17
|
|
4
4
|
|
|
5
5
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
|
-
`git diff npm/chat/v0.5.
|
|
6
|
+
`git diff npm/chat/v0.5.16..npm/chat/v0.5.17 -- apps/shared/chat`).
|
|
7
7
|
No source changes intended and no consumer action required.
|
|
8
8
|
|
|
9
9
|
## 0.5.10 — message Print is the one message print
|
|
@@ -66,7 +66,11 @@ import { markResourcesSubmitted } from "../instance-resources/instance-resources
|
|
|
66
66
|
import { flushRemarkWrites, hasPendingRemarkWrites } from "../instance-resources/remarks.js";
|
|
67
67
|
import { withFreshRemarkRefs } from "../instance-resources/remarks-wire.js";
|
|
68
68
|
import { isOrganizationSelectionCancelled } from "../../../../host/org.js";
|
|
69
|
-
import {
|
|
69
|
+
import {
|
|
70
|
+
runBeforeSend,
|
|
71
|
+
startHostConversation,
|
|
72
|
+
startsConversationOnFirstSend
|
|
73
|
+
} from "../../../../host/conversation-hooks.js";
|
|
70
74
|
function hasConversationAtExecutionBoundary(state, conversationId) {
|
|
71
75
|
return state.conversations.byConversationId[conversationId] !== void 0;
|
|
72
76
|
}
|
|
@@ -154,6 +158,35 @@ function holdBehindInFlightSend(dispatch, getState, args) {
|
|
|
154
158
|
const smartExecute = createAsyncThunk(
|
|
155
159
|
"instances/smartExecute",
|
|
156
160
|
async ({ conversationId, surfaceKey, whileRunning = "queue", submission: handed }, { getState, dispatch }) => {
|
|
161
|
+
if (!handed && startsConversationOnFirstSend(conversationId)) {
|
|
162
|
+
const draft = captureSubmission(getState(), conversationId);
|
|
163
|
+
if (isEmptySubmission(draft)) return;
|
|
164
|
+
if (draft.resources.length > 0) {
|
|
165
|
+
toast.info("Attachments can't be added yet", {
|
|
166
|
+
description: "Send your first message as text \u2014 attachments work from the next one."
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
detachFromComposer(dispatch, getState, conversationId, draft);
|
|
171
|
+
let realId = null;
|
|
172
|
+
try {
|
|
173
|
+
realId = await startHostConversation(conversationId, { text: draft.text });
|
|
174
|
+
} catch (error) {
|
|
175
|
+
returnToComposer(dispatch, getState, conversationId, draft);
|
|
176
|
+
toast.error("Message not sent", {
|
|
177
|
+
description: error instanceof Error ? error.message : String(error)
|
|
178
|
+
});
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (!realId) {
|
|
182
|
+
returnToComposer(dispatch, getState, conversationId, draft);
|
|
183
|
+
toast.error("Message not sent", { description: "The conversation could not be started." });
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
dispatch(setUserInputText({ conversationId: realId, text: draft.text, userValues: draft.userValues }));
|
|
187
|
+
await dispatch(smartExecute({ conversationId: realId, surfaceKey, whileRunning }));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
157
190
|
if (!handed && !hasConversationAtExecutionBoundary(getState(), conversationId)) {
|
|
158
191
|
await awaitLaunchingConversation(getState, conversationId);
|
|
159
192
|
}
|
|
@@ -15,6 +15,13 @@
|
|
|
15
15
|
* it. Must not throw (a throw is reported and swallowed).
|
|
16
16
|
* startConversation the host names the next conversation's id; the client
|
|
17
17
|
* never mints one.
|
|
18
|
+
* startsOnFirstSend this conversation is a DRAFT: it has no server-side
|
|
19
|
+
* conversation yet (the thing it talks about does not
|
|
20
|
+
* exist). The first send calls `startConversation` — the
|
|
21
|
+
* host creates what it must and names the REAL
|
|
22
|
+
* conversation (instance already in the store) — and the
|
|
23
|
+
* words travel to that one. Text only; the draft is
|
|
24
|
+
* never sent to a server under its own id.
|
|
18
25
|
* everyTurnThroughMandate
|
|
19
26
|
* every turn (not only turn 1) POSTs the mandate route,
|
|
20
27
|
* with the gate's variables + context — for a mandate
|
|
@@ -45,7 +52,11 @@ export interface ConversationHostHooks {
|
|
|
45
52
|
beforeSend?: (input: HostBeforeSendInput) => Promise<HostTurnExtras | HostSendRefused>;
|
|
46
53
|
held?: HostHeld;
|
|
47
54
|
onEvent?: (event: TypedStreamEvent, ctx: HostStreamTapContext) => void;
|
|
48
|
-
startConversation?: (
|
|
55
|
+
startConversation?: (input?: {
|
|
56
|
+
text: string;
|
|
57
|
+
}) => Promise<string>;
|
|
58
|
+
/** With `startConversation`: this id is a draft; the first send goes through `startConversation`. */
|
|
59
|
+
startsOnFirstSend?: boolean;
|
|
49
60
|
everyTurnThroughMandate?: boolean;
|
|
50
61
|
/** How a stored user turn reads on screen (display only; the record is unchanged). */
|
|
51
62
|
displayUserText?: (text: string) => string;
|
|
@@ -81,8 +92,12 @@ export declare function takeTurnExtras(conversationId: string): HostTurnExtras |
|
|
|
81
92
|
export declare function tapStreamEvent(conversationId: string, requestId: string, event: unknown): void;
|
|
82
93
|
/** Should this conversation's later turns also POST the mandate route? */
|
|
83
94
|
export declare function continuesThroughMandate(conversationId: string): boolean;
|
|
95
|
+
/** Is this id a draft whose first send must first create the real conversation? */
|
|
96
|
+
export declare function startsConversationOnFirstSend(conversationId: string): boolean;
|
|
84
97
|
/** Ask the conversation's host for the next conversation id; null when it has no say. */
|
|
85
|
-
export declare function startHostConversation(conversationId: string
|
|
98
|
+
export declare function startHostConversation(conversationId: string, input?: {
|
|
99
|
+
text: string;
|
|
100
|
+
}): Promise<string | null>;
|
|
86
101
|
/**
|
|
87
102
|
* Subscribe to changes of this conversation's held sentence: the host's own
|
|
88
103
|
* source, and the registry (a registration swaps which source is listened to).
|
|
@@ -58,9 +58,13 @@ function tapStreamEvent(conversationId, requestId, event) {
|
|
|
58
58
|
function continuesThroughMandate(conversationId) {
|
|
59
59
|
return hooksByConversation.get(conversationId)?.everyTurnThroughMandate === true;
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
function startsConversationOnFirstSend(conversationId) {
|
|
62
|
+
const hooks = hooksByConversation.get(conversationId);
|
|
63
|
+
return hooks?.startsOnFirstSend === true && typeof hooks.startConversation === "function";
|
|
64
|
+
}
|
|
65
|
+
async function startHostConversation(conversationId, input) {
|
|
62
66
|
const start = hooksByConversation.get(conversationId)?.startConversation;
|
|
63
|
-
return start ? start() : null;
|
|
67
|
+
return start ? start(input) : null;
|
|
64
68
|
}
|
|
65
69
|
function subscribeConversationHeld(conversationId, listener) {
|
|
66
70
|
let current;
|
|
@@ -93,6 +97,7 @@ export {
|
|
|
93
97
|
registerConversationHooks,
|
|
94
98
|
runBeforeSend,
|
|
95
99
|
startHostConversation,
|
|
100
|
+
startsConversationOnFirstSend,
|
|
96
101
|
subscribeConversationHeld,
|
|
97
102
|
subscribeConversationHooks,
|
|
98
103
|
takeTurnExtras,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-matrx/chat",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.17",
|
|
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. 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",
|
|
@@ -167,24 +167,24 @@
|
|
|
167
167
|
"uuid": "^14.0.2",
|
|
168
168
|
"zod": "^4.6.5",
|
|
169
169
|
"@ai-matrx/agents": "latest",
|
|
170
|
+
"@ai-matrx/alchemy": "latest",
|
|
170
171
|
"@ai-matrx/associations": "latest",
|
|
171
172
|
"@ai-matrx/browser-audio": "latest",
|
|
172
173
|
"@ai-matrx/canvas": "latest",
|
|
173
174
|
"@ai-matrx/content-ir": "latest",
|
|
174
|
-
"@ai-matrx/content-ir-react": "latest",
|
|
175
175
|
"@ai-matrx/data": "latest",
|
|
176
|
+
"@ai-matrx/content-ir-react": "latest",
|
|
177
|
+
"@ai-matrx/diff": "latest",
|
|
176
178
|
"@ai-matrx/design-system": "latest",
|
|
177
|
-
"@ai-matrx/icons": "latest",
|
|
178
179
|
"@ai-matrx/kit": "latest",
|
|
179
|
-
"@ai-matrx/media": "latest",
|
|
180
|
-
"@ai-matrx/print": "latest",
|
|
181
180
|
"@ai-matrx/realtime": "latest",
|
|
182
181
|
"@ai-matrx/records": "latest",
|
|
183
|
-
"@ai-matrx/records-ui": "latest",
|
|
184
182
|
"@ai-matrx/rich-content": "latest",
|
|
183
|
+
"@ai-matrx/records-ui": "latest",
|
|
185
184
|
"@ai-matrx/rich-editor": "latest",
|
|
186
|
-
"@ai-matrx/
|
|
187
|
-
"@ai-matrx/
|
|
185
|
+
"@ai-matrx/print": "latest",
|
|
186
|
+
"@ai-matrx/icons": "latest",
|
|
187
|
+
"@ai-matrx/media": "latest"
|
|
188
188
|
},
|
|
189
189
|
"devDependencies": {
|
|
190
190
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
@@ -299,5 +299,6 @@
|
|
|
299
299
|
"deps:write": "node ./scripts/finish-build.mjs --write-deps",
|
|
300
300
|
"check:side-panel-bundle": "node ./scripts/check-side-panel-bundle.mjs",
|
|
301
301
|
"check:side-effects": "node ../scripts/check-side-effects-listed.mjs . && node ../scripts/check-side-effects-listed.mjs --self-test"
|
|
302
|
-
}
|
|
302
|
+
},
|
|
303
|
+
"gitHead": "72c166ca9e3b90dc0f6648754257142aba4756b6"
|
|
303
304
|
}
|