mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[hooks] add non-streaming (non-stdin style) shell-only PreToolUse support (#15211)
- add `PreToolUse` hook for bash-like tool execution only at first - block shell execution before dispatch with deny-only hook behavior - introduces common.rs matcher framework for matching when hooks are run example run: ``` › run three parallel echo commands, and the second one should echo "[block-pre-tool-use]" as a test • Running the three echo commands in parallel now and I’ll report the output directly. • Running PreToolUse hook: name for demo pre tool use hook • Running PreToolUse hook: name for demo pre tool use hook • Running PreToolUse hook: name for demo pre tool use hook PreToolUse hook (completed) warning: wizard-tower PreToolUse demo inspected Bash: echo "first parallel echo" PreToolUse hook (blocked) warning: wizard-tower PreToolUse demo blocked a Bash command on purpose. feedback: PreToolUse demo blocked the command. Remove [block-pre-tool-use] to continue. PreToolUse hook (completed) warning: wizard-tower PreToolUse demo inspected Bash: echo "third parallel echo" • Ran echo "first parallel echo" └ first parallel echo • Ran echo "third parallel echo" └ third parallel echo • Three little waves went out in parallel. 1. printed first parallel echo 2. was blocked before execution because it contained the exact test string [block-pre-tool-use] 3. printed third parallel echo There was also an unrelated macOS defaults warning around the successful commands, but the echoes themselves worked fine. If you want, I can rerun the second one with a slightly modified string so it passes cleanly. ```
This commit is contained in:
committed by
GitHub
Unverified
parent
18f1a08bc9
commit
73bbb07ba8
@@ -1,6 +1,8 @@
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
|
||||
use codex_hooks::PreToolUseOutcome;
|
||||
use codex_hooks::PreToolUseRequest;
|
||||
use codex_hooks::SessionStartOutcome;
|
||||
use codex_hooks::UserPromptSubmitOutcome;
|
||||
use codex_hooks::UserPromptSubmitRequest;
|
||||
@@ -109,6 +111,36 @@ pub(crate) async fn run_pending_session_start_hooks(
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn run_pre_tool_use_hooks(
|
||||
sess: &Arc<Session>,
|
||||
turn_context: &Arc<TurnContext>,
|
||||
tool_use_id: String,
|
||||
command: String,
|
||||
) -> Option<String> {
|
||||
let request = PreToolUseRequest {
|
||||
session_id: sess.conversation_id,
|
||||
turn_id: turn_context.sub_id.clone(),
|
||||
cwd: turn_context.cwd.clone(),
|
||||
transcript_path: sess.hook_transcript_path().await,
|
||||
model: turn_context.model_info.slug.clone(),
|
||||
permission_mode: hook_permission_mode(turn_context),
|
||||
tool_name: "Bash".to_string(),
|
||||
tool_use_id,
|
||||
command,
|
||||
};
|
||||
let preview_runs = sess.hooks().preview_pre_tool_use(&request);
|
||||
emit_hook_started_events(sess, turn_context, preview_runs).await;
|
||||
|
||||
let PreToolUseOutcome {
|
||||
hook_events,
|
||||
should_block,
|
||||
block_reason,
|
||||
} = sess.hooks().run_pre_tool_use(request).await;
|
||||
emit_hook_completed_events(sess, turn_context, hook_events).await;
|
||||
|
||||
if should_block { block_reason } else { None }
|
||||
}
|
||||
|
||||
pub(crate) async fn run_user_prompt_submit_hooks(
|
||||
sess: &Arc<Session>,
|
||||
turn_context: &Arc<TurnContext>,
|
||||
|
||||
Reference in New Issue
Block a user