opencode/packages/tui/test/util/subagent.test.ts
2026-06-30 14:27:20 -04:00

187 lines
5.6 KiB
TypeScript

import { describe, expect, test } from "bun:test"
import { foregroundSubagentCount, subagentDisplayState } from "../../src/util/subagent"
describe("foregroundSubagentCount", () => {
test("counts running subagent timeline rows before child session output is available", () => {
expect(
foregroundSubagentCount({
sessionID: "parent",
sessions: [],
messages: [
{
type: "assistant",
content: [
{ type: "tool", name: "subagent", state: { status: "running", structured: {} } },
{ type: "tool", name: "task", state: { status: "running", structured: {} } },
],
},
],
status: () => "idle",
}),
).toBe(2)
})
test("does not double-count running rows that match known child sessions", () => {
expect(
foregroundSubagentCount({
sessionID: "parent",
sessions: [{ id: "child-1", parentID: "parent", title: "Audit slow path" }],
messages: [
{
type: "assistant",
content: [
{
type: "tool",
name: "subagent",
state: { status: "running", input: { description: "Audit slow path" }, structured: {} },
},
],
},
],
status: () => "running",
}),
).toBe(1)
})
test("counts mixed timeline-only and session-only foreground subagents", () => {
expect(
foregroundSubagentCount({
sessionID: "parent",
sessions: [{ id: "child-1", parentID: "parent", title: "Known child" }],
messages: [
{
type: "assistant",
content: [
{
type: "tool",
name: "subagent",
state: { status: "running", input: { description: "New child" }, structured: {} },
},
],
},
],
status: () => "running",
}),
).toBe(2)
})
test("does not undercount duplicate descriptions when only one child session is synced", () => {
expect(
foregroundSubagentCount({
sessionID: "parent",
sessions: [{ id: "child-1", parentID: "parent", title: "Same task" }],
messages: [
{
type: "assistant",
content: [
{
type: "tool",
name: "subagent",
state: { status: "running", input: { description: "Same task" }, structured: {} },
},
{
type: "tool",
name: "subagent",
state: { status: "running", input: { description: "Same task" }, structured: {} },
},
],
},
],
status: () => "running",
}),
).toBe(2)
})
test("counts running child sessions", () => {
expect(
foregroundSubagentCount({
sessionID: "parent",
sessions: [
{ id: "child-1", parentID: "parent" },
{ id: "child-2", parentID: "parent" },
{ id: "child-3", parentID: "other" },
],
messages: [],
status: (sessionID) => (sessionID === "child-1" || sessionID === "child-3" ? "running" : "idle"),
}),
).toBe(1)
})
test("excludes running subagents already marked as backgrounded in the timeline", () => {
expect(
foregroundSubagentCount({
sessionID: "parent",
sessions: [
{ id: "child-1", parentID: "parent" },
{ id: "child-2", parentID: "parent" },
],
messages: [
{
type: "assistant",
content: [
{
type: "tool",
name: "subagent",
state: {
status: "completed",
structured: { sessionID: "child-1", background: true },
},
},
{
type: "tool",
name: "task",
state: {
status: "completed",
structured: { sessionId: "child-2", background: false },
},
},
],
},
],
status: () => "running",
}),
).toBe(1)
})
})
describe("subagentDisplayState", () => {
test("keeps a backgrounded subagent spinning while the child session is running", () => {
expect(
subagentDisplayState({
toolStatus: "completed",
metadata: { sessionID: "child", status: "running", background: true },
sessionStatus: () => "running",
}),
).toEqual({ background: true, running: true, icon: "│" })
})
test("shows a checkmark once a backgrounded child session is no longer running", () => {
expect(
subagentDisplayState({
toolStatus: "completed",
metadata: { sessionID: "child", status: "running", background: true },
sessionStatus: () => "idle",
}),
).toEqual({ background: true, running: false, icon: "✓" })
})
test("does not spin forever from stale background metadata without a child session ID", () => {
expect(
subagentDisplayState({
toolStatus: "completed",
metadata: { status: "running", background: true },
sessionStatus: () => "idle",
}),
).toEqual({ background: true, running: false, icon: "✓" })
})
test("does not show a checkmark for errored subagent rows", () => {
expect(
subagentDisplayState({
toolStatus: "error",
metadata: { background: true },
sessionStatus: () => "idle",
}),
).toEqual({ background: true, running: false, icon: "│" })
})
})