@ai-matrx/messaging 0.10.0 → 0.10.2
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 +38 -0
- package/README.md +6 -0
- package/dist/index.cjs +29 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +29 -9
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +79 -25
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +37 -3
- package/dist/react.d.ts +37 -3
- package/dist/react.js +85 -26
- package/dist/react.js.map +1 -1
- package/package.json +2 -2
package/dist/react.cjs
CHANGED
|
@@ -73,6 +73,7 @@ __export(react_exports, {
|
|
|
73
73
|
createOutbox: () => createOutbox,
|
|
74
74
|
createReadCache: () => createReadCache,
|
|
75
75
|
createWebOutboxStorage: () => createWebOutboxStorage,
|
|
76
|
+
effectiveActorKey: () => effectiveActorKey,
|
|
76
77
|
extractReferences: () => extractReferences,
|
|
77
78
|
formatConversationTime: () => formatConversationTime,
|
|
78
79
|
formatDateSeparator: () => formatDateSeparator,
|
|
@@ -1909,15 +1910,27 @@ function MessagingRuntime(props) {
|
|
|
1909
1910
|
const transport = props.transport;
|
|
1910
1911
|
const agents = props.agents;
|
|
1911
1912
|
const maxTranscriptMessages = props.maxTranscriptMessages;
|
|
1913
|
+
const sourceApp = props.sourceApp;
|
|
1914
|
+
const sourceFeature = props.sourceFeature;
|
|
1912
1915
|
const ai = (0, import_react.useMemo)(() => {
|
|
1913
1916
|
if (transport === void 0 || agents === void 0 || !ready) return null;
|
|
1914
1917
|
return createMessagingAi({
|
|
1915
1918
|
transport,
|
|
1916
1919
|
organizationId,
|
|
1917
1920
|
agents,
|
|
1918
|
-
...maxTranscriptMessages !== void 0 ? { maxTranscriptMessages } : {}
|
|
1921
|
+
...maxTranscriptMessages !== void 0 ? { maxTranscriptMessages } : {},
|
|
1922
|
+
...sourceApp !== void 0 ? { sourceApp } : {},
|
|
1923
|
+
...sourceFeature !== void 0 ? { sourceFeature } : {}
|
|
1919
1924
|
});
|
|
1920
|
-
}, [
|
|
1925
|
+
}, [
|
|
1926
|
+
transport,
|
|
1927
|
+
agents,
|
|
1928
|
+
ready,
|
|
1929
|
+
organizationId,
|
|
1930
|
+
maxTranscriptMessages,
|
|
1931
|
+
sourceApp,
|
|
1932
|
+
sourceFeature
|
|
1933
|
+
]);
|
|
1921
1934
|
const renderers = props.actionRenderers;
|
|
1922
1935
|
const rendererMap = (0, import_react.useMemo)(() => {
|
|
1923
1936
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -2036,18 +2049,20 @@ function groupMessages(messages, args = {}) {
|
|
|
2036
2049
|
let current = null;
|
|
2037
2050
|
let previousDay = null;
|
|
2038
2051
|
for (const message of messages) {
|
|
2052
|
+
const actorKey = args.actorKey?.(message) ?? `principal:${message.senderId}`;
|
|
2039
2053
|
const day = message.createdAt.slice(0, 10);
|
|
2040
2054
|
const startsNewDay = day !== previousDay;
|
|
2041
2055
|
previousDay = day;
|
|
2042
2056
|
const last = current?.messages.at(-1);
|
|
2043
2057
|
const withinWindow = last !== void 0 && Math.abs(Date.parse(message.createdAt) - Date.parse(last.createdAt)) <= windowMs;
|
|
2044
|
-
if (current !== null && current.senderId === message.senderId && withinWindow && !startsNewDay) {
|
|
2058
|
+
if (current !== null && current.senderId === message.senderId && current.actorKey === actorKey && withinWindow && !startsNewDay) {
|
|
2045
2059
|
current.messages.push(message);
|
|
2046
2060
|
continue;
|
|
2047
2061
|
}
|
|
2048
2062
|
if (current !== null) groups.push(current);
|
|
2049
2063
|
current = {
|
|
2050
2064
|
senderId: message.senderId,
|
|
2065
|
+
actorKey,
|
|
2051
2066
|
messages: [message],
|
|
2052
2067
|
dateSeparator: startsNewDay ? formatDateSeparator(message.createdAt, now, args.locale) : null
|
|
2053
2068
|
};
|
|
@@ -2369,19 +2384,36 @@ var import_react5 = require("react");
|
|
|
2369
2384
|
|
|
2370
2385
|
// src/core/actor.ts
|
|
2371
2386
|
function readActorHint(metadata) {
|
|
2372
|
-
const
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2387
|
+
const envelope = metadata;
|
|
2388
|
+
const raw = envelope["actor"];
|
|
2389
|
+
if (typeof raw === "object" && raw !== null && !Array.isArray(raw)) {
|
|
2390
|
+
const record = raw;
|
|
2391
|
+
const agentId = record["agentId"] ?? record["agent_id"];
|
|
2392
|
+
if (typeof agentId !== "string" || agentId.length === 0) return null;
|
|
2393
|
+
const name2 = record["agentName"] ?? record["agent_name"];
|
|
2394
|
+
const avatar2 = record["agentAvatarUrl"] ?? record["agent_avatar_url"];
|
|
2395
|
+
return {
|
|
2396
|
+
agentId,
|
|
2397
|
+
...typeof name2 === "string" && name2.length > 0 ? { agentName: name2 } : {},
|
|
2398
|
+
...typeof avatar2 === "string" && avatar2.length > 0 ? { agentAvatarUrl: avatar2 } : {}
|
|
2399
|
+
};
|
|
2400
|
+
}
|
|
2401
|
+
const actorKind = envelope["actor_kind"] ?? envelope["actorKind"];
|
|
2402
|
+
if (actorKind !== "agent") return null;
|
|
2403
|
+
const id = envelope["actor_id"] ?? envelope["actorId"];
|
|
2404
|
+
const name = envelope["actor_label"] ?? envelope["actorLabel"];
|
|
2405
|
+
const avatar = envelope["actor_avatar_url"] ?? envelope["actorAvatarUrl"];
|
|
2379
2406
|
return {
|
|
2380
|
-
agentId,
|
|
2407
|
+
...typeof id === "string" && id.length > 0 ? { agentId: id } : {},
|
|
2381
2408
|
...typeof name === "string" && name.length > 0 ? { agentName: name } : {},
|
|
2382
2409
|
...typeof avatar === "string" && avatar.length > 0 ? { agentAvatarUrl: avatar } : {}
|
|
2383
2410
|
};
|
|
2384
2411
|
}
|
|
2412
|
+
function effectiveActorKey(message) {
|
|
2413
|
+
const hint = readActorHint(message.metadata);
|
|
2414
|
+
if (hint === null) return `principal:${message.senderId}`;
|
|
2415
|
+
return `agent:${hint.agentId ?? hint.agentName ?? "anonymous"}`;
|
|
2416
|
+
}
|
|
2385
2417
|
function resolveActor(message, sender) {
|
|
2386
2418
|
const hint = readActorHint(message.metadata);
|
|
2387
2419
|
const humanName = sender?.displayName ?? message.senderId;
|
|
@@ -2777,7 +2809,7 @@ function ConversationView(props) {
|
|
|
2777
2809
|
);
|
|
2778
2810
|
const anyOnline = others.some((participant) => online.has(participant.userId));
|
|
2779
2811
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `mx-msg__thread${props.className !== void 0 ? ` ${props.className}` : ""}`, children: [
|
|
2780
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-msg__header", children: [
|
|
2812
|
+
props.showHeader !== false ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-msg__header", children: [
|
|
2781
2813
|
props.onBack !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2782
2814
|
"button",
|
|
2783
2815
|
{
|
|
@@ -2812,8 +2844,8 @@ function ConversationView(props) {
|
|
|
2812
2844
|
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(UsersIcon, {})
|
|
2813
2845
|
}
|
|
2814
2846
|
) : null })
|
|
2815
|
-
] }),
|
|
2816
|
-
ai.available.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-msg__ai-bar", children: ai.available.map((capability) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
2847
|
+
] }) : null,
|
|
2848
|
+
props.showAi !== false && ai.available.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-msg__ai-bar", children: ai.available.map((capability) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
2817
2849
|
"button",
|
|
2818
2850
|
{
|
|
2819
2851
|
type: "button",
|
|
@@ -2827,7 +2859,7 @@ function ConversationView(props) {
|
|
|
2827
2859
|
},
|
|
2828
2860
|
capability
|
|
2829
2861
|
)) }) : null,
|
|
2830
|
-
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: [
|
|
2862
|
+
props.showAi !== false && 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: [
|
|
2831
2863
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-msg__ai-output-label", children: ai.activeCapability !== null ? `${AI_LABELS[ai.activeCapability]}\u2026` : "Working\u2026" }),
|
|
2832
2864
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2833
2865
|
"span",
|
|
@@ -2836,7 +2868,7 @@ function ConversationView(props) {
|
|
|
2836
2868
|
style: { display: "block", height: 11, width: "72%" }
|
|
2837
2869
|
}
|
|
2838
2870
|
)
|
|
2839
|
-
] }) }) : 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: [
|
|
2871
|
+
] }) }) : props.showAi !== false && ai.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-msg__ai-output", style: { color: "var(--mx-msg-danger)" }, children: ai.error }) : props.showAi !== false && ai.result !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-msg__ai-output", children: [
|
|
2840
2872
|
ai.result.text,
|
|
2841
2873
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2842
2874
|
"button",
|
|
@@ -2861,26 +2893,24 @@ function ConversationView(props) {
|
|
|
2861
2893
|
children: "Load earlier messages"
|
|
2862
2894
|
}
|
|
2863
2895
|
) : null,
|
|
2864
|
-
groupMessages(messages).map((group) => {
|
|
2896
|
+
groupMessages(messages, { actorKey: effectiveActorKey }).map((group) => {
|
|
2865
2897
|
const first = group.messages[0];
|
|
2866
2898
|
if (first === void 0) return null;
|
|
2867
|
-
const isMine = group.senderId === selfId;
|
|
2868
2899
|
const sender = conversation.participants.find(
|
|
2869
2900
|
(participant) => participant.userId === group.senderId
|
|
2870
2901
|
) ?? null;
|
|
2902
|
+
const actor = resolveActor(first, sender);
|
|
2903
|
+
const isMine = group.senderId === selfId && !actor.isAgent;
|
|
2871
2904
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
2872
2905
|
group.dateSeparator !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-msg__day", children: group.dateSeparator }) : null,
|
|
2873
2906
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2874
2907
|
MessageGroupView,
|
|
2875
2908
|
{
|
|
2876
2909
|
messages: group.messages,
|
|
2877
|
-
|
|
2910
|
+
actor,
|
|
2878
2911
|
isMine,
|
|
2879
2912
|
onRetry: conversation.retry,
|
|
2880
2913
|
onReply: composer.setReplyTo,
|
|
2881
|
-
pendingIds: new Set(
|
|
2882
|
-
conversation.pending.filter((entry) => entry.state === "failed").map((entry) => entry.clientMessageId)
|
|
2883
|
-
),
|
|
2884
2914
|
failedEntryIdByClientId: new Map(
|
|
2885
2915
|
conversation.pending.map((entry) => [entry.clientMessageId, entry.id])
|
|
2886
2916
|
)
|
|
@@ -2893,13 +2923,20 @@ function ConversationView(props) {
|
|
|
2893
2923
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TypingDots, {}),
|
|
2894
2924
|
typists.label
|
|
2895
2925
|
] }) : null }),
|
|
2896
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2926
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2927
|
+
ComposerView,
|
|
2928
|
+
{
|
|
2929
|
+
composer,
|
|
2930
|
+
disabled: false,
|
|
2931
|
+
...props.renderComposerInput !== void 0 ? { renderInput: props.renderComposerInput } : {}
|
|
2932
|
+
}
|
|
2933
|
+
)
|
|
2897
2934
|
] });
|
|
2898
2935
|
}
|
|
2899
2936
|
function MessageGroupView(props) {
|
|
2900
2937
|
const first = props.messages[0];
|
|
2901
2938
|
if (first === void 0) return null;
|
|
2902
|
-
const actor =
|
|
2939
|
+
const actor = props.actor;
|
|
2903
2940
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `mx-msg__group${props.isMine ? " mx-msg__group--mine" : ""}`, children: [
|
|
2904
2941
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2905
2942
|
Avatar,
|
|
@@ -3086,7 +3123,24 @@ function ComposerView(props) {
|
|
|
3086
3123
|
}
|
|
3087
3124
|
)
|
|
3088
3125
|
] }) : null,
|
|
3089
|
-
|
|
3126
|
+
props.renderInput !== void 0 ? props.renderInput({
|
|
3127
|
+
value: composer.value,
|
|
3128
|
+
disabled: props.disabled,
|
|
3129
|
+
canSend: composer.canSend,
|
|
3130
|
+
placeholder: "Write a reply\u2026",
|
|
3131
|
+
onChange: (value) => {
|
|
3132
|
+
composer.setValue(value);
|
|
3133
|
+
composer.onKeystroke();
|
|
3134
|
+
},
|
|
3135
|
+
onKeyDown: (event) => {
|
|
3136
|
+
if (event.key !== "Enter" || event.shiftKey) return;
|
|
3137
|
+
const isTouch = typeof globalThis.matchMedia === "function" && globalThis.matchMedia("(pointer: coarse)").matches;
|
|
3138
|
+
if (isTouch) return;
|
|
3139
|
+
event.preventDefault();
|
|
3140
|
+
composer.send();
|
|
3141
|
+
},
|
|
3142
|
+
onSubmit: composer.send
|
|
3143
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-msg__composer-row", children: [
|
|
3090
3144
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3091
3145
|
"textarea",
|
|
3092
3146
|
{
|