mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(sidebar): trim working badge label and name working agents in tooltip (#1408)
Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@sprout-oss.stage.blox.sqprod.co>
This commit is contained in:
co-authored by
npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w
parent
c444e3445b
commit
697f63ddcc
@@ -193,11 +193,18 @@ describe("activeAgentTurnsStore", () => {
|
||||
|
||||
const summaries = getActiveTurnsByChannel();
|
||||
assert.deepEqual(
|
||||
summaries.map(({ channelId, agentCount }) => ({
|
||||
summaries.map(({ channelId, agentCount, agentPubkeys }) => ({
|
||||
channelId,
|
||||
agentCount,
|
||||
agentPubkeys,
|
||||
})),
|
||||
[{ channelId: "shared", agentCount: 2 }],
|
||||
[
|
||||
{
|
||||
channelId: "shared",
|
||||
agentCount: 2,
|
||||
agentPubkeys: [AGENT, AGENT_2],
|
||||
},
|
||||
],
|
||||
);
|
||||
assert.equal(
|
||||
summaries[0].anchorAt,
|
||||
|
||||
@@ -49,6 +49,8 @@ export type ActiveChannelTurnSummary = {
|
||||
channelId: string;
|
||||
anchorAt: number;
|
||||
agentCount: number;
|
||||
agentPubkeys: string[];
|
||||
agentNames?: string[];
|
||||
};
|
||||
|
||||
// Module-level state: agentPubkey → turnId → ActiveTurn
|
||||
@@ -478,6 +480,7 @@ export function getActiveTurnsByChannel(): ActiveChannelTurnSummary[] {
|
||||
channelId,
|
||||
anchorAt: summary.anchorAt,
|
||||
agentCount: summary.agentPubkeys.size,
|
||||
agentPubkeys: [...summary.agentPubkeys].sort(),
|
||||
}))
|
||||
.sort((a, b) => a.channelId.localeCompare(b.channelId));
|
||||
cachedChannelTurnSummaries = result;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
|
||||
import { resolveActiveWorkingChannelNames } from "./useActiveWorkingChannelsById.ts";
|
||||
|
||||
describe("resolveActiveWorkingChannelNames", () => {
|
||||
it("resolves active agent pubkeys to managed agent names", () => {
|
||||
const resolved = resolveActiveWorkingChannelNames(
|
||||
{
|
||||
channelId: "chan-1",
|
||||
anchorAt: 0,
|
||||
agentCount: 2,
|
||||
agentPubkeys: ["AAAA", "bbbb"],
|
||||
},
|
||||
[
|
||||
{ pubkey: "aaaa", name: "Ned" },
|
||||
{ pubkey: "BBBB", name: "Bart" },
|
||||
],
|
||||
);
|
||||
|
||||
assert.deepEqual(resolved.agentNames, ["Ned", "Bart"]);
|
||||
});
|
||||
|
||||
it("omits unresolved active agents from the resolved names", () => {
|
||||
const resolved = resolveActiveWorkingChannelNames(
|
||||
{
|
||||
channelId: "chan-1",
|
||||
anchorAt: 0,
|
||||
agentCount: 2,
|
||||
agentPubkeys: ["AAAA", "cccc"],
|
||||
},
|
||||
[{ pubkey: "aaaa", name: "Ned" }],
|
||||
);
|
||||
|
||||
assert.deepEqual(resolved.agentNames, ["Ned"]);
|
||||
});
|
||||
});
|
||||
@@ -7,6 +7,24 @@ import {
|
||||
} from "@/features/agents/activeAgentTurnsStore";
|
||||
import { useManagedAgentsQuery } from "@/features/agents/hooks";
|
||||
import { useManagedAgentObserverBridge } from "@/features/agents/observerRelayStore";
|
||||
import { normalizePubkey } from "@/shared/lib/pubkey";
|
||||
|
||||
export function resolveActiveWorkingChannelNames(
|
||||
summary: ActiveChannelTurnSummary,
|
||||
managedAgents: readonly { pubkey: string; name: string }[],
|
||||
): ActiveChannelTurnSummary {
|
||||
const namesByPubkey = new Map(
|
||||
managedAgents.map((agent) => [normalizePubkey(agent.pubkey), agent.name]),
|
||||
);
|
||||
|
||||
return {
|
||||
...summary,
|
||||
agentNames: summary.agentPubkeys.flatMap((pubkey) => {
|
||||
const name = namesByPubkey.get(normalizePubkey(pubkey));
|
||||
return name ? [name] : [];
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export function useActiveWorkingChannelsById(): ReadonlyMap<
|
||||
string,
|
||||
@@ -25,8 +43,14 @@ export function useActiveWorkingChannelsById(): ReadonlyMap<
|
||||
return React.useMemo(
|
||||
() =>
|
||||
new Map(
|
||||
activeWorkingChannels.map((summary) => [summary.channelId, summary]),
|
||||
activeWorkingChannels.map((summary) => {
|
||||
const resolvedSummary = resolveActiveWorkingChannelNames(
|
||||
summary,
|
||||
managedAgents,
|
||||
);
|
||||
return [resolvedSummary.channelId, resolvedSummary];
|
||||
}),
|
||||
),
|
||||
[activeWorkingChannels],
|
||||
[activeWorkingChannels, managedAgents],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
|
||||
import { formatWorkingTooltip } from "./SidebarSection.tsx";
|
||||
|
||||
function summary(agentNames, agentCount = agentNames.length) {
|
||||
return {
|
||||
channelId: "chan-1",
|
||||
anchorAt: 0,
|
||||
agentCount,
|
||||
agentPubkeys: Array.from(
|
||||
{ length: agentCount },
|
||||
(_, index) => `agent-${index}-pubkey`,
|
||||
),
|
||||
agentNames,
|
||||
};
|
||||
}
|
||||
|
||||
describe("formatWorkingTooltip", () => {
|
||||
it("names one known agent", () => {
|
||||
assert.equal(formatWorkingTooltip(summary(["Ned"])), "Ned working");
|
||||
});
|
||||
|
||||
it("names one known agent and counts one additional agent", () => {
|
||||
assert.equal(
|
||||
formatWorkingTooltip(summary(["Ned", "Bart"])),
|
||||
"Ned and 1 agent working",
|
||||
);
|
||||
});
|
||||
|
||||
it("names one known agent and counts multiple additional agents", () => {
|
||||
assert.equal(
|
||||
formatWorkingTooltip(summary(["Ned", "Bart", "Carl"])),
|
||||
"Ned and 2 agents working",
|
||||
);
|
||||
});
|
||||
|
||||
it("uses a singular count when all agents are unknown", () => {
|
||||
assert.equal(formatWorkingTooltip(summary([], 1)), "1 agent working");
|
||||
});
|
||||
|
||||
it("uses a plural count when all agents are unknown", () => {
|
||||
assert.equal(formatWorkingTooltip(summary([], 3)), "3 agents working");
|
||||
});
|
||||
|
||||
it("counts unknown agents with the named lead", () => {
|
||||
assert.equal(
|
||||
formatWorkingTooltip(summary(["Ned"], 3)),
|
||||
"Ned and 2 agents working",
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -99,6 +99,27 @@ function UnreadDotBadge({
|
||||
);
|
||||
}
|
||||
|
||||
function formatAgentCount(count: number) {
|
||||
return `${count} ${count === 1 ? "agent" : "agents"}`;
|
||||
}
|
||||
|
||||
export function formatWorkingTooltip(
|
||||
summary: ActiveChannelTurnSummary,
|
||||
): string {
|
||||
const leadName = summary.agentNames?.[0];
|
||||
|
||||
if (!leadName) {
|
||||
return `${formatAgentCount(summary.agentCount)} working`;
|
||||
}
|
||||
|
||||
const remainingAgentCount = summary.agentCount - 1;
|
||||
if (remainingAgentCount <= 0) {
|
||||
return `${leadName} working`;
|
||||
}
|
||||
|
||||
return `${leadName} and ${formatAgentCount(remainingAgentCount)} working`;
|
||||
}
|
||||
|
||||
function ChannelWorkingBadge({
|
||||
channelName,
|
||||
isActive,
|
||||
@@ -111,9 +132,8 @@ function ChannelWorkingBadge({
|
||||
const now = useNow(1000);
|
||||
const elapsed = formatElapsed(now - summary.anchorAt);
|
||||
const label =
|
||||
summary.agentCount > 1
|
||||
? `${summary.agentCount} working · ${elapsed}`
|
||||
: `Working · ${elapsed}`;
|
||||
summary.agentCount > 1 ? `${elapsed} (${summary.agentCount})` : elapsed;
|
||||
const title = formatWorkingTooltip(summary);
|
||||
|
||||
return (
|
||||
<span
|
||||
@@ -124,7 +144,7 @@ function ChannelWorkingBadge({
|
||||
: "bg-primary/10 text-primary",
|
||||
)}
|
||||
data-testid={`channel-working-${channelName}`}
|
||||
title={label}
|
||||
title={title}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user