fix: align /agents ids with subagent targets

This commit is contained in:
Tak Hoffman
2026-03-24 16:29:49 -05:00
parent a4ccd75ff3
commit 9f4f997472
2 changed files with 94 additions and 5 deletions

View File

@@ -75,4 +75,71 @@ describe("handleSubagentsAgentsAction", () => {
expect(result.reply?.text).toContain("current worker label");
expect(result.reply?.text).not.toContain("stale worker label");
});
it("keeps /agents numbering aligned with target resolution when hidden recent rows exist", () => {
const hiddenSessionKey = "agent:main:subagent:hidden-recent";
const visibleSessionKey = "agent:main:subagent:visible-bound";
listBySessionMock.mockImplementation((sessionKey: string) =>
sessionKey === visibleSessionKey
? [
{
bindingId: "binding-visible",
targetSessionKey: visibleSessionKey,
targetKind: "subagent",
conversation: {
channel: "discord",
accountId: "default",
conversationId: "thread-visible",
},
status: "active",
boundAt: Date.now() - 20_000,
},
]
: [],
);
const result = handleSubagentsAgentsAction({
params: {
ctx: {
Provider: "discord",
Surface: "discord",
},
command: {
channel: "discord",
},
},
requesterKey: "agent:main:main",
runs: [
{
runId: "run-hidden-recent",
childSessionKey: hiddenSessionKey,
requesterSessionKey: "agent:main:main",
requesterDisplayKey: "main",
task: "hidden recent worker",
cleanup: "keep",
createdAt: Date.now() - 10_000,
startedAt: Date.now() - 10_000,
endedAt: Date.now() - 5_000,
outcome: { status: "ok" },
},
{
runId: "run-visible-bound",
childSessionKey: visibleSessionKey,
requesterSessionKey: "agent:main:main",
requesterDisplayKey: "main",
task: "visible bound worker",
cleanup: "keep",
createdAt: Date.now() - 20_000,
startedAt: Date.now() - 20_000,
endedAt: Date.now() - 15_000,
outcome: { status: "ok" },
},
],
restTokens: [],
} as never);
expect(result.reply?.text).toContain("2. visible bound worker");
expect(result.reply?.text).not.toContain("1. visible bound worker");
expect(result.reply?.text).not.toContain("hidden recent worker");
});
});

View File

@@ -3,6 +3,7 @@ import { getSessionBindingService } from "../../../infra/outbound/session-bindin
import type { CommandHandlerResult } from "../commands-types.js";
import { formatRunLabel, sortSubagentRuns } from "../subagents-utils.js";
import {
RECENT_WINDOW_MINUTES,
type SubagentsCommandContext,
resolveChannelAccountId,
resolveCommandSurfaceChannel,
@@ -46,12 +47,34 @@ export function handleSubagentsAgentsAction(ctx: SubagentsCommandContext): Comma
return resolved;
};
const visibleRuns: typeof runs = [];
const dedupedRuns: typeof runs = [];
const seenChildSessionKeys = new Set<string>();
for (const entry of sortSubagentRuns(runs)) {
if (seenChildSessionKeys.has(entry.childSessionKey)) {
continue;
}
seenChildSessionKeys.add(entry.childSessionKey);
dedupedRuns.push(entry);
}
const recentCutoff = Date.now() - RECENT_WINDOW_MINUTES * 60_000;
const numericOrder = [
...dedupedRuns.filter(
(entry) => !entry.endedAt || countPendingDescendantRuns(entry.childSessionKey) > 0,
),
...dedupedRuns.filter(
(entry) =>
entry.endedAt &&
countPendingDescendantRuns(entry.childSessionKey) === 0 &&
entry.endedAt >= recentCutoff,
),
];
const indexByChildSessionKey = new Map(
numericOrder.map((entry, idx) => [entry.childSessionKey, idx + 1] as const),
);
const visibleRuns: typeof dedupedRuns = [];
for (const entry of dedupedRuns) {
const visible =
!entry.endedAt ||
countPendingDescendantRuns(entry.childSessionKey) > 0 ||
@@ -59,7 +82,6 @@ export function handleSubagentsAgentsAction(ctx: SubagentsCommandContext): Comma
if (!visible) {
continue;
}
seenChildSessionKeys.add(entry.childSessionKey);
visibleRuns.push(entry);
}
@@ -67,7 +89,6 @@ export function handleSubagentsAgentsAction(ctx: SubagentsCommandContext): Comma
if (visibleRuns.length === 0) {
lines.push("(none)");
} else {
let index = 1;
for (const entry of visibleRuns) {
const binding = resolveSessionBindings(entry.childSessionKey)[0];
const bindingText = binding
@@ -78,8 +99,9 @@ export function handleSubagentsAgentsAction(ctx: SubagentsCommandContext): Comma
: channel === "discord" || channel === "telegram"
? "unbound"
: "bindings available on discord/telegram";
lines.push(`${index}. ${formatRunLabel(entry)} (${bindingText})`);
index += 1;
const resolvedIndex = indexByChildSessionKey.get(entry.childSessionKey);
const prefix = resolvedIndex ? `${resolvedIndex}.` : "-";
lines.push(`${prefix} ${formatRunLabel(entry)} (${bindingText})`);
}
}