@ai-matrx/chat 0.7.26 → 0.7.27
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 +29 -4
- package/dist/action-requests/components/ActionRequestAnswerForm.d.ts +7 -0
- package/dist/action-requests/components/ActionRequestAnswerForm.js +3 -1
- package/dist/agents/components/inputs/smart-input/composer/ComposerSplash.js +2 -1
- package/dist/agents/redux/execution-system/thunks/run-headless-agent-json.js +8 -0
- package/dist/host/admin-seat.js +2 -0
- package/dist/messenger/MessengerAvatar.d.ts +18 -0
- package/dist/messenger/MessengerAvatar.js +31 -0
- package/dist/messenger/MessengerContactList.d.ts +16 -0
- package/dist/messenger/MessengerContactList.js +210 -0
- package/dist/messenger/MessengerDetails.d.ts +20 -0
- package/dist/messenger/MessengerDetails.js +35 -0
- package/dist/messenger/MessengerMenu.d.ts +21 -0
- package/dist/messenger/MessengerMenu.js +58 -0
- package/dist/messenger/MessengerRail.d.ts +11 -0
- package/dist/messenger/MessengerRail.js +184 -0
- package/dist/messenger/MessengerShell.d.ts +6 -0
- package/dist/messenger/MessengerShell.js +115 -0
- package/dist/messenger/MessengerThreadHeader.d.ts +8 -0
- package/dist/messenger/MessengerThreadHeader.js +62 -0
- package/dist/messenger/contract.d.ts +149 -0
- package/dist/messenger/contract.js +28 -0
- package/dist/messenger/people/format-time.d.ts +6 -0
- package/dist/messenger/people/format-time.js +14 -0
- package/dist/messenger/people/usePeopleMessengerSource.d.ts +35 -0
- package/dist/messenger/people/usePeopleMessengerSource.js +213 -0
- package/package.json +31 -5
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { Archive, Bot, CheckCheck, Copy, MessageCircle, MessageSquareText, Pin, PinOff, Plus, RefreshCw, Users } from "lucide-react";
|
|
5
|
+
import {
|
|
6
|
+
ConversationView,
|
|
7
|
+
asConversationId,
|
|
8
|
+
useConversations,
|
|
9
|
+
useMessagingHost,
|
|
10
|
+
useOnlineUserIds
|
|
11
|
+
} from "@ai-matrx/messaging/react";
|
|
12
|
+
import { MessengerDetails } from "../MessengerDetails.js";
|
|
13
|
+
import { MessengerAvatar } from "../MessengerAvatar.js";
|
|
14
|
+
import { formatMessengerTime } from "./format-time.js";
|
|
15
|
+
const SPACE_ALL = "chats";
|
|
16
|
+
const SPACE_PEOPLE = "people";
|
|
17
|
+
const SPACE_AGENTS = "agents";
|
|
18
|
+
const SPACE_ARCHIVED = "archived";
|
|
19
|
+
function copyText(text) {
|
|
20
|
+
void globalThis.navigator?.clipboard?.writeText(text).catch(() => void 0);
|
|
21
|
+
}
|
|
22
|
+
function usePeopleMessengerSource(options = {}) {
|
|
23
|
+
const host = useMessagingHost();
|
|
24
|
+
const inbox = useConversations();
|
|
25
|
+
const selfId = host?.identity.userId ?? "";
|
|
26
|
+
const activeId = inbox.activeConversationId;
|
|
27
|
+
const online = useOnlineUserIds(activeId);
|
|
28
|
+
const {
|
|
29
|
+
title = "Chats",
|
|
30
|
+
profile,
|
|
31
|
+
onNewConversation,
|
|
32
|
+
pinnedConversationIds,
|
|
33
|
+
onTogglePin,
|
|
34
|
+
renderConversation,
|
|
35
|
+
conversationMenuExtras
|
|
36
|
+
} = options;
|
|
37
|
+
return useMemo(() => {
|
|
38
|
+
const pinned = new Set(pinnedConversationIds ?? []);
|
|
39
|
+
const byId = /* @__PURE__ */ new Map();
|
|
40
|
+
for (const summary of inbox.conversations) byId.set(summary.conversation.id, summary);
|
|
41
|
+
const toContact = (s) => {
|
|
42
|
+
const own = s.lastMessageSenderId !== null && s.lastMessageSenderId === selfId;
|
|
43
|
+
const content = s.lastMessageContent ?? void 0;
|
|
44
|
+
return {
|
|
45
|
+
id: s.conversation.id,
|
|
46
|
+
name: s.displayName,
|
|
47
|
+
avatar: s.displayImageUrl ? { kind: "image", src: s.displayImageUrl } : { kind: "monogram" },
|
|
48
|
+
time: formatMessengerTime(s.lastMessageAt),
|
|
49
|
+
preview: content !== void 0 && own ? `You: ${content}` : content,
|
|
50
|
+
unread: s.unreadCount,
|
|
51
|
+
muted: s.isMuted,
|
|
52
|
+
pinned: pinned.has(s.conversation.id),
|
|
53
|
+
searchText: s.participants.map((p) => `${p.displayName} ${p.email ?? ""}`).join(" ")
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
const all = inbox.conversations.map(toContact);
|
|
57
|
+
const pinOrder = [...pinned];
|
|
58
|
+
const contacts = [
|
|
59
|
+
...all.filter((c) => c.pinned).sort((a, b) => pinOrder.indexOf(a.id) - pinOrder.indexOf(b.id)),
|
|
60
|
+
...all.filter((c) => !c.pinned)
|
|
61
|
+
];
|
|
62
|
+
const markRead = (id) => void host?.engine.markRead(asConversationId(id));
|
|
63
|
+
const conversationMenu = (contact, includeOpen) => {
|
|
64
|
+
const summary = byId.get(contact.id);
|
|
65
|
+
const entries = [];
|
|
66
|
+
if (includeOpen) {
|
|
67
|
+
entries.push({ id: "open", label: "Open", icon: MessageSquareText, onSelect: () => inbox.select(asConversationId(contact.id)) });
|
|
68
|
+
}
|
|
69
|
+
entries.push({
|
|
70
|
+
id: "mark-read",
|
|
71
|
+
label: "Mark as read",
|
|
72
|
+
icon: CheckCheck,
|
|
73
|
+
disabled: (contact.unread ?? 0) === 0,
|
|
74
|
+
onSelect: () => markRead(contact.id)
|
|
75
|
+
});
|
|
76
|
+
if (onTogglePin) {
|
|
77
|
+
entries.push(
|
|
78
|
+
contact.pinned ? { id: "unpin", label: "Unpin", icon: PinOff, onSelect: () => onTogglePin(contact.id) } : { id: "pin", label: "Pin", icon: Pin, onSelect: () => onTogglePin(contact.id) }
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
entries.push({ id: "copy-name", label: "Copy name", icon: Copy, onSelect: () => copyText(contact.name) });
|
|
82
|
+
const extras = summary && conversationMenuExtras ? conversationMenuExtras(summary) : [];
|
|
83
|
+
if (extras.length > 0) entries.push({ id: "extras", separator: true }, ...extras);
|
|
84
|
+
return entries;
|
|
85
|
+
};
|
|
86
|
+
const kindUnread = inbox.kindUnread;
|
|
87
|
+
const spaces = [
|
|
88
|
+
{ id: SPACE_ALL, label: "Chats", icon: MessageCircle, count: kindUnread ? kindUnread.people + kindUnread.agents : void 0 },
|
|
89
|
+
{ id: SPACE_PEOPLE, label: "People", icon: Users, count: kindUnread?.people },
|
|
90
|
+
{ id: SPACE_AGENTS, label: "Agents", icon: Bot, count: kindUnread?.agents }
|
|
91
|
+
];
|
|
92
|
+
const archived = {
|
|
93
|
+
id: SPACE_ARCHIVED,
|
|
94
|
+
label: "Archived",
|
|
95
|
+
icon: Archive,
|
|
96
|
+
count: inbox.archivedCount?.count
|
|
97
|
+
};
|
|
98
|
+
const activeSpaceId = inbox.archiveFilter === "archived" ? SPACE_ARCHIVED : inbox.kindFilter === "people" ? SPACE_PEOPLE : inbox.kindFilter === "agents" ? SPACE_AGENTS : SPACE_ALL;
|
|
99
|
+
const selectSpace = (id) => {
|
|
100
|
+
if (id === SPACE_ARCHIVED) {
|
|
101
|
+
inbox.setArchiveFilter("archived");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (inbox.archiveFilter !== "active") inbox.setArchiveFilter("active");
|
|
105
|
+
inbox.setKindFilter(id === SPACE_PEOPLE ? "people" : id === SPACE_AGENTS ? "agents" : "all");
|
|
106
|
+
};
|
|
107
|
+
const refresh = () => inbox.retry();
|
|
108
|
+
const filters = [
|
|
109
|
+
{ id: "unread", label: "Unread", test: (c) => (c.unread ?? 0) > 0 },
|
|
110
|
+
{ id: "groups", label: "Groups", test: (c) => byId.get(c.id)?.conversation.type === "group" }
|
|
111
|
+
];
|
|
112
|
+
if (onTogglePin) filters.push({ id: "pinned", label: "Pinned", test: (c) => c.pinned === true });
|
|
113
|
+
const headerSubtitle = (summary) => {
|
|
114
|
+
if (!summary) return void 0;
|
|
115
|
+
const others = summary.participants.filter((p) => p.userId !== selfId);
|
|
116
|
+
if (summary.conversation.type === "group") return others.map((p) => p.displayName).join(", ") || void 0;
|
|
117
|
+
return others.some((p) => online.has(p.userId)) ? "online" : void 0;
|
|
118
|
+
};
|
|
119
|
+
return {
|
|
120
|
+
title,
|
|
121
|
+
rail: [...spaces, { id: "more", label: "More", spaces: [archived] }],
|
|
122
|
+
activeSpaceId,
|
|
123
|
+
onSelectSpace: selectSpace,
|
|
124
|
+
spaceMenu: (space) => [
|
|
125
|
+
{ id: "open", label: `Show ${space.label}`, icon: space.icon, onSelect: () => selectSpace(space.id) },
|
|
126
|
+
{ id: "refresh", label: "Refresh", icon: RefreshCw, onSelect: refresh }
|
|
127
|
+
],
|
|
128
|
+
profile,
|
|
129
|
+
contacts,
|
|
130
|
+
listState: {
|
|
131
|
+
loading: inbox.isInitialLoading,
|
|
132
|
+
error: inbox.loadError,
|
|
133
|
+
retry: inbox.retry,
|
|
134
|
+
hasMore: inbox.hasMore,
|
|
135
|
+
loadMore: inbox.loadMore,
|
|
136
|
+
emptyLabel: activeSpaceId === SPACE_ARCHIVED ? "No archived chats" : "No chats yet"
|
|
137
|
+
},
|
|
138
|
+
filters,
|
|
139
|
+
activeContactId: activeId,
|
|
140
|
+
onSelectContact: (id) => inbox.select(asConversationId(id)),
|
|
141
|
+
contactMenu: (contact) => conversationMenu(contact, true),
|
|
142
|
+
listMenu: () => {
|
|
143
|
+
const entries = [];
|
|
144
|
+
if (onNewConversation) entries.push({ id: "new", label: "New chat", icon: Plus, onSelect: onNewConversation });
|
|
145
|
+
entries.push(
|
|
146
|
+
activeSpaceId === SPACE_ARCHIVED ? { id: "unarchived", label: "Back to chats", icon: MessageCircle, onSelect: () => selectSpace(SPACE_ALL) } : { id: "archived", label: "Archived chats", icon: Archive, onSelect: () => selectSpace(SPACE_ARCHIVED) },
|
|
147
|
+
{ id: "refresh", label: "Refresh", icon: RefreshCw, onSelect: refresh }
|
|
148
|
+
);
|
|
149
|
+
return entries;
|
|
150
|
+
},
|
|
151
|
+
onNew: onNewConversation,
|
|
152
|
+
newLabel: "New chat",
|
|
153
|
+
header: (contact) => ({
|
|
154
|
+
title: contact.name,
|
|
155
|
+
subtitle: headerSubtitle(byId.get(contact.id)),
|
|
156
|
+
avatar: contact.avatar
|
|
157
|
+
}),
|
|
158
|
+
headerMenu: (contact) => conversationMenu(contact, false),
|
|
159
|
+
renderThread: (contact) => {
|
|
160
|
+
const id = asConversationId(contact.id);
|
|
161
|
+
return renderConversation ? renderConversation(id) : /* @__PURE__ */ jsx(ConversationView, { conversationId: id, showHeader: false, appearance: "messenger", className: "min-h-0 flex-1" });
|
|
162
|
+
},
|
|
163
|
+
renderDetails: (contact) => {
|
|
164
|
+
const summary = byId.get(contact.id);
|
|
165
|
+
const members = summary?.participants ?? [];
|
|
166
|
+
return /* @__PURE__ */ jsx(
|
|
167
|
+
MessengerDetails,
|
|
168
|
+
{
|
|
169
|
+
name: contact.name,
|
|
170
|
+
avatar: contact.avatar,
|
|
171
|
+
subtitle: summary?.conversation.type === "group" ? `${members.length} members` : headerSubtitle(summary),
|
|
172
|
+
tabs: [
|
|
173
|
+
{
|
|
174
|
+
id: "members",
|
|
175
|
+
label: "Members",
|
|
176
|
+
content: /* @__PURE__ */ jsx("ul", { className: "flex flex-col", children: members.map((member) => /* @__PURE__ */ jsxs("li", { className: "flex min-w-0 items-center gap-3 rounded-lg px-2 py-2", children: [
|
|
177
|
+
/* @__PURE__ */ jsx(
|
|
178
|
+
MessengerAvatar,
|
|
179
|
+
{
|
|
180
|
+
name: member.displayName,
|
|
181
|
+
avatar: member.avatarUrl ? { kind: "image", src: member.avatarUrl } : { kind: "monogram" },
|
|
182
|
+
size: "header"
|
|
183
|
+
}
|
|
184
|
+
),
|
|
185
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
186
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-[14px] text-foreground", children: member.userId === selfId ? `${member.displayName} (You)` : member.displayName }),
|
|
187
|
+
member.email ? /* @__PURE__ */ jsx("span", { className: "truncate text-[12px] text-muted-foreground", children: member.email }) : null
|
|
188
|
+
] })
|
|
189
|
+
] }, member.userId)) })
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}, [
|
|
197
|
+
host,
|
|
198
|
+
inbox,
|
|
199
|
+
selfId,
|
|
200
|
+
activeId,
|
|
201
|
+
online,
|
|
202
|
+
title,
|
|
203
|
+
profile,
|
|
204
|
+
onNewConversation,
|
|
205
|
+
pinnedConversationIds,
|
|
206
|
+
onTogglePin,
|
|
207
|
+
renderConversation,
|
|
208
|
+
conversationMenuExtras
|
|
209
|
+
]);
|
|
210
|
+
}
|
|
211
|
+
export {
|
|
212
|
+
usePeopleMessengerSource
|
|
213
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-matrx/chat",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.27",
|
|
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",
|
|
@@ -3260,6 +3260,31 @@
|
|
|
3260
3260
|
"import": "./dist/mandates/useStartMandateWorkflow.js",
|
|
3261
3261
|
"default": "./dist/mandates/useStartMandateWorkflow.js"
|
|
3262
3262
|
},
|
|
3263
|
+
"./messenger/MessengerAvatar": {
|
|
3264
|
+
"types": "./dist/messenger/MessengerAvatar.d.ts",
|
|
3265
|
+
"import": "./dist/messenger/MessengerAvatar.js",
|
|
3266
|
+
"default": "./dist/messenger/MessengerAvatar.js"
|
|
3267
|
+
},
|
|
3268
|
+
"./messenger/MessengerDetails": {
|
|
3269
|
+
"types": "./dist/messenger/MessengerDetails.d.ts",
|
|
3270
|
+
"import": "./dist/messenger/MessengerDetails.js",
|
|
3271
|
+
"default": "./dist/messenger/MessengerDetails.js"
|
|
3272
|
+
},
|
|
3273
|
+
"./messenger/MessengerShell": {
|
|
3274
|
+
"types": "./dist/messenger/MessengerShell.d.ts",
|
|
3275
|
+
"import": "./dist/messenger/MessengerShell.js",
|
|
3276
|
+
"default": "./dist/messenger/MessengerShell.js"
|
|
3277
|
+
},
|
|
3278
|
+
"./messenger/contract": {
|
|
3279
|
+
"types": "./dist/messenger/contract.d.ts",
|
|
3280
|
+
"import": "./dist/messenger/contract.js",
|
|
3281
|
+
"default": "./dist/messenger/contract.js"
|
|
3282
|
+
},
|
|
3283
|
+
"./messenger/people/usePeopleMessengerSource": {
|
|
3284
|
+
"types": "./dist/messenger/people/usePeopleMessengerSource.d.ts",
|
|
3285
|
+
"import": "./dist/messenger/people/usePeopleMessengerSource.js",
|
|
3286
|
+
"default": "./dist/messenger/people/usePeopleMessengerSource.js"
|
|
3287
|
+
},
|
|
3263
3288
|
"./next/navigation": {
|
|
3264
3289
|
"types": "./dist/next/navigation.d.ts",
|
|
3265
3290
|
"import": "./dist/next/navigation.js",
|
|
@@ -4687,19 +4712,20 @@
|
|
|
4687
4712
|
"@ai-matrx/browser-audio": "latest",
|
|
4688
4713
|
"@ai-matrx/canvas": "latest",
|
|
4689
4714
|
"@ai-matrx/content-ir": "latest",
|
|
4715
|
+
"@ai-matrx/content-ir-react": "latest",
|
|
4690
4716
|
"@ai-matrx/data": "latest",
|
|
4691
4717
|
"@ai-matrx/design-system": "latest",
|
|
4692
4718
|
"@ai-matrx/icons": "latest",
|
|
4693
4719
|
"@ai-matrx/kit": "latest",
|
|
4694
4720
|
"@ai-matrx/diff": "latest",
|
|
4721
|
+
"@ai-matrx/messaging": "latest",
|
|
4695
4722
|
"@ai-matrx/print": "latest",
|
|
4696
|
-
"@ai-matrx/media": "latest",
|
|
4697
4723
|
"@ai-matrx/realtime": "latest",
|
|
4698
4724
|
"@ai-matrx/records": "latest",
|
|
4699
4725
|
"@ai-matrx/records-ui": "latest",
|
|
4726
|
+
"@ai-matrx/rich-content": "latest",
|
|
4700
4727
|
"@ai-matrx/rich-editor": "latest",
|
|
4701
|
-
"@ai-matrx/
|
|
4702
|
-
"@ai-matrx/rich-content": "latest"
|
|
4728
|
+
"@ai-matrx/media": "latest"
|
|
4703
4729
|
},
|
|
4704
4730
|
"devDependencies": {
|
|
4705
4731
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
@@ -4818,5 +4844,5 @@
|
|
|
4818
4844
|
"check:side-effects": "node ../scripts/check-side-effects-listed.mjs . && node ../scripts/check-side-effects-listed.mjs --self-test",
|
|
4819
4845
|
"check:public-surface": "node ./scripts/sync-public-surface.mjs --check && node ./scripts/sync-public-surface.mjs --self-test"
|
|
4820
4846
|
},
|
|
4821
|
-
"gitHead": "
|
|
4847
|
+
"gitHead": "da1cefa8706b65633e000a46c417e22d410d499f"
|
|
4822
4848
|
}
|