authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-09-05 00:19:29-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-05 00:19:29-07:00
log3bcde91f8215ec24eeffdd4abdee8fcb8a5e94f9
treeebf2617ec9c603e85aabbe1c9a8212836267efcf
parentda1bebbb11701b58ebdde5ee019f3aeef3d42b27
signature Signed by PGP key B5690EEEBB952194

refactor(client-runtime): remove unused subagent selectors (#9992)


2 files changed, 0 insertions(+), 117 deletions(-)

packages/client-runtime/src/state/subagentRuntime.test.ts-62
......@@ -5,10 +5,6 @@ import {
55 foldSubagentActivities,
66 formatSubagentModelLabel,
77 formatSubagentTokenCount,
8 isAgentAttributedToolActivity,
9 isSubagentActivityKind,
10 isTimelineBypassActivity,
11 workflowCardMembers,
128} from "./subagentRuntime.ts";
139
1410let sequence = 0;
......@@ -557,64 +553,6 @@ describe("deriveAgentPanelModel", () => {
557553 });
558554});
559555
560describe("workflowCardMembers", () => {
561 it("orders by urgency (failed, running, waiting) and reports overflow", () => {
562 const roster = fold([
563 activity("task.started", { taskId: "wf-1", taskType: "local_workflow" }),
564 ...[..."abcdefghij"].map((letter, index) =>
565 activity("task.progress", {
566 taskId: `wf-1:wf:${index}`,
567 title: `agent-${letter}`,
568 status: index === 3 ? "failed" : index < 3 ? "completed" : "running",
569 ...(index === 3 ? { error: "died" } : {}),
570 parentAgentId: "wf-1",
571 agentIndex: index,
572 phaseIndex: 0,
573 phaseTitle: "Work",
574 }),
575 ),
576 ]);
577 const model = deriveAgentPanelModel({ agents: roster });
578 const { visible, overflow } = workflowCardMembers(model.workflows[0]!, 8);
579 expect(visible).toHaveLength(8);
580 expect(overflow).toBe(2);
581 expect(visible[0]!.status).toBe("failed");
582 expect(visible.filter((agent) => agent.status === "completed").length).toBeLessThanOrEqual(2);
583 });
584});
585
586describe("timeline predicates", () => {
587 it("recognizes subagent activity kinds as fold input", () => {
588 for (const kind of [
589 "task.started",
590 "task.progress",
591 "task.updated",
592 "task.completed",
593 "tool.progress",
594 ]) {
595 expect(isSubagentActivityKind(kind)).toBe(true);
596 }
597 expect(isSubagentActivityKind("tool.completed")).toBe(false);
598 });
599
600 it("attributed tool rows are re-homed; unattributed rows stay in the timeline", () => {
601 expect(isAgentAttributedToolActivity(activity("tool.completed", { agentId: "task-1" }))).toBe(
602 true,
603 );
604 expect(isAgentAttributedToolActivity(activity("tool.completed", {}))).toBe(false);
605 expect(isAgentAttributedToolActivity(activity("tool.completed", { agentId: " " }))).toBe(
606 false,
607 );
608 });
609
610 it("timelineBypass rows never render in the parent chat", () => {
611 expect(isTimelineBypassActivity(activity("task.progress", { timelineBypass: true }))).toBe(
612 true,
613 );
614 expect(isTimelineBypassActivity(activity("task.progress", {}))).toBe(false);
615 });
616});
617
618556describe("formatSubagentTokenCount", () => {
619557 it("formats plain counters", () => {
620558 expect(formatSubagentTokenCount(950)).toBe("950");
packages/client-runtime/src/state/subagentRuntime.ts-55
......@@ -861,61 +861,6 @@ export function deriveAgentPanelModel({
861861 };
862862}
863863
864/**
865 * Members ordered by urgency for the capped inline workflow card: running and
866 * failed first, then waiting, then most recently updated.
867 */
868export function workflowCardMembers(
869 group: AgentPanelWorkflowGroup,
870 limit: number,
871): { readonly visible: ReadonlyArray<RuntimeSubagent>; readonly overflow: number } {
872 const all = [...group.phases.flatMap((phase) => phase.members), ...group.unphasedMembers];
873 const urgency = (agent: RuntimeSubagent): number => {
874 if (agent.status === "failed") return 0;
875 if (agent.status === "running") return 1;
876 if (agent.status === "waiting") return 2;
877 return 3;
878 };
879 const ordered = all
880 .slice()
881 .sort((a, b) => urgency(a) - urgency(b) || b.updatedAt.localeCompare(a.updatedAt));
882 return {
883 visible: ordered.slice(0, limit),
884 overflow: Math.max(0, ordered.length - limit),
885 };
886}
887
888/** Kinds the timeline should not render as generic rows (fold input only). */
889export function isSubagentActivityKind(kind: string): boolean {
890 return (
891 kind === "task.started" ||
892 kind === "task.progress" ||
893 kind === "task.updated" ||
894 kind === "task.completed" ||
895 kind === "tool.progress"
896 );
897}
898
899/**
900 * Quiet-timeline guarantee: tool rows attributed to an owning agent belong in
901 * the Agents surface, not the parent chat. Unattributed rows must stay.
902 */
903export function isAgentAttributedToolActivity(activity: OrchestrationThreadActivity): boolean {
904 if (typeof activity.payload !== "object" || activity.payload === null) {
905 return false;
906 }
907 const payload = activity.payload as Record<string, unknown>;
908 return typeof payload.agentId === "string" && payload.agentId.trim().length > 0;
909}
910
911/** Timeline-bypassing synthesized rows (Codex children, workflow members). */
912export function isTimelineBypassActivity(activity: OrchestrationThreadActivity): boolean {
913 if (typeof activity.payload !== "object" || activity.payload === null) {
914 return false;
915 }
916 return (activity.payload as Record<string, unknown>).timelineBypass === true;
917}
918
919864/**
920865 * Compact model chip text: strips vendor prefixes/date-or-context suffixes
921866 * ("claude-sonnet-5[1m]" → "sonnet-5[1m]", "claude-opus-4-20250514" →