diff --git a/apps/mobile/src/lib/threadActivity.test.ts b/apps/mobile/src/lib/threadActivity.test.ts index 1cf78cc29f3f..8c1c8e237917 100644 --- a/apps/mobile/src/lib/threadActivity.test.ts +++ b/apps/mobile/src/lib/threadActivity.test.ts @@ -975,6 +975,36 @@ describe("buildThreadFeed", () => { ).toBe(true); }); + it("keeps a running subagent visible after its run settles, then folds it once it finishes", () => { + const subagent = (status: "running" | "completed") => + ({ + ...base("item-subagent", "2026-06-20T00:00:01.000Z", 1), + status, + type: "subagent", + subagentId: NodeId.make("child-agent"), + origin: "app_owned", + driver: ProviderDriverKind.make("claudeAgent"), + providerInstanceId: ProviderInstanceId.make("claudeAgent"), + childThreadId: sourceThreadId, + prompt: "Wait five minutes", + result: null, + }) satisfies OrchestrationV2TurnItem; + const present = (status: "running" | "completed") => + deriveThreadFeedPresentation( + buildThreadFeed([ + projected(userMessage(), 0), + projected(subagent(status), 1), + projected(command("2026-06-20T00:00:02.000Z"), 2), + projected(assistantMessage("2026-06-20T00:00:03.000Z"), 3), + ]), + null, + new Set(), + ).map((entry) => entry.type); + + expect(present("running")).toEqual(["message", "activity-group", "run-fold", "message"]); + expect(present("completed")).toEqual(["message", "run-fold", "message"]); + }); + it("folds settled V2 run work while keeping the terminal assistant message visible", () => { const feed = buildThreadFeed([ projected(userMessage(), 0), diff --git a/apps/mobile/src/lib/threadActivity.ts b/apps/mobile/src/lib/threadActivity.ts index 927fd59b7dec..ecd4739f299b 100644 --- a/apps/mobile/src/lib/threadActivity.ts +++ b/apps/mobile/src/lib/threadActivity.ts @@ -48,7 +48,7 @@ import type { RunAttemptId, ScheduledTaskId, } from "@t3tools/contracts"; -import { RunId, ThreadId } from "@t3tools/contracts"; +import { isOrchestrationV2WorkActive, RunId, ThreadId } from "@t3tools/contracts"; import { classifyToolActivity, collectToolFilePaths, @@ -1107,7 +1107,10 @@ function deriveThreadFeedRunFolds( (activity) => activity.prominent || activity.projectedItem.item.type === "notification" || - activity.projectedItem.item.type === "handoff", + activity.projectedItem.item.type === "handoff" || + // A subagent outlives the run that started it; its card stays reachable until it settles. + (activity.projectedItem.item.type === "subagent" && + isOrchestrationV2WorkActive(activity.projectedItem.item.status)), ) ), )