Merge branch 'codex/tool-json-schema-dsl' into codex/canonical-tool-output
# Conflicts: # .agents/notes/implemented/feature/2026-06-30-interception-seams.md # docs/config-catalog.md # docs/cookbook/adding-a-tool.i18n.yaml # docs/cookbook/adding-a-tool.md # docs/cookbook/adding-a-tool.zh.md # docs/cordis-catalog/events.md # docs/cordis-catalog/services.md # docs/core-data-structures/tools.md # docs/event-producer-consumer.md # docs/persistence-catalog.md # examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl # examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/stdout.expected.jsonl # packages/bash/tool-bash/src/index.ts # packages/core/agent-loop/src/tool-calls.ts # packages/core/agent-loop/tests/cancel.spec.ts # packages/core/agent-loop/tests/contract-regressions.spec.ts # packages/core/agent-loop/tests/tool-calls.spec.ts # packages/core/tools/README.md # packages/core/tools/src/index.ts # packages/core/tools/tests/code-mode.spec.ts # packages/core/tools/tests/tools.spec.ts # packages/fs/tool-fs-search/tests/integration.spec.ts # packages/fs/tool-fs-search/tests/tools.spec.ts # packages/fs/tool-fs/tests/integration.spec.ts # packages/mcp/mcp-client/src/tools.ts # packages/timeout/timeout-policy/tests/timeout-policy.spec.ts # packages/web/tool-web/tests/integration.spec.ts # packages/web/tool-web/tests/tool-web.spec.ts
This commit is contained in:
@@ -105,6 +105,32 @@ describe('hooks-codex bridge', () => {
|
||||
expect(JSON.stringify(adapter.requests[1]!.messages)).toContain('keep going: address the goal')
|
||||
})
|
||||
|
||||
it('turn cancellation aborts and reaps a running UserPromptSubmit hook before idle', async () => {
|
||||
const dir = configDir()
|
||||
const pidFile = join(dir, 'pid')
|
||||
const marker = join(dir, 'started')
|
||||
const slow = script(dir, 'slow-prompt.sh', `#!/usr/bin/env bash\necho $$ > "${pidFile}"\ntouch "${marker}"\nsleep 30\n`)
|
||||
writeHooks(dir, { UserPromptSubmit: [{ hooks: [{ type: 'command', command: slow }] }] })
|
||||
|
||||
const adapter = new MockAdapter([textResponse('must not run')])
|
||||
const ctx = await harness(dir, adapter)
|
||||
const agent = ctx.agentLoop.create(SessionId('cancel-prompt-hook'), { provider: 'mock', model: 'mock' })
|
||||
agent.send([{ type: 'text', text: 'cancel the hook' }])
|
||||
await waitFor(() => existsSync(marker))
|
||||
const pid = Number(readFileSync(pidFile, 'utf8').trim())
|
||||
|
||||
const idle = agent.whenIdle()
|
||||
agent.cancel({ kind: 'user' })
|
||||
await idle
|
||||
|
||||
expect(() => process.kill(pid, 0)).toThrow()
|
||||
expect(adapter.requests).toHaveLength(0)
|
||||
expect(events(agent).findLast(event => event.type === 'turn/end')).toMatchObject({
|
||||
data: { reason: { kind: 'aborted' } },
|
||||
})
|
||||
expect(events(agent).some(event => event.type === 'hook/result' && event.data.point === 'UserPromptSubmit')).toBe(true)
|
||||
})
|
||||
|
||||
it('only the five bridge-supported Codex events are honored — a SubagentStop entry is ignored', async () => {
|
||||
const dir = configDir()
|
||||
const s = script(dir, 'x.sh', '#!/usr/bin/env bash\nexit 2\n')
|
||||
|
||||
Reference in New Issue
Block a user