Share stop hook output parsing

This commit is contained in:
Abhinav Vedmala
2026-05-14 18:09:27 -07:00
parent 41f0d70a21
commit 2ae69e629f
2 changed files with 12 additions and 48 deletions

View File

@@ -87,7 +87,6 @@ use crate::schema::PreToolUsePermissionDecisionWire;
use crate::schema::SessionStartCommandOutputWire;
use crate::schema::StopCommandOutputWire;
use crate::schema::SubagentStartCommandOutputWire;
use crate::schema::SubagentStopCommandOutputWire;
use crate::schema::UserPromptSubmitCommandOutputWire;
pub(crate) fn parse_session_start(stdout: &str) -> Option<SessionStartOutput> {
@@ -274,35 +273,11 @@ pub(crate) fn parse_user_prompt_submit(stdout: &str) -> Option<UserPromptSubmitO
})
}
pub(crate) fn parse_stop(stdout: &str) -> Option<StopOutput> {
pub(crate) fn parse_stop(stdout: &str, event_name: &str) -> Option<StopOutput> {
let wire: StopCommandOutputWire = parse_json(stdout)?;
Some(stop_output_from_parts(
"Stop",
wire.decision,
wire.reason,
wire.universal,
))
}
pub(crate) fn parse_subagent_stop(stdout: &str) -> Option<StopOutput> {
let wire: SubagentStopCommandOutputWire = parse_json(stdout)?;
Some(stop_output_from_parts(
"SubagentStop",
wire.decision,
wire.reason,
wire.universal,
))
}
fn stop_output_from_parts(
event_name: &str,
decision: Option<BlockDecisionWire>,
reason: Option<String>,
universal_wire: HookUniversalOutputWire,
) -> StopOutput {
let should_block = matches!(decision, Some(BlockDecisionWire::Block));
let should_block = matches!(wire.decision, Some(BlockDecisionWire::Block));
let invalid_block_reason = if should_block
&& match reason.as_deref() {
&& match wire.reason.as_deref() {
Some(reason) => reason.trim().is_empty(),
None => true,
} {
@@ -310,12 +285,12 @@ fn stop_output_from_parts(
} else {
None
};
StopOutput {
universal: UniversalOutput::from(universal_wire),
Some(StopOutput {
universal: UniversalOutput::from(wire.universal),
should_block: should_block && invalid_block_reason.is_none(),
reason,
reason: wire.reason,
invalid_block_reason,
}
})
}
impl From<HookUniversalOutputWire> for UniversalOutput {

View File

@@ -126,13 +126,7 @@ pub(super) fn parse_completed(
run_result: CommandRunResult,
turn_id: Option<String>,
) -> dispatcher::ParsedHandler<StopHandlerData> {
parse_stop_completed(
handler,
run_result,
turn_id,
"Stop",
output_parser::parse_stop,
)
parse_stop_completed(handler, run_result, turn_id, "Stop")
}
pub(super) fn parse_subagent_stop_completed(
@@ -140,13 +134,7 @@ pub(super) fn parse_subagent_stop_completed(
run_result: CommandRunResult,
turn_id: Option<String>,
) -> dispatcher::ParsedHandler<StopHandlerData> {
parse_stop_completed(
handler,
run_result,
turn_id,
"SubagentStop",
output_parser::parse_subagent_stop,
)
parse_stop_completed(handler, run_result, turn_id, "SubagentStop")
}
fn parse_stop_completed(
@@ -154,7 +142,6 @@ fn parse_stop_completed(
run_result: CommandRunResult,
turn_id: Option<String>,
hook_name: &str,
parse_output: fn(&str) -> Option<output_parser::StopOutput>,
) -> dispatcher::ParsedHandler<StopHandlerData> {
let invalid_json_hook_name = if hook_name == "Stop" {
"stop"
@@ -181,7 +168,9 @@ fn parse_stop_completed(
Some(0) => {
let trimmed_stdout = run_result.stdout.trim();
if trimmed_stdout.is_empty() {
} else if let Some(parsed) = parse_output(&run_result.stdout) {
} else if let Some(parsed) =
output_parser::parse_stop(&run_result.stdout, hook_name)
{
if let Some(system_message) = parsed.universal.system_message {
entries.push(HookOutputEntry {
kind: HookOutputEntryKind::Warning,