Skip to content

Commit 0851322

Browse files
tellahonpub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w
authored andcommitted
fix(agents): classify agent members for activity ingress
- Update channel activity candidate resolution to treat ChannelMember.isAgent the same as bot role membership. - Keep agent typing classification and Activity panel scoping aligned so agent typing does not fall through to the generic human typing row. - Add regression coverage for isAgent channel members being created as activity candidates and retained in channel scope.
1 parent c8d85ef commit 0851322

2 files changed

Lines changed: 93 additions & 2 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import assert from "node:assert/strict";
2+
import test from "node:test";
3+
4+
import {
5+
buildChannelAgentSessionCandidates,
6+
getChannelAgentSessionAgents,
7+
} from "./agentSessionCandidates.ts";
8+
9+
const CHANNEL = {
10+
id: "channel-1",
11+
name: "general",
12+
channelType: "stream",
13+
visibility: "private",
14+
description: "",
15+
topic: null,
16+
purpose: null,
17+
memberCount: 0,
18+
memberPubkeys: [],
19+
lastMessageAt: null,
20+
archivedAt: null,
21+
participants: [],
22+
participantPubkeys: [],
23+
isMember: true,
24+
ttlSeconds: null,
25+
ttlDeadline: null,
26+
};
27+
28+
function member(overrides) {
29+
return {
30+
pubkey: "aa".repeat(32),
31+
role: "member",
32+
isAgent: false,
33+
joinedAt: "2024-01-01T00:00:00Z",
34+
displayName: "Agent",
35+
...overrides,
36+
};
37+
}
38+
39+
test("buildChannelAgentSessionCandidates includes members marked isAgent", () => {
40+
const candidates = buildChannelAgentSessionCandidates({
41+
channelMembers: [
42+
member({
43+
pubkey: "11".repeat(32),
44+
role: "member",
45+
isAgent: true,
46+
displayName: "Ned",
47+
}),
48+
],
49+
managedAgents: [],
50+
relayAgents: [],
51+
});
52+
53+
assert.deepEqual(
54+
candidates.map((agent) => ({
55+
name: agent.name,
56+
pubkey: agent.pubkey,
57+
source: agent.agentSource,
58+
})),
59+
[{ name: "Ned", pubkey: "11".repeat(32), source: "member-bot" }],
60+
);
61+
});
62+
63+
test("getChannelAgentSessionAgents keeps isAgent member candidates in channel scope", () => {
64+
const channelMembers = [
65+
member({
66+
pubkey: "22".repeat(32),
67+
role: "member",
68+
isAgent: true,
69+
displayName: "Ned",
70+
}),
71+
];
72+
const candidates = buildChannelAgentSessionCandidates({
73+
channelMembers,
74+
managedAgents: [],
75+
relayAgents: [],
76+
});
77+
78+
const scoped = getChannelAgentSessionAgents({
79+
activeChannel: CHANNEL,
80+
activeChannelId: CHANNEL.id,
81+
agents: candidates,
82+
channelMembers,
83+
});
84+
85+
assert.equal(scoped.length, 1);
86+
assert.equal(scoped[0].pubkey, "22".repeat(32));
87+
});

desktop/src/features/channels/lib/agentSessionCandidates.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ function relayStatusToManagedStatus(
2222
return status === "offline" ? "stopped" : "deployed";
2323
}
2424

25+
function isAgentChannelMember(member: ChannelMember) {
26+
return member.role === "bot" || member.isAgent;
27+
}
28+
2529
export function buildChannelAgentSessionCandidates({
2630
channelMembers,
2731
managedAgents,
@@ -61,7 +65,7 @@ export function buildChannelAgentSessionCandidates({
6165

6266
for (const member of channelMembers ?? []) {
6367
const key = normalizePubkey(member.pubkey);
64-
if (member.role !== "bot" || byPubkey.has(key)) {
68+
if (!isAgentChannelMember(member) || byPubkey.has(key)) {
6569
continue;
6670
}
6771

@@ -98,7 +102,7 @@ export function getChannelAgentSessionAgents({
98102
const botMemberPubkeys = channelMembers
99103
? new Set(
100104
channelMembers
101-
.filter((member) => member.role === "bot")
105+
.filter(isAgentChannelMember)
102106
.map((member) => normalizePubkey(member.pubkey)),
103107
)
104108
: null;

0 commit comments

Comments
 (0)