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:
Taylor Ho
2026-06-30 16:27:34 -07:00
committed by GitHub
co-authored by npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w
parent c444e3445b
commit 697f63ddcc
6 changed files with 151 additions and 8 deletions
@@ -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>