mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
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.
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import {
|
||||
buildChannelAgentSessionCandidates,
|
||||
getChannelAgentSessionAgents,
|
||||
} from "./agentSessionCandidates.ts";
|
||||
|
||||
const CHANNEL = {
|
||||
id: "channel-1",
|
||||
name: "general",
|
||||
channelType: "stream",
|
||||
visibility: "private",
|
||||
description: "",
|
||||
topic: null,
|
||||
purpose: null,
|
||||
memberCount: 0,
|
||||
memberPubkeys: [],
|
||||
lastMessageAt: null,
|
||||
archivedAt: null,
|
||||
participants: [],
|
||||
participantPubkeys: [],
|
||||
isMember: true,
|
||||
ttlSeconds: null,
|
||||
ttlDeadline: null,
|
||||
};
|
||||
|
||||
function member(overrides) {
|
||||
return {
|
||||
pubkey: "aa".repeat(32),
|
||||
role: "member",
|
||||
isAgent: false,
|
||||
joinedAt: "2024-01-01T00:00:00Z",
|
||||
displayName: "Agent",
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
test("buildChannelAgentSessionCandidates includes members marked isAgent", () => {
|
||||
const candidates = buildChannelAgentSessionCandidates({
|
||||
channelMembers: [
|
||||
member({
|
||||
pubkey: "11".repeat(32),
|
||||
role: "member",
|
||||
isAgent: true,
|
||||
displayName: "Ned",
|
||||
}),
|
||||
],
|
||||
managedAgents: [],
|
||||
relayAgents: [],
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
candidates.map((agent) => ({
|
||||
name: agent.name,
|
||||
pubkey: agent.pubkey,
|
||||
source: agent.agentSource,
|
||||
})),
|
||||
[{ name: "Ned", pubkey: "11".repeat(32), source: "member-bot" }],
|
||||
);
|
||||
});
|
||||
|
||||
test("getChannelAgentSessionAgents keeps isAgent member candidates in channel scope", () => {
|
||||
const channelMembers = [
|
||||
member({
|
||||
pubkey: "22".repeat(32),
|
||||
role: "member",
|
||||
isAgent: true,
|
||||
displayName: "Ned",
|
||||
}),
|
||||
];
|
||||
const candidates = buildChannelAgentSessionCandidates({
|
||||
channelMembers,
|
||||
managedAgents: [],
|
||||
relayAgents: [],
|
||||
});
|
||||
|
||||
const scoped = getChannelAgentSessionAgents({
|
||||
activeChannel: CHANNEL,
|
||||
activeChannelId: CHANNEL.id,
|
||||
agents: candidates,
|
||||
channelMembers,
|
||||
});
|
||||
|
||||
assert.equal(scoped.length, 1);
|
||||
assert.equal(scoped[0].pubkey, "22".repeat(32));
|
||||
});
|
||||
@@ -22,6 +22,10 @@ function relayStatusToManagedStatus(
|
||||
return status === "offline" ? "stopped" : "deployed";
|
||||
}
|
||||
|
||||
function isAgentChannelMember(member: ChannelMember) {
|
||||
return member.role === "bot" || member.isAgent;
|
||||
}
|
||||
|
||||
export function buildChannelAgentSessionCandidates({
|
||||
channelMembers,
|
||||
managedAgents,
|
||||
@@ -61,7 +65,7 @@ export function buildChannelAgentSessionCandidates({
|
||||
|
||||
for (const member of channelMembers ?? []) {
|
||||
const key = normalizePubkey(member.pubkey);
|
||||
if (member.role !== "bot" || byPubkey.has(key)) {
|
||||
if (!isAgentChannelMember(member) || byPubkey.has(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -98,7 +102,7 @@ export function getChannelAgentSessionAgents({
|
||||
const botMemberPubkeys = channelMembers
|
||||
? new Set(
|
||||
channelMembers
|
||||
.filter((member) => member.role === "bot")
|
||||
.filter(isAgentChannelMember)
|
||||
.map((member) => normalizePubkey(member.pubkey)),
|
||||
)
|
||||
: null;
|
||||
|
||||
Reference in New Issue
Block a user