test: close the per-file coverage gaps for the scoping surface
Every subject-extractor row of the invariants carrier table is exercised with a matching and a foreign-keyed carrier; the HMR re-apply seed path (sessions of agents that predate the plugin are marked started) is pinned; the scoped tool-provider disposal, plural restrict() validation, singular scopeHost absentee, tool-subagent passthrough, stale-stage drop, and disposing-parent spawn (INACTIVE_EFFECT, no orphan) each gain their test. Two genuinely defensive branches carry justified v8-ignore markers.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { Context } from 'cordis'
|
||||
import Loader from '@cordisjs/plugin-loader'
|
||||
import LlmService from '@deepseek-ai/dsh-llm'
|
||||
@@ -377,4 +377,23 @@ describe('dsh-subagent-spawn', () => {
|
||||
expect(ctx.agents.list().length).toBe(before)
|
||||
})
|
||||
})
|
||||
|
||||
it('spawning from a DISPOSING parent fails loud with no orphaned child (INACTIVE_EFFECT teaching error)', async () => {
|
||||
const { ctx } = await setup([])
|
||||
// A handle-owned parent we can dispose (config agents dispose with the loop fiber).
|
||||
const parentHandle = ctx.agents.create({
|
||||
agentId: AgentId('doomed-parent'),
|
||||
sessionId: SessionId('doomed-s'),
|
||||
agentOptions: { model: 'mock' },
|
||||
})
|
||||
await parentHandle.dispose()
|
||||
const before = ctx.agents.list().length
|
||||
expect(() => ctx.subagents.start('spawn', {
|
||||
prompt: [{ type: 'text', text: 'do X' }],
|
||||
parent: parentHandle.agent,
|
||||
})).toThrow(/inactive context/)
|
||||
// The freshly created child's disposal was initiated before the rethrow
|
||||
// (fire-and-forget — start() throws synchronously); quiescence follows.
|
||||
await vi.waitFor(() => { expect(ctx.agents.list().length).toBe(before) })
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user