@ai-matrx/messaging 0.9.0 → 0.10.1
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 +54 -0
- package/README.md +29 -4
- package/dist/index.cjs +35 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -35
- package/dist/index.d.ts +73 -35
- package/dist/index.js +35 -22
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +87 -33
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +97 -36
- package/dist/react.d.ts +97 -36
- package/dist/react.js +87 -33
- package/dist/react.js.map +1 -1
- package/dist/styles.css +10 -0
- package/package.json +1 -1
package/dist/react.cjs
CHANGED
|
@@ -95,6 +95,7 @@ __export(react_exports, {
|
|
|
95
95
|
resolveActor: () => resolveActor,
|
|
96
96
|
splitText: () => splitText,
|
|
97
97
|
summarizeText: () => summarizeText,
|
|
98
|
+
unreadCutoff: () => unreadCutoff,
|
|
98
99
|
useComposer: () => useComposer,
|
|
99
100
|
useConversation: () => useConversation,
|
|
100
101
|
useConversations: () => useConversations,
|
|
@@ -354,6 +355,12 @@ ${JSON.stringify(references, null, 2)}
|
|
|
354
355
|
}
|
|
355
356
|
|
|
356
357
|
// src/core/ai.ts
|
|
358
|
+
function unreadCutoff(messages, unreadCount) {
|
|
359
|
+
if (unreadCount <= 0) return null;
|
|
360
|
+
const index = messages.length - unreadCount - 1;
|
|
361
|
+
if (index < 0) return null;
|
|
362
|
+
return messages[index]?.createdAt ?? null;
|
|
363
|
+
}
|
|
357
364
|
function nameOf(participants, senderId) {
|
|
358
365
|
return participants.find((p) => p.userId === senderId)?.displayName ?? senderId;
|
|
359
366
|
}
|
|
@@ -374,22 +381,23 @@ function buildTranscript(messages, participants, limit, since) {
|
|
|
374
381
|
}
|
|
375
382
|
function createMessagingAi(options) {
|
|
376
383
|
const limit = options.maxTranscriptMessages ?? 200;
|
|
377
|
-
function
|
|
378
|
-
const
|
|
379
|
-
if (
|
|
384
|
+
function identityFor(capability) {
|
|
385
|
+
const identity = options.agents[capability];
|
|
386
|
+
if (identity === void 0 || identity.agentId.length === 0) {
|
|
380
387
|
throw new MessagingError(
|
|
381
388
|
"misconfigured",
|
|
382
389
|
`Messaging AI capability "${capability}" has no agent configured`,
|
|
383
|
-
`Pass agents={{ ${capability}: "<agent-id>" }} to <MessagingProvider>. Agent definitions live in the database, never in this package \u2014 the
|
|
390
|
+
`Pass agents={{ ${capability}: { agentId: "<agent-id>" } }} to <MessagingProvider>. Agent definitions live in the database, never in this package \u2014 the identity is the only part a host injects. Until then the UI hides this action rather than offering a button that cannot work.`
|
|
384
391
|
);
|
|
385
392
|
}
|
|
386
|
-
return
|
|
393
|
+
return identity;
|
|
387
394
|
}
|
|
388
|
-
async function run(capability, variables, userInput, signal) {
|
|
389
|
-
const
|
|
395
|
+
async function run(capability, variables, userInput, signal, onText) {
|
|
396
|
+
const identity = identityFor(capability);
|
|
397
|
+
const overrides = identity.configOverrides;
|
|
390
398
|
const completed = await (0, import_matrx.runAgentToCompletion)(
|
|
391
399
|
options.transport,
|
|
392
|
-
agentId,
|
|
400
|
+
identity.agentId,
|
|
393
401
|
{
|
|
394
402
|
...(0, import_matrx.newEphemeralConversationStart)(),
|
|
395
403
|
organization_id: options.organizationId,
|
|
@@ -398,9 +406,15 @@ function createMessagingAi(options) {
|
|
|
398
406
|
initiation: "user",
|
|
399
407
|
// THE USER-INPUT LAW: structured content is NEVER here.
|
|
400
408
|
...userInput !== null ? { user_input: userInput } : {},
|
|
409
|
+
// The settings half of the injected identity, verbatim. An absent one
|
|
410
|
+
// is OMITTED rather than sent as null: the agent's own settings stand.
|
|
411
|
+
...overrides != null ? { config_overrides: overrides } : {},
|
|
401
412
|
variables
|
|
402
413
|
},
|
|
403
|
-
|
|
414
|
+
{
|
|
415
|
+
...signal !== void 0 ? { signal } : {},
|
|
416
|
+
...onText !== void 0 ? { onChunk: onText } : {}
|
|
417
|
+
}
|
|
404
418
|
);
|
|
405
419
|
return {
|
|
406
420
|
capability,
|
|
@@ -433,27 +447,26 @@ function createMessagingAi(options) {
|
|
|
433
447
|
...args.since != null ? { unread_since: args.since } : {}
|
|
434
448
|
};
|
|
435
449
|
}
|
|
450
|
+
function configured(capability) {
|
|
451
|
+
const identity = options.agents[capability];
|
|
452
|
+
return identity !== void 0 && identity.agentId.length > 0;
|
|
453
|
+
}
|
|
436
454
|
return {
|
|
437
455
|
available: () => ["catchUp", "summarize", "actionItems", "draftReply"].filter(
|
|
438
|
-
|
|
439
|
-
const id = options.agents[capability];
|
|
440
|
-
return typeof id === "string" && id.length > 0;
|
|
441
|
-
}
|
|
456
|
+
configured
|
|
442
457
|
),
|
|
443
|
-
isAvailable
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
catchMeUp: (args) => run("catchUp", variablesFor(args), null, args.signal),
|
|
448
|
-
summarize: (args) => run("summarize", variablesFor(args), null, args.signal),
|
|
449
|
-
extractActionItems: (args) => run("actionItems", variablesFor(args), null, args.signal),
|
|
458
|
+
isAvailable: configured,
|
|
459
|
+
catchMeUp: (args) => run("catchUp", variablesFor(args), null, args.signal, args.onText),
|
|
460
|
+
summarize: (args) => run("summarize", variablesFor(args), null, args.signal, args.onText),
|
|
461
|
+
extractActionItems: (args) => run("actionItems", variablesFor(args), null, args.signal, args.onText),
|
|
450
462
|
draftReply: (args) => run(
|
|
451
463
|
"draftReply",
|
|
452
464
|
variablesFor(args),
|
|
453
465
|
// The ONE genuine human utterance in this module: what the user asked
|
|
454
466
|
// the drafter for. Everything else rode `variables`.
|
|
455
467
|
args.instruction !== void 0 && args.instruction.trim().length > 0 ? args.instruction.trim() : null,
|
|
456
|
-
args.signal
|
|
468
|
+
args.signal,
|
|
469
|
+
args.onText
|
|
457
470
|
)
|
|
458
471
|
};
|
|
459
472
|
}
|
|
@@ -1895,14 +1908,28 @@ function MessagingRuntime(props) {
|
|
|
1895
1908
|
}, [engine]);
|
|
1896
1909
|
const transport = props.transport;
|
|
1897
1910
|
const agents = props.agents;
|
|
1911
|
+
const maxTranscriptMessages = props.maxTranscriptMessages;
|
|
1912
|
+
const sourceApp = props.sourceApp;
|
|
1913
|
+
const sourceFeature = props.sourceFeature;
|
|
1898
1914
|
const ai = (0, import_react.useMemo)(() => {
|
|
1899
1915
|
if (transport === void 0 || agents === void 0 || !ready) return null;
|
|
1900
1916
|
return createMessagingAi({
|
|
1901
1917
|
transport,
|
|
1902
1918
|
organizationId,
|
|
1903
|
-
agents
|
|
1919
|
+
agents,
|
|
1920
|
+
...maxTranscriptMessages !== void 0 ? { maxTranscriptMessages } : {},
|
|
1921
|
+
...sourceApp !== void 0 ? { sourceApp } : {},
|
|
1922
|
+
...sourceFeature !== void 0 ? { sourceFeature } : {}
|
|
1904
1923
|
});
|
|
1905
|
-
}, [
|
|
1924
|
+
}, [
|
|
1925
|
+
transport,
|
|
1926
|
+
agents,
|
|
1927
|
+
ready,
|
|
1928
|
+
organizationId,
|
|
1929
|
+
maxTranscriptMessages,
|
|
1930
|
+
sourceApp,
|
|
1931
|
+
sourceFeature
|
|
1932
|
+
]);
|
|
1906
1933
|
const renderers = props.actionRenderers;
|
|
1907
1934
|
const rendererMap = (0, import_react.useMemo)(() => {
|
|
1908
1935
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -2230,6 +2257,10 @@ function useMessagingAi(conversationId) {
|
|
|
2230
2257
|
const host = useMessagingHost();
|
|
2231
2258
|
const conversation = useConversation(conversationId);
|
|
2232
2259
|
const [isRunning, setRunning] = (0, import_react3.useState)(false);
|
|
2260
|
+
const [partialText, setPartialText] = (0, import_react3.useState)("");
|
|
2261
|
+
const [activeCapability, setActiveCapability] = (0, import_react3.useState)(
|
|
2262
|
+
null
|
|
2263
|
+
);
|
|
2233
2264
|
const [result, setResult] = (0, import_react3.useState)(null);
|
|
2234
2265
|
const [error, setError] = (0, import_react3.useState)(null);
|
|
2235
2266
|
const abortRef = (0, import_react3.useRef)(null);
|
|
@@ -2243,11 +2274,15 @@ function useMessagingAi(conversationId) {
|
|
|
2243
2274
|
return {
|
|
2244
2275
|
available: ai?.available() ?? [],
|
|
2245
2276
|
isRunning,
|
|
2277
|
+
partialText,
|
|
2278
|
+
activeCapability,
|
|
2246
2279
|
result,
|
|
2247
2280
|
error,
|
|
2248
2281
|
clear: () => {
|
|
2249
2282
|
setResult(null);
|
|
2250
2283
|
setError(null);
|
|
2284
|
+
setPartialText("");
|
|
2285
|
+
setActiveCapability(null);
|
|
2251
2286
|
},
|
|
2252
2287
|
run: (capability, args = {}) => {
|
|
2253
2288
|
if (ai === null || conversationId === null) return;
|
|
@@ -2256,22 +2291,32 @@ function useMessagingAi(conversationId) {
|
|
|
2256
2291
|
abortRef.current = controller;
|
|
2257
2292
|
setRunning(true);
|
|
2258
2293
|
setError(null);
|
|
2294
|
+
setResult(null);
|
|
2295
|
+
setPartialText("");
|
|
2296
|
+
setActiveCapability(capability);
|
|
2259
2297
|
const base = {
|
|
2260
2298
|
conversationId,
|
|
2261
2299
|
messages: conversation.messages,
|
|
2262
2300
|
participants: conversation.participants,
|
|
2263
|
-
signal: controller.signal
|
|
2301
|
+
signal: controller.signal,
|
|
2302
|
+
// Live progress. Aborted runs stop painting immediately — a cancelled
|
|
2303
|
+
// answer must not keep growing on screen.
|
|
2304
|
+
onText: (text) => {
|
|
2305
|
+
if (!controller.signal.aborted) setPartialText(text);
|
|
2306
|
+
}
|
|
2264
2307
|
};
|
|
2265
2308
|
const call = () => {
|
|
2266
2309
|
switch (capability) {
|
|
2267
|
-
case "catchUp":
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2310
|
+
case "catchUp":
|
|
2311
|
+
return ai.catchMeUp({
|
|
2312
|
+
...base,
|
|
2313
|
+
// "What did I miss" is about the UNREAD tail. Sending the whole
|
|
2314
|
+
// window made this capability a second Summarize.
|
|
2315
|
+
since: unreadCutoff(
|
|
2316
|
+
conversation.messages,
|
|
2317
|
+
conversation.summary?.unreadCount ?? 0
|
|
2318
|
+
)
|
|
2319
|
+
});
|
|
2275
2320
|
case "summarize":
|
|
2276
2321
|
return ai.summarize(base);
|
|
2277
2322
|
case "actionItems":
|
|
@@ -2794,7 +2839,16 @@ function ConversationView(props) {
|
|
|
2794
2839
|
},
|
|
2795
2840
|
capability
|
|
2796
2841
|
)) }) : null,
|
|
2797
|
-
ai.isRunning ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-msg__ai-output", "aria-busy": "true",
|
|
2842
|
+
ai.isRunning ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-msg__ai-output", "aria-busy": "true", "aria-live": "polite", children: ai.partialText.length > 0 ? ai.partialText : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
2843
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-msg__ai-output-label", children: ai.activeCapability !== null ? `${AI_LABELS[ai.activeCapability]}\u2026` : "Working\u2026" }),
|
|
2844
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2845
|
+
"span",
|
|
2846
|
+
{
|
|
2847
|
+
className: "mx-msg__skeleton",
|
|
2848
|
+
style: { display: "block", height: 11, width: "72%" }
|
|
2849
|
+
}
|
|
2850
|
+
)
|
|
2851
|
+
] }) }) : ai.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-msg__ai-output", style: { color: "var(--mx-msg-danger)" }, children: ai.error }) : ai.result !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-msg__ai-output", children: [
|
|
2798
2852
|
ai.result.text,
|
|
2799
2853
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2800
2854
|
"button",
|