fix(vscode): hide sub-agent sessions from recents

This commit is contained in:
marius-kilocode
2026-05-21 13:51:43 +02:00
parent c03f3a016a
commit 637527d80e
5 changed files with 56 additions and 6 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---
Hide sub-agent sessions from recent session shortcuts in the extension.
@@ -9,6 +9,7 @@ import {
buildCostBreakdown,
collapseCostBreakdown,
childID,
recentSessions,
} from "../../webview-ui/src/context/session-utils"
import type { Part } from "../../webview-ui/src/types/messages"
@@ -84,6 +85,36 @@ describe("computeStatus", () => {
})
})
describe("recentSessions", () => {
const at = (day: number) => `2026-01-${String(day).padStart(2, "0")}T00:00:00.000Z`
const info = (id: string, day: number, parentID?: string | null) => ({
id,
updatedAt: at(day),
...(parentID === undefined ? {} : { parentID }),
})
it("keeps the newest root sessions after removing sub-agents", () => {
const result = recentSessions([
info("old-root", 1),
info("child", 6, "old-root"),
info("new-root", 5),
info("blank-parent", 4, ""),
info("mid-root", 3, null),
info("fourth-root", 2),
])
expect(result.map((session) => session.id)).toEqual(["new-root", "mid-root", "fourth-root"])
})
it("does not mutate the session list while sorting recents", () => {
const sessions = [info("old", 1), info("new", 3), info("mid", 2)]
recentSessions(sessions)
expect(sessions.map((session) => session.id)).toEqual(["old", "new", "mid"])
})
})
describe("calcTotalCost", () => {
it("returns 0 for empty messages", () => {
expect(calcTotalCost([])).toBe(0)
@@ -7,6 +7,8 @@
* Returns the action to take: select a session by ID, go to local, or do nothing.
*/
import { isRootSession } from "../src/context/session-utils"
/** Sentinel value for the local repo selection. */
export const LOCAL = "local" as const
@@ -20,7 +22,7 @@ export function filterUnassignedSessions<T extends SessionLike>(
local: Set<string>,
): T[] {
return [...sessions]
.filter((s) => (s.parentID === undefined || s.parentID === null) && !worktree.has(s.id) && !local.has(s.id))
.filter((s) => isRootSession(s) && !worktree.has(s.id) && !local.has(s.id))
.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
}
@@ -17,6 +17,7 @@ import { createAutoScroll } from "@kilocode/kilo-ui/hooks"
import { useSession } from "../../context/session"
import { useServer } from "../../context/server"
import { useLanguage } from "../../context/language"
import { recentSessions } from "../../context/session-utils"
import { formatRelativeDate } from "../../utils/date"
import { FeedbackDialog } from "./FeedbackDialog"
import { VscodeSessionTurn } from "./VscodeSessionTurn"
@@ -93,11 +94,7 @@ export const MessageList: Component<MessageListProps> = (props) => {
)
const isEmpty = () => turns().length === 0 && !session.loading() && !boundary()
const recent = createMemo(() =>
[...session.sessions()]
.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())
.slice(0, 3),
)
const recent = createMemo(() => recentSessions(session.sessions()))
const activeUserID = createMemo(() => getActiveUserMessageID(session.messages(), session.statusInfo()))
const queuedIDs = createMemo(() => new Set(queuedUserMessageIDs(session.messages(), session.statusInfo())))
@@ -14,6 +14,21 @@ export function snapshotProgress(part: SnapshotPart | undefined): boolean {
return (part.text ?? "").includes("Initializing snapshot")
}
type ParentSession = { parentID?: string | null }
type RecentSession = ParentSession & { updatedAt: string }
export function isRootSession(session: ParentSession): boolean {
return session.parentID === undefined || session.parentID === null
}
export function recentSessions<T extends RecentSession>(sessions: T[]): T[] {
return [...sessions]
.filter(isRootSession)
.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())
.slice(0, 3)
}
/** Minimal message shape for cost breakdown helpers. */
export type CostMessage = { id: string; role: string; cost?: number }