feat(subagents): archive finished children and show native names

Keep native provider sessions intact while letting users clear completed children from the track. Persist dismissed provider child IDs so history replay does not restore them.
This commit is contained in:
Mohamed Boudra
2026-07-15 00:10:30 +02:00
parent d706c4339b
commit f62359fae0
33 changed files with 518 additions and 41 deletions
@@ -73,4 +73,32 @@ describe("provider subagent protocol", () => {
}),
).toMatchObject({ payload: { subagents: [{ id: "child-1" }] } });
});
test("accepts one archive-finished operation across managed and provider children", () => {
expect(
SessionInboundMessageSchema.parse({
type: "agent.subagents.archive_finished.request",
parentAgentId: "parent-1",
requestId: "request-1",
}),
).toMatchObject({ parentAgentId: "parent-1" });
expect(
SessionOutboundMessageSchema.parse({
type: "agent.subagents.archive_finished.response",
payload: {
requestId: "request-1",
parentAgentId: "parent-1",
archivedAgentIds: ["managed-1"],
dismissedProviderSubagentIds: ["native-1"],
error: null,
},
}),
).toMatchObject({
payload: {
archivedAgentIds: ["managed-1"],
dismissedProviderSubagentIds: ["native-1"],
},
});
});
});
+21
View File
@@ -1308,6 +1308,12 @@ export const ProviderSubagentListRequestMessageSchema = z.object({
requestId: z.string(),
});
export const ArchiveFinishedSubagentsRequestMessageSchema = z.object({
type: z.literal("agent.subagents.archive_finished.request"),
parentAgentId: z.string(),
requestId: z.string(),
});
export const ProviderSubagentTimelineRequestMessageSchema = z.object({
type: z.literal("agent.provider_subagents.timeline.get.request"),
parentAgentId: z.string(),
@@ -2149,6 +2155,7 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
DaemonUpdateRequestMessageSchema,
FetchAgentTimelineRequestMessageSchema,
ProviderSubagentListRequestMessageSchema,
ArchiveFinishedSubagentsRequestMessageSchema,
ProviderSubagentTimelineRequestMessageSchema,
AgentForkContextRequestMessageSchema,
SetAgentModeRequestMessageSchema,
@@ -2431,6 +2438,8 @@ export const ServerInfoStatusPayloadSchema = z
agentForkContext: z.boolean().optional(),
// COMPAT(providerSubagents): added in v0.1.107, remove gate after 2027-01-12.
providerSubagents: z.boolean().optional(),
// COMPAT(archiveFinishedSubagents): added in v0.1.108, remove gate after 2027-01-14.
archiveFinishedSubagents: z.boolean().optional(),
// COMPAT(workspacePinning): added in v0.1.107, remove gate after 2027-01-12.
workspacePinning: z.boolean().optional(),
// COMPAT(workspaceGithubClone): added in v0.1.108, remove gate after 2027-01-13.
@@ -3066,6 +3075,17 @@ export const ProviderSubagentListResponseMessageSchema = z.object({
}),
});
export const ArchiveFinishedSubagentsResponseMessageSchema = z.object({
type: z.literal("agent.subagents.archive_finished.response"),
payload: z.object({
requestId: z.string(),
parentAgentId: z.string(),
archivedAgentIds: z.array(z.string()),
dismissedProviderSubagentIds: z.array(z.string()),
error: z.string().nullable(),
}),
});
export const ProviderSubagentTimelineResponseMessageSchema = z.object({
type: z.literal("agent.provider_subagents.timeline.get.response"),
payload: z.object({
@@ -4373,6 +4393,7 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
FetchAgentResponseMessageSchema,
FetchAgentTimelineResponseMessageSchema,
ProviderSubagentListResponseMessageSchema,
ArchiveFinishedSubagentsResponseMessageSchema,
ProviderSubagentTimelineResponseMessageSchema,
ProviderSubagentUpdateMessageSchema,
AgentForkContextResponseMessageSchema,