feat(subagent): deliver continuable child settlement to parents
A continuable child that stopped without reporting — an error, a token ceiling, cancellation, teardown — left its parent nothing to act on. The continuation manager now delivers an unconditional settlement notice to the durable direct parent before releasing ownership, folding consumed work (foldConsumedWork supersedes findLastMessageTurnEnd) so a claimed-but-unrun prompt reads as aborted rather than completed, waking an idle parent, steering a busy one, and never waking a closing tree.
This commit is contained in:
@@ -82,6 +82,20 @@ describe('startInProcessRun', () => {
|
||||
await run.dispose()
|
||||
})
|
||||
|
||||
it('reports a prompt a pre-step rejection discarded as refusal, not completion', async () => {
|
||||
const { ctx, parent } = await setup([])
|
||||
// A UserPromptSubmit deny or a policy plugin: the child claims its prompt,
|
||||
// the rejection discards it, and the turn closes `blocked` with no step.
|
||||
ctx.on('agent/pre-step', async ({ agent: subject }, next) => {
|
||||
if (subject === parent) return next()
|
||||
return { kind: 'reject' as const }
|
||||
})
|
||||
|
||||
const run = await startInProcessRun(request(parent), {})
|
||||
await expect(run.result).resolves.toMatchObject({ stopReason: 'refusal' })
|
||||
await run.dispose()
|
||||
})
|
||||
|
||||
it('does not add a final durability checkpoint to a foreground run', async () => {
|
||||
const { ctx, parent } = await setup([textResponse('driver answer')])
|
||||
let flushes = 0
|
||||
|
||||
Reference in New Issue
Block a user