Support asynchronous command hooks (#37533)

## Why

Hook configurations can mark command handlers as asynchronous, but Codex previously skipped those handlers outside `SessionEnd`.

## What changed

- Run asynchronous command hooks in the background with a per-session concurrency limit, while keeping `SessionEnd` hooks synchronous.
- Prevent asynchronous hooks from blocking, stopping, rewriting, or otherwise controlling the operation that launched them.
- Deliver warnings and additional context at safe turn boundaries: inject results into an active turn after sampling, or buffer them ahead of the next user prompt when the session is idle.
- Preserve in-flight hooks across configuration reloads, scope spilled output to the thread, and abort outstanding work during session shutdown.

## Testing

Add unit and integration coverage for background scheduling, concurrency, output parsing, active and idle result delivery, configuration reloads, and shutdown cleanup.

GitOrigin-RevId: 8094552e4afe7b47b09a61bb575bb20f4e491d8d
This commit is contained in:
Abhinav authored and copyberry committed 2026-08-08 04:24:12 +00:00
1 parent 61a3dd4387
commit 6f647caa9b
29 files changed
+1514 -429

No files matched your search

+3
View File
@@ -590,6 +590,9 @@ async fn shutdown_session_runtime(sess: &Arc<Session>) {
}
let _ = sess.conversation.shutdown().await;
sess.abort_all_tasks(TurnAbortReason::Interrupted).await;
sess.hooks().shutdown().await;
sess.async_hook_results.close();
while sess.async_hook_results.try_recv().is_ok() {}
sess.services
.unified_exec_manager
.terminate_all_processes()