Sessions: restore managed Sessions resumed before the creation listener was installed

This commit is contained in:
2026-11-04 18:37:42 +08:00
parent e96f84fe00
commit 4d00454496
3 changed files with 43 additions and 1 deletions
+19
View File
@@ -1711,6 +1711,25 @@ it('selects its own preset again for a main Session or worker a person switched
await expect(presets.select.mock.results[0]!.value).rejects.toMatchObject({ code: 'agent-preset/locked' })
})
it('restores sessions that DSH resumed while setup was running, before its creation listener existed', async () => {
const { sessionId } = await acceptedTicket()
const worker = agents.get(sessionId)!
const sessionTools = tools.get(sessionId)!
controller.create.mockClear()
// `restart()` keeps the same live agents (DSH's registry is not torn down with the plugin), exactly the state where a
// Web UI resumed this worker during setup: no new `agent/created` will arrive. Stopping the old Runtime disposes its
// registrations; clear the fixture's observations so only a restore can put them back.
sections.clear(); restricts.clear(); guards.clear()
runtime = await restart()
await runtime.ready
expect(sessionTools.has('orchestrator_report')).toBe(true)
expect(sections.get(sessionId)!.text({}).includes('dsh-superagent prompt revision')).toBe(true)
expect(restricts.get(sessionId)).toBeDefined()
// Decoration was restored in place on the already-live agent; the Session was never recreated.
expect(agents.get(sessionId)).toBe(worker)
expect(controller.create).not.toHaveBeenCalledWith(expect.objectContaining({ sessionId }))
})
it('gives a subagent of a worker only the worker\'s work tools, and none once the ticket ended', async () => {
const { ticket, sessionId } = await acceptedTicket()
// DSH creates the subagent under the standard preset, with the worker's Session as its parent.