mirror of
https://github.com/stablyai/orca.git
synced 2026-09-30 08:03:12 +00:00
fix: cancel hook completion on title working (#4175)
This commit is contained in:
@@ -646,6 +646,36 @@ describe('agent completion coordinator', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('cancels a hook completion when title tracking observes resumed work before quiet', () => {
|
||||
const dispatchCompletion = vi.fn()
|
||||
const coordinator = createAgentCompletionCoordinator({
|
||||
paneKey: 'tab-1:leaf-1',
|
||||
getPtyId: () => 'pty-1',
|
||||
getSettings: () => null,
|
||||
inspectProcess: vi.fn(),
|
||||
dispatchCompletion,
|
||||
isLive: () => true
|
||||
})
|
||||
|
||||
coordinator.observeHookStatus({
|
||||
state: 'working',
|
||||
prompt: 'run the goal',
|
||||
agentType: 'codex'
|
||||
})
|
||||
coordinator.observeHookStatus({
|
||||
state: 'done',
|
||||
prompt: 'run the goal',
|
||||
agentType: 'codex'
|
||||
})
|
||||
expect(coordinator.hasPendingHookDoneCompletion()).toBe(true)
|
||||
|
||||
coordinator.observeTitleWorking()
|
||||
expect(coordinator.hasPendingHookDoneCompletion()).toBe(false)
|
||||
vi.advanceTimersByTime(HOOK_DONE_QUIET_MS)
|
||||
|
||||
expect(dispatchCompletion).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it.each([
|
||||
'claude',
|
||||
'codex',
|
||||
|
||||
@@ -361,6 +361,9 @@ export function createAgentCompletionCoordinator(
|
||||
}
|
||||
|
||||
function recordTitleWorking(): boolean {
|
||||
// Why: hooks can report `done` before title tracking notices the next
|
||||
// milestone. The title working signal must cancel that provisional done.
|
||||
clearPendingHookDone()
|
||||
if (
|
||||
lastCompletionSource === 'hook' &&
|
||||
Date.now() - lastCompletionAt < COMPLETION_REPLAY_GUARD_MS
|
||||
|
||||
@@ -4565,6 +4565,63 @@ describe('connectPanePty', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('restores a suppressed terminal bell when a delayed hook completion resumes via title tracking', async () => {
|
||||
const { connectPanePty } = await import('./pty-connection')
|
||||
const transport = createMockTransport('pty-hook')
|
||||
transportFactoryQueue.push(transport)
|
||||
|
||||
vi.useFakeTimers()
|
||||
const pane = createPane(1)
|
||||
const manager = createManager(1)
|
||||
const deps = createDeps()
|
||||
|
||||
connectPanePty(pane as never, manager as never, deps as never)
|
||||
|
||||
const statusHandler = createdTransportOptions[0]?.onAgentStatus as
|
||||
| ((payload: {
|
||||
state: 'working' | 'done'
|
||||
prompt: string
|
||||
agentType: 'codex'
|
||||
lastAssistantMessage?: string
|
||||
}) => void)
|
||||
| undefined
|
||||
const bellHandler = createdTransportOptions[0]?.onBell as (() => void) | undefined
|
||||
const workingHandler = createdTransportOptions[0]?.onAgentBecameWorking as
|
||||
| (() => void)
|
||||
| undefined
|
||||
if (!statusHandler || !bellHandler || !workingHandler) {
|
||||
throw new Error('Expected hook status, bell, and working handlers to be registered')
|
||||
}
|
||||
|
||||
statusHandler({
|
||||
state: 'working',
|
||||
prompt: 'finish the implementation',
|
||||
agentType: 'codex'
|
||||
})
|
||||
statusHandler({
|
||||
state: 'done',
|
||||
prompt: 'finish the implementation',
|
||||
agentType: 'codex',
|
||||
lastAssistantMessage: 'Milestone complete.'
|
||||
})
|
||||
bellHandler()
|
||||
vi.advanceTimersByTime(AGENT_TASK_COMPLETE_NOTIFICATION_GRACE_MS)
|
||||
expect(deps.dispatchNotification).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({ source: 'terminal-bell' })
|
||||
)
|
||||
|
||||
workingHandler()
|
||||
vi.advanceTimersByTime(AGENT_TASK_COMPLETE_NOTIFICATION_GRACE_MS)
|
||||
|
||||
expect(deps.dispatchNotification).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ source: 'terminal-bell' })
|
||||
)
|
||||
vi.advanceTimersByTime(AGENT_TASK_COMPLETE_NOTIFICATION_MAX_WAIT_MS)
|
||||
expect(deps.dispatchNotification).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({ source: 'agent-task-complete' })
|
||||
)
|
||||
})
|
||||
|
||||
it('restores a suppressed terminal bell when the pending agent completion is canceled', async () => {
|
||||
const { connectPanePty } = await import('./pty-connection')
|
||||
const transport = createMockTransport()
|
||||
|
||||
Reference in New Issue
Block a user