feat(atlas): update boulder continuation injector with lineage support

Update continuation injector to work with new lineage detection.
Refine idle event handling for proper subagent session tracking
and agent mismatch detection.

🤖 Generated with assistance of OhMyOpenCode
This commit is contained in:
YeonGyu-Kim
2026-04-05 15:34:13 +09:00
parent 24ca704821
commit 91c1c32c13
3 changed files with 135 additions and 6 deletions
@@ -31,7 +31,7 @@ describe("injectBoulderContinuation", () => {
} as unknown as PluginInput
// when
await injectBoulderContinuation({
const result = await injectBoulderContinuation({
ctx,
sessionID: "ses_test_123",
planName: "test-plan",
@@ -42,6 +42,7 @@ describe("injectBoulderContinuation", () => {
})
// then
expect(result).toBe("injected")
expect(promptAsyncMock).toHaveBeenCalledTimes(1)
expect(promptAsyncMock).toHaveBeenCalledWith(
expect.objectContaining({
@@ -51,4 +52,73 @@ describe("injectBoulderContinuation", () => {
}),
)
})
test("#given background tasks are running #when injector checks again #then it reports skipped background tasks without mutating failure count", async () => {
// given
registerAgentName("atlas")
const promptAsyncMock = mock(async (_request: unknown) => undefined)
const messagesMock = mock(async () => ({ data: [] }))
const sessionState = { promptFailureCount: 2, lastContinuationInjectedAt: 123 }
const ctx = {
directory: "/tmp",
client: {
session: {
messages: messagesMock,
promptAsync: promptAsyncMock,
},
},
} as unknown as PluginInput
// when
const result = await injectBoulderContinuation({
ctx,
sessionID: "ses_test_123",
planName: "test-plan",
remaining: 1,
total: 2,
agent: "atlas",
backgroundManager: {
getTasksByParentSession: () => [{ status: "running" }],
} as unknown as Parameters<typeof injectBoulderContinuation>[0]["backgroundManager"],
sessionState,
})
// then
expect(result).toBe("skipped_background_tasks")
expect(promptAsyncMock).not.toHaveBeenCalled()
expect(sessionState.promptFailureCount).toBe(2)
expect(sessionState.lastContinuationInjectedAt).toBe(123)
})
test("#given the continuation agent is unavailable #when injector runs #then it reports skipped agent unavailable without prompting", async () => {
// given
const promptAsyncMock = mock(async (_request: unknown) => undefined)
const messagesMock = mock(async () => ({ data: [] }))
const ctx = {
directory: "/tmp",
client: {
session: {
messages: messagesMock,
promptAsync: promptAsyncMock,
},
},
} as unknown as PluginInput
// when
const result = await injectBoulderContinuation({
ctx,
sessionID: "ses_test_123",
planName: "test-plan",
remaining: 1,
total: 2,
agent: "missing-agent",
sessionState: { promptFailureCount: 0 },
})
// then
expect(result).toBe("skipped_agent_unavailable")
expect(promptAsyncMock).not.toHaveBeenCalled()
})
})